diff options
author | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2022-02-15 21:52:01 +0100 |
---|---|---|
committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2022-02-15 21:52:01 +0100 |
commit | 77301e8a2accf45c1e9cd55b60e9caf720a20155 (patch) | |
tree | a63b8bd07590b0f0b3655f851ed3b1f65c5d2241 /code/environments/production/modules/certregen/spec/acceptance | |
parent | 40236de30e742094fa7e8fbaaac34995121f6466 (diff) | |
download | puppet.FWSECK-master.tar.gz puppet.FWSECK-master.tar.bz2 puppet.FWSECK-master.zip |
Diffstat (limited to 'code/environments/production/modules/certregen/spec/acceptance')
12 files changed, 564 insertions, 0 deletions
diff --git a/code/environments/production/modules/certregen/spec/acceptance/ca_spec.rb b/code/environments/production/modules/certregen/spec/acceptance/ca_spec.rb new file mode 100644 index 0000000..c9df863 --- /dev/null +++ b/code/environments/production/modules/certregen/spec/acceptance/ca_spec.rb @@ -0,0 +1,60 @@ +require 'spec_helper_acceptance' + +describe "puppet certregen ca" do + if hosts_with_role(hosts, 'master').length>0 then + context 'regen ca on master' do + + context 'C99811 - without --ca_serial' do + it 'should provide ca serial id via stderr' do + on(master, puppet("certregen ca"), :acceptable_exit_codes => 1) do |result| + expect(result.stderr).to match(/rerun this command with --ca_serial ([0-9a-fA-F]+)/) + end + end + end + + context "C99815 - 'puppet certregen ca --ca_serial'" do + before(:all) do + serial = get_ca_serial_id_on(master) + today = get_time_on(master) + @future = today + 5*YEAR + @regen_result = on(master, "puppet certregen ca --ca_serial #{serial}") + end + it 'should output the updated CA expiration date' do + expect(@regen_result.stdout).to match( /CA expiration is now #{@future.utc.strftime('%Y-%m-%d')}/ ) + end + it 'should update CA cert enddate' do + enddate = get_ca_enddate_time_on(master) + expect(enddate - @future).to be < 10.0 + end + end + + context 'C99816 - invalid ca_serial id' do + it 'should yield an error' do + on(master, puppet("certregen ca --ca_serial FD"), :acceptable_exit_codes => 1) do |result| + expect(result.stderr).to match(/The serial number of the current CA certificate .* does not match the serial number given on the command line \(FD\)/) + expect(result.stderr).to match(/rerun this command with --ca_serial ([0-9a-fA-F]+)/) + end + end + end + + context "C99817 - 'puppet certregen ca --ca_serial --ca_ttl 1d'" do + before(:all) do + today = get_time_on(master) + @tomorrow = today + 1*DAY + + serial = get_ca_serial_id_on(master) + @regen_result = on(master, "puppet certregen ca --ca_serial #{serial} --ca_ttl 1d") + end + + it 'should output the updated CA expiration date' do + expect(@regen_result.stdout).to match( /CA expiration is now #{@tomorrow.utc.strftime('%Y-%m-%d')}/ ) + end + it 'should update CA cert enddate' do + enddate = get_ca_enddate_time_on(master) + expect(enddate - @tomorrow).to be < 10.0 + end + end + + end + end +end diff --git a/code/environments/production/modules/certregen/spec/acceptance/healthcheck_spec.rb b/code/environments/production/modules/certregen/spec/acceptance/healthcheck_spec.rb new file mode 100644 index 0000000..387810d --- /dev/null +++ b/code/environments/production/modules/certregen/spec/acceptance/healthcheck_spec.rb @@ -0,0 +1,135 @@ +require 'spec_helper_acceptance' +require 'yaml' +require 'json' + +describe "puppet certregen healthcheck" do + if hosts_with_role(hosts, 'master').length>0 then + + context 'C99803 - cert with more than 10 percent of life' do + before(:all) do + serial = get_ca_serial_id_on(master) + on(master, "puppet certregen ca --ca_serial #{serial}") + end + it 'should not produce a health warning' do + on(master, "puppet certregen healthcheck") do |result| + expect(result.stderr).to be_empty + expect(result.stdout).to match(/No certificates are approaching expiration/) + end + end + end + + context 'C99804 - cert with less than 10 percent of life' do + before(:all) do + serial = get_ca_serial_id_on(master) + # patch puppet to defeat copywrite date check when generating historical CA + patch_puppet_date_check_on(master) + @today = get_time_on(master) + # set back the clock in order to create a CA that will be approaching its EOL + past = @today - (5*YEAR - 20*DAY) + on(master, "date #{past.strftime('%m%d%H%M%Y')}") + # create old CA + on(master, "puppet certregen ca --ca_serial #{serial}") + # update to current time + on(master, "date #{@today.strftime('%m%d%H%M%Y')}") + # revert patch to defeat copywrite date check + patch_puppet_date_check_on(master, 'reverse') + end + + it 'system should have current date' do + today = get_time_on(master) + expect(today.utc.strftime('%Y-%m-%d')).to eq @today.utc.strftime('%Y-%m-%d') + end + + it 'should warn about pending expiration' do + enddate = get_ca_enddate_time_on(master) + on(master, "puppet certregen healthcheck") do |result| + expect(result.stdout).to match(/Status:\s+expiring/) + expect(result.stdout).to match(/Expiration date:\s+#{enddate.utc.strftime('%Y-%m-%d')}/) + end + end + + end + + context 'C99805 - expired cert' do + before(:all) do + serial = get_ca_serial_id_on(master) + on(master, "puppet certregen ca --ca_serial #{serial} --ca_ttl 1s") + sleep 2 + end + it 'should produce a health warning' do + on(master, "puppet certregen healthcheck") do |result| + expect(result.stdout.gsub("\n", " ")).to match(/ca.*Status: expired/) + end + end + end + + context '--all flag' do + + context 'C99806 --all' do + before(:all) do + on(master, puppet("cert list --all")) do |result| + @certs = result.stdout.scan(/\) ([A-F0-9:]+) /) + end + @result = on(master, "puppet certregen healthcheck --all") + end + it 'should contain expiration data for ca cert' do + expect(@result.stdout).to match(/"ca".*\n\s*Status:\s*[Ee]xpir/) + end + it 'should contain expiration data for all node certs' do + @certs.each do |cert| + expect(@result.stdout).to include cert[0] + end + end + end + + context '--render-as flag' do + + context 'C99808 - --render-as yaml' do + before(:all) do + on(master, puppet("cert list --all")) do |result| + @certs = result.stdout.scan(/\) ([A-F0-9:]+) /) + end + @result = on(master, "puppet certregen healthcheck --all --render-as yaml") + @yaml = YAML.load(@result.stdout) + end + it 'should return valid yaml' do + expect(YAML.parse(@result.stdout)).to be_instance_of(Psych::Nodes::Document) + end + it 'should contain expiration data for ca cert' do + ca = @yaml.find { |record| record[:name] == 'ca' } + expect(ca).not_to be nil + expect(ca[:expiry][:status]).to eq(:expired) + end + it 'should contain expiration data for all node certs' do + @certs.each do |cert| + expect(@yaml.find { |record| record[:digest] =~ /#{cert[0]}/ }).not_to be nil + end + end + end + + context 'C99809 - --render-as json prints valid json containing expiration data' do + before(:all) do + on(master, puppet("cert list --all")) do |result| + @certs = result.stdout.scan(/\) ([A-F0-9:]+) /) + end + @json = JSON.parse(on(master, "puppet certregen healthcheck --all --render-as json").stdout) + end + it 'should return valid json' do + expect(@json).not_to be nil + end + it 'should contain expiration data for ca cert' do + ca = @json.find { |record| record['name'] == 'ca' } + expect(ca).not_to be nil + end + it 'should contain expiration data for all node certs' do + @certs.each do |cert| + expect(@json.find { |record| record['digest'] =~ /#{cert[0]}/ }).not_to be nil + end + end + end + + end + end + + end +end diff --git a/code/environments/production/modules/certregen/spec/acceptance/help_spec.rb b/code/environments/production/modules/certregen/spec/acceptance/help_spec.rb new file mode 100644 index 0000000..7d1e83d --- /dev/null +++ b/code/environments/production/modules/certregen/spec/acceptance/help_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper_acceptance' + +describe "pupper help certregen" do + # NOTE: MODULES-4733 certregen is not currently compatible with ruby < 1.9 + ruby_ver = 0 + on(default, 'ruby --version') do |result| + m = /\d+\.\d+\.\d+/.match(result.stdout) + ruby_ver = m[0] if m + end + unless version_is_less(ruby_ver, '1.9') then + describe "C98923 - Verify that 'puppet certregen --help' prints help text" do + # NOTE: `--help` only works on puppet version 4+ + if version_is_less( '3.9.9', on(default, puppet('--version')).stdout) + describe command("puppet certregen --help") do + its(:stdout) { should match( /.*USAGE: puppet certregen <action>.*/ ) } + its(:stdout) { should match( /.*See 'puppet man certregen' or 'man puppet-certregen' for full help.*/ ) } + end + end + end + describe "C99812 - Verify that 'puppet help certregen' prints help text" do + describe command("puppet help certregen") do + its(:stdout) { should match( /.*USAGE: puppet certregen <action>.*/ ) } + its(:stdout) { should match( /.*See 'puppet man certregen' or 'man puppet-certregen' for full help.*/ ) } + end + end + describe "C99813 - Verify that 'puppet help certregen healthcheck' prints help text for healthcheck subcommand" do + describe command("puppet help certregen healthcheck") do + its(:stdout) { should match( /.*USAGE: puppet certregen healthcheck .*/ ) } + its(:stdout) { should match( /.*See 'puppet man certregen' or 'man puppet-certregen' for full help.*/ ) } + end + end + describe "C99814 - Verify that 'puppet help certregen ca' prints help text for ca subcommand" do + describe command("puppet help certregen ca") do + its(:stdout) { should match( /.*USAGE: puppet certregen ca .*/ ) } + its(:stdout) { should match( /.*See 'puppet man certregen' or 'man puppet-certregen' for full help.*/ ) } + end + end + end +end diff --git a/code/environments/production/modules/certregen/spec/acceptance/helpers.rb b/code/environments/production/modules/certregen/spec/acceptance/helpers.rb new file mode 100644 index 0000000..dba7d81 --- /dev/null +++ b/code/environments/production/modules/certregen/spec/acceptance/helpers.rb @@ -0,0 +1,83 @@ +require 'openssl' + +# Time constants in seconds +HOUR = 60 * 60 +DAY = 24 * HOUR +YEAR = 365 * DAY + +# Retrieve CA Certificate from the given host +# +# @param [Host] host single Beaker::Host +# +# @return [OpenSSL::X509::Certificate] Certificate object +def get_ca_cert_on(host) + if host[:roles].include? 'master' then + dir = on(host, puppet('config', 'print', 'cadir')).stdout.chomp + ca_path = "#{dir}/ca_crt.pem" + else + dir = on(host, puppet('config', 'print', 'certdir')).stdout.chomp + ca_path = "#{dir}/ca.pem" + end + on(host, "cat #{ca_path}") do |result| + cert = OpenSSL::X509::Certificate.new(result.stdout) + return cert + end +end + +# Execute `date` command on host with optional arguments +# and get back a Ruby Time object +# +# @param [Host] host single Beaker::Host to run the command on +# @param [Array<String>] args Array of arguments to be appended to the +# `date` command +# @return [Time] Ruby Time object +def get_time_on(host, args = []) + arg_string = args.join(' ') + date = on(host, "date #{arg_string}").stdout.chomp + return Time.parse(date) +end + +# Retrieve the CA enddate on a given host as a Ruby time object +# +# @param [Host] host single Beaker::Host to get CA enddate from +# +# @return [Time] Ruby Time object, or nil if error +def get_ca_enddate_time_on(host) + cert = get_ca_cert_on(host) + return cert.not_after if cert + return nil +end + +# Retrieve the current ca_serial value for `puppet certgen ca` on a given host +# +# @param [Host] host single Beaker::Host to get ca_serial from +# +# @return [String] ca_serial in hexadecimal, or nil if error +def get_ca_serial_id_on(host) + cert = get_ca_cert_on(host) + return cert.serial.to_s(16) if cert + return nil +end + +# Patch puppet to get around the date check validation. +# +# This method is used to patch puppet in order to prevent it from failing to +# create a CA if the system clock is turned back in time by years. The same +# method is used to reverse the patch with the `reverse` parameter. +# +# @param [Host] host single Beaker::Host to run the command on +# @param [String] reverse causes the patch to be reversed +def patch_puppet_date_check_on(host, reverse=nil) + reverse = '--reverse' if reverse + apply_manifest_on(host, 'package { "patch": ensure => present}') + interface_documentation_file = "/opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/interface/documentation.rb" + patch =<<EOF +305c305 +< raise ArgumentError, "copyright with a year \#{fault} is very strange; did you accidentally add or subtract two years?" +--- +> #raise ArgumentError, "copyright with a year \#{fault} is very strange; did you accidentally add or subtract two years?" +EOF + patch_file = host.tmpfile('iface_doc_patch') + create_remote_file(host, patch_file, patch) + on(host, "patch #{reverse} #{interface_documentation_file} < #{patch_file}", :acceptable_exit_codes => [0,1]) +end diff --git a/code/environments/production/modules/certregen/spec/acceptance/nodesets/centos-7-x64.yml b/code/environments/production/modules/certregen/spec/acceptance/nodesets/centos-7-x64.yml new file mode 100644 index 0000000..5eebdef --- /dev/null +++ b/code/environments/production/modules/certregen/spec/acceptance/nodesets/centos-7-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-7-x64: + roles: + - agent + - default + platform: el-7-x86_64 + hypervisor: vagrant + box: puppetlabs/centos-7.2-64-nocm +CONFIG: + type: foss diff --git a/code/environments/production/modules/certregen/spec/acceptance/nodesets/debian-8-x64.yml b/code/environments/production/modules/certregen/spec/acceptance/nodesets/debian-8-x64.yml new file mode 100644 index 0000000..fef6e63 --- /dev/null +++ b/code/environments/production/modules/certregen/spec/acceptance/nodesets/debian-8-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + debian-8-x64: + roles: + - agent + - default + platform: debian-8-amd64 + hypervisor: vagrant + box: puppetlabs/debian-8.2-64-nocm +CONFIG: + type: foss diff --git a/code/environments/production/modules/certregen/spec/acceptance/nodesets/default.yml b/code/environments/production/modules/certregen/spec/acceptance/nodesets/default.yml new file mode 100644 index 0000000..dba339c --- /dev/null +++ b/code/environments/production/modules/certregen/spec/acceptance/nodesets/default.yml @@ -0,0 +1,10 @@ +HOSTS: + ubuntu-1404-x64: + roles: + - agent + - default + platform: ubuntu-14.04-amd64 + hypervisor: vagrant + box: puppetlabs/ubuntu-14.04-64-nocm +CONFIG: + type: foss diff --git a/code/environments/production/modules/certregen/spec/acceptance/nodesets/docker/centos-7.yml b/code/environments/production/modules/certregen/spec/acceptance/nodesets/docker/centos-7.yml new file mode 100644 index 0000000..a3333aa --- /dev/null +++ b/code/environments/production/modules/certregen/spec/acceptance/nodesets/docker/centos-7.yml @@ -0,0 +1,12 @@ +HOSTS: + centos-7-x64: + platform: el-7-x86_64 + hypervisor: docker + image: centos:7 + docker_preserve_image: true + docker_cmd: '["/usr/sbin/init"]' + # install various tools required to get the image up to usable levels + docker_image_commands: + - 'yum install -y crontabs tar wget openssl sysvinit-tools iproute which initscripts' +CONFIG: + trace_limit: 200 diff --git a/code/environments/production/modules/certregen/spec/acceptance/nodesets/docker/debian-8.yml b/code/environments/production/modules/certregen/spec/acceptance/nodesets/docker/debian-8.yml new file mode 100644 index 0000000..df5c319 --- /dev/null +++ b/code/environments/production/modules/certregen/spec/acceptance/nodesets/docker/debian-8.yml @@ -0,0 +1,11 @@ +HOSTS: + debian-8-x64: + platform: debian-8-amd64 + hypervisor: docker + image: debian:8 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get update && apt-get install -y net-tools wget locales strace lsof && echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen' +CONFIG: + trace_limit: 200 diff --git a/code/environments/production/modules/certregen/spec/acceptance/nodesets/docker/ubuntu-14.04.yml b/code/environments/production/modules/certregen/spec/acceptance/nodesets/docker/ubuntu-14.04.yml new file mode 100644 index 0000000..b1efa58 --- /dev/null +++ b/code/environments/production/modules/certregen/spec/acceptance/nodesets/docker/ubuntu-14.04.yml @@ -0,0 +1,12 @@ +HOSTS: + ubuntu-1404-x64: + platform: ubuntu-14.04-amd64 + hypervisor: docker + image: ubuntu:14.04 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + # ensure that upstart is booting correctly in the container + - 'rm /usr/sbin/policy-rc.d && rm /sbin/initctl && dpkg-divert --rename --remove /sbin/initctl && apt-get update && apt-get install -y net-tools wget && locale-gen en_US.UTF-8' +CONFIG: + trace_limit: 200 diff --git a/code/environments/production/modules/certregen/spec/acceptance/workflow_regen_after_expire_spec.rb b/code/environments/production/modules/certregen/spec/acceptance/workflow_regen_after_expire_spec.rb new file mode 100644 index 0000000..3ae0a9e --- /dev/null +++ b/code/environments/production/modules/certregen/spec/acceptance/workflow_regen_after_expire_spec.rb @@ -0,0 +1,105 @@ +require 'spec_helper_acceptance' +require 'json' + +# https://forge.puppet.com/puppetlabs/certregen#revive-a-ca-thats-already-expired +describe "C99821 - workflow - regen CA after it expires" do + if find_install_type == 'pe' then + # This workflow only works with a master to manage the CA + # This workflow only works with a puppetdb instance to query hostnames from + context 'create CA to be expired and update agents' do + before(:all) do + ttl = 60 + serial = get_ca_serial_id_on(master) + on(master, puppet("certregen ca --ca_serial #{serial} --ca_ttl #{ttl}s")) + start = Time.now + agents.each do |agent| + on(agent, puppet('agent -t'), :acceptable_exit_codes => [0,2]) + end + finish = Time.now + elapsed_time = (finish - start).to_i + sleep (ttl - elapsed_time) if elapsed_time < ttl + sleep 1 + end + + it 'should warn that ca is expired' do + on(master, puppet("certregen healthcheck")) do |result| + expect(result.stdout).to match(/Status:\s+expired/) + end + end + + context 'regenerate CA' do + before(:all) do + serial = get_ca_serial_id_on(master) + on(master, puppet("certregen ca --ca_serial #{serial}")) + end + + it 'should update CA cert enddate' do + enddate = get_ca_enddate_time_on(master) + future = get_time_on(master, ['-d', "'5 years'"]) + expect(future - enddate).to be <= (48*HOUR) + end + + context 'automatically distribute new ca to linux hosts' do + before(:all) do + # distribute ssh key for root to agents + on(master, "ssh-keygen -t rsa -f $HOME/.ssh/id_rsa -P ''") + on(master, "cat $HOME/.ssh/id_rsa.pub") do |result| + key_array = result.stdout.split(' ') + fail_test('could not get ssh key from master') unless key_array.size > 1 + @public_key = key_array[1] + end + agents.each do |agent| + unless agent['platform'] =~ /windows/ + args = ['ensure=present', + "user='root'", + "type='rsa'", + "key='#{@public_key}'", + ] + on(agent, puppet_resource('ssh_authorized_key', master.hostname, args)) + on(master, "ssh -o StrictHostKeyChecking=no #{agent.hostname} ls") + end + end + on(master, "/opt/puppetlabs/puppet/bin/gem install chloride") + result = on(master, puppet("certregen redistribute")) + @report = JSON.parse(result.stdout) + end + + after(:all) do + on(master, "rm -f $HOME/.ssh/id_rsa $HOME/.ssh/id_rsa.pub", :acceptable_exit_codes => [0,1]) + agents.each do |agent| + on(agent, puppet_resource('ssh_authorized_key', master.hostname, ['ensure=absent', "user='root'"]), :acceptable_exit_codes => [0,1]) + end + end + + it 'should emit a report in valid json' do + expect(@report).not_to be nil + end + it 'should emit a report with a succeeded key' do + expect(@report['succeeded']).not_to be nil + end + it 'should emit a report with a failed key' do + expect(@report['failed']).not_to be nil + end + it 'should report success on all linux agents' do + agents.each do |agent| + if agent['platform'] =~ /debian|ubuntu|cumulus|huaweios|el-|centos|fedora|redhat|oracle|scientific|eos|archlinux|sles/ + expect(@report['succeeded']).to include agent.hostname + end + end + end + it 'should update CA cert on all linux agents' do + master_enddate = get_ca_enddate_time_on(master) + agents.each do |agent| + if agent['platform'] =~ /debian|ubuntu|cumulus|huaweios|el-|centos|fedora|redhat|oracle|scientific|eos|archlinux|sles/ + on(agent, puppet('agent -t'), :acceptable_exit_codes => [0,2]) + enddate = get_ca_enddate_time_on(agent) + expect(enddate).to eq master_enddate + end + end + end + end + + end + end + end +end diff --git a/code/environments/production/modules/certregen/spec/acceptance/workflow_regen_before_expire_spec.rb b/code/environments/production/modules/certregen/spec/acceptance/workflow_regen_before_expire_spec.rb new file mode 100644 index 0000000..bad7a84 --- /dev/null +++ b/code/environments/production/modules/certregen/spec/acceptance/workflow_regen_before_expire_spec.rb @@ -0,0 +1,77 @@ +require 'spec_helper_acceptance' + +# https://forge.puppet.com/puppetlabs/certregen#refresh-a-ca-thats-expiring-soon +describe "C99818 - workflow - regen CA before it expires" do + if hosts_with_role(hosts, 'master').length>0 then + # This workflow only works with a master to manage the CA + context 'setting CA to expire soon' do + before(:all) do + serial = get_ca_serial_id_on(master) + + # patch puppet to defeat copywrite date check when generating historical CA + patch_puppet_date_check_on(master) + + # determine current time on master + @today = get_time_on(master) + + # set back the clock in order to create a CA that will be approaching its EOL + past = @today - (5*YEAR - 20*DAY) + on(master, "date #{past.strftime('%m%d%H%M%Y')}") + # create old CA + on(master, puppet(" certregen ca --ca_serial #{serial}")) + # update to current time + on(master, "date #{@today.strftime('%m%d%H%M%Y')}") + end + + it 'should have current date' do + today = get_time_on(master) + expect(today.utc.strftime('%Y-%m-%d')).to eq @today.utc.strftime('%Y-%m-%d') + end + + it 'should warn about pending expiration' do + enddate = get_ca_enddate_time_on(master) + on(master, puppet("certregen healthcheck")) do |result| + expect(result.stdout).to match(/Status:\s+expiring/) + expect(result.stdout).to match(/Expiration date:\s+#{enddate.utc.strftime('%Y-%m-%d')}/) + end + end + + context 'restoring previously patched puppet' do + before(:all) do + # revert patch to defeat copywrite date check + patch_puppet_date_check_on(master, 'reverse') + end + + context 'regenerating CA prior to expiration' do + before(:all) do + serial = get_ca_serial_id_on(master) + on(master, puppet("certregen ca --ca_serial #{serial}")) + end + # validate time stamp + it 'should update CA cert enddate' do + enddate = get_ca_enddate_time_on(master) + future = get_time_on(master, ['-d', "'5 years'"]) + expect(future - enddate).to be <= (48*HOUR) + end + + context 'distribute new ca to linux hosts that have been classified with `certregen::client`' do + before(:all) do + create_remote_file(master, '/etc/puppetlabs/code/environments/production/manifests/ca.pp', 'include certregen::client') + on(master, 'chmod 755 /etc/puppetlabs/code/environments/production/manifests/ca.pp') + on(master, puppet('agent -t'), :acceptable_exit_codes => [0,2]) + end + it 'should update CA cert on all linux agents' do + master_enddate = get_ca_enddate_time_on(master) + agents.each do |agent| + on(agent, puppet('agent -t'), :acceptable_exit_codes => [0,2]) + enddate = get_ca_enddate_time_on(agent) + expect(enddate).to eq master_enddate + end + end + end + + end + end + end + end +end |