From: Merritt Krakowitzer Date: Tue, 20 Jan 2015 19:27:52 +0000 (+0200) Subject: Merge branch 'master' of https://github.com/puppetlabs/puppetlabs-apt into f3792625... X-Git-Tag: 1.8.0~21^2 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=4f0ebaced75699bf8456f045375a32c7bc12408a;hp=38582d02cd36274ecd79932aef30b5c1330d16f4;p=puppet-modules%2Fpuppetlabs-apt.git Merge branch 'master' of https://github.com/puppetlabs/puppetlabs-apt into f3792625/trusted_param --- diff --git a/lib/facter/apt_updates.rb b/lib/facter/apt_updates.rb index 77e667e..014782e 100644 --- a/lib/facter/apt_updates.rb +++ b/lib/facter/apt_updates.rb @@ -2,18 +2,23 @@ apt_package_updates = nil Facter.add("apt_has_updates") do confine :osfamily => 'Debian' if File.executable?("/usr/lib/update-notifier/apt-check") - apt_package_updates = Facter::Util::Resolution.exec('/usr/lib/update-notifier/apt-check 2>/dev/null').split(';') + apt_check_result = Facter::Util::Resolution.exec('/usr/lib/update-notifier/apt-check 2>&1') + if not apt_check_result.nil? and apt_check_result =~ /^\d+;\d+$/ + apt_package_updates = apt_check_result.split(';') + end end setcode do - apt_package_updates != ['0', '0'] unless apt_package_updates.nil? + if not apt_package_updates.nil? and apt_package_updates.length == 2 + apt_package_updates != ['0', '0'] + end end end Facter.add("apt_package_updates") do confine :apt_has_updates => true setcode do - packages = Facter::Util::Resolution.exec('/usr/lib/update-notifier/apt-check -p 2>/dev/null').split("\n") + packages = Facter::Util::Resolution.exec('/usr/lib/update-notifier/apt-check -p 2>&1').split("\n") if Facter.version < '2.0.0' packages.join(',') else diff --git a/lib/puppet/provider/apt_key/apt_key.rb b/lib/puppet/provider/apt_key/apt_key.rb index 1a7f17c..67a8aa0 100644 --- a/lib/puppet/provider/apt_key/apt_key.rb +++ b/lib/puppet/provider/apt_key/apt_key.rb @@ -13,27 +13,35 @@ end Puppet::Type.type(:apt_key).provide(:apt_key) do - KEY_LINE = { - :date => '[0-9]{4}-[0-9]{2}-[0-9]{2}', - :key_type => '(R|D)', - :key_size => '\d{4}', - :key_id => '[0-9a-fA-F]+', - :expires => 'expire(d|s)', - } - confine :osfamily => :debian defaultfor :osfamily => :debian commands :apt_key => 'apt-key' def self.instances + cli_args = ['adv','--list-keys', '--with-colons', '--fingerprint'] + if RUBY_VERSION > '1.8.7' - key_output = apt_key('list').encode('UTF-8', 'binary', :invalid => :replace, :undef => :replace, :replace => '') + key_output = apt_key(cli_args).encode('UTF-8', 'binary', :invalid => :replace, :undef => :replace, :replace => '') else - key_output = apt_key('list') + key_output = apt_key(cli_args) end + + pub_line, fpr_line = nil + key_array = key_output.split("\n").collect do |line| - line_hash = key_line_hash(line) - next unless line_hash + if line.start_with?('pub') + pub_line = line + elsif line.start_with?('fpr') + fpr_line = line + end + + next unless (pub_line and fpr_line) + + line_hash = key_line_hash(pub_line, fpr_line) + + # reset everything + pub_line, fpr_line = nil + expired = false if line_hash[:key_expiry] @@ -41,14 +49,17 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do end new( - :name => line_hash[:key_id], - :id => line_hash[:key_id], - :ensure => :present, - :expired => expired, - :expiry => line_hash[:key_expiry], - :size => line_hash[:key_size], - :type => line_hash[:key_type] == 'R' ? :rsa : :dsa, - :created => line_hash[:key_created] + :name => line_hash[:key_fingerprint], + :id => line_hash[:key_long], + :fingerprint => line_hash[:key_fingerprint], + :short => line_hash[:key_short], + :long => line_hash[:key_long], + :ensure => :present, + :expired => expired, + :expiry => line_hash[:key_expiry], + :size => line_hash[:key_size], + :type => line_hash[:key_type], + :created => line_hash[:key_created] ) end key_array.compact! @@ -57,59 +68,50 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do def self.prefetch(resources) apt_keys = instances resources.keys.each do |name| - if name.length == 16 - shortname=name[8..-1] - else - shortname=name - end - if provider = apt_keys.find{ |key| key.name == shortname } - resources[name].provider = provider + if name.length == 40 + if provider = apt_keys.find{ |key| key.fingerprint == name } + resources[name].provider = provider + end + elsif name.length == 16 + if provider = apt_keys.find{ |key| key.long == name } + resources[name].provider = provider + end + elsif name.length == 8 + if provider = apt_keys.find{ |key| key.short == name } + resources[name].provider = provider + end end end end - def self.key_line_hash(line) - line_array = line.match(key_line_regexp).to_a - return nil if line_array.length < 5 + def self.key_line_hash(pub_line, fpr_line) + pub_split = pub_line.split(':') + fpr_split = fpr_line.split(':') + fingerprint = fpr_split.last return_hash = { - :key_id => line_array[3], - :key_size => line_array[1], - :key_type => line_array[2], - :key_created => line_array[4], - :key_expiry => nil, + :key_fingerprint => fingerprint, + :key_long => fingerprint[-16..-1], # last 16 characters of fingerprint + :key_short => fingerprint[-8..-1], # last 8 characters of fingerprint + :key_size => pub_split[2], + :key_type => nil, + :key_created => pub_split[5], + :key_expiry => pub_split[6].empty? ? nil : pub_split[6], } - return_hash[:key_expiry] = line_array[7] if line_array.length == 8 - return return_hash - end + # set key type based on types defined in /usr/share/doc/gnupg/DETAILS.gz + case pub_split[3] + when "1" + return_hash[:key_type] = :rsa + when "17" + return_hash[:key_type] = :dsa + when "18" + return_hash[:key_type] = :ecc + when "19" + return_hash[:key_type] = :ecdsa + end - def self.key_line_regexp - # This regexp is trying to match the following output - # pub 4096R/4BD6EC30 2010-07-10 [expires: 2016-07-08] - # pub 1024D/CD2EFD2A 2009-12-15 - regexp = /\A - pub # match only the public key, not signatures - \s+ # bunch of spaces after that - (#{KEY_LINE[:key_size]}) # size of the key, usually a multiple of 1024 - #{KEY_LINE[:key_type]} # type of the key, usually R or D - \/ # separator between key_type and key_id - (#{KEY_LINE[:key_id]}) # hex id of the key - \s+ # bunch of spaces after that - (#{KEY_LINE[:date]}) # date the key was added to the keyring - # following an optional block which indicates if the key has an expiration - # date and if it has expired yet - ( - \s+ # again with thes paces - \[ # we open with a square bracket - #{KEY_LINE[:expires]} # expires or expired - \: # a colon - \s+ # more spaces - (#{KEY_LINE[:date]}) # date indicating key expiry - \] # we close with a square bracket - )? # end of the optional block - \Z/x - regexp + return return_hash end def source_to_file(value) @@ -164,8 +166,10 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do end def destroy - #Currently del only removes the first key, we need to recursively list and ensure all with id are absent. - apt_key('del', resource[:id]) + begin + apt_key('del', resource.provider.short) + r = execute(["#{command(:apt_key)} list | grep '/#{resource.provider.short}\s'"], :failonfail => false) + end while r.exitstatus == 0 @property_hash.clear end diff --git a/lib/puppet/type/apt_key.rb b/lib/puppet/type/apt_key.rb index 8aa4081..70825ac 100644 --- a/lib/puppet/type/apt_key.rb +++ b/lib/puppet/type/apt_key.rb @@ -28,8 +28,8 @@ Puppet::Type.newtype(:apt_key) do newparam(:id, :namevar => true) do desc 'The ID of the key you want to manage.' # GPG key ID's should be either 32-bit (short) or 64-bit (long) key ID's - # and may start with the optional 0x - newvalues(/\A(0x)?[0-9a-fA-F]{8}\Z/, /\A(0x)?[0-9a-fA-F]{16}\Z/) + # and may start with the optional 0x, or they can be 40-digit key fingerprints + newvalues(/\A(0x)?[0-9a-fA-F]{8}\Z/, /\A(0x)?[0-9a-fA-F]{16}\Z/, /\A(0x)?[0-9a-fA-F]{40}\Z/) munge do |value| if value.start_with?('0x') id = value.partition('0x').last.upcase @@ -66,6 +66,30 @@ Puppet::Type.newtype(:apt_key) do desc 'Additional options to pass to apt-key\'s --keyserver-options.' end + newproperty(:fingerprint) do + desc <<-EOS + The 40-digit hexadecimal fingerprint of the specified GPG key. + + This property is read-only. + EOS + end + + newproperty(:long) do + desc <<-EOS + The 16-digit hexadecimal id of the specified GPG key. + + This property is read-only. + EOS + end + + newproperty(:short) do + desc <<-EOS + The 8-digit hexadecimal id of the specified GPG key. + + This property is read-only. + EOS + end + newproperty(:expired) do desc <<-EOS Indicates if the key has expired. @@ -92,7 +116,7 @@ Puppet::Type.newtype(:apt_key) do newproperty(:type) do desc <<-EOS - The key type, either RSA or DSA. + The key type, one of: rsa, dsa, ecc, ecdsa This property is read-only. EOS diff --git a/manifests/init.pp b/manifests/init.pp index 89fb684..d64b013 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,47 +1,56 @@ -# Class: apt +# == Class: apt # # This module manages the initial configuration of apt. # -# Parameters: -# The parameters listed here are not required in general and were -# added for use cases related to development environments. +# The parameters listed here are not required in general and were +# added for use cases related to development environments. # -# disable_keys - disables the requirement for all packages to be signed +# === Parameters # -# always_apt_update - rather apt should be updated on every run (intended -# for development environments where package updates are frequent) +# [*disable_keys*] +# Disables the requirement for all packages to be signed # -# apt_update_frequency - *string* Supported values: -# **always**: Will fire `apt-get update` at every puppet run. Intended to +# [*always_apt_update*] +# Rather apt should be updated on every run (intended +# for development environments where package updates are frequent) +# +# [*apt_update_frequency*] +# String: Supported values: +# **always**: Will fire `apt-get update` at every puppet run. Intended to # deprecate the `always_apt_update` parameter. -# **daily**: Trigger `apt-get update` if the value of the fact +# *daily**: Trigger `apt-get update` if the value of the fact # `apt_update_last_success` is less than current epoch time - 86400. # *notifying the apt_update exec will trigger apt-get update regardless* -# **weekly**: Trigger `apt-get update` if the value of the fact +# *weekly**: Trigger `apt-get update` if the value of the fact # `apt_update_last_success` is less than current epoch time - 604800. # *notifying the apt_update exec will trigger apt-get update regardless* -# **reluctantly**: *Default* only run apt-get update if the exec resource `apt_update` is notified. +# *reluctantly**: *Default* only run apt-get update if the exec resource `apt_update` is notified. # -# purge_sources_list - Accepts true or false. Defaults to false If set to -# true, Puppet will purge all unmanaged entries from sources.list +# [*purge_sources_list*] +# Accepts true or false. Defaults to false If set to +# true, Puppet will purge all unmanaged entries from sources.list # -# purge_sources_list_d - Accepts true or false. Defaults to false. If set -# to true, Puppet will purge all unmanaged entries from sources.list.d +# [*purge_sources_list_d*] +# Accepts true or false. Defaults to false. If set +# to true, Puppet will purge all unmanaged entries from sources.list.d # -# update_timeout - Overrides the exec timeout in seconds for apt-get update. -# If not set defaults to Exec's default (300) +# [*update_timeout*] +# Overrides the exec timeout in seconds for apt-get update. +# If not set defaults to Exec's default (300) # -# update_tries - Number of times that `apt-get update` will be tried. Use this -# to work around transient DNS and HTTP errors. By default, the command -# will only be run once. +# [*update_tries*] +# Number of times that `apt-get update` will be tried. Use this +# to work around transient DNS and HTTP errors. By default, the command +# will only be run once. # -# Actions: +# === Examples +# +# class { 'apt': } +# +# === Requires +# +# puppetlabs/stdlib >= 2.2.1 # -# Requires: -# puppetlabs/stdlib -# Sample Usage: -# class { 'apt': } - class apt( $always_apt_update = false, $apt_update_frequency = 'reluctantly', diff --git a/manifests/key.pp b/manifests/key.pp index c51f4bf..ce5fc25 100644 --- a/manifests/key.pp +++ b/manifests/key.pp @@ -10,9 +10,11 @@ # [*key*] # _default_: +$title+, the title/name of the resource # -# Is a GPG key ID. This key ID is validated with a regex enforcing it -# to only contain valid hexadecimal characters, be precisely 8 or 16 -# characters long and optionally prefixed with 0x. +# Is a GPG key ID or full key fingerprint. This value is validated with +# a regex enforcing it to only contain valid hexadecimal characters, be +# precisely 8 or 16 hexadecimal characters long and optionally prefixed +# with 0x for key IDs, or 40 hexadecimal characters long for key +# fingerprints. # # [*ensure*] # _default_: +present+ @@ -57,7 +59,7 @@ define apt::key ( $key_options = undef, ) { - validate_re($key, ['\A(0x)?[0-9a-fA-F]{8}\Z', '\A(0x)?[0-9a-fA-F]{16}\Z']) + validate_re($key, ['\A(0x)?[0-9a-fA-F]{8}\Z', '\A(0x)?[0-9a-fA-F]{16}\Z', '\A(0x)?[0-9a-fA-F]{40}\Z']) validate_re($ensure, ['\Aabsent|present\Z',]) if $key_content { diff --git a/spec/acceptance/apt_key_provider_spec.rb b/spec/acceptance/apt_key_provider_spec.rb index 3f2536c..24277d2 100644 --- a/spec/acceptance/apt_key_provider_spec.rb +++ b/spec/acceptance/apt_key_provider_spec.rb @@ -1,20 +1,29 @@ require 'spec_helper_acceptance' -PUPPETLABS_GPG_KEY_ID = '4BD6EC30' -PUPPETLABS_GPG_LONG_KEY_ID = '1054B7A24BD6EC30' -PUPPETLABS_APT_URL = 'apt.puppetlabs.com' -PUPPETLABS_GPG_KEY_FILE = 'pubkey.gpg' -CENTOS_GPG_KEY_ID = 'C105B9DE' -CENTOS_REPO_URL = 'ftp.cvut.cz/centos' -CENTOS_GPG_KEY_FILE = 'RPM-GPG-KEY-CentOS-6' +PUPPETLABS_GPG_KEY_SHORT_ID = '4BD6EC30' +PUPPETLABS_GPG_KEY_LONG_ID = '1054B7A24BD6EC30' +PUPPETLABS_GPG_KEY_FINGERPRINT = '47B320EB4C7C375AA9DAE1A01054B7A24BD6EC30' +PUPPETLABS_APT_URL = 'apt.puppetlabs.com' +PUPPETLABS_GPG_KEY_FILE = 'pubkey.gpg' +CENTOS_GPG_KEY_SHORT_ID = 'C105B9DE' +CENTOS_GPG_KEY_LONG_ID = '0946FCA2C105B9DE' +CENTOS_GPG_KEY_FINGERPRINT = 'C1DAC52D1664E8A4386DBA430946FCA2C105B9DE' +CENTOS_REPO_URL = 'ftp.cvut.cz/centos' +CENTOS_GPG_KEY_FILE = 'RPM-GPG-KEY-CentOS-6' + +SHOULD_NEVER_EXIST_ID = '4BD6EC30' + +KEY_CHECK_COMMAND = "apt-key adv --list-keys --with-colons --fingerprint | grep " +PUPPETLABS_KEY_CHECK_COMMAND = "#{KEY_CHECK_COMMAND} #{PUPPETLABS_GPG_KEY_FINGERPRINT}" +CENTOS_KEY_CHECK_COMMAND = "#{KEY_CHECK_COMMAND} #{CENTOS_GPG_KEY_FINGERPRINT}" describe 'apt_key' do before(:each) do # Delete twice to make sure everything is cleaned # up after the short key collision - shell("apt-key del #{PUPPETLABS_GPG_KEY_ID}", + shell("apt-key del #{PUPPETLABS_GPG_KEY_SHORT_ID}", :acceptable_exit_codes => [0,1,2]) - shell("apt-key del #{PUPPETLABS_GPG_KEY_ID}", + shell("apt-key del #{PUPPETLABS_GPG_KEY_SHORT_ID}", :acceptable_exit_codes => [0,1,2]) end @@ -22,12 +31,16 @@ describe 'apt_key' do key_versions = { '32bit key id' => '4BD6EC30', '64bit key id' => '1054B7A24BD6EC30', + '160bit key fingerprint' => '47B320EB4C7C375AA9DAE1A01054B7A24BD6EC30', '32bit lowercase key id' => '4bd6ec30', '64bit lowercase key id' => '1054b7a24bd6ec30', + '160bit lowercase key fingerprint' => '47b320eb4c7c375aa9dae1a01054b7a24bd6ec30', '0x formatted 32bit key id' => '0x4BD6EC30', '0x formatted 64bit key id' => '0x1054B7A24BD6EC30', + '0x formatted 160bit key fingerprint' => '0x47B320EB4C7C375AA9DAE1A01054B7A24BD6EC30', '0x formatted 32bit lowercase key id' => '0x4bd6ec30', '0x formatted 64bit lowercase key id' => '0x1054b7a24bd6ec30', + '0x formatted 160bit lowercase key fingerprint' => '0x47b320eb4c7c375aa9dae1a01054b7a24bd6ec30', } key_versions.each do |key, value| @@ -42,7 +55,7 @@ describe 'apt_key' do apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_changes => true) - shell("apt-key list | grep #{PUPPETLABS_GPG_KEY_ID}") + shell(PUPPETLABS_KEY_CHECK_COMMAND) end end end @@ -67,25 +80,25 @@ describe 'apt_key' do it 'is removed' do pp = <<-EOS apt_key { 'centos': - id => '#{CENTOS_GPG_KEY_ID}', + id => '#{CENTOS_GPG_KEY_LONG_ID}', ensure => 'absent', } EOS # Install the key first shell("apt-key adv --keyserver keyserver.ubuntu.com \ - --recv-keys #{CENTOS_GPG_KEY_ID}") - shell("apt-key list | grep #{CENTOS_GPG_KEY_ID}") + --recv-keys #{CENTOS_GPG_KEY_FINGERPRINT}") + shell(CENTOS_KEY_CHECK_COMMAND) # Time to remove it using Puppet apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_failures => true) - shell("apt-key list | grep #{CENTOS_GPG_KEY_ID}", + shell(CENTOS_KEY_CHECK_COMMAND, :acceptable_exit_codes => [1]) shell("apt-key adv --keyserver keyserver.ubuntu.com \ - --recv-keys #{CENTOS_GPG_KEY_ID}") + --recv-keys #{CENTOS_GPG_KEY_FINGERPRINT}") end end @@ -93,21 +106,21 @@ describe 'apt_key' do it 'is removed' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'absent', } EOS # Install the key first shell("apt-key adv --keyserver keyserver.ubuntu.com \ - --recv-keys #{PUPPETLABS_GPG_LONG_KEY_ID}") - shell("apt-key list | grep #{PUPPETLABS_GPG_KEY_ID}") + --recv-keys #{PUPPETLABS_GPG_KEY_LONG_ID}") + shell(PUPPETLABS_KEY_CHECK_COMMAND) # Time to remove it using Puppet apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_failures => true) - shell("apt-key list | grep #{PUPPETLABS_GPG_KEY_ID}", + shell(PUPPETLABS_KEY_CHECK_COMMAND, :acceptable_exit_codes => [1]) end end @@ -118,7 +131,7 @@ describe 'apt_key' do it 'works' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_FINGERPRINT}', ensure => 'present', content => "-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.12 (GNU/Linux) @@ -185,7 +198,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_failures => true) - shell("apt-key list | grep #{PUPPETLABS_GPG_KEY_ID}") + shell(PUPPETLABS_KEY_CHECK_COMMAND) end end @@ -193,7 +206,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= it 'fails' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'present', content => 'For posterity: such content, much bogus, wow', } @@ -211,7 +224,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= it 'works' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'present', server => 'pgp.mit.edu', } @@ -219,7 +232,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_failures => true) - shell("apt-key list | grep #{PUPPETLABS_GPG_KEY_ID}") + shell(PUPPETLABS_KEY_CHECK_COMMAND) end end @@ -227,7 +240,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= it 'works' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_FINGERPRINT}', ensure => 'present', server => 'hkp://pgp.mit.edu:80', } @@ -235,7 +248,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_failures => true) - shell("apt-key list | grep #{PUPPETLABS_GPG_KEY_ID}") + shell(PUPPETLABS_KEY_CHECK_COMMAND) end end @@ -243,7 +256,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= it 'fails' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'present', server => 'nonexistant.key.server', } @@ -259,7 +272,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= it 'fails' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'present', server => '.pgp.key.server', } @@ -277,7 +290,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= it 'works' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'present', source => 'http://#{PUPPETLABS_APT_URL}/#{PUPPETLABS_GPG_KEY_FILE}', } @@ -285,13 +298,13 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_failures => true) - shell("apt-key list | grep #{PUPPETLABS_GPG_KEY_ID}") + shell(PUPPETLABS_KEY_CHECK_COMMAND) end it 'fails with a 404' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'present', source => 'http://#{PUPPETLABS_APT_URL}/herpderp.gpg', } @@ -305,7 +318,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= it 'fails with a socket error' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'present', source => 'http://apt.puppetlabss.com/herpderp.gpg', } @@ -319,14 +332,14 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= context 'ftp://' do before(:each) do - shell("apt-key del #{CENTOS_GPG_KEY_ID}", + shell("apt-key del #{CENTOS_GPG_KEY_LONG_ID}", :acceptable_exit_codes => [0,1,2]) end it 'works' do pp = <<-EOS apt_key { 'CentOS 6': - id => '#{CENTOS_GPG_KEY_ID}', + id => '#{CENTOS_GPG_KEY_LONG_ID}', ensure => 'present', source => 'ftp://#{CENTOS_REPO_URL}/#{CENTOS_GPG_KEY_FILE}', } @@ -334,13 +347,13 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_failures => true) - shell("apt-key list | grep #{CENTOS_GPG_KEY_ID}") + shell(CENTOS_KEY_CHECK_COMMAND) end it 'fails with a 550' do pp = <<-EOS apt_key { 'CentOS 6': - id => '#{CENTOS_GPG_KEY_ID}', + id => '#{SHOULD_NEVER_EXIST_ID}', ensure => 'present', source => 'ftp://#{CENTOS_REPO_URL}/herpderp.gpg', } @@ -354,7 +367,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= it 'fails with a socket error' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'present', source => 'ftp://apt.puppetlabss.com/herpderp.gpg', } @@ -370,7 +383,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= it 'works' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'present', source => 'https://#{PUPPETLABS_APT_URL}/#{PUPPETLABS_GPG_KEY_FILE}', } @@ -378,13 +391,13 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_failures => true) - shell("apt-key list | grep #{PUPPETLABS_GPG_KEY_ID}") + shell(PUPPETLABS_KEY_CHECK_COMMAND) end it 'fails with a 404' do pp = <<-EOS apt_key { 'puppetlabs': - id => '4BD6EC30', + id => '#{SHOULD_NEVER_EXIST_ID}', ensure => 'present', source => 'https://#{PUPPETLABS_APT_URL}/herpderp.gpg', } @@ -398,7 +411,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= it 'fails with a socket error' do pp = <<-EOS apt_key { 'puppetlabs': - id => '4BD6EC30', + id => '#{SHOULD_NEVER_EXIST_ID}', ensure => 'present', source => 'https://apt.puppetlabss.com/herpderp.gpg', } @@ -431,7 +444,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_failures => true) - shell("apt-key list | grep #{PUPPETLABS_GPG_KEY_ID}") + shell(PUPPETLABS_KEY_CHECK_COMMAND) end end @@ -439,7 +452,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= it 'fails' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'present', source => '/tmp/totally_bogus.file', } @@ -462,7 +475,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= it 'fails' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'present', source => '/tmp/fake-key.gpg', } @@ -480,7 +493,7 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= it 'works' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'present', keyserver_options => 'debug', } @@ -488,19 +501,19 @@ ugVIB2pi+8u84f+an4Hml4xlyijgYu05pqNvnLRyJDLd61hviLC8GYU= apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_failures => true) - shell("apt-key list | grep #{PUPPETLABS_GPG_KEY_ID}") + shell(PUPPETLABS_KEY_CHECK_COMMAND) end it 'fails on invalid options' do pp = <<-EOS apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_ID}', + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', ensure => 'present', keyserver_options => 'this is totally bonkers', } EOS - shell("apt-key del #{PUPPETLABS_GPG_KEY_ID}", :acceptable_exit_codes => [0,1,2]) + shell("apt-key del #{PUPPETLABS_GPG_KEY_FINGERPRINT}", :acceptable_exit_codes => [0,1,2]) apply_manifest(pp, :expect_failures => true) do |r| expect(r.stderr).to match(/--keyserver-options this is totally/) end diff --git a/spec/defines/key_spec.rb b/spec/defines/key_spec.rb index dbb67c4..b09dc5b 100644 --- a/spec/defines/key_spec.rb +++ b/spec/defines/key_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe 'apt::key', :type => :define do let(:facts) { { :lsbdistid => 'Debian' } } - GPG_KEY_ID = '4BD6EC30' + GPG_KEY_ID = '47B320EB4C7C375AA9DAE1A01054B7A24BD6EC30' let :title do GPG_KEY_ID diff --git a/spec/defines/source_spec.rb b/spec/defines/source_spec.rb index e5db5c5..ae47ccf 100644 --- a/spec/defines/source_spec.rb +++ b/spec/defines/source_spec.rb @@ -1,7 +1,8 @@ require 'spec_helper' describe 'apt::source', :type => :define do - GPG_KEY_ID = '4BD6EC30' + GPG_KEY_ID = '47B320EB4C7C375AA9DAE1A01054B7A24BD6EC30' + let :title do 'my_source' diff --git a/spec/unit/facter/apt_has_updates_spec.rb b/spec/unit/facter/apt_has_updates_spec.rb index 691fb32..f8a3f20 100644 --- a/spec/unit/facter/apt_has_updates_spec.rb +++ b/spec/unit/facter/apt_has_updates_spec.rb @@ -6,27 +6,49 @@ describe 'apt_has_updates fact' do describe 'on non-Debian distro' do before { - Facter.fact(:osfamily).expects(:value).returns 'RedHat' + Facter.fact(:osfamily).expects(:value).at_least(1).returns 'RedHat' } it { should be_nil } end describe 'on Debian based distro missing update-notifier-common' do before { - Facter.fact(:osfamily).expects(:value).returns 'Debian' + Facter.fact(:osfamily).expects(:value).at_least(1).returns 'Debian' File.stubs(:executable?) # Stub all other calls File.expects(:executable?).with('/usr/lib/update-notifier/apt-check').returns false } it { should be_nil } end + describe 'on Debian based distro with broken packages' do + before { + Facter.fact(:osfamily).expects(:value).at_least(1).returns 'Debian' + File.stubs(:executable?) # Stub all other calls + Facter::Util::Resolution.stubs(:exec) # Catch all other calls + File.expects(:executable?).with('/usr/lib/update-notifier/apt-check').returns true + Facter::Util::Resolution.expects(:exec).with('/usr/lib/update-notifier/apt-check 2>&1').returns "E: Error: BrokenCount > 0" + } + it { should be_nil } + end + + describe 'on Debian based distro with unknown error with semicolons' do + before { + Facter.fact(:osfamily).expects(:value).at_least(1).returns 'Debian' + File.stubs(:executable?) # Stub all other calls + Facter::Util::Resolution.stubs(:exec) # Catch all other calls + File.expects(:executable?).with('/usr/lib/update-notifier/apt-check').returns true + Facter::Util::Resolution.expects(:exec).with('/usr/lib/update-notifier/apt-check 2>&1').returns "E: Unknown Error: 'This error contains something that could be parsed like 4;3' (10)" + } + it { should be_nil } + end + describe 'on Debian based distro' do before { - Facter.fact(:osfamily).expects(:value).returns 'Debian' + Facter.fact(:osfamily).expects(:value).at_least(1).returns 'Debian' File.stubs(:executable?) # Stub all other calls Facter::Util::Resolution.stubs(:exec) # Catch all other calls File.expects(:executable?).with('/usr/lib/update-notifier/apt-check').returns true - Facter::Util::Resolution.expects(:exec).with('/usr/lib/update-notifier/apt-check 2>/dev/null').returns "4;3" + Facter::Util::Resolution.expects(:exec).with('/usr/lib/update-notifier/apt-check 2>&1').returns "4;3" } it { should be true } end diff --git a/spec/unit/facter/apt_package_updates_spec.rb b/spec/unit/facter/apt_package_updates_spec.rb index c0f54f2..5c7a624 100644 --- a/spec/unit/facter/apt_package_updates_spec.rb +++ b/spec/unit/facter/apt_package_updates_spec.rb @@ -17,8 +17,8 @@ describe 'apt_package_updates fact' do File.stubs(:executable?) # Stub all other calls Facter::Util::Resolution.stubs(:exec) # Catch all other calls File.expects(:executable?).with('/usr/lib/update-notifier/apt-check').returns true - Facter::Util::Resolution.expects(:exec).with('/usr/lib/update-notifier/apt-check 2>/dev/null').returns "1;2" - Facter::Util::Resolution.expects(:exec).with('/usr/lib/update-notifier/apt-check -p 2>/dev/null').returns "puppet-common\nlinux-generic\nlinux-image-generic" + Facter::Util::Resolution.expects(:exec).with('/usr/lib/update-notifier/apt-check 2>&1').returns "1;2" + Facter::Util::Resolution.expects(:exec).with('/usr/lib/update-notifier/apt-check -p 2>&1').returns "puppet-common\nlinux-generic\nlinux-image-generic" } it { if Facter.version < '2.0.0' diff --git a/spec/unit/facter/apt_security_updates_spec.rb b/spec/unit/facter/apt_security_updates_spec.rb index a5d26c7..4bc760f 100644 --- a/spec/unit/facter/apt_security_updates_spec.rb +++ b/spec/unit/facter/apt_security_updates_spec.rb @@ -17,7 +17,7 @@ describe 'apt_security_updates fact' do File.stubs(:executable?) # Stub all other calls Facter::Util::Resolution.stubs(:exec) # Catch all other calls File.expects(:executable?).with('/usr/lib/update-notifier/apt-check').returns true - Facter::Util::Resolution.expects(:exec).with('/usr/lib/update-notifier/apt-check 2>/dev/null').returns "14;7" + Facter::Util::Resolution.expects(:exec).with('/usr/lib/update-notifier/apt-check 2>&1').returns "14;7" } it { should == 7 } end diff --git a/spec/unit/facter/apt_updates_spec.rb b/spec/unit/facter/apt_updates_spec.rb index 538466f..7e9b77f 100644 --- a/spec/unit/facter/apt_updates_spec.rb +++ b/spec/unit/facter/apt_updates_spec.rb @@ -17,7 +17,7 @@ describe 'apt_updates fact' do File.stubs(:executable?) # Stub all other calls Facter::Util::Resolution.stubs(:exec) # Catch all other calls File.expects(:executable?).with('/usr/lib/update-notifier/apt-check').returns true - Facter::Util::Resolution.expects(:exec).with('/usr/lib/update-notifier/apt-check 2>/dev/null').returns "14;7" + Facter::Util::Resolution.expects(:exec).with('/usr/lib/update-notifier/apt-check 2>&1').returns "14;7" } it { should == 14 } end