From 9f2fd0cb6d191e7883a140fb160d8fefaa685a66 Mon Sep 17 00:00:00 2001 From: Eimhin Laverty Date: Tue, 18 Sep 2018 17:55:55 +0100 Subject: [PATCH] (MODULES-3307) - Auto update expired keys --- lib/puppet/provider/apt_key/apt_key.rb | 25 ++- lib/puppet/type/apt_key.rb | 8 + locales/puppetlabs-apt.pot | 211 +++++++---------------- manifests/key.pp | 10 +- spec/acceptance/apt_key_provider_spec.rb | 173 +++++++++++++++++-- spec/defines/key_compat_spec.rb | 2 +- spec/defines/key_spec.rb | 19 +- spec/unit/puppet/type/apt_key_spec.rb | 13 ++ 8 files changed, 289 insertions(+), 172 deletions(-) diff --git a/lib/puppet/provider/apt_key/apt_key.rb b/lib/puppet/provider/apt_key/apt_key.rb index 2646422..5a66e34 100644 --- a/lib/puppet/provider/apt_key/apt_key.rb +++ b/lib/puppet/provider/apt_key/apt_key.rb @@ -179,8 +179,31 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do file end + # Update a key if it is expired + def update_expired_key + # Return without doing anything if refresh or expired is false + return unless resource[:refresh] == true && resource[:expired] == true + + # Execute command to update key + command = [] + + unless resource[:source].nil? && resource[:content].nil? + raise(_('an unexpected condition occurred while trying to add the key: %{_resource}') % { _resource: resource[:id] }) + end + + # Breaking up the command like this is needed because it blows up + # if --recv-keys isn't the last argument. + command.push('adv', '--keyserver', resource[:server]) + unless resource[:options].nil? + command.push('--keyserver-options', resource[:options]) + end + command.push('--recv-keys', resource[:id]) + end + def exists? - @property_hash[:ensure] == :present + update_expired_key + # report expired keys as non-existing when refresh => true + @property_hash[:ensure] == :present && !(resource[:refresh] && @property_hash[:expired]) end def create diff --git a/lib/puppet/type/apt_key.rb b/lib/puppet/type/apt_key.rb index 10bffb4..5150ee8 100644 --- a/lib/puppet/type/apt_key.rb +++ b/lib/puppet/type/apt_key.rb @@ -1,4 +1,5 @@ require 'pathname' +require 'puppet/parameter/boolean' Puppet::Type.newtype(:apt_key) do @doc = <<-MANIFEST @@ -22,6 +23,9 @@ Puppet::Type.newtype(:apt_key) do ensurable validate do + if self[:refresh] == true && self[:ensure] == :absent + raise(_('ensure => absent and refresh => true are mutually exclusive')) + end if self[:content] && self[:source] raise(_('The properties content and source are mutually exclusive.')) end @@ -71,6 +75,10 @@ Puppet::Type.newtype(:apt_key) do desc 'Additional options to pass to apt-key\'s --keyserver-options.' end + newparam(:refresh, boolean: true, parent: Puppet::Parameter::Boolean) do + desc 'When true, recreate an existing expired key' + end + newproperty(:fingerprint) do desc <<-MANIFEST The 40-digit hexadecimal fingerprint of the specified GPG key. diff --git a/locales/puppetlabs-apt.pot b/locales/puppetlabs-apt.pot index e43d009..5701be9 100644 --- a/locales/puppetlabs-apt.pot +++ b/locales/puppetlabs-apt.pot @@ -1,22 +1,4 @@ -# #-#-#-#-# accounts.pot (PACKAGE VERSION) #-#-#-#-# -# #-#-#-#-# accounts.pot (PACKAGE VERSION) #-#-#-#-# -# #-#-#-#-# puppetlabs-apt.pot (puppetlabs-apt 6.0.0-9-g1d5c598) #-#-#-#-# -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2018 Puppet, Inc. -# This file is distributed under the same license as the puppetlabs-apt package. -# FIRST AUTHOR , 2018. -# -# #-#-#-#-# puppetlabs-apt_metadata.pot (PACKAGE VERSION) #-#-#-#-# -# -# #-#-#-#-# puppetlabs-apt.pot (puppetlabs-apt 6.0.0-9-g1d5c598) #-#-#-#-# -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2018 Puppet, Inc. -# This file is distributed under the same license as the puppetlabs-apt package. -# FIRST AUTHOR , 2018. -# -# #-#-#-#-# puppetlabs-apt_metadata.pot (PACKAGE VERSION) #-#-#-#-# -# -# #-#-#-#-# puppetlabs-apt.pot (puppetlabs-apt 6.0.0-9-g1d5c598) #-#-#-#-# +# #-#-#-#-# puppetlabs-apt.pot (puppetlabs-apt 6.0.0-27-gbb0f842) #-#-#-#-# # SOME DESCRIPTIVE TITLE. # Copyright (C) 2018 Puppet, Inc. # This file is distributed under the same license as the puppetlabs-apt package. @@ -27,82 +9,10 @@ #, fuzzy msgid "" msgstr "" -"#-#-#-#-# accounts.pot (PACKAGE VERSION) #-#-#-#-#\n" -"#-#-#-#-# accounts.pot (PACKAGE VERSION) #-#-#-#-#\n" -"#-#-#-#-# puppet.pot (PACKAGE VERSION) #-#-#-#-#\n" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-08-30 14:54:05 +0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 2.0.0\n" -"#-#-#-#-# puppetlabs-apt.pot (puppetlabs-apt 6.0.0-9-g1d5c598) #-#-#-#-#\n" -"Project-Id-Version: puppetlabs-apt 6.0.0-9-g1d5c598\n" -"\n" -"Report-Msgid-Bugs-To: docs@puppet.com\n" -"POT-Creation-Date: 2018-08-30 14:48+0100\n" -"PO-Revision-Date: 2018-08-30 14:48+0100\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -"#-#-#-#-# puppetlabs-apt_metadata.pot (PACKAGE VERSION) #-#-#-#-#\n" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To:\n" -"POT-Creation-Date: 2018-08-30T14:54:45+01:00\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 2.0.0\n" -"#-#-#-#-# puppet.pot (PACKAGE VERSION) #-#-#-#-#\n" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-08-30 14:54:05 +0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 2.0.0\n" -"#-#-#-#-# puppetlabs-apt.pot (puppetlabs-apt 6.0.0-9-g1d5c598) #-#-#-#-#\n" -"Project-Id-Version: puppetlabs-apt 6.0.0-9-g1d5c598\n" -"\n" -"Report-Msgid-Bugs-To: docs@puppet.com\n" -"POT-Creation-Date: 2018-08-30 14:48+0100\n" -"PO-Revision-Date: 2018-08-30 14:48+0100\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -"#-#-#-#-# puppetlabs-apt_metadata.pot (PACKAGE VERSION) #-#-#-#-#\n" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To:\n" -"POT-Creation-Date: 2018-08-30T14:54:45+01:00\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 2.0.0\n" "#-#-#-#-# puppet.pot (PACKAGE VERSION) #-#-#-#-#\n" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-08-30 16:09:57 +0100\n" +"POT-Creation-Date: 2018-09-21 09:17:33 +0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -110,12 +20,12 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Translate Toolkit 2.0.0\n" -"#-#-#-#-# puppetlabs-apt.pot (puppetlabs-apt 6.0.0-9-g1d5c598) #-#-#-#-#\n" -"Project-Id-Version: puppetlabs-apt 6.0.0-9-g1d5c598\n" +"#-#-#-#-# puppetlabs-apt.pot (puppetlabs-apt 6.0.0-27-gbb0f842) #-#-#-#-#\n" +"Project-Id-Version: puppetlabs-apt 6.0.0-27-gbb0f842\n" "\n" "Report-Msgid-Bugs-To: docs@puppet.com\n" -"POT-Creation-Date: 2018-08-30 16:09+0100\n" -"PO-Revision-Date: 2018-08-30 16:09+0100\n" +"POT-Creation-Date: 2018-09-21 09:27+0100\n" +"PO-Revision-Date: 2018-09-21 09:27+0100\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" @@ -126,7 +36,7 @@ msgstr "" "#-#-#-#-# puppetlabs-apt_metadata.pot (PACKAGE VERSION) #-#-#-#-#\n" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To:\n" -"POT-Creation-Date: 2018-08-30T14:54:45+01:00\n" +"POT-Creation-Date: 2018-09-21T09:17:39+01:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -135,132 +45,133 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Translate Toolkit 2.0.0\n" -#. ./manifests/backports.pp:36 +#. ./manifests/backports.pp:69 msgid "" "If not on Debian or Ubuntu, you must explicitly pass location, release, " "repos, and key" msgstr "" -#. ./manifests/backports.pp:50 +#. ./manifests/backports.pp:95 msgid "pin must be either a string, number or hash" msgstr "" -#. ./manifests/conf.pp:11 +#. ./manifests/conf.pp:25 msgid "Need to pass in content parameter" msgstr "" -#. ./manifests/init.pp:37 - ./manifests/params.pp:5 +#. ./manifests/init.pp:143 ./manifests/params.pp:8 msgid "This module only works on Debian or derivatives like Ubuntu" msgstr "" -#. ./manifests/params.pp:97 -msgid "Unable to determine value for fact os['name']" +#. ./manifests/key.pp:47 +msgid "key with id %{_id} already ensured as absent" +msgstr "" + +#. ./manifests/key.pp:81 +msgid "key with id %{_id} already ensured as present" +msgstr "" + +#. ./manifests/key.pp:97 +msgid "Invalid 'ensure' value '%{_ensure}' for apt::key" msgstr "" -#. ./manifests/pin.pp:52 +#. ./manifests/params.pp:100 +msgid "Unable to determine value for fact os[\"name\"]" +msgstr "" + +#. ./manifests/pin.pp:84 msgid "parameters release, origin, and version are mutually exclusive" msgstr "" -#. ./manifests/pin.pp:56 +#. ./manifests/pin.pp:88 msgid "parameter version cannot be used in general form" msgstr "" -#. ./manifests/pin.pp:59 +#. ./manifests/pin.pp:91 msgid "parameters release and origin are mutually exclusive" msgstr "" -#. ./manifests/ppa.pp:10 - ./manifests/source.pp:25 +#. ./manifests/ppa.pp:30 ./manifests/source.pp:79 msgid "lsbdistcodename fact not available: release parameter required" msgstr "" -#. ./manifests/ppa.pp:14 +#. ./manifests/ppa.pp:34 msgid "apt::ppa is not currently supported on Debian." msgstr "" -#. ./manifests/setting.pp:11 +#. ./manifests/setting.pp:31 msgid "apt::setting cannot have both content and source" msgstr "" -#. ./manifests/setting.pp:15 +#. ./manifests/setting.pp:35 msgid "apt::setting needs either of content or source" msgstr "" -#. ./manifests/setting.pp:23 +#. ./manifests/setting.pp:43 msgid "" "apt::setting resource name/title must start with either 'conf-', 'pref-' or " "'list-'" msgstr "" -#. ./manifests/setting.pp:29 +#. ./manifests/setting.pp:49 msgid "apt::setting priority must be an integer or a zero-padded integer" msgstr "" -#. ./manifests/source.pp:33 +#. ./manifests/source.pp:87 msgid "cannot create a source entry without specifying a location" msgstr "" -#. ./manifests/source.pp:47 +#. ./manifests/source.pp:101 msgid "key hash must contain at least an id entry" msgstr "" -#. ./manifests/source.pp:86 +#. ./manifests/source.pp:140 msgid "Received invalid value for pin parameter" msgstr "" -#: ../lib/puppet/provider/apt_key/apt_key.rb:122 +#: ../lib/puppet/provider/apt_key/apt_key.rb:124 msgid "The file %{_value} does not exist" msgstr "" -#: ../lib/puppet/provider/apt_key/apt_key.rb:218 -msgid "This is a read-only property." +#: ../lib/puppet/provider/apt_key/apt_key.rb:144 +msgid "%{_e} for %{_resource}" msgstr "" -#: ../lib/puppet/type/apt_key.rb:23 -msgid "The properties content and source are mutually exclusive." +#: ../lib/puppet/provider/apt_key/apt_key.rb:146 +msgid "could not resolve %{_resource}" msgstr "" -#. metadata.json -#: .summary +#: ../lib/puppet/provider/apt_key/apt_key.rb:173 msgid "" -"Provides an interface for managing Apt source, key, and definitions with " -"Puppet" -msgstr "" - -#. ./manifests/params.pp:97 -msgid "Unable to determine value for fact os[\"name\"]" -msgstr "" - -#. ./manifests/key.pp:29 -msgid "key with id %{_id} already ensured as absent" +"The id in your manifest %{_resource} and the fingerprint from content/source " +"don't match. Check for an error in the id and content/source is legitimate." msgstr "" -#. ./manifests/key.pp:62 -msgid "key with id %{_id} already ensured as present" +#: ../lib/puppet/provider/apt_key/apt_key.rb:191 +#: ../lib/puppet/provider/apt_key/apt_key.rb:227 +msgid "" +"an unexpected condition occurred while trying to add the key: %{_resource}" msgstr "" -#. ./manifests/key.pp:78 -msgid "Invalid 'ensure' value '%{_ensure}' for apt::key" +#: ../lib/puppet/provider/apt_key/apt_key.rb:243 +msgid "This is a read-only property." msgstr "" -#: ../lib/puppet/provider/apt_key/apt_key.rb:142 -msgid "%{_e} for %{_resource}" +#: ../lib/puppet/type/apt_key.rb:27 +msgid "ensure => absent and refresh => true are mutually exclusive" msgstr "" -#: ../lib/puppet/provider/apt_key/apt_key.rb:144 -msgid "could not resolve %{_resource}" +#: ../lib/puppet/type/apt_key.rb:30 +msgid "The properties content and source are mutually exclusive." msgstr "" -#: ../lib/puppet/provider/apt_key/apt_key.rb:171 -msgid "" -"The id in your manifest %{_resource} and the fingerprint from content/source " -"don't match. Check for an error in the id and content/source is legitimate." +#: ../lib/puppet/type/apt_key.rb:33 +msgid "The id should be a full fingerprint (40 characters), see README." msgstr "" -#: ../lib/puppet/provider/apt_key/apt_key.rb:202 +#. metadata.json +#: .summary msgid "" -"an unexpected condition occurred while trying to add the key: %{_resource}" -msgstr "" - -#: ../lib/puppet/type/apt_key.rb:26 -msgid "The id should be a full fingerprint (40 characters), see README." +"Provides an interface for managing Apt source, key, and definitions with " +"Puppet" msgstr "" diff --git a/manifests/key.pp b/manifests/key.pp index 93cc27d..70e3e5f 100644 --- a/manifests/key.pp +++ b/manifests/key.pp @@ -15,7 +15,8 @@ # characters, optionally prefixed with "0x") or a full key fingerprint (40 hexadecimal characters). # # @param ensure -# Specifies whether the key should exist. Valid options: 'present' and 'absent'. +# Specifies whether the key should exist. Valid options: 'present', 'absent' or 'refreshed'. Using 'refreshed' will make keys auto +# update when they have expired (assuming a new key exists on the key server). # # @param content # Supplies the entire GPG key. Useful in case the key can't be fetched from a remote location and using a file resource is inconvenient. @@ -33,7 +34,7 @@ # define apt::key ( Pattern[/\A(0x)?[0-9a-fA-F]{8}\Z/, /\A(0x)?[0-9a-fA-F]{16}\Z/, /\A(0x)?[0-9a-fA-F]{40}\Z/] $id = $title, - Enum['present', 'absent'] $ensure = present, + Enum['present', 'absent', 'refreshed'] $ensure = present, Optional[String] $content = undef, Optional[Pattern[/\Ahttps?:\/\//, /\Aftp:\/\//, /\A\/\w+/]] $source = undef, Pattern[/\A((hkp|http|https):\/\/)?([a-z\d])([a-z\d-]{0,61}\.)+[a-z\d]+(:\d{2,5})?$/] $server = $::apt::keyserver, @@ -41,14 +42,15 @@ define apt::key ( ) { case $ensure { - present: { + /^(refreshed|present)$/: { if defined(Anchor["apt_key ${id} absent"]){ fail(translate('key with id %{_id} already ensured as absent'),{'_id' => id}) } if !defined(Anchor["apt_key ${id} present"]) { apt_key { $title: - ensure => $ensure, + ensure => present, + refresh => $ensure == 'refreshed', id => $id, source => $source, content => $content, diff --git a/spec/acceptance/apt_key_provider_spec.rb b/spec/acceptance/apt_key_provider_spec.rb index de3be33..ae278fb 100644 --- a/spec/acceptance/apt_key_provider_spec.rb +++ b/spec/acceptance/apt_key_provider_spec.rb @@ -1,19 +1,23 @@ require 'spec_helper_acceptance' -PUPPETLABS_GPG_KEY_SHORT_ID = 'EF8D349F'.freeze -PUPPETLABS_GPG_KEY_LONG_ID = '7F438280EF8D349F'.freeze -PUPPETLABS_GPG_KEY_FINGERPRINT = '6F6B15509CF8E59E6E469F327F438280EF8D349F'.freeze -PUPPETLABS_APT_URL = 'apt.puppetlabs.com'.freeze -PUPPETLABS_GPG_KEY_FILE = 'DEB-GPG-KEY-puppet'.freeze -CENTOS_GPG_KEY_SHORT_ID = 'C105B9DE'.freeze -CENTOS_GPG_KEY_LONG_ID = '0946FCA2C105B9DE'.freeze -CENTOS_GPG_KEY_FINGERPRINT = 'C1DAC52D1664E8A4386DBA430946FCA2C105B9DE'.freeze -CENTOS_REPO_URL = 'ftp.cvut.cz/centos'.freeze -CENTOS_GPG_KEY_FILE = 'RPM-GPG-KEY-CentOS-6'.freeze -SHOULD_NEVER_EXIST_ID = 'EF8D349F'.freeze -KEY_CHECK_COMMAND = 'apt-key adv --list-keys --with-colons --fingerprint | grep '.freeze -PUPPETLABS_KEY_CHECK_COMMAND = "#{KEY_CHECK_COMMAND} #{PUPPETLABS_GPG_KEY_FINGERPRINT}".freeze -CENTOS_KEY_CHECK_COMMAND = "#{KEY_CHECK_COMMAND} #{CENTOS_GPG_KEY_FINGERPRINT}".freeze +PUPPETLABS_GPG_KEY_SHORT_ID = 'EF8D349F'.freeze +PUPPETLABS_GPG_KEY_LONG_ID = '7F438280EF8D349F'.freeze +PUPPETLABS_GPG_KEY_FINGERPRINT = '6F6B15509CF8E59E6E469F327F438280EF8D349F'.freeze +PUPPETLABS_APT_URL = 'apt.puppetlabs.com'.freeze +PUPPETLABS_GPG_KEY_FILE = 'DEB-GPG-KEY-puppet'.freeze +CENTOS_GPG_KEY_SHORT_ID = 'C105B9DE'.freeze +CENTOS_GPG_KEY_LONG_ID = '0946FCA2C105B9DE'.freeze +CENTOS_GPG_KEY_FINGERPRINT = 'C1DAC52D1664E8A4386DBA430946FCA2C105B9DE'.freeze +CENTOS_REPO_URL = 'ftp.cvut.cz/centos'.freeze +CENTOS_GPG_KEY_FILE = 'RPM-GPG-KEY-CentOS-6'.freeze +PUPPETLABS_EXP_KEY_LONG_ID = '47B320EB4C7C375AA9DAE1A01054B7A24BD6EC30'.freeze +PUPPETLABS_EXP_KEY_DATES = 'pub:e:4096:1:1054B7A24BD6EC30:2010-07-10:2017-01-05::-:Puppet Labs Release Key'.freeze +SHOULD_NEVER_EXIST_ID = 'EF8D349F'.freeze +KEY_CHECK_COMMAND = 'apt-key adv --list-keys --with-colons --fingerprint | grep '.freeze +PUPPETLABS_KEY_CHECK_COMMAND = "#{KEY_CHECK_COMMAND} #{PUPPETLABS_GPG_KEY_FINGERPRINT}".freeze +CENTOS_KEY_CHECK_COMMAND = "#{KEY_CHECK_COMMAND} #{CENTOS_GPG_KEY_FINGERPRINT}".freeze +PUPPETLABS_EXP_CHECK_COMMAND = "#{KEY_CHECK_COMMAND} '#{PUPPETLABS_EXP_KEY_DATES}'".freeze +DEBIAN_PUPPETLABS_EXP_CHECK_COMMAND = 'apt-key list | grep -F -A 1 \'pub rsa4096 2010-07-10 [SC] [expired: 2017-01-05]\' | grep \'47B3 20EB 4C7C 375A A9DA E1A0 1054 B7A2 4BD6 EC30\''.freeze def populate_default_options_pp(value) default_options_pp = <<-MANIFEST @@ -60,6 +64,84 @@ ensure_absent_long_key_pp = <<-MANIFEST } MANIFEST +refresh_pp = <<-MANIFEST + apt_key { '#{PUPPETLABS_EXP_KEY_LONG_ID}': + id => '#{PUPPETLABS_EXP_KEY_LONG_ID}', + ensure => 'present', + content => '-----BEGIN PGP PUBLIC KEY BLOCK----- + Version: GnuPG v1 + + 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 + fBt3Tu1IYpw= + =cXcR + -----END PGP PUBLIC KEY BLOCK-----' + } + MANIFEST + gpg_key_pp = <<-MANIFEST apt_key { 'puppetlabs': id => '#{PUPPETLABS_GPG_KEY_FINGERPRINT}', @@ -548,6 +630,34 @@ fingerprint_does_not_match_pp = <<-MANIFEST } MANIFEST +refresh_true_pp = <<-MANIFEST + apt_key { '#{PUPPETLABS_EXP_KEY_LONG_ID}': + id => '#{PUPPETLABS_EXP_KEY_LONG_ID}', + ensure => 'present', + refresh => true, + } + MANIFEST + +refresh_false_pp = <<-MANIFEST + apt_key { '#{PUPPETLABS_EXP_KEY_LONG_ID}': + id => '#{PUPPETLABS_EXP_KEY_LONG_ID}', + ensure => 'present', + refresh => false, + } +MANIFEST + +refresh_del_key_pp = <<-MANIFEST + apt_key { '#{PUPPETLABS_EXP_KEY_LONG_ID}': + ensure => 'absent', + } +MANIFEST + +refresh_check_for_dirmngr_pp = <<-MANIFEST + package { 'dirmngr': + ensure => 'present', + } +MANIFEST + describe 'apt_key' do before(:each) do # Delete twice to make sure everything is cleaned @@ -831,4 +941,39 @@ describe 'apt_key' do end end end + + describe 'refresh' do + if fact('osfamily') == 'Debian' && (fact('lsbdistcodename') == 'stretch' || fact('lsbdistcodename') == 'bionic') + # Set Debian Stetch specific value of puppetlabs_exp_check_command + let(:puppetlabs_exp_check_command) { DEBIAN_PUPPETLABS_EXP_CHECK_COMMAND } + else + # Set default value of puppetlabs_exp_check_command + let(:puppetlabs_exp_check_command) { PUPPETLABS_EXP_CHECK_COMMAND } + end + before(:each) do + if fact('lsbdistcodename') == 'stretch' || fact('lsbdistcodename') == 'bionic' + # Ensure dirmngr package is installed + apply_manifest(refresh_check_for_dirmngr_pp, acceptable_exit_codes: [0, 2]) + # Export environment variable to disable apt-key warning when using grep + shell('export APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1') + end + # Delete the Puppet Labs Release Key and install an expired version of the key + apply_manifest(refresh_del_key_pp) + apply_manifest(refresh_pp, catch_failures: true) + end + context 'when refresh => true' do + it 'updates an expired key' do + apply_manifest(refresh_true_pp) + # Check key has been updated to new version + shell(puppetlabs_exp_check_command.to_s, acceptable_exit_codes: [0]) + end + end + context 'when refresh => false' do + it 'does not replace an expired key' do + apply_manifest(refresh_false_pp) + # Expired key is present and has not been updated by the new version + shell(puppetlabs_exp_check_command.to_s, acceptable_exit_codes: [1]) + end + end + end end diff --git a/spec/defines/key_compat_spec.rb b/spec/defines/key_compat_spec.rb index ae247d2..7a6804c 100644 --- a/spec/defines/key_compat_spec.rb +++ b/spec/defines/key_compat_spec.rb @@ -319,7 +319,7 @@ describe 'apt::key', type: :define do end it 'fails' do - is_expected.to raise_error(%r{Enum\['absent', 'present'\]}) + is_expected.to raise_error(%r{Enum\['absent', 'present', 'refreshed'\]}) end end diff --git a/spec/defines/key_spec.rb b/spec/defines/key_spec.rb index b4ccf16..cf596e9 100644 --- a/spec/defines/key_spec.rb +++ b/spec/defines/key_spec.rb @@ -99,6 +99,21 @@ describe 'apt::key' do end end + describe 'ensure => refreshed' do + let :params do + { + ensure: 'refreshed', + } + end + + it 'contains the apt_key with refresh => true' do + is_expected.to contain_apt_key(title).with( + ensure: 'present', + refresh: true, + ) + end + end + describe 'set a bunch of things!' do let :params do { @@ -317,7 +332,7 @@ describe 'apt::key' do end context 'with invalid ensure' do - ['foo', 'aabsent', 'absenta', 'apresent', 'presenta'].each do |param| + ['foo', 'aabsent', 'absenta', 'apresent', 'presenta', 'refresh', 'arefreshed', 'refresheda'].each do |param| let :params do { ensure: param, @@ -325,7 +340,7 @@ describe 'apt::key' do end it 'fails' do - is_expected.to raise_error(%r{for Enum\['absent', 'present'\], got}) + is_expected.to raise_error(%r{for Enum\['absent', 'present', 'refreshed'\], got}) end end end diff --git a/spec/unit/puppet/type/apt_key_spec.rb b/spec/unit/puppet/type/apt_key_spec.rb index a25d827..5b205e9 100644 --- a/spec/unit/puppet/type/apt_key_spec.rb +++ b/spec/unit/puppet/type/apt_key_spec.rb @@ -28,6 +28,10 @@ describe Puppet::Type.type(:apt_key) do it 'content is not set' do expect(resource[:content]).to eq nil end + + it 'refresh is not set' do + expect(resource[:refresh]).to eq nil + end end context 'with a lowercase 32bit key id' do @@ -138,6 +142,15 @@ describe Puppet::Type.type(:apt_key) do }.to raise_error(%r{content and source are mutually exclusive}) end + it 'raises an error if refresh => true and ensure => absent' do + expect { + Puppet::Type.type(:apt_key).new(id: 'EF8D349F', + source: 'http://apt.puppetlabs.com/pubkey.gpg', + ensure: :absent, + refresh: :true) + }.to raise_error(%r{ensure => absent and refresh => true are mutually exclusive}) + end + it 'raises an error if a weird length key is used' do expect { Puppet::Type.type(:apt_key).new(id: 'FEF8D349F', -- 2.32.3