Skip to content

Commit 991fd1e

Browse files
committed
Merge remote-tracking branch 'upstream/5.5.x' into 6.0.x
* upstream/5.5.x: (maint) Remove unnecessary condition (PUP-9357) Redact checks if sensitive (packaging) Updating the puppet.pot file (maint) Enable windows tests (PUP-8213) Display correct message when certname is mismatched (packaging) Updating the puppet.pot file (PUP-9076) Do not push nil on server context (maint) modify test to regex, rather than exact (maint) Clarify error on Timeout::Error exception Conflicts: lib/puppet/configurer.rb lib/puppet/network/http/connection.rb locales/puppet.pot spec/unit/configurer_spec.rb spec/unit/network/http/connection_spec.rb In 5.5.x, if the connection rescues an SSLError, then it calls `verify_certificate_identity` first before checking for validation errors. In 6.0.x, that logic was moved to Puppet::Util::SSL.handle_connection_error, so apply the same change there. About configurer, enable tests that were previously skipped on Windows, but continue skipping on JRuby. If we exhaust the server list, then it is now a hard error, so update conflicted tests.
2 parents d30a9be + c77417e commit 991fd1e

File tree

7 files changed

+81
-47
lines changed

7 files changed

+81
-47
lines changed

lib/puppet/configurer.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,13 @@ def run(options = {})
226226
# mode. We shouldn't try to do any failover in that case.
227227
if options[:catalog].nil? && do_failover
228228
server, port = find_functional_server
229+
if server.nil?
230+
raise Puppet::Error, _("Could not select a functional puppet master from server_list: '%{server_list}'") % { server_list: Puppet[:server_list] }
231+
else
232+
Puppet.debug _("Selected puppet server: %{server}:%{port}") % { server: server, port: port }
233+
report.master_used = "#{server}:#{port}"
234+
end
229235
Puppet.override(server: server, serverport: port) do
230-
if server
231-
Puppet.debug _("Selected puppet server: %{server}:%{port}") % { server: server, port: port }
232-
report.master_used = "#{server}:#{port}"
233-
else
234-
Puppet.warning _("Could not select a functional puppet server")
235-
end
236236
completed = run_internal(options)
237237
end
238238
else

lib/puppet/network/http/connection.rb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -298,12 +298,22 @@ def apply_options_to(request, options)
298298
def execute_request(connection, request)
299299
start = Time.now
300300
connection.request(request)
301-
rescue EOFError => e
301+
rescue => exception
302302
elapsed = (Time.now - start).to_f.round(3)
303-
uri = @site.addr + request.path.split('?')[0]
304-
eof = EOFError.new(_('request %{uri} interrupted after %{elapsed} seconds') % {uri: uri, elapsed: elapsed})
305-
eof.set_backtrace(e.backtrace) unless e.backtrace.empty?
306-
raise eof
303+
uri = [@site.addr, request.path.split('?')[0]].join('/')
304+
eclass = exception.class
305+
306+
err = case exception
307+
when EOFError
308+
eclass.new(_('request %{uri} interrupted after %{elapsed} seconds') % {uri: uri, elapsed: elapsed})
309+
when Timeout::Error
310+
eclass.new(_('request %{uri} timed out after %{elapsed} seconds') % {uri: uri, elapsed: elapsed})
311+
else
312+
eclass.new(_('request %{uri} failed: %{msg}') % {uri: uri, msg: exception.message})
313+
end
314+
315+
err.set_backtrace(exception.backtrace) unless exception.backtrace.empty?
316+
raise err
307317
end
308318

309319
def with_connection(site, &block)

lib/puppet/type/exec.rb

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -622,18 +622,26 @@ def current_username
622622

623623
private
624624
def set_sensitive_parameters(sensitive_parameters)
625-
# Respect sensitive commands
626-
set_one_sensitive_parameter(:command, sensitive_parameters)
627-
set_one_sensitive_parameter(:unless, sensitive_parameters)
628-
set_one_sensitive_parameter(:onlyif, sensitive_parameters)
629-
super(sensitive_parameters)
630-
end
625+
# If any are sensitive, mark all as sensitive
626+
sensitive = false
627+
parameters_to_check = [:command, :unless, :onlyif]
628+
629+
parameters_to_check.each do |p|
630+
if sensitive_parameters.include?(p)
631+
sensitive_parameters.delete(p)
632+
sensitive = true
633+
end
634+
end
631635

632-
def set_one_sensitive_parameter(parameter, sensitive_parameters)
633-
if sensitive_parameters.include?(parameter)
634-
sensitive_parameters.delete(parameter)
635-
parameter(parameter).sensitive = true
636+
if sensitive
637+
parameters_to_check.each do |p|
638+
if parameters.include?(p)
639+
parameter(p).sensitive = true
640+
end
641+
end
636642
end
643+
644+
super(sensitive_parameters)
637645
end
638646
end
639647
end

lib/puppet/util/ssl.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,7 @@ def self.handle_connection_error(error, verifier, host)
7070
# can be nil
7171
peer_cert = verifier.peer_certs.last
7272

73-
if error.message.include? "certificate verify failed"
74-
msg = error.message
75-
msg << ": [" + verifier.verify_errors.join('; ') + "]"
76-
raise Puppet::Error, msg, error.backtrace
77-
elsif peer_cert && !OpenSSL::SSL.verify_certificate_identity(peer_cert, host)
73+
if peer_cert && !OpenSSL::SSL.verify_certificate_identity(peer_cert, host)
7874
valid_certnames = [peer_cert.subject.to_s.sub(/.*=/, ''),
7975
*Puppet::SSL::Certificate.subject_alt_names_for(peer_cert)].uniq
8076
if valid_certnames.size > 1
@@ -85,6 +81,10 @@ def self.handle_connection_error(error, verifier, host)
8581

8682
msg = _("Server hostname '%{host}' did not match server certificate; %{expected_certnames}") % { host: host, expected_certnames: expected_certnames }
8783
raise Puppet::Error, msg, error.backtrace
84+
elsif !verifier.verify_errors.empty?
85+
msg = error.message
86+
msg << ": [" + verifier.verify_errors.join('; ') + "]"
87+
raise Puppet::Error, msg, error.backtrace
8888
else
8989
raise error
9090
end

spec/unit/configurer_spec.rb

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,26 +1034,25 @@ def expects_neither_new_or_cached_catalog
10341034
Puppet.settings[:server_list] = ["myserver:123"]
10351035
response = Net::HTTPInternalServerError.new(nil, 500, 'Internal Server Error')
10361036
Puppet::Network::HttpPool.stubs(:http_ssl_instance).with('myserver', '123').returns(mock('request', get: response))
1037-
@agent.stubs(:run_internal)
10381037

10391038
Puppet.expects(:debug).with("Puppet server myserver:123 is unavailable: 500 Internal Server Error")
1040-
@agent.run
1039+
expect{ @agent.run }.to raise_error(Puppet::Error, /Could not select a functional puppet master from server_list/)
10411040
end
10421041

1043-
it "should fallback to an empty server when failover fails" do
1042+
it "should error when no servers in 'server_list' are reachable" do
10441043
Puppet.settings[:server_list] = ["myserver:123"]
10451044
error = Net::HTTPError.new(400, 'dummy server communication error')
1046-
Puppet::Network::HttpPool.stubs(:http_ssl_instance).with('myserver', '123').returns(error)
1047-
@agent.stubs(:run_internal)
1045+
Puppet::Network::HttpPool.stubs(:http_ssl_instance).with('myserver', '123').returns(mock('request', get: error))
10481046

10491047
options = {}
1050-
@agent.run(options)
1048+
expect{ @agent.run(options) }.to raise_error(Puppet::Error, /Could not select a functional puppet master from server_list/)
10511049
expect(options[:report].master_used).to be_nil
10521050
end
10531051

10541052
it "should not make multiple node requets when the server is found" do
10551053
Puppet.settings[:server_list] = ["myserver:123"]
1056-
Puppet::Network::HttpPool.expects(:http_ssl_instance).once
1054+
response = Net::HTTPOK.new(nil, 200, 'OK')
1055+
Puppet::Network::HttpPool.stubs(:http_ssl_instance).with('myserver', '123').returns(mock('request', get: response))
10571056
@agent.stubs(:run_internal)
10581057

10591058
@agent.run

spec/unit/network/http/connection_spec.rb

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,27 +78,43 @@
7878
WebMock.enable!
7979
end
8080

81-
it "should provide a useful error message when one is available and certificate validation fails", :unless => Puppet::Util::Platform.windows? do
81+
it "should provide a useful error message when one is available and certificate validation fails in ruby 2.4 and up" do
8282
connection = Puppet::Network::HTTP::Connection.new(
8383
host, port,
8484
:verify => ConstantErrorValidator.new(:fails_with => 'certificate verify failed',
8585
:error_string => 'shady looking signature'))
8686

8787
expect do
8888
connection.get('request')
89-
end.to raise_error(Puppet::Error, "certificate verify failed: [shady looking signature]")
89+
end.to raise_error(Puppet::Error, /certificate verify failed: \[shady looking signature\]/)
9090
end
9191

92-
it "should provide a helpful error message when hostname was not match with server certificate", :unless => Puppet::Util::Platform.windows? || RUBY_PLATFORM == 'java' do
92+
it "should provide a helpful error message when hostname does not match server certificate before ruby 2.4", :unless => RUBY_PLATFORM == 'java' do
9393
Puppet[:confdir] = tmpdir('conf')
9494

9595
connection = Puppet::Network::HTTP::Connection.new(
9696
host, port,
9797
:verify => ConstantErrorValidator.new(
98-
:fails_with => 'hostname was not match with server certificate',
98+
:fails_with => "hostname 'myserver' does not match the server certificate",
9999
:peer_certs => [Puppet::TestCa.new.generate('not_my_server',
100100
:subject_alt_names => 'DNS:foo,DNS:bar,DNS:baz,DNS:not_my_server')[:cert]]))
101+
expect do
102+
connection.get('request')
103+
end.to raise_error(Puppet::Error) do |error|
104+
error.message =~ /\AServer hostname 'my_server' did not match server certificate; expected one of (.+)/
105+
expect($1.split(', ')).to match_array(%w[DNS:foo DNS:bar DNS:baz DNS:not_my_server not_my_server])
106+
end
107+
end
108+
109+
it "should provide a helpful error message when hostname does not match server certificate in ruby 2.4 or greater" do
110+
Puppet[:confdir] = tmpdir('conf')
101111

112+
connection = Puppet::Network::HTTP::Connection.new(
113+
host, port,
114+
:verify => ConstantErrorValidator.new(
115+
:fails_with => "certificate verify failed",
116+
:peer_certs => [Puppet::TestCa.new.generate('not_my_server',
117+
:subject_alt_names => 'DNS:foo,DNS:bar,DNS:baz,DNS:not_my_server')[:cert]]))
102118
expect do
103119
connection.get('request')
104120
end.to raise_error(Puppet::Error) do |error|
@@ -117,7 +133,7 @@
117133
end.to raise_error(/some other message/)
118134
end
119135

120-
it "should check all peer certificates for upcoming expiration", :unless => Puppet::Util::Platform.windows? || RUBY_PLATFORM == 'java' do
136+
it "should check all peer certificates for upcoming expiration", :unless => RUBY_PLATFORM == 'java' do
121137
Puppet[:confdir] = tmpdir('conf')
122138
cert = Puppet::TestCa.new.generate('server',
123139
:subject_alt_names => 'DNS:foo,DNS:bar,DNS:baz,DNS:server')[:cert]

spec/unit/type/exec_spec.rb

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ def exec_stub(options = {})
4646
dummy = Puppet::Type.type(:exec).new(:name => @command)
4747
dummy.provider.class.any_instance.stubs(:validatecmd)
4848
dummy.provider.class.any_instance.stubs(:checkexe).returns(true)
49-
pass_status = stub('status', :exitstatus => 0)
50-
fail_status = stub('status', :exitstatus => 1)
51-
dummy.provider.class.any_instance.stubs(:run).with(:true, true).returns(['test output pass', pass_status])
52-
dummy.provider.class.any_instance.stubs(:run).with(:false, true).returns(['test output fail', fail_status])
49+
pass_status = stub('status', :exitstatus => 0, :split => ["pass output"])
50+
fail_status = stub('status', :exitstatus => 1, :split => ["fail output"])
51+
Puppet::Util::Execution.stubs(:execute).with(:true, anything).returns(pass_status)
52+
Puppet::Util::Execution.stubs(:execute).with(:false, anything).returns(fail_status)
5353

5454
test = Puppet::Type.type(:exec).new(type_args)
5555

@@ -212,12 +212,13 @@ def exec_stub(options = {})
212212
expect(@logs).to include(an_object_having_attributes(level: :debug, message: output))
213213
end
214214

215-
it "should log a message with a redacted command if command or #{check} is sensitive" do
216-
output = "'[command redacted]' won't be executed because of failed check '#{check}'"
217-
test = exec_stub({:command => @command, check => result, :sensitive_parameters => [:command, check]})
215+
it "should log a message with a redacted command and check if #{check} is sensitive" do
216+
output1 = "Executing check '[redacted]'"
217+
output2 = "'[command redacted]' won't be executed because of failed check '#{check}'"
218+
test = exec_stub({:command => @command, check => result, :sensitive_parameters => [check]})
218219
expect(test.check_all_attributes).to eq(false)
219-
220-
expect(@logs).to include(an_object_having_attributes(level: :debug, message: output))
220+
expect(@logs).to include(an_object_having_attributes(level: :debug, message: output1))
221+
expect(@logs).to include(an_object_having_attributes(level: :debug, message: output2))
221222
end
222223
end
223224
end

0 commit comments

Comments
 (0)