puppet 8.0.1-universal-darwin → 8.2.0-universal-darwin
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CODEOWNERS +5 -5
- data/Gemfile.lock +47 -39
- data/ext/project_data.yaml +1 -1
- data/lib/puppet/defaults.rb +37 -7
- data/lib/puppet/http/client.rb +12 -5
- data/lib/puppet/http/service/ca.rb +32 -2
- data/lib/puppet/node/environment.rb +6 -4
- data/lib/puppet/pops/evaluator/deferred_resolver.rb +20 -3
- data/lib/puppet/ssl/oids.rb +2 -0
- data/lib/puppet/ssl/ssl_provider.rb +1 -1
- data/lib/puppet/ssl/state_machine.rb +143 -14
- data/lib/puppet/thread_local.rb +1 -4
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet/x509/cert_provider.rb +29 -0
- data/locales/puppet.pot +2346 -2310
- data/man/man5/puppet.conf.5 +31 -3
- data/man/man8/puppet-agent.8 +1 -1
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +1 -1
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +1 -1
- data/man/man8/puppet-filebucket.8 +1 -1
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- data/man/man8/puppet-lookup.8 +1 -1
- data/man/man8/puppet-module.8 +1 -1
- data/man/man8/puppet-node.8 +1 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +1 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-script.8 +1 -1
- data/man/man8/puppet-ssl.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/ssl/127.0.0.1-key.pem +107 -107
- data/spec/fixtures/ssl/127.0.0.1.pem +52 -51
- data/spec/fixtures/ssl/bad-basic-constraints.pem +56 -56
- data/spec/fixtures/ssl/bad-int-basic-constraints.pem +53 -53
- data/spec/fixtures/ssl/ca.pem +54 -54
- data/spec/fixtures/ssl/crl.pem +26 -26
- data/spec/fixtures/ssl/ec-key.pem +11 -11
- data/spec/fixtures/ssl/ec.pem +33 -32
- data/spec/fixtures/ssl/encrypted-ec-key.pem +12 -12
- data/spec/fixtures/ssl/encrypted-key.pem +108 -108
- data/spec/fixtures/ssl/intermediate-agent-crl.pem +26 -26
- data/spec/fixtures/ssl/intermediate-agent.pem +56 -56
- data/spec/fixtures/ssl/intermediate-crl.pem +29 -29
- data/spec/fixtures/ssl/intermediate.pem +53 -53
- data/spec/fixtures/ssl/oid-key.pem +107 -107
- data/spec/fixtures/ssl/oid.pem +51 -50
- data/spec/fixtures/ssl/pluto-key.pem +107 -107
- data/spec/fixtures/ssl/pluto.pem +52 -51
- data/spec/fixtures/ssl/renewed.pem +67 -0
- data/spec/fixtures/ssl/request-key.pem +107 -107
- data/spec/fixtures/ssl/request.pem +50 -48
- data/spec/fixtures/ssl/revoked-key.pem +107 -107
- data/spec/fixtures/ssl/revoked.pem +51 -50
- data/spec/fixtures/ssl/signed-key.pem +107 -107
- data/spec/fixtures/ssl/signed.pem +49 -48
- data/spec/fixtures/ssl/tampered-cert.pem +51 -50
- data/spec/fixtures/ssl/tampered-csr.pem +50 -48
- data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +107 -107
- data/spec/fixtures/ssl/unknown-127.0.0.1.pem +50 -49
- data/spec/fixtures/ssl/unknown-ca-key.pem +107 -107
- data/spec/fixtures/ssl/unknown-ca.pem +54 -54
- data/spec/integration/application/agent_spec.rb +63 -13
- data/spec/integration/application/apply_spec.rb +14 -0
- data/spec/integration/http/client_spec.rb +16 -0
- data/spec/lib/puppet/test_ca.rb +3 -10
- data/spec/unit/application/lookup_spec.rb +1 -0
- data/spec/unit/defaults_spec.rb +2 -40
- data/spec/unit/file_system/path_pattern_spec.rb +15 -0
- data/spec/unit/http/service/ca_spec.rb +83 -0
- data/spec/unit/ssl/ssl_provider_spec.rb +20 -0
- data/spec/unit/ssl/state_machine_spec.rb +143 -3
- data/spec/unit/x509/cert_provider_spec.rb +49 -0
- data/tasks/generate_cert_fixtures.rake +4 -0
- metadata +5 -9
data/spec/unit/defaults_spec.rb
CHANGED
@@ -3,46 +3,8 @@ require 'puppet/settings'
|
|
3
3
|
|
4
4
|
describe "Defaults" do
|
5
5
|
describe ".default_diffargs" do
|
6
|
-
|
7
|
-
|
8
|
-
allow(Facter).to receive(:value).with(:kernel).and_return("AIX")
|
9
|
-
end
|
10
|
-
|
11
|
-
describe "on 5.3" do
|
12
|
-
before(:each) do
|
13
|
-
allow(Facter).to receive(:value).with(:kernelmajversion).and_return("5300")
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should be empty" do
|
17
|
-
expect(Puppet.default_diffargs).to eq("")
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
[ "",
|
22
|
-
nil,
|
23
|
-
"6300",
|
24
|
-
"7300",
|
25
|
-
].each do |kernel_version|
|
26
|
-
describe "on kernel version #{kernel_version.inspect}" do
|
27
|
-
before(:each) do
|
28
|
-
allow(Facter).to receive(:value).with(:kernelmajversion).and_return(kernel_version)
|
29
|
-
end
|
30
|
-
|
31
|
-
it "should be '-u'" do
|
32
|
-
expect(Puppet.default_diffargs).to eq("-u")
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
describe "on everything else" do
|
39
|
-
before(:each) do
|
40
|
-
allow(Facter).to receive(:value).with(:kernel).and_return("NOT_AIX")
|
41
|
-
end
|
42
|
-
|
43
|
-
it "should be '-u'" do
|
44
|
-
expect(Puppet.default_diffargs).to eq("-u")
|
45
|
-
end
|
6
|
+
it "should be '-u'" do
|
7
|
+
expect(Puppet.default_diffargs).to eq("-u")
|
46
8
|
end
|
47
9
|
end
|
48
10
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'puppet_spec/files'
|
3
3
|
require 'puppet/file_system'
|
4
|
+
require 'puppet/util'
|
4
5
|
|
5
6
|
describe Puppet::FileSystem::PathPattern do
|
6
7
|
include PuppetSpec::Files
|
@@ -132,6 +133,20 @@ describe Puppet::FileSystem::PathPattern do
|
|
132
133
|
File.join(dir, "found_two")])
|
133
134
|
end
|
134
135
|
|
136
|
+
it 'globs wildcard patterns properly' do
|
137
|
+
# See PUP-11788 and https://github.com/jruby/jruby/issues/7836.
|
138
|
+
pending 'JRuby does not properly handle Dir.glob' if Puppet::Util::Platform.jruby?
|
139
|
+
|
140
|
+
dir = tmpdir('globtest')
|
141
|
+
create_file_in(dir, 'foo.pp')
|
142
|
+
create_file_in(dir, 'foo.pp.pp')
|
143
|
+
|
144
|
+
pattern = Puppet::FileSystem::PathPattern.absolute(File.join(dir, '**/*.pp'))
|
145
|
+
|
146
|
+
expect(pattern.glob).to match_array([File.join(dir, 'foo.pp'),
|
147
|
+
File.join(dir, 'foo.pp.pp')])
|
148
|
+
end
|
149
|
+
|
135
150
|
def create_file_in(dir, name)
|
136
151
|
File.open(File.join(dir, name), "w") { |f| f.puts "data" }
|
137
152
|
end
|
@@ -95,6 +95,18 @@ describe Puppet::HTTP::Service::Ca do
|
|
95
95
|
expect(err.response.code).to eq(404)
|
96
96
|
end
|
97
97
|
end
|
98
|
+
|
99
|
+
it 'raises a 304 response error if it is unmodified' do
|
100
|
+
stub_request(:get, url).to_return(status: [304, 'Not Modified'])
|
101
|
+
|
102
|
+
expect {
|
103
|
+
subject.get_certificate('ca', if_modified_since: Time.now)
|
104
|
+
}.to raise_error do |err|
|
105
|
+
expect(err).to be_an_instance_of(Puppet::HTTP::ResponseError)
|
106
|
+
expect(err.message).to eq("Not Modified")
|
107
|
+
expect(err.response.code).to eq(304)
|
108
|
+
end
|
109
|
+
end
|
98
110
|
end
|
99
111
|
|
100
112
|
context 'when getting CRLs' do
|
@@ -195,4 +207,75 @@ describe Puppet::HTTP::Service::Ca do
|
|
195
207
|
end
|
196
208
|
end
|
197
209
|
end
|
210
|
+
|
211
|
+
context 'when getting certificates' do
|
212
|
+
let(:cert) { cert_fixture('signed.pem') }
|
213
|
+
let(:pem) { cert.to_pem }
|
214
|
+
let(:url) { "https://www.example.com/puppet-ca/v1/certificate_renewal" }
|
215
|
+
let(:cert_context) { Puppet::SSL::SSLContext.new(client_cert: pem) }
|
216
|
+
let(:client) { Puppet::HTTP::Client.new(ssl_context: cert_context) }
|
217
|
+
let(:session) { Puppet::HTTP::Session.new(client, []) }
|
218
|
+
let(:subject) { client.create_session.route_to(:ca) }
|
219
|
+
|
220
|
+
it "gets a certificate from the 'certificate_renewal' endpoint" do
|
221
|
+
stub_request(:post, url).to_return(body: pem)
|
222
|
+
|
223
|
+
_, body = subject.post_certificate_renewal(cert_context)
|
224
|
+
expect(body).to eq(pem)
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'returns the request response' do
|
228
|
+
stub_request(:post, url).to_return(body: 'pem')
|
229
|
+
|
230
|
+
resp, _ = subject.post_certificate_renewal(cert_context)
|
231
|
+
expect(resp).to be_a(Puppet::HTTP::Response)
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'accepts text/plain responses' do
|
235
|
+
stub_request(:post, url).with(headers: {'Accept' => 'text/plain'})
|
236
|
+
|
237
|
+
subject.post_certificate_renewal(cert_context)
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'raises an ArgumentError if the SSL context does not contain a client cert' do
|
241
|
+
stub_request(:post, url)
|
242
|
+
expect { subject.post_certificate_renewal(ssl_context) }.to raise_error(ArgumentError, 'SSL context must contain a client certificate.')
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'raises response error if unsuccessful' do
|
246
|
+
stub_request(:post, url).to_return(status: [400, 'Bad Request'])
|
247
|
+
|
248
|
+
expect {
|
249
|
+
subject.post_certificate_renewal(cert_context)
|
250
|
+
}.to raise_error do |err|
|
251
|
+
expect(err).to be_an_instance_of(Puppet::HTTP::ResponseError)
|
252
|
+
expect(err.message).to eq('Bad Request')
|
253
|
+
expect(err.response.code).to eq(400)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'raises a response error if unsuccessful' do
|
258
|
+
stub_request(:post, url).to_return(status: [404, 'Not Found'])
|
259
|
+
|
260
|
+
expect {
|
261
|
+
subject.post_certificate_renewal(cert_context)
|
262
|
+
}.to raise_error do |err|
|
263
|
+
expect(err).to be_an_instance_of(Puppet::HTTP::ResponseError)
|
264
|
+
expect(err.message).to eq("Not Found")
|
265
|
+
expect(err.response.code).to eq(404)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'raises a response error if unsuccessful' do
|
270
|
+
stub_request(:post, url).to_return(status: [404, 'Forbidden'])
|
271
|
+
|
272
|
+
expect {
|
273
|
+
subject.post_certificate_renewal(cert_context)
|
274
|
+
}.to raise_error do |err|
|
275
|
+
expect(err).to be_an_instance_of(Puppet::HTTP::ResponseError)
|
276
|
+
expect(err.message).to eq("Forbidden")
|
277
|
+
expect(err.response.code).to eq(404)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
198
281
|
end
|
@@ -634,4 +634,24 @@ describe Puppet::SSL::SSLProvider do
|
|
634
634
|
"The CSR for host 'CN=signed' does not match the public key")
|
635
635
|
end
|
636
636
|
end
|
637
|
+
|
638
|
+
context 'printing' do
|
639
|
+
let(:client_cert) { cert_fixture('signed.pem') }
|
640
|
+
let(:private_key) { key_fixture('signed-key.pem') }
|
641
|
+
let(:config) { { cacerts: global_cacerts, crls: global_crls, client_cert: client_cert, private_key: private_key } }
|
642
|
+
|
643
|
+
it 'prints in debug' do
|
644
|
+
Puppet[:log_level] = 'debug'
|
645
|
+
|
646
|
+
ctx = subject.create_context(**config)
|
647
|
+
subject.print(ctx)
|
648
|
+
expect(@logs.map(&:message)).to include(
|
649
|
+
/Verified CA certificate 'CN=Test CA' fingerprint/,
|
650
|
+
/Verified CA certificate 'CN=Test CA Subauthority' fingerprint/,
|
651
|
+
/Verified client certificate 'CN=signed' fingerprint/,
|
652
|
+
/Using CRL 'CN=Test CA' authorityKeyIdentifier '(keyid:)?[A-Z0-9:]{59}' crlNumber '0'/,
|
653
|
+
/Using CRL 'CN=Test CA Subauthority' authorityKeyIdentifier '(keyid:)?[A-Z0-9:]{59}' crlNumber '0'/
|
654
|
+
)
|
655
|
+
end
|
656
|
+
end
|
637
657
|
end
|
@@ -30,7 +30,9 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
30
30
|
Puppet[:daemonize] = false
|
31
31
|
Puppet[:ssl_lockfile] = tmpfile('ssllock')
|
32
32
|
allow(Kernel).to receive(:sleep)
|
33
|
-
|
33
|
+
future = Time.now + (5 * 60)
|
34
|
+
allow_any_instance_of(Puppet::X509::CertProvider).to receive(:crl_last_update).and_return(future)
|
35
|
+
allow_any_instance_of(Puppet::X509::CertProvider).to receive(:ca_last_update).and_return(future)
|
34
36
|
end
|
35
37
|
|
36
38
|
def expected_digest(name, content)
|
@@ -396,6 +398,16 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
396
398
|
expect(File).to_not exist(Puppet[:localcacert])
|
397
399
|
end
|
398
400
|
|
401
|
+
it 'skips CA refresh if it has not expired' do
|
402
|
+
Puppet[:ca_refresh_interval] = '1y'
|
403
|
+
Puppet::FileSystem.touch(Puppet[:localcacert], mtime: Time.now)
|
404
|
+
|
405
|
+
allow_any_instance_of(Puppet::X509::CertProvider).to receive(:load_cacerts).and_return(cacerts)
|
406
|
+
|
407
|
+
# we're expecting a net/http request to never be made
|
408
|
+
state.next_state
|
409
|
+
end
|
410
|
+
|
399
411
|
context 'when verifying CA cert bundle' do
|
400
412
|
before :each do
|
401
413
|
allow(cert_provider).to receive(:load_cacerts).and_return(nil)
|
@@ -436,6 +448,69 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
436
448
|
expect(st.message).to eq("CA bundle with digest (SHA256) #{fingerprint} did not match expected digest WR:ON:G!")
|
437
449
|
end
|
438
450
|
end
|
451
|
+
|
452
|
+
context 'when refreshing a CA bundle' do
|
453
|
+
before :each do
|
454
|
+
Puppet[:ca_refresh_interval] = '1s'
|
455
|
+
allow_any_instance_of(Puppet::X509::CertProvider).to receive(:load_cacerts).and_return(cacerts)
|
456
|
+
|
457
|
+
yesterday = Time.now - (24 * 60 * 60)
|
458
|
+
allow_any_instance_of(Puppet::X509::CertProvider).to receive(:ca_last_update).and_return(yesterday)
|
459
|
+
end
|
460
|
+
|
461
|
+
let(:new_ca_bundle) do
|
462
|
+
# add 'unknown' cert to the bundle
|
463
|
+
[cacert, cert_fixture('intermediate.pem'), cert_fixture('unknown-ca.pem')].map(&:to_pem)
|
464
|
+
end
|
465
|
+
|
466
|
+
it 'uses the local CA if it has not been modified' do
|
467
|
+
stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 304)
|
468
|
+
|
469
|
+
expect(state.next_state.ssl_context.cacerts).to eq(cacerts)
|
470
|
+
end
|
471
|
+
|
472
|
+
it 'uses the local CA if refreshing fails in HTTP layer' do
|
473
|
+
stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 503)
|
474
|
+
|
475
|
+
expect(state.next_state.ssl_context.cacerts).to eq(cacerts)
|
476
|
+
end
|
477
|
+
|
478
|
+
it 'uses the local CA if refreshing fails in TCP layer' do
|
479
|
+
stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_raise(Errno::ECONNREFUSED)
|
480
|
+
|
481
|
+
expect(state.next_state.ssl_context.cacerts).to eq(cacerts)
|
482
|
+
end
|
483
|
+
|
484
|
+
it 'uses the updated crl for the future requests' do
|
485
|
+
stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 200, body: new_ca_bundle.join)
|
486
|
+
|
487
|
+
expect(state.next_state.ssl_context.cacerts.map(&:to_pem)).to eq(new_ca_bundle)
|
488
|
+
end
|
489
|
+
|
490
|
+
it 'updates the `last_update` time on successful CA refresh' do
|
491
|
+
stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 200, body: new_ca_bundle.join)
|
492
|
+
|
493
|
+
expect_any_instance_of(Puppet::X509::CertProvider).to receive(:ca_last_update=).with(be_within(60).of(Time.now))
|
494
|
+
|
495
|
+
state.next_state
|
496
|
+
end
|
497
|
+
|
498
|
+
it "does not update the `last_update` time when CA refresh fails" do
|
499
|
+
stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_raise(Errno::ECONNREFUSED)
|
500
|
+
|
501
|
+
expect_any_instance_of(Puppet::X509::CertProvider).to receive(:ca_last_update=).never
|
502
|
+
|
503
|
+
state.next_state
|
504
|
+
end
|
505
|
+
|
506
|
+
it 'forces the NeedCRLs to refresh' do
|
507
|
+
stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 200, body: new_ca_bundle.join)
|
508
|
+
|
509
|
+
st = state.next_state
|
510
|
+
expect(st).to be_an_instance_of(Puppet::SSL::StateMachine::NeedCRLs)
|
511
|
+
expect(st.force_crl_refresh).to eq(true)
|
512
|
+
end
|
513
|
+
end
|
439
514
|
end
|
440
515
|
|
441
516
|
context 'NeedCRLs' do
|
@@ -533,6 +608,7 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
533
608
|
|
534
609
|
allow_any_instance_of(Puppet::X509::CertProvider).to receive(:load_crls).and_return(crls)
|
535
610
|
|
611
|
+
# we're expecting a net/http request to never be made
|
536
612
|
state.next_state
|
537
613
|
end
|
538
614
|
|
@@ -669,6 +745,26 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
669
745
|
state.next_state
|
670
746
|
}.to raise_error(OpenSSL::PKey::RSAError)
|
671
747
|
end
|
748
|
+
|
749
|
+
it "transitions to Done if current time plus renewal interval is less than cert's \"NotAfter\" time" do
|
750
|
+
allow(cert_provider).to receive(:load_private_key).and_return(private_key)
|
751
|
+
allow(cert_provider).to receive(:load_client_cert).and_return(client_cert)
|
752
|
+
|
753
|
+
st = state.next_state
|
754
|
+
expect(st).to be_instance_of(Puppet::SSL::StateMachine::Done)
|
755
|
+
end
|
756
|
+
|
757
|
+
it "returns NeedRenewedCert if current time plus renewal interval is greater than cert's \"NotAfter\" time" do
|
758
|
+
client_cert.not_after=(Time.now + 300)
|
759
|
+
allow(cert_provider).to receive(:load_private_key).and_return(private_key)
|
760
|
+
allow(cert_provider).to receive(:load_client_cert).and_return(client_cert)
|
761
|
+
|
762
|
+
ssl_context = Puppet::SSL::SSLContext.new(cacerts: [cacert], client_cert: client_cert, crls: [crl])
|
763
|
+
state = Puppet::SSL::StateMachine::NeedKey.new(machine, ssl_context)
|
764
|
+
|
765
|
+
st = state.next_state
|
766
|
+
expect(st).to be_instance_of(Puppet::SSL::StateMachine::NeedRenewedCert)
|
767
|
+
end
|
672
768
|
end
|
673
769
|
|
674
770
|
context 'in state NeedSubmitCSR' do
|
@@ -710,7 +806,7 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
710
806
|
state.next_state
|
711
807
|
end
|
712
808
|
|
713
|
-
it 'includes CSR attributes' do
|
809
|
+
it 'includes CSR attributes', :unless => RUBY_PLATFORM == 'java' do
|
714
810
|
Puppet[:csr_attributes] = write_csr_attributes(
|
715
811
|
'custom_attributes' => {
|
716
812
|
'1.3.6.1.4.1.34380.1.2.1' => 'CSR specific info',
|
@@ -724,7 +820,8 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
724
820
|
csr.custom_attributes
|
725
821
|
).to contain_exactly(
|
726
822
|
{'oid' => '1.3.6.1.4.1.34380.1.2.1', 'value' => 'CSR specific info'},
|
727
|
-
{'oid' => '1.3.6.1.4.1.34380.1.2.2', 'value' => 'more CSR specific info'}
|
823
|
+
{'oid' => '1.3.6.1.4.1.34380.1.2.2', 'value' => 'more CSR specific info'},
|
824
|
+
{'oid' => 'pp_auth_auto_renew', 'value' => 'true'}
|
728
825
|
)
|
729
826
|
end.to_return(status: 200)
|
730
827
|
|
@@ -973,5 +1070,48 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
973
1070
|
expect(state.next_state).to be_an_instance_of(Puppet::SSL::StateMachine::LockFailure)
|
974
1071
|
end
|
975
1072
|
end
|
1073
|
+
|
1074
|
+
context 'in state NeedRenewedCert' do
|
1075
|
+
before :each do
|
1076
|
+
client_cert.not_after=(Time.now + 300)
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
let(:ssl_context) { Puppet::SSL::SSLContext.new(cacerts: cacerts, client_cert: client_cert, crls: crls,)}
|
1080
|
+
let(:state) { Puppet::SSL::StateMachine::NeedRenewedCert.new(machine, ssl_context, private_key) }
|
1081
|
+
let(:renewed_cert) { cert_fixture('renewed.pem') }
|
1082
|
+
|
1083
|
+
it 'returns Done with renewed cert when successful' do
|
1084
|
+
allow(cert_provider).to receive(:save_client_cert)
|
1085
|
+
stub_request(:post, %r{puppet-ca/v1/certificate_renewal}).to_return(status: 200, body: renewed_cert.to_pem)
|
1086
|
+
|
1087
|
+
st = state.next_state
|
1088
|
+
expect(st).to be_an_instance_of(Puppet::SSL::StateMachine::Done)
|
1089
|
+
expect(st.ssl_context[:client_cert]).to eq(renewed_cert)
|
1090
|
+
end
|
1091
|
+
|
1092
|
+
it 'logs a warning message when failing with a non-404 status' do
|
1093
|
+
stub_request(:post, %r{puppet-ca/v1/certificate_renewal}).to_return(status: 400, body: 'Failed to automatically renew certificate: 400 Bad request')
|
1094
|
+
|
1095
|
+
expect(Puppet).to receive(:warning).with(/Failed to automatically renew certificate/)
|
1096
|
+
st = state.next_state
|
1097
|
+
expect(st).to be_an_instance_of(Puppet::SSL::StateMachine::Done)
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
it 'logs an info message when failing with 404' do
|
1101
|
+
stub_request(:post, %r{puppet-ca/v1/certificate_renewal}).to_return(status: 404, body: 'Certificate autorenewal has not been enabled on the server.')
|
1102
|
+
|
1103
|
+
expect(Puppet).to receive(:info).with('Certificate autorenewal has not been enabled on the server.')
|
1104
|
+
st = state.next_state
|
1105
|
+
expect(st).to be_an_instance_of(Puppet::SSL::StateMachine::Done)
|
1106
|
+
end
|
1107
|
+
|
1108
|
+
it 'logs a warning message when failing with no HTTP status' do
|
1109
|
+
stub_request(:post, %r{puppet-ca/v1/certificate_renewal}).to_raise(Errno::ECONNREFUSED)
|
1110
|
+
|
1111
|
+
expect(Puppet).to receive(:warning).with(/Unable to automatically renew certificate:/)
|
1112
|
+
st = state.next_state
|
1113
|
+
expect(st).to be_an_instance_of(Puppet::SSL::StateMachine::Done)
|
1114
|
+
end
|
1115
|
+
end
|
976
1116
|
end
|
977
1117
|
end
|
@@ -586,6 +586,55 @@ describe Puppet::X509::CertProvider do
|
|
586
586
|
end
|
587
587
|
end
|
588
588
|
|
589
|
+
context 'when creating', :unless => RUBY_PLATFORM == 'java' do
|
590
|
+
context 'requests' do
|
591
|
+
let(:name) { 'tom' }
|
592
|
+
let(:requestdir) { tmpdir('cert_provider') }
|
593
|
+
let(:provider) { create_provider(requestdir: requestdir) }
|
594
|
+
let(:key) { OpenSSL::PKey::RSA.new(Puppet[:keylength]) }
|
595
|
+
|
596
|
+
it 'has the auto-renew attribute by default for agents that support automatic renewal' do
|
597
|
+
csr = provider.create_request(name, key)
|
598
|
+
# need to create CertificateRequest instance from csr in order to view CSR attributes
|
599
|
+
wrapped_csr = Puppet::SSL::CertificateRequest.from_instance csr
|
600
|
+
expect(wrapped_csr.custom_attributes).to include('oid' => 'pp_auth_auto_renew', 'value' => 'true')
|
601
|
+
end
|
602
|
+
|
603
|
+
it 'does not have the auto-renew attribute for agents that do not support automatic renewal' do
|
604
|
+
Puppet[:hostcert_renewal_interval] = 0
|
605
|
+
csr = provider.create_request(name, key)
|
606
|
+
wrapped_csr = Puppet::SSL::CertificateRequest.from_instance csr
|
607
|
+
expect(wrapped_csr.custom_attributes.length).to eq(0)
|
608
|
+
end
|
609
|
+
end
|
610
|
+
end
|
611
|
+
|
612
|
+
context 'CA last update time' do
|
613
|
+
let(:ca_path) { tmpfile('pem_ca') }
|
614
|
+
|
615
|
+
it 'returns nil if the CA does not exist' do
|
616
|
+
provider = create_provider(capath: '/does/not/exist')
|
617
|
+
|
618
|
+
expect(provider.ca_last_update).to be_nil
|
619
|
+
end
|
620
|
+
|
621
|
+
it 'returns the last update time' do
|
622
|
+
time = Time.now - 30
|
623
|
+
Puppet::FileSystem.touch(ca_path, mtime: time)
|
624
|
+
provider = create_provider(capath: ca_path)
|
625
|
+
|
626
|
+
expect(provider.ca_last_update).to be_within(1).of(time)
|
627
|
+
end
|
628
|
+
|
629
|
+
it 'sets the last update time' do
|
630
|
+
time = Time.now - 30
|
631
|
+
provider = create_provider(capath: ca_path)
|
632
|
+
provider.ca_last_update = time
|
633
|
+
|
634
|
+
expect(Puppet::FileSystem.stat(ca_path).mtime).to be_within(1).of(time)
|
635
|
+
end
|
636
|
+
end
|
637
|
+
|
589
638
|
context 'CRL last update time' do
|
590
639
|
let(:crl_path) { tmpfile('pem_crls') }
|
591
640
|
|
@@ -94,6 +94,10 @@ task(:gen_cert_fixtures) do
|
|
94
94
|
save(dir, 'signed.pem', signed[:cert])
|
95
95
|
save(dir, 'signed-key.pem', signed[:private_key])
|
96
96
|
|
97
|
+
# Create a cert for host "renewed" and issued by "Test CA Subauthority"
|
98
|
+
renewed = ca.create_cert('renewed', inter[:cert], inter[:private_key], reuse_key: signed[:private_key])
|
99
|
+
save(dir, 'renewed.pem', renewed[:cert])
|
100
|
+
|
97
101
|
# Create an encrypted version of the above private key for host "signed"
|
98
102
|
save(dir, 'encrypted-key.pem', signed[:private_key]) do |x509|
|
99
103
|
# private key password was chosen at random
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.0
|
4
|
+
version: 8.2.0
|
5
5
|
platform: universal-darwin
|
6
6
|
authors:
|
7
7
|
- Puppet Labs
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: facter
|
@@ -113,9 +113,6 @@ dependencies:
|
|
113
113
|
- - "~>"
|
114
114
|
- !ruby/object:Gem::Version
|
115
115
|
version: '1.0'
|
116
|
-
- - "<"
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
version: 1.2.0
|
119
116
|
type: :runtime
|
120
117
|
prerelease: false
|
121
118
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -123,9 +120,6 @@ dependencies:
|
|
123
120
|
- - "~>"
|
124
121
|
- !ruby/object:Gem::Version
|
125
122
|
version: '1.0'
|
126
|
-
- - "<"
|
127
|
-
- !ruby/object:Gem::Version
|
128
|
-
version: 1.2.0
|
129
123
|
- !ruby/object:Gem::Dependency
|
130
124
|
name: deep_merge
|
131
125
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1346,6 +1340,7 @@ files:
|
|
1346
1340
|
- spec/fixtures/ssl/oid.pem
|
1347
1341
|
- spec/fixtures/ssl/pluto-key.pem
|
1348
1342
|
- spec/fixtures/ssl/pluto.pem
|
1343
|
+
- spec/fixtures/ssl/renewed.pem
|
1349
1344
|
- spec/fixtures/ssl/request-key.pem
|
1350
1345
|
- spec/fixtures/ssl/request.pem
|
1351
1346
|
- spec/fixtures/ssl/revoked-key.pem
|
@@ -2537,7 +2532,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
2537
2532
|
- !ruby/object:Gem::Version
|
2538
2533
|
version: 1.3.1
|
2539
2534
|
requirements: []
|
2540
|
-
rubygems_version: 3.
|
2535
|
+
rubygems_version: 3.4.12
|
2541
2536
|
signing_key:
|
2542
2537
|
specification_version: 4
|
2543
2538
|
summary: Puppet, an automated configuration management tool
|
@@ -2609,6 +2604,7 @@ test_files:
|
|
2609
2604
|
- spec/fixtures/ssl/oid.pem
|
2610
2605
|
- spec/fixtures/ssl/pluto-key.pem
|
2611
2606
|
- spec/fixtures/ssl/pluto.pem
|
2607
|
+
- spec/fixtures/ssl/renewed.pem
|
2612
2608
|
- spec/fixtures/ssl/request-key.pem
|
2613
2609
|
- spec/fixtures/ssl/request.pem
|
2614
2610
|
- spec/fixtures/ssl/revoked-key.pem
|