Skip to content

Commit 2b8dbb8

Browse files
committed
patch
1 parent 5be1dd7 commit 2b8dbb8

File tree

1 file changed

+62
-22
lines changed

1 file changed

+62
-22
lines changed

lib/puppet/provider/base_dsc_lite/powershell.rb

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
require 'pathname'
44
require 'json'
5+
require 'erb' # ensure ERB is available
6+
require 'puppet/pops/evaluator/deferred_resolver'
57
require_relative '../../../puppet_x/puppetlabs/dsc_lite/powershell_hash_formatter'
68

79
Puppet::Type.type(:base_dsc_lite).provide(:powershell) do
@@ -31,6 +33,8 @@
3133
Puppet (including 3.x), or to a Puppet version newer than 3.x.
3234
UPGRADE
3335

36+
# ---------- class helpers ----------
37+
3438
def self.upgrade_message
3539
Puppet.warning DSC_LITE_MODULE_PUPPET_UPGRADE_MSG unless @upgrade_warning_issued
3640
@upgrade_warning_issued = true
@@ -40,6 +44,25 @@ def self.vendored_modules_path
4044
File.expand_path(Pathname.new(__FILE__).dirname + '../../../' + 'puppet_x/dsc_resources')
4145
end
4246

47+
def self.template_path
48+
File.expand_path(Pathname.new(__FILE__).dirname)
49+
end
50+
51+
def self.format_dsc_lite(dsc_value)
52+
PuppetX::PuppetLabs::DscLite::PowerShellHashFormatter.format(dsc_value)
53+
end
54+
55+
def self.escape_quotes(text)
56+
text.gsub("'", "''")
57+
end
58+
59+
def self.redact_content(content)
60+
# Redact Sensitive unwraps that appear as "'secret' # PuppetSensitive"
61+
content.gsub(%r{= '.+' # PuppetSensitive;?(\\n)?$}, "= '[REDACTED]'")
62+
end
63+
64+
# ---------- instance helpers ----------
65+
4366
def dsc_parameters
4467
resource.parameters_with_value.select do |p|
4568
p.name.to_s.include? 'dsc_'
@@ -52,10 +75,6 @@ def dsc_property_param
5275
end
5376
end
5477

55-
def self.template_path
56-
File.expand_path(Pathname.new(__FILE__).dirname)
57-
end
58-
5978
def set_timeout
6079
resource[:dsc_timeout] ? resource[:dsc_timeout] * 1000 : 1_200_000
6180
end
@@ -65,11 +84,42 @@ def ps_manager
6584
Pwsh::Manager.instance(command(:powershell), Pwsh::Manager.powershell_args, debug: debug_output)
6685
end
6786

87+
# Minimal provider-side formatter for ERB (keeps patched templates working)
88+
def format_for_ps(value)
89+
self.class.format_dsc_lite(value)
90+
end
91+
92+
# ---- Option 1: force-resolve all Deferreds in the catalog before rendering ----
93+
def force_resolve_catalog_deferred!
94+
cat = resource&.catalog
95+
return unless cat
96+
97+
facts = Puppet.lookup(:facts) { nil }
98+
env = if cat.respond_to?(:environment_instance)
99+
cat.environment_instance
100+
else
101+
Puppet.lookup(:current_environment) { nil }
102+
end
103+
104+
begin
105+
Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(facts, cat, env, true)
106+
Puppet.debug('DSC_lite: DeferredResolver.resolve_and_replace() invoked on catalog')
107+
rescue StandardError => e
108+
Puppet.debug("DSC_lite: resolve_and_replace failed: #{e.class}: #{e.message}")
109+
end
110+
end
111+
112+
# ---------- provider operations ----------
113+
68114
def exists?
69115
timeout = set_timeout
70116
Puppet.debug "Dsc Timeout: #{timeout} milliseconds"
71117
version = Facter.value(:powershell_version)
72118
Puppet.debug "PowerShell Version: #{version}"
119+
120+
# Ensure all Deferreds (including nested) are resolved prior to ERB rendering
121+
force_resolve_catalog_deferred!
122+
73123
script_content = ps_script_content('test')
74124
Puppet.debug "\n" + self.class.redact_content(script_content)
75125

@@ -97,6 +147,10 @@ def exists?
97147
def create
98148
timeout = set_timeout
99149
Puppet.debug "Dsc Timeout: #{timeout} milliseconds"
150+
151+
# Ensure all Deferreds (including nested) are resolved prior to ERB rendering
152+
force_resolve_catalog_deferred!
153+
100154
script_content = ps_script_content('set')
101155
Puppet.debug "\n" + self.class.redact_content(script_content)
102156

@@ -138,24 +192,6 @@ def notify_reboot_pending
138192
end
139193
end
140194

141-
def self.format_dsc_lite(dsc_value)
142-
PuppetX::PuppetLabs::DscLite::PowerShellHashFormatter.format(dsc_value)
143-
end
144-
145-
def self.escape_quotes(text)
146-
text.gsub("'", "''")
147-
end
148-
149-
def self.redact_content(content)
150-
# Note that here we match after an equals to ensure we redact the value being passed, but not the key.
151-
# This means a redaction of a string not including '= ' before the string value will not redact.
152-
# Every secret unwrapped in this module will unwrap as "'secret' # PuppetSensitive" and, currently,
153-
# always inside a hash table to be passed along. This means we can (currently) expect the value to
154-
# always come after an equals sign.
155-
# Note that the line may include a semi-colon and/or a newline character after the sensitive unwrap.
156-
content.gsub(%r{= '.+' # PuppetSensitive;?(\\n)?$}, "= '[REDACTED]'")
157-
end
158-
159195
def ps_script_content(mode)
160196
self.class.ps_script_content(mode, resource, self)
161197
end
@@ -165,6 +201,10 @@ def self.ps_script_content(mode, resource, provider)
165201
@param_hash = resource
166202
template_name = resource.generic_dsc ? '/invoke_generic_dsc_resource.ps1.erb' : '/invoke_dsc_resource.ps1.erb'
167203
file = File.new(template_path + template_name, encoding: Encoding::UTF_8)
204+
205+
# Make vendored_modules_path available in ERB (used by invoke_dsc_resource.ps1.erb)
206+
vendored_modules_path = self.vendored_modules_path
207+
168208
template = ERB.new(file.read, trim_mode: '-')
169209
template.result(binding)
170210
end

0 commit comments

Comments
 (0)