Skip to content

Commit 1f413e9

Browse files
(maint) Merge up cb7a659 to main
Generated by CI * commit 'cb7a6591ac29a6935c543d5b8970258b8c91139c': (PUP-11853) Wait for request completion before closing (packaging) Updating manpage file for 7.x (PUP-11846) Refactor marking sensitive parameters (PUP-11846) Add test for Deferred(Sensitive) file content (PUP-11846) Handle unprocessed, deferred sensitive
2 parents 37d460c + cb7a659 commit 1f413e9

File tree

4 files changed

+62
-8
lines changed

4 files changed

+62
-8
lines changed

lib/puppet/http/client.rb

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ def execute_streaming(request, options: {}, &block)
368368
apply_auth(request, basic_auth) if redirects.zero?
369369

370370
# don't call return within the `request` block
371+
close_and_sleep = nil
371372
http.request(request) do |nethttp|
372373
response = Puppet::HTTP::ResponseNetHTTP.new(request.uri, nethttp)
373374
begin
@@ -381,12 +382,14 @@ def execute_streaming(request, options: {}, &block)
381382
interval = @retry_after_handler.retry_after_interval(request, response, retries)
382383
retries += 1
383384
if interval
384-
if http.started?
385-
Puppet.debug("Closing connection for #{Puppet::HTTP::Site.from_uri(request.uri)}")
386-
http.finish
385+
close_and_sleep = proc do
386+
if http.started?
387+
Puppet.debug("Closing connection for #{Puppet::HTTP::Site.from_uri(request.uri)}")
388+
http.finish
389+
end
390+
Puppet.warning(_("Sleeping for %{interval} seconds before retrying the request") % { interval: interval })
391+
::Kernel.sleep(interval)
387392
end
388-
Puppet.warning(_("Sleeping for %{interval} seconds before retrying the request") % { interval: interval })
389-
::Kernel.sleep(interval)
390393
next
391394
end
392395
end
@@ -405,6 +408,10 @@ def execute_streaming(request, options: {}, &block)
405408

406409
done = true
407410
end
411+
ensure
412+
# If a server responded with a retry, make sure the connection is closed and then
413+
# sleep the specified time.
414+
close_and_sleep.call if close_and_sleep
408415
end
409416
end
410417

lib/puppet/pops/evaluator/deferred_resolver.rb

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ def initialize(proc)
1010
end
1111

1212
def resolve
13-
@proc.call
13+
val = @proc.call
14+
# Deferred sensitive values will be marked as such in resolve_futures()
15+
if val.is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive)
16+
val.unwrap
17+
else
18+
val
19+
end
1420
end
1521
end
1622

@@ -88,8 +94,12 @@ def resolve_futures(catalog)
8894
#
8995
if resolved.is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive)
9096
resolved = resolved.unwrap
91-
unless r.sensitive_parameters.include?(k.to_sym)
92-
r.sensitive_parameters = (r.sensitive_parameters + [k.to_sym]).freeze
97+
mark_sensitive_parameters(r, k)
98+
# If the value is a DeferredValue and it has an argument of type PSensitiveType, mark it as sensitive
99+
# The DeferredValue.resolve method will unwrap it during catalog application
100+
elsif resolved.is_a?(Puppet::Pops::Evaluator::DeferredValue)
101+
if v.arguments.any? {|arg| arg.is_a?(Puppet::Pops::Types::PSensitiveType)}
102+
mark_sensitive_parameters(r, k)
93103
end
94104
end
95105
overrides[ k ] = resolved
@@ -98,6 +108,13 @@ def resolve_futures(catalog)
98108
end
99109
end
100110

111+
def mark_sensitive_parameters(r, k)
112+
unless r.sensitive_parameters.include?(k.to_sym)
113+
r.sensitive_parameters = (r.sensitive_parameters + [k.to_sym]).freeze
114+
end
115+
end
116+
private :mark_sensitive_parameters
117+
101118
def resolve(x)
102119
if x.class == @deferred_class
103120
resolve_future(x)

spec/integration/application/apply_spec.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,5 +763,19 @@ def bogus()
763763
.and output(/Notify\[runs before file\]/).to_stdout
764764
.and output(/Validation of File.* failed: You cannot specify more than one of content, source, target/).to_stderr
765765
end
766+
767+
it "applies deferred sensitive file content" do
768+
manifest = <<~END
769+
file { '#{deferred_file}':
770+
ensure => file,
771+
content => Deferred('new', [Sensitive, "hello\n"])
772+
}
773+
END
774+
apply.command_line.args = ['-e', manifest]
775+
expect {
776+
apply.run
777+
}.to exit_with(0)
778+
.and output(/ensure: changed \[redacted\] to \[redacted\]/).to_stdout
779+
end
766780
end
767781
end

spec/integration/http/client_spec.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,22 @@
175175
end
176176
end
177177

178+
context 'ensure that retrying does not attempt to read the body after closing the connection' do
179+
let(:client) { Puppet::HTTP::Client.new(retry_limit: 1) }
180+
it 'raises a retry error instead' do
181+
response_proc = -> (req, res) {
182+
res['Retry-After'] = 1
183+
res.status = 503
184+
}
185+
186+
https_server.start_server(response_proc: response_proc) do |port|
187+
uri = URI("https://127.0.0.1:#{port}")
188+
kwargs = {headers: {'Content-Type' => 'text/plain'}, options: {ssl_context: root_context}}
189+
expect{client.post(uri, '', **kwargs)}.to raise_error(Puppet::HTTP::TooManyRetryAfters)
190+
end
191+
end
192+
end
193+
178194
context 'persistent connections' do
179195
it "detects when the server has closed the connection and reconnects" do
180196
Puppet[:http_debug] = true

0 commit comments

Comments
 (0)