diff --git a/lib/puppet/pops/evaluator/deferred_resolver.rb b/lib/puppet/pops/evaluator/deferred_resolver.rb index 8bcc89237df..c36b3697cc0 100644 --- a/lib/puppet/pops/evaluator/deferred_resolver.rb +++ b/lib/puppet/pops/evaluator/deferred_resolver.rb @@ -9,7 +9,13 @@ def initialize(proc) end def resolve - @proc.call + val = @proc.call + # Deferred sensitive values will be marked as such in resolve_futures() + if val.is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive) + val.unwrap + else + val + end end end @@ -87,8 +93,12 @@ def resolve_futures(catalog) # if resolved.is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive) resolved = resolved.unwrap - unless r.sensitive_parameters.include?(k.to_sym) - r.sensitive_parameters = (r.sensitive_parameters + [k.to_sym]).freeze + mark_sensitive_parameters(r, k) + # If the value is a DeferredValue and it has an argument of type PSensitiveType, mark it as sensitive + # The DeferredValue.resolve method will unwrap it during catalog application + elsif resolved.is_a?(Puppet::Pops::Evaluator::DeferredValue) + if v.arguments.any? {|arg| arg.is_a?(Puppet::Pops::Types::PSensitiveType)} + mark_sensitive_parameters(r, k) end end overrides[ k ] = resolved @@ -97,6 +107,13 @@ def resolve_futures(catalog) end end + def mark_sensitive_parameters(r, k) + unless r.sensitive_parameters.include?(k.to_sym) + r.sensitive_parameters = (r.sensitive_parameters + [k.to_sym]).freeze + end + end + private :mark_sensitive_parameters + def resolve(x) if x.class == @deferred_class resolve_future(x) diff --git a/spec/integration/application/apply_spec.rb b/spec/integration/application/apply_spec.rb index 87415157a24..cedeb0ed717 100644 --- a/spec/integration/application/apply_spec.rb +++ b/spec/integration/application/apply_spec.rb @@ -755,5 +755,19 @@ def bogus() .and output(/Notify\[runs before file\]/).to_stdout .and output(/Validation of File.* failed: You cannot specify more than one of content, source, target/).to_stderr end + + it "applies deferred sensitive file content" do + manifest = <<~END + file { '#{deferred_file}': + ensure => file, + content => Deferred('new', [Sensitive, "hello\n"]) + } + END + apply.command_line.args = ['-e', manifest] + expect { + apply.run + }.to exit_with(0) + .and output(/ensure: changed \[redacted\] to \[redacted\]/).to_stdout + end end end