Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
$script:ErrorActionPreference = 'Stop'
$script:WarningPreference = 'SilentlyContinue'

function new-pscredential
{
[CmdletBinding()]
param (
[parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
[string]$user,
[parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
[string]$password
)

$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PSCredential ($user, $secpasswd)
return $credentials
}

$response = @{
indesiredstate = $false
rebootrequired = $false
errormessage = ''
}

$invokeParams = @{
Name = '<%= resource.name %>'
ModuleName = '<%= resource.parameters[:module_name].value %>'
Method = '<%= dsc_invoke_method %>'
Property = @{
<% provider.dsc_property_param.each do |p| -%><%= format_dsc_lite(p.value) %>
<% end -%>
}
}

try{
$result = Invoke-DscResource @invokeParams
}catch{
$response.errormessage = $_.Exception.Message
return ($response | ConvertTo-Json -Compress)
}

# keep the switch for when Test passes back changed properties
switch ($invokeParams.Method) {
'Test' {
$response.indesiredstate = $result.InDesiredState
return ($response | ConvertTo-Json -Compress)
}
'Set' {
$response.indesiredstate = $true
$response.rebootrequired = $result.RebootRequired
return ($response | ConvertTo-Json -Compress)
}
}
22 changes: 21 additions & 1 deletion lib/puppet/provider/base_dsc_lite/powershell.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ def dsc_parameters
end
end

def dsc_property_param
resource.parameters_with_value.select{ |pr| pr.name == :dsc_properties }.each do |p|
p.name.to_s =~ /dsc_/
end
end

def self.template_path
File.expand_path(Pathname.new(__FILE__).dirname)
end
Expand All @@ -83,6 +89,7 @@ def exists?
version = Facter.value(:powershell_version)
Puppet.debug "PowerShell Version: #{version}"
script_content = ps_script_content('test')
require 'pry';binding.pry
Puppet.debug "\n" + script_content

fail DSC_MODULE_POWERSHELL_UPGRADE_MSG if !PuppetX::DscLite::PowerShellManager.compatible_version_of_powershell?
Expand Down Expand Up @@ -184,6 +191,15 @@ def self.format_dsc_value(dsc_value)
end
end

def self.format_dsc_lite(dsc_value)
case
when dsc_value.class.name == 'Hash'
dsc_value.collect{|k, v| format_dsc_value(k) + ' = ' + format_dsc_value(v) + ';' }.join("\n")
else
fail "unsupported type #{dsc_value.class} of value '#{dsc_value}'"
end
end

def self.escape_quotes(text)
text.gsub("'", "''")
end
Expand All @@ -195,7 +211,11 @@ def ps_script_content(mode)
def self.ps_script_content(mode, resource, provider)
dsc_invoke_method = mode
@param_hash = resource
template = ERB.new(File.new(template_path + "/invoke_dsc_resource.ps1.erb").read, nil, '-')
# TODO: double-check that 'type' is the right thing to check
template_name = resource.type == 'dsc' ?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uses the type to figure out which template to load.

'invoke_generic_dsc_resource.ps1.erb' :
'invoke_dsc_resource.ps1.erb'
template = ERB.new(File.new(template_path + "/#{template_name}").read, nil, '-')
template.result(binding)
end
end
58 changes: 58 additions & 0 deletions lib/puppet/type/dsc.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
require 'pathname'

Puppet::Type.newtype(:dsc) do
require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc'
require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers'

ensurable do
newvalue(:exists?) { provider.exists? }
newvalue(:present) { provider.create }
newvalue(:absent) { provider.destroy }
defaultto { :present }
end

newparam(:name, :namevar => true ) do
end

newparam(:module_name) do
def mof_type; 'string' end
def mof_is_embedded?; false end
desc "wakka_module_name"
isrequired
validate do |value|
unless value.kind_of?(String)
fail("Invalid value '#{value}'. Should be a string")
end
end
end

newparam(:dsc_name) do
def mof_type; 'string' end
def mof_is_embedded?; false end
desc "Name"
isrequired
validate do |value|
unless value.kind_of?(String)
fail("Invalid value '#{value}'. Should be a string")
end
end
end

newparam(:dsc_properties, :array_matching => :all) do
desc "Properties"
def mof_type; 'hash' end
def mof_is_embedded?; false end
validate do |value|
unless value.kind_of?(Array) || value.kind_of?(Hash)
fail("Invalid value '#{value}'. Should be an array of hashes or a hash")
end
end
end
end

Puppet::Type.type(:dsc).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do
confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117'))
defaultfor :operatingsystem => :windows

mk_resource_methods
end
44 changes: 44 additions & 0 deletions lib/puppet_x/puppetlabs/dsc_lite/dsc_type_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,50 @@ def self.ensure_reboot_relationship(resource, pending_relationships)

pending_relationships
end

def self.validate_MSFT_xWebBindingInformation(mof_type_map, name, value)
required = ['protocol']
allowed = ['bindinginformation','ipaddress','port','hostname','certificatethumbprint','certificatestorename','sslflags']
lowkey_hash = Hash[value.map { |k, v| [k.to_s.downcase, v] }]

missing = required - lowkey_hash.keys
unless missing.empty?
fail "#{name} is missing the following required keys: #{missing.join(',')}"
end

extraneous = lowkey_hash.keys - required - allowed
unless extraneous.empty?
fail "#{name} includes invalid keys: #{extraneous.join(',')}"
end

lowkey_hash.keys.each do |key|
if lowkey_hash[key]
validate_mof_type(mof_type_map[key], 'MSFT_xWebBindingInformation', key, lowkey_hash[key])
end
end
end

def self.validate_MSFT_xWebAuthenticationInformation(mof_type_map, name, value)
required = []
allowed = ['anonymous','basic','digest','windows']
lowkey_hash = Hash[value.map { |k, v| [k.to_s.downcase, v] }]

missing = required - lowkey_hash.keys
unless missing.empty?
fail "#{name} is missing the following required keys: #{missing.join(',')}"
end

extraneous = lowkey_hash.keys - required - allowed
unless extraneous.empty?
fail "#{name} includes invalid keys: #{extraneous.join(',')}"
end

lowkey_hash.keys.each do |key|
if lowkey_hash[key]
validate_mof_type(mof_type_map[key], 'MSFT_xWebAuthenticationInformation', key, lowkey_hash[key])
end
end
end
end
end
end