diff --git a/lib/puppet/ssl/state_machine.rb b/lib/puppet/ssl/state_machine.rb index 3bc1fb66f4..e1674b0b26 100644 --- a/lib/puppet/ssl/state_machine.rb +++ b/lib/puppet/ssl/state_machine.rb @@ -121,6 +121,10 @@ def refresh_ca(ssl_ctx, last_update) rescue Puppet::HTTP::ResponseError => e if e.response.code == 304 Puppet.info(_("CA certificate is unmodified, using existing CA certificate")) + # 304 confirms the local CA is current, so reset the TTL. + # Otherwise ca_last_update (backed by ca.pem mtime) never advances + # past the initial download and needs_refresh? triggers on every run. + @cert_provider.ca_last_update = Time.now else Puppet.info(_("Failed to refresh CA certificate, using existing CA certificate: %{message}") % { message: e.message }) end @@ -219,6 +223,8 @@ def refresh_crl(ssl_ctx, last_update) rescue Puppet::HTTP::ResponseError => e if e.response.code == 304 Puppet.info(_("CRL is unmodified, using existing CRL")) + # 304 confirms the local CRL is current, so reset the TTL. + @cert_provider.crl_last_update = Time.now else Puppet.info(_("Failed to refresh CRL, using existing CRL: %{message}") % { message: e.message }) end diff --git a/spec/unit/ssl/state_machine_spec.rb b/spec/unit/ssl/state_machine_spec.rb index 87ff5a416a..c5134282e2 100644 --- a/spec/unit/ssl/state_machine_spec.rb +++ b/spec/unit/ssl/state_machine_spec.rb @@ -495,6 +495,14 @@ def expect_lockfile_to_contain(pid) state.next_state end + it 'updates the `last_update` time on 304 Not Modified so ca_refresh_interval is respected' do + stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 304) + + expect_any_instance_of(Puppet::X509::CertProvider).to receive(:ca_last_update=).with(be_within(60).of(Time.now)) + + state.next_state + end + it "does not update the `last_update` time when CA refresh fails" do stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_raise(Errno::ECONNREFUSED) @@ -658,6 +666,14 @@ def expect_lockfile_to_contain(pid) state.next_state end + + it 'updates the `last_update` time on 304 Not Modified so crl_refresh_interval is respected' do + stub_request(:get, %r{puppet-ca/v1/certificate_revocation_list/ca}).to_return(status: 304) + + expect_any_instance_of(Puppet::X509::CertProvider).to receive(:crl_last_update=).with(be_within(60).of(Time.now)) + + state.next_state + end end end