Skip to content

Instantly share code, notes, and snippets.

@TraGicCode
Last active December 4, 2017 10:34
Show Gist options
  • Save TraGicCode/d323bd80bd6209c9ed52ff3e3a14f7e3 to your computer and use it in GitHub Desktop.
Save TraGicCode/d323bd80bd6209c9ed52ff3e3a14f7e3 to your computer and use it in GitHub Desktop.
require_relative '../../../puppet_x/tragiccode/wsusserver_type_helpers'
Puppet::Type.type(:wsusserver_approvalrule).provide(:powershell) do
commands :powershell => 'powershell.exe'
def initialize(value = {})
super(value)
@property_flush = {}
end
# Initializes property_hash
def self.instances
get_approval_rules = <<-EOF
(Get-WsusServer).GetInstallApprovalRules() | % {
New-Object -TypeName PSObject -Property @{
name = $PSItem.Name
enabled = $PSItem.Enabled
rule_id = $PSItem.Id
}
} | ConvertTo-Json -Depth 10
EOF
output = powershell(get_approval_rules)
json_parsed_output = JSON.parse(output)
Puppet.debug("json parsed approval rules are #{json_parsed_output}")
json_parsed_output.collect do |rule|
Puppet.debug("json parsed rule is #{rule['name']} #{rule['enabled']} #{rule['rule_id']}")
new(
ensure: :present,
name: rule['name'],
enabled: rule['enabled'].to_s,
rule_id: rule['rule_id']
)
end
end
# Get all resource in catalog and associate them with
# an instance this provider found on the target system
def self.prefetch(resources)
Puppet.debug("Prefetching approval_rules")
approval_rules = instances
resources.each do |name, resource|
if provider = approval_rules.find{ |approval_rule| approval_rule.name == resource[:name] }
Puppet.debug("Assigning #{resource[:name]}, #{resource[:enabled]}");
resources[name].provider = provider
end
end
end
def exists?
Puppet.debug("Checking if #{resource[:name]} exists")
@property_hash[:ensure] == :present
end
def create
Puppet.debug("Creating #{resource[:name]}")
create_approval_rule = <<-EOF
$approval_rule = (Get-WsusServer).CreateInstallApprovalRule('#{resource[:name]}')
$approval_rule.Enabled = $#{resource[:enabled]}
$approval_rule.Save()
EOF
output = powershell(create_approval_rule)
end
def destroy
Puppet.debug("Deleting #{resource[:name]}")
delete_approval_rule = <<-EOF
$wsus_server = Get-WsusServer
$approval_rule = $wsus_server.GetInstallApprovalRules() | Where-Object { $PSItem.Name -eq '#{resource[:name]}' }
$wsus_server.DeleteInstallApprovalRule($approval_rule.Id)
EOF
output = powershell(delete_approval_rule)
end
def enabled
@property_hash[:enabled]
end
def enabled=(value)
@property_flush[:enabled] = value
end
def rule_id
@property_hash[:rule_id]
end
def read_only(value)
fail('This is a read-only property.')
end
alias :rule_id= :read_only
def should_flush_properties?
!@property_flush.empty?
end
def flush
Puppet.debug("Flushing #{resource[:name]}")
if should_flush_properties?
flush_approval_rule = "$approval_rule = (Get-WsusServer).GetInstallApprovalRules() | Where-Object { $PSItem.Name -eq '#{resource[:name]}' }"
flush_approval_rule << "\n$approval_rule.Enabled = $#{@property_flush[:enabled]}" if @property_flush[:enabled]
flush_approval_rule << "\n$approval_rule.Save()"
powershell(flush_approval_rule)
end
# Remember readonly properties are only ever shown on puppet resource query commands so this works fine!
@property_hash = resource.to_hash
end
end
Puppet::Type.newtype(:wsusserver_approvalrule) do
@doc = 'Creates an automatic approval rule for wsusserver.'
newproperty(:ensure, :parent => Puppet::Property::Ensure) do
desc 'Specifies whether the approval rule should be present or absent.'
newvalue(:present) do
provider.create
end
newvalue(:installed) do
provider.create
end
newvalue(:absent) do
provider.destroy
end
end
newparam(:name, namevar: true) do
desc 'The name of the approval rule.'
validate do |value|
# Checking for nil? does nothing since you cannot EVER set the namevar to undef, or ''. Puppet will throw
# an error before it ever gets here to your custom validation!
# Approval Rules must pass this regex: ^[^~!@#$%^&*()=+\[\]{}\\|;:'"<>\/]+$
fail('A non-empty approval rule must be specified.') if value.empty? || value.nil?
fail('The approval rule name cannot contain any of the characters certain special characeters.') if value !~ /^[^~!@#$%^&*()=+\[\]{}\\|;:\'"<>\/]+$/
end
end
newproperty(:rule_id) do
desc 'The auto-generated id of the approval rule. This property is read-only.'
end
newproperty(:enabled) do
desc 'Specifies whether the rule is enabled or disabled.'
newvalue(:true)
newvalue(:false)
munge do |value|
PuppetX::Tragiccode::TypeHelpers.munge_boolean(value)
end
end
# newproperty(:classifications, :array_matching => :all) do
# desc 'Specifies the classifications in which this rule should apply to.'
# end
# newproperty(:products, :array_matching => :all) do
# desc 'Specifies the products in which this rule should apply to.'
# end
# newproperty(:computer_groups, :array_matching => :all) do
# desc 'Specifies the computer groups in which this rule should apply to.'
# end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment