From: sheenaajay Date: Wed, 3 Jul 2019 14:21:02 +0000 (+0100) Subject: Merge pull request #867 from eimlav/pdksync_modules-9482 X-Git-Tag: v7.1.0~2 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=6d0c3f5537345f27675f044a2181dcadce75fafb;hp=175a89281282fd7b53d5953faef05f122d5eedf3;p=puppet-modules%2Fpuppetlabs-apt.git Merge pull request #867 from eimlav/pdksync_modules-9482 (MODULES-9482) Bump translate dependency upper range --- diff --git a/.fixtures.yml b/.fixtures.yml index b419b4d..6c2bda8 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -4,5 +4,8 @@ fixtures: "repo": "git://github.com/puppetlabs/puppetlabs-stdlib.git" "translate": "repo": "https://github.com/puppetlabs/puppetlabs-translate" + facts: 'git://github.com/puppetlabs/puppetlabs-facts.git' + puppet_agent: 'git://github.com/puppetlabs/puppetlabs-puppet_agent.git' + provision: 'git://github.com/puppetlabs/provision.git' symlinks: "apt": "#{source_dir}" diff --git a/.gitignore b/.gitignore index 650022e..3f4e2e8 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ /convert_report.txt /update_report.txt .DS_Store +.envrc +/inventory.yaml diff --git a/.pdkignore b/.pdkignore index b713b3b..54d2cda 100644 --- a/.pdkignore +++ b/.pdkignore @@ -22,6 +22,8 @@ /convert_report.txt /update_report.txt .DS_Store +.envrc +/inventory.yaml /appveyor.yml /.fixtures.yml /Gemfile @@ -30,8 +32,10 @@ /.gitlab-ci.yml /.pdkignore /Rakefile +/rakelib/ /.rspec /.rubocop.yml /.travis.yml /.yardopts /spec/ +/.vscode/ diff --git a/.puppet-lint.rc b/.puppet-lint.rc index e69de29..cc96ece 100644 --- a/.puppet-lint.rc +++ b/.puppet-lint.rc @@ -0,0 +1 @@ +--relative diff --git a/.rubocop.yml b/.rubocop.yml index b25405c..ee74e8c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,7 +1,7 @@ --- require: -- rubocop-i18n - rubocop-rspec +- rubocop-i18n AllCops: DisplayCopNames: true TargetRubyVersion: '2.1' @@ -21,10 +21,12 @@ AllCops: Metrics/LineLength: Description: People have wide screens, use them. Max: 200 +GetText: + Enabled: false GetText/DecorateString: Description: We don't want to decorate test output. Exclude: - - spec/* + - spec/**/* RSpec/BeforeAfterAll: Description: Beware of using after(:all) as it may cause state to leak between tests. A necessary evil in acceptance testing. diff --git a/.sync.yml b/.sync.yml index ad63bcd..090130d 100644 --- a/.sync.yml +++ b/.sync.yml @@ -1,24 +1,25 @@ --- +.gitignore: + required: + - ---.project + +.gitlab-ci.yml: + unmanaged: true + +.rubocop.yml: + default_configs: + inherit_from: .rubocop_todo.yml + require: + - rubocop-i18n + - rubocop-rspec + .travis.yml: - docker_sets: - - set: docker/debian-8 - - set: docker/ubuntu-14.04 - docker_defaults: - bundler_args: "" - secure: "" - branches: - - release + unmanaged: true + +appveyor.yml: + delete: true Gemfile: - required: - ':system_tests': - - gem: 'puppet-module-posix-system-r#{minor_version}' - platforms: ruby - - gem: 'puppet-module-win-system-r#{minor_version}' - platforms: - - mswin - - mingw - - x64_mingw optional: ':development': - gem: 'github_changelog_generator' @@ -27,19 +28,10 @@ Gemfile: condition: "Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.2.2')" - gem: puppet-lint-i18n -.rubocop.yml: - default_configs: - inherit_from: .rubocop_todo.yml - require: - - rubocop-i18n - - rubocop-rspec - Rakefile: requires: - puppet_pot_generator/rake_tasks -appveyor.yml: - delete: true - -.gitlab-ci.yml: - unmanaged: true +spec/spec_helper.rb: + mock_with: ':rspec' + coverage_report: true diff --git a/.travis.yml b/.travis.yml index d7e4f48..0b2378e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ --- -dist: trusty language: ruby cache: bundler before_install: @@ -12,39 +11,60 @@ script: - 'bundle exec rake $CHECK' bundler_args: --without system_tests rvm: - - 2.5.1 -env: - global: - - BEAKER_PUPPET_COLLECTION=puppet6 PUPPET_GEM_VERSION="~> 6.0" + - 2.5.3 +stages: + - static + - spec + - acceptance + - + if: tag =~ ^v\d + name: deploy matrix: fast_finish: true include: - - bundler_args: + bundler_args: dist: trusty - env: PUPPET_INSTALL_TYPE=agent BEAKER_debug=true BEAKER_PUPPET_COLLECTION=puppet6 BEAKER_set=docker/debian-8 BEAKER_TESTMODE=apply - rvm: 2.5.1 - script: bundle exec rake beaker + env: PLATFORMS=deb_puppet5 + rvm: 2.5.3 + before_script: + - bundle exec rake 'litmus:provision_list[travis_deb]' + - bundle exec bolt command run 'apt-get install wget -y' --inventoryfile inventory.yaml --nodes='localhost*' + - bundle exec rake 'litmus:install_agent[puppet5]' + - bundle exec rake litmus:install_module + script: + - bundle exec rake litmus:acceptance:parallel services: docker + stage: acceptance sudo: required - - bundler_args: + bundler_args: dist: trusty - env: PUPPET_INSTALL_TYPE=agent BEAKER_debug=true BEAKER_PUPPET_COLLECTION=puppet6 BEAKER_set=docker/ubuntu-14.04 BEAKER_TESTMODE=apply - rvm: 2.5.1 - script: bundle exec rake beaker + env: PLATFORM=deb_puppet6 + rvm: 2.5.3 + before_script: + - bundle exec rake 'litmus:provision_list[travis_deb]' + - bundle exec bolt command run 'apt-get install wget -y' --inventoryfile inventory.yaml --nodes='localhost*' + - bundle exec rake 'litmus:install_agent[puppet6]' + - bundle exec rake litmus:install_module + script: + - bundle exec rake litmus:acceptance:parallel services: docker sudo: required - - env: CHECK="syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop" - - - env: CHECK=parallel_spec + env: CHECK="check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop syntax lint metadata_lint" + stage: static - env: PUPPET_GEM_VERSION="~> 5.0" CHECK=parallel_spec - rvm: 2.4.4 + rvm: 2.4.5 + stage: spec + - + env: PUPPET_GEM_VERSION="~> 6.0" CHECK=parallel_spec + rvm: 2.5.3 + stage: spec - - env: PUPPET_GEM_VERSION="~> 4.0" CHECK=parallel_spec RUBYGEMS_VERSION=2.7.8 - rvm: 2.1.9 + env: DEPLOY_TO_FORGE=yes + stage: deploy branches: only: - master @@ -52,12 +72,3 @@ branches: - release notifications: email: false -deploy: - provider: puppetforge - user: puppet - password: - secure: "" - on: - tags: true - all_branches: true - condition: "$DEPLOY_TO_FORGE = yes" diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..6177782 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "jpogran.puppet-vscode", + "rebornix.Ruby" + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 46a2d4b..df3890f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,37 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org). +## [v7.0.1](https://github.com/puppetlabs/puppetlabs-apt/tree/v7.0.1) (2019-05-13) + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-apt/compare/7.0.0...v7.0.1) + +## [7.0.0](https://github.com/puppetlabs/puppetlabs-apt/tree/7.0.0) (2019-04-24) + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-apt/compare/6.3.0...7.0.0) + +### Changed + +- pdksync - \(MODULES-8444\) - Raise lower Puppet bound [\#853](https://github.com/puppetlabs/puppetlabs-apt/pull/853) ([david22swan](https://github.com/david22swan)) + +### Added + +- Allow weak SSL verification for apt\_key [\#849](https://github.com/puppetlabs/puppetlabs-apt/pull/849) ([tuxmea](https://github.com/tuxmea)) + +## [6.3.0](https://github.com/puppetlabs/puppetlabs-apt/tree/6.3.0) (2019-01-21) + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-apt/compare/6.2.1...6.3.0) + +### Added + +- Add support for dist-upgrade & autoremove action [\#832](https://github.com/puppetlabs/puppetlabs-apt/pull/832) ([aboks](https://github.com/aboks)) +- \(MODULES-8321\) - Add manage\_auth\_conf parameter [\#831](https://github.com/puppetlabs/puppetlabs-apt/pull/831) ([eimlav](https://github.com/eimlav)) + +### Fixed + +- \(MODULES-8418\) Fix /etc/apt/auth.conf owner changing endlessly [\#836](https://github.com/puppetlabs/puppetlabs-apt/pull/836) ([antaflos](https://github.com/antaflos)) +- pdksync - \(FM-7655\) Fix rubygems-update for ruby \< 2.3 [\#835](https://github.com/puppetlabs/puppetlabs-apt/pull/835) ([tphoney](https://github.com/tphoney)) +- \(MODULES-8326\) - apt-transport-https not ensured properly [\#830](https://github.com/puppetlabs/puppetlabs-apt/pull/830) ([eimlav](https://github.com/eimlav)) + ## [6.2.1](https://github.com/puppetlabs/puppetlabs-apt/tree/6.2.1) (2018-11-20) [Full Changelog](https://github.com/puppetlabs/puppetlabs-apt/compare/6.2.0...6.2.1) diff --git a/Gemfile b/Gemfile index d85a609..0287895 100644 --- a/Gemfile +++ b/Gemfile @@ -17,21 +17,18 @@ ruby_version_segments = Gem::Version.new(RUBY_VERSION.dup).segments minor_version = ruby_version_segments[0..1].join('.') group :development do - gem "fast_gettext", '1.1.0', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.1.0') - gem "fast_gettext", require: false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.1.0') - gem "json_pure", '<= 2.0.1', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0') - gem "json", '= 1.8.1', require: false if Gem::Version.new(RUBY_VERSION.dup) == Gem::Version.new('2.1.9') - gem "json", '<= 2.0.4', require: false if Gem::Version.new(RUBY_VERSION.dup) == Gem::Version.new('2.4.4') - gem "puppet-module-posix-default-r#{minor_version}", require: false, platforms: [:ruby] - gem "puppet-module-posix-dev-r#{minor_version}", require: false, platforms: [:ruby] - gem "puppet-module-win-default-r#{minor_version}", require: false, platforms: [:mswin, :mingw, :x64_mingw] - gem "puppet-module-win-dev-r#{minor_version}", require: false, platforms: [:mswin, :mingw, :x64_mingw] - gem "github_changelog_generator", require: false, git: 'https://github.com/skywinder/github-changelog-generator', ref: '20ee04ba1234e9e83eb2ffb5056e23d641c7a018' if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.2.2') - gem "puppet-lint-i18n", require: false -end -group :system_tests do - gem "puppet-module-posix-system-r#{minor_version}", require: false, platforms: [:ruby] - gem "puppet-module-win-system-r#{minor_version}", require: false, platforms: [:mswin, :mingw, :x64_mingw] + gem "fast_gettext", '1.1.0', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.1.0') + gem "fast_gettext", require: false if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.1.0') + gem "json_pure", '<= 2.0.1', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0') + gem "json", '= 1.8.1', require: false if Gem::Version.new(RUBY_VERSION.dup) == Gem::Version.new('2.1.9') + gem "json", '= 2.0.4', require: false if Gem::Requirement.create('~> 2.4.2').satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "json", '= 2.1.0', require: false if Gem::Requirement.create(['>= 2.5.0', '< 2.7.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "puppet-module-posix-default-r#{minor_version}", '~> 0.3', require: false, platforms: [:ruby] + gem "puppet-module-posix-dev-r#{minor_version}", '~> 0.3', require: false, platforms: [:ruby] + gem "puppet-module-win-default-r#{minor_version}", '~> 0.3', require: false, platforms: [:mswin, :mingw, :x64_mingw] + gem "puppet-module-win-dev-r#{minor_version}", '~> 0.3', require: false, platforms: [:mswin, :mingw, :x64_mingw] + gem "github_changelog_generator", require: false, git: 'https://github.com/skywinder/github-changelog-generator', ref: '20ee04ba1234e9e83eb2ffb5056e23d641c7a018' if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.2.2') + gem "puppet-lint-i18n", require: false end puppet_version = ENV['PUPPET_GEM_VERSION'] diff --git a/README.md b/README.md index 105c3f0..a5abc07 100644 --- a/README.md +++ b/README.md @@ -305,6 +305,6 @@ Class['apt::update'] -> Package <| provider == 'apt' |> Puppet modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can't access the huge number of platforms and myriad hardware, software, and deployment configurations that Puppet is intended to serve. We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. -For more information, see our [module contribution guide.](https://docs.puppetlabs.com/forge/contributing.html) +For more information, see our [module contribution guide.](https://puppet.com/docs/puppet/latest/contributing.html) To see who's already involved, see the [list of contributors.](https://github.com/puppetlabs/puppetlabs-apt/graphs/contributors) diff --git a/REFERENCE.md b/REFERENCE.md index 081866d..06aff21 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -65,8 +65,8 @@ Default value: $apt::params::provider Data type: `String` -Specifies a keyserver to provide the GPG key. Valid options: a string containing a domain name or a full URL (http://, https://, -hkp:// or hkps://). The hkps:// protocol is currently only supported on Ubuntu 18.04. +Specifies a keyserver to provide the GPG key. Valid options: a string containing a domain name or a full URL (http://, https://, or +hkp://). Default value: $apt::params::keyserver @@ -189,6 +189,15 @@ Creates new `apt::setting` resources. Valid options: a hash to be passed to the Default value: $apt::params::settings +##### `manage_auth_conf` + +Data type: `Boolean` + +Specifies whether to manage the /etc/apt/auth.conf file. When true, the file will be overwritten with the entries specified in +the auth_conf_entries parameter. When false, the file will be ignored (note that this does not set the file to absent. + +Default value: $apt::params::manage_auth_conf + ##### `auth_conf_entries` Data type: `Array[Apt::Auth_conf_entry]` @@ -196,10 +205,18 @@ Data type: `Array[Apt::Auth_conf_entry]` An optional array of login configuration settings (hashes) that are recorded in the file /etc/apt/auth.conf. This file has a netrc-like format (similar to what curl uses) and contains the login configuration for APT sources and proxies that require authentication. See https://manpages.debian.org/testing/apt/apt_auth.conf.5.en.html for details. If specified each hash must contain the keys machine, login and -password and no others. +password and no others. Specifying manage_auth_conf and not specifying this parameter will set /etc/apt/auth.conf to absent. Default value: $apt::params::auth_conf_entries +##### `auth_conf_owner` + +Data type: `String` + +The owner of the file /etc/apt/auth.conf. Default: '_apt' or 'root' on old releases. + +Default value: $apt::params::auth_conf_owner + ##### `root` Data type: `String` @@ -488,6 +505,14 @@ hkp:// or hkps://). The hkps:// protocol is currently only supported on Ubuntu 1 Default value: $::apt::keyserver +##### `weak_ssl` + +Data type: `Boolean` + +Specifies whether strict SSL verification on a https URL should be disabled. Valid options: true or false. + +Default value: `false` + ##### `options` Data type: `Optional[String]` @@ -859,7 +884,7 @@ Allows you to perform apt functions ##### `action` -Data type: `Enum[update, upgrade]` +Data type: `Enum[update, upgrade, dist-upgrade, autoremove]` Action to perform diff --git a/Rakefile b/Rakefile index cf0d523..13b58c8 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,4 @@ +require 'puppet_litmus/rake_tasks' if Bundler.rubygems.find_name('puppet_litmus').any? require 'puppetlabs_spec_helper/rake_tasks' require 'puppet-syntax/tasks/puppet-syntax' require 'puppet_blacksmith/rake_tasks' if Bundler.rubygems.find_name('puppet-blacksmith').any? @@ -15,7 +16,7 @@ end def changelog_project return unless Rake.application.top_level_tasks.include? "changelog" - returnVal = nil || JSON.load(File.read('metadata.json'))['name'] + returnVal = nil || JSON.load(File.read('metadata.json'))['source'].match(%r{.*/([^/]*)})[1] raise "unable to find the changelog_project in .sync.yml or the name in metadata.json" if returnVal.nil? puts "GitHubChangelogGenerator project:#{returnVal}" returnVal @@ -23,7 +24,7 @@ end def changelog_future_release return unless Rake.application.top_level_tasks.include? "changelog" - returnVal = JSON.load(File.read('metadata.json'))['version'] + returnVal = "v%s" % JSON.load(File.read('metadata.json'))['version'] raise "unable to find the future_release (version) in metadata.json" if returnVal.nil? puts "GitHubChangelogGenerator future_release:#{returnVal}" returnVal diff --git a/distelli-manifest.yml b/distelli-manifest.yml new file mode 100644 index 0000000..294ac2e --- /dev/null +++ b/distelli-manifest.yml @@ -0,0 +1,25 @@ +team-modules/puppetlabs-apt: + PreBuild: + - source /opt/rh/rh-ruby25/enable + - echo "--- LETS update BUNDLER ---" + - bundle install --path vendor/bundle --jobs 3 + Build: + - echo "--- PROVISIONING ---" + - source /opt/rh/rh-ruby25/enable + - bundle exec rake litmus:provision_list[release_checks] + - cat inventory.yaml + - echo "--- AGENT INSTALLATION ---" + - bundle exec rake litmus:install_agent + - echo "--- MODULE INSTALLATION ---" + - bundle exec rake litmus:install_module + - echo "--- TESTS RUNNING ---" + - bundle exec rake litmus:acceptance:parallel + AfterBuildSuccess: + - source /opt/rh/rh-ruby25/enable + - bundle exec rake litmus:tear_down + AfterBuildFailure: + - source /opt/rh/rh-ruby25/enable + - bundle exec rake litmus:tear_down + CommitData: + - RepoType: Git + - RepoPath: . diff --git a/lib/facter/apt_updates.rb b/lib/facter/apt_updates.rb index 7a701c1..c2f38a8 100644 --- a/lib/facter/apt_updates.rb +++ b/lib/facter/apt_updates.rb @@ -48,44 +48,28 @@ end Facter.add('apt_package_updates') do confine apt_has_updates: true setcode do - if Facter.version < '2.0.0' - apt_package_updates[0].join(',') - else - apt_package_updates[0] - end + apt_package_updates[0] end end Facter.add('apt_package_dist_updates') do confine apt_has_dist_updates: true setcode do - if Facter.version < '2.0.0' - apt_dist_updates[0].join(',') - else - apt_dist_updates[0] - end + apt_dist_updates[0] end end Facter.add('apt_package_security_updates') do confine apt_has_updates: true setcode do - if Facter.version < '2.0.0' - apt_package_updates[1].join(',') - else - apt_package_updates[1] - end + apt_package_updates[1] end end Facter.add('apt_package_security_dist_updates') do confine apt_has_dist_updates: true setcode do - if Facter.version < '2.0.0' - apt_dist_updates[1].join(',') - else - apt_dist_updates[1] - end + apt_dist_updates[1] end end diff --git a/lib/puppet/provider/apt_key/apt_key.rb b/lib/puppet/provider/apt_key/apt_key.rb index 2bcaf8d..9f70cc6 100644 --- a/lib/puppet/provider/apt_key/apt_key.rb +++ b/lib/puppet/provider/apt_key/apt_key.rb @@ -2,14 +2,6 @@ require 'open-uri' require 'net/ftp' require 'tempfile' -if RUBY_VERSION == '1.8.7' - # Mothers cry, puppies die and Ruby 1.8.7's open-uri needs to be - # monkeypatched to support passing in :ftp_passive_mode. - require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', - 'puppet_x', 'apt_key', 'patch_openuri.rb')) - OpenURI::Options[:ftp_active_mode] = false -end - Puppet::Type.type(:apt_key).provide(:apt_key) do desc 'apt-key provider for apt_key resource' @@ -134,7 +126,11 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do # Only send basic auth if URL contains userinfo # Some webservers (e.g. Amazon S3) return code 400 if empty basic auth is sent if parsed_value.userinfo.nil? - key = parsed_value.read + key = if parsed_value.scheme == 'https' && resource[:weak_ssl] == true + open(parsed_value, ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE).read + else + parsed_value.read + end else user_pass = parsed_value.userinfo.split(':') parsed_value.userinfo = '' @@ -245,12 +241,6 @@ Puppet::Type.type(:apt_key).provide(:apt_key) do mk_resource_methods - # Needed until PUP-1470 is fixed and we can drop support for Puppet versions - # before that. - def expired - @property_hash[:expired] - end - # Alias the setters of read-only properties # to the read_only function. alias_method :created=, :read_only diff --git a/lib/puppet/type/apt_key.rb b/lib/puppet/type/apt_key.rb index 467f568..8c5c84c 100644 --- a/lib/puppet/type/apt_key.rb +++ b/lib/puppet/type/apt_key.rb @@ -80,6 +80,11 @@ Puppet::Type.newtype(:apt_key) do defaultto false end + newparam(:weak_ssl, boolean: true, parent: Puppet::Parameter::Boolean) do + desc 'When true and source uses https, accepts download of keys without SSL verfication' + defaultto false + end + newproperty(:fingerprint) do desc <<-MANIFEST The 40-digit hexadecimal fingerprint of the specified GPG key. diff --git a/manifests/init.pp b/manifests/init.pp index b23acc7..d95bbe6 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -6,11 +6,11 @@ # Specifies the provider that should be used by apt::update. # # @param keyserver -# Specifies a keyserver to provide the GPG key. Valid options: a string containing a domain name or a full URL (http://, https://, or +# Specifies a keyserver to provide the GPG key. Valid options: a string containing a domain name or a full URL (http://, https://, or # hkp://). # # @param ppa_options -# Supplies options to be passed to the `add-apt-repository` command. +# Supplies options to be passed to the `add-apt-repository` command. # # @param ppa_package # Names the package that provides the `apt-add-repository` command. @@ -18,13 +18,13 @@ # @param backports # Specifies some of the default parameters used by apt::backports. Valid options: a hash made up from the following keys: # -# @option backports [String] :location +# @option backports [String] :location # See apt::backports for documentation. # -# @option backports [String] :repos +# @option backports [String] :repos # See apt::backports for documentation. # -# @option backports [String] :key +# @option backports [String] :key # See apt::backports for documentation. # # @param confs @@ -34,9 +34,9 @@ # Configures various update settings. Valid options: a hash made up from the following keys: # # @option update [String] :frequency -# Specifies how often to run `apt-get update`. If the exec resource `apt_update` is notified, `apt-get update` runs regardless of this value. -# Valid options: 'always' (at every Puppet run); 'daily' (if the value of `apt_update_last_success` is less than current epoch time minus 86400); -# 'weekly' (if the value of `apt_update_last_success` is less than current epoch time minus 604800); and 'reluctantly' (only if the exec resource +# Specifies how often to run `apt-get update`. If the exec resource `apt_update` is notified, `apt-get update` runs regardless of this value. +# Valid options: 'always' (at every Puppet run); 'daily' (if the value of `apt_update_last_success` is less than current epoch time minus 86400); +# 'weekly' (if the value of `apt_update_last_success` is less than current epoch time minus 604800); and 'reluctantly' (only if the exec resource # `apt_update` is notified). Default: 'reluctantly'. # # @option update [Integer] :loglevel @@ -86,28 +86,31 @@ # the auth_conf_entries parameter. When false, the file will be ignored (note that this does not set the file to absent. # # @param auth_conf_entries -# An optional array of login configuration settings (hashes) that are recorded in the file /etc/apt/auth.conf. This file has a netrc-like -# format (similar to what curl uses) and contains the login configuration for APT sources and proxies that require authentication. See -# https://manpages.debian.org/testing/apt/apt_auth.conf.5.en.html for details. If specified each hash must contain the keys machine, login and +# An optional array of login configuration settings (hashes) that are recorded in the file /etc/apt/auth.conf. This file has a netrc-like +# format (similar to what curl uses) and contains the login configuration for APT sources and proxies that require authentication. See +# https://manpages.debian.org/testing/apt/apt_auth.conf.5.en.html for details. If specified each hash must contain the keys machine, login and # password and no others. Specifying manage_auth_conf and not specifying this parameter will set /etc/apt/auth.conf to absent. # +# @param auth_conf_owner +# The owner of the file /etc/apt/auth.conf. Default: '_apt' or 'root' on old releases. +# # @param root # Specifies root directory of Apt executable. # # @param sources_list -# Specifies the path of the sources_list file to use. +# Specifies the path of the sources_list file to use. # # @param sources_list_d -# Specifies the path of the sources_list.d file to use. +# Specifies the path of the sources_list.d file to use. # # @param conf_d -# Specifies the path of the conf.d file to use. +# Specifies the path of the conf.d file to use. # # @param preferences -# Specifies the path of the preferences file to use. +# Specifies the path of the preferences file to use. # # @param preferences_d -# Specifies the path of the preferences.d file to use. +# Specifies the path of the preferences.d file to use. # # @param config_files # A hash made up of the various configuration files used by Apt. @@ -134,6 +137,7 @@ class apt ( Boolean $manage_auth_conf = $apt::params::manage_auth_conf, Array[Apt::Auth_conf_entry] $auth_conf_entries = $apt::params::auth_conf_entries, + String $auth_conf_owner = $apt::params::auth_conf_owner, String $root = $apt::params::root, String $sources_list = $apt::params::sources_list, String $sources_list_d = $apt::params::sources_list_d, @@ -284,7 +288,7 @@ class apt ( file { '/etc/apt/auth.conf': ensure => $auth_conf_ensure, - owner => 'root', + owner => $auth_conf_owner, group => 'root', mode => '0600', content => "${confheadertmp}${auth_conf_tmp}", diff --git a/manifests/key.pp b/manifests/key.pp index 13b4770..1f9a495 100644 --- a/manifests/key.pp +++ b/manifests/key.pp @@ -29,6 +29,9 @@ # Specifies a keyserver to provide the GPG key. Valid options: a string containing a domain name or a full URL (http://, https://, # hkp:// or hkps://). The hkps:// protocol is currently only supported on Ubuntu 18.04. # +# @param weak_ssl +# Specifies whether strict SSL verification on a https URL should be disabled. Valid options: true or false. +# # @param options # Passes additional options to `apt-key adv --keyserver-options`. # @@ -38,6 +41,7 @@ define apt::key ( Optional[String] $content = undef, Optional[Pattern[/\Ahttps?:\/\//, /\Aftp:\/\//, /\A\/\w+/]] $source = undef, Pattern[/\A((hkp|hkps|http|https):\/\/)?([a-z\d])([a-z\d-]{0,61}\.)+[a-z\d]+(:\d{2,5})?$/] $server = $::apt::keyserver, + Boolean $weak_ssl = false, Optional[String] $options = undef, ) { @@ -49,13 +53,14 @@ define apt::key ( if !defined(Anchor["apt_key ${id} present"]) { apt_key { $title: - ensure => present, - refresh => $ensure == 'refreshed', - id => $id, - source => $source, - content => $content, - server => $server, - options => $options, + ensure => present, + refresh => $ensure == 'refreshed', + id => $id, + source => $source, + content => $content, + server => $server, + weak_ssl => $weak_ssl, + options => $options, } -> anchor { "apt_key ${id} present": } case $facts['os']['name'] { @@ -83,12 +88,13 @@ define apt::key ( if !defined(Anchor["apt_key ${id} absent"]){ apt_key { $title: - ensure => $ensure, - id => $id, - source => $source, - content => $content, - server => $server, - options => $options, + ensure => $ensure, + id => $id, + source => $source, + content => $content, + server => $server, + weak_ssl => $weak_ssl, + options => $options, } -> anchor { "apt_key ${id} absent": } } } diff --git a/manifests/params.pp b/manifests/params.pp index 52b9bca..76f06b9 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -82,11 +82,15 @@ class apt::params { 'Debian': { $backports = { 'location' => 'http://deb.debian.org/debian', - 'key' => 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', 'repos' => 'main contrib non-free', } $ppa_options = undef $ppa_package = undef + if versioncmp($facts['os']['release']['major'], '9') >= 0 { + $auth_conf_owner = '_apt' + } else { + $auth_conf_owner = 'root' + } } 'Ubuntu': { $backports = { @@ -96,6 +100,11 @@ class apt::params { } $ppa_options = '-y' $ppa_package = 'software-properties-common' + if versioncmp($facts['os']['release']['full'], '16.04') >= 0 { + $auth_conf_owner = '_apt' + } else { + $auth_conf_owner = 'root' + } } undef: { fail(translate('Unable to determine value for fact os[\"name\"]')) @@ -104,6 +113,7 @@ class apt::params { $ppa_options = undef $ppa_package = undef $backports = undef + $auth_conf_owner = 'root' } } } diff --git a/metadata.json b/metadata.json index 8c78ad3..e46abab 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-apt", - "version": "6.2.1", + "version": "7.0.1", "author": "puppetlabs", "summary": "Provides an interface for managing Apt source, key, and definitions with Puppet", "license": "Apache-2.0", @@ -10,7 +10,7 @@ "dependencies": [ { "name": "puppetlabs/stdlib", - "version_requirement": ">= 4.16.0 < 6.0.0" + "version_requirement": ">= 4.16.0 < 7.0.0" }, { "name": "puppetlabs/translate", @@ -37,10 +37,10 @@ "requirements": [ { "name": "puppet", - "version_requirement": ">= 4.8.0 < 7.0.0" + "version_requirement": ">= 5.5.10 < 7.0.0" } ], - "template-url": "https://github.com/puppetlabs/pdk-templates/", - "template-ref": "heads/master-0-g20af4c6", - "pdk-version": "1.8.0" -} \ No newline at end of file + "template-url": "https://github.com/puppetlabs/pdk-templates/#master", + "template-ref": "heads/master-0-g2b33205", + "pdk-version": "1.10.0" +} diff --git a/provision.yaml b/provision.yaml new file mode 100644 index 0000000..e20c29d --- /dev/null +++ b/provision.yaml @@ -0,0 +1,13 @@ +--- +default: + provisioner: docker + images: ['waffleimage/debian8'] +travis_deb: + provisioner: docker + images: ['debian:8', 'debian:9', 'ubuntu:14.04', 'ubuntu:16.04', 'ubuntu:18.04'] +waffle_deb: + provisioner: docker + images: ['waffleimage/debian8', 'waffleimage/debian9', 'waffleimage/ubuntu14.04', 'waffleimage/ubuntu16.04', 'waffleimage/ubuntu18.04'] +release_checks: + provisioner: vmpooler + images: ['debian-8-x86_64', 'debian-9-x86_64', 'ubuntu-1404-x86_64', 'ubuntu-1604-x86_64', 'ubuntu-1804-x86_64'] diff --git a/spec/acceptance/apt_key_provider_spec.rb b/spec/acceptance/apt_key_provider_spec.rb index fdb2ec6..0c4539d 100644 --- a/spec/acceptance/apt_key_provider_spec.rb +++ b/spec/acceptance/apt_key_provider_spec.rb @@ -19,19 +19,9 @@ CENTOS_KEY_CHECK_COMMAND = "#{KEY_CHECK_COMMAND} #{CENTOS_GPG_KEY_FIN 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 - apt_key { 'puppetlabs': - id => '#{value}', - ensure => 'present', - } - MANIFEST - default_options_pp -end - def install_key(key) retry_on_error_matching do - shell("apt-key adv --no-tty --keyserver pgp.mit.edu --recv-keys #{key}") + run_shell("apt-key adv --no-tty --keyserver pgp.mit.edu --recv-keys #{key}") end end @@ -44,26 +34,6 @@ def apply_manifest_twice(manifest_pp) end end -invalid_key_length_pp = <<-MANIFEST - apt_key { 'puppetlabs': - id => '8280EF8D349F', - } - MANIFEST - -ensure_absent_pp = <<-MANIFEST - apt_key { 'centos': - id => '#{CENTOS_GPG_KEY_LONG_ID}', - ensure => 'absent', - } - MANIFEST - -ensure_absent_long_key_pp = <<-MANIFEST - apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', - ensure => 'absent', - } - MANIFEST - refresh_pp = <<-MANIFEST apt_key { '#{PUPPETLABS_EXP_KEY_LONG_ID}': id => '#{PUPPETLABS_EXP_KEY_LONG_ID}', @@ -462,24 +432,16 @@ bogus_key_pp = <<-MANIFEST } MANIFEST -hkps_pool_pp = <<-MANIFEST - apt_key { 'puppetlabs': - id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', - ensure => 'present', - server => 'pgp.mit.edu', - } - MANIFEST - hkp_pool_pp = <<-MANIFEST apt_key { 'puppetlabs': id => '#{PUPPETLABS_GPG_KEY_FINGERPRINT}', ensure => 'present', - server => 'hkp://pgp.mit.edu:80', + server => 'hkp://keyserver.ubuntu.com:80', } MANIFEST -hkps_protocol_supported = fact('operatingsystem') =~ %r{Ubuntu} && \ - fact('operatingsystemrelease') =~ %r{^18\.04} +hkps_protocol_supported = os[:family] =~ %r{Ubuntu} && \ + os[:family][:release][:full] =~ %r{^18\.04} if hkps_protocol_supported hkps_ubuntu_pp = <<-MANIFEST @@ -571,6 +533,15 @@ https_works_pp = <<-MANIFEST } MANIFEST +https_with_weak_ssl_works_pp = <<-MANIFEST + apt_key { 'puppetlabs': + id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', + ensure => 'present', + source => 'https://#{PUPPETLABS_APT_URL}/#{PUPPETLABS_GPG_KEY_FILE}', + weak_ssl => true, + } + MANIFEST + https_userinfo_pp = <<-MANIFEST apt_key { 'puppetlabs': id => '#{PUPPETLABS_GPG_KEY_LONG_ID}', @@ -675,74 +646,30 @@ 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_SHORT_ID}", - acceptable_exit_codes: [0, 1, 2]) - shell("apt-key del #{PUPPETLABS_GPG_KEY_SHORT_ID}", - acceptable_exit_codes: [0, 1, 2]) - end - - describe 'default options' do - key_versions = { - '32bit key id' => PUPPETLABS_GPG_KEY_SHORT_ID.to_s, - '64bit key id' => PUPPETLABS_GPG_KEY_LONG_ID.to_s, - '160bit key fingerprint' => PUPPETLABS_GPG_KEY_FINGERPRINT.to_s, - '32bit lowercase key id' => PUPPETLABS_GPG_KEY_SHORT_ID.downcase.to_s, - '64bit lowercase key id' => PUPPETLABS_GPG_KEY_LONG_ID.downcase.to_s, - '160bit lowercase key fingerprint' => PUPPETLABS_GPG_KEY_FINGERPRINT.downcase.to_s, - '0x formatted 32bit key id' => "0x#{PUPPETLABS_GPG_KEY_SHORT_ID}", - '0x formatted 64bit key id' => "0x#{PUPPETLABS_GPG_KEY_LONG_ID}", - '0x formatted 160bit key fingerprint' => "0x#{PUPPETLABS_GPG_KEY_FINGERPRINT}", - '0x formatted 32bit lowercase key id' => "0x#{PUPPETLABS_GPG_KEY_SHORT_ID.downcase}", - '0x formatted 64bit lowercase key id' => "0x#{PUPPETLABS_GPG_KEY_LONG_ID.downcase}", - '0x formatted 160bit lowercase key fingerprint' => "0x#{PUPPETLABS_GPG_KEY_FINGERPRINT.downcase}", - } - - key_versions.each do |key, value| # rubocop:disable Lint/UnusedBlockArgument - context 'when key.to_s' do - it 'works' do - apply_manifest_twice(populate_default_options_pp(value)) - shell(PUPPETLABS_KEY_CHECK_COMMAND) - end - end - end - - context 'with invalid length key id' do - it 'fails' do - apply_manifest(invalid_key_length_pp, expect_failures: true) do |r| - expect(r.stderr).to match(%r{Valid values match}) - end - end - end + run_shell("apt-key del #{PUPPETLABS_GPG_KEY_SHORT_ID}", expect_failures: true) + run_shell("apt-key del #{PUPPETLABS_GPG_KEY_SHORT_ID}", expect_failures: true) end describe 'ensure =>' do - context 'when absent' do - it 'is removed' do - # Install the key first (retry because key pool may timeout) - install_key(CENTOS_GPG_KEY_FINGERPRINT) - shell(CENTOS_KEY_CHECK_COMMAND) - - # Time to remove it using Puppet - apply_manifest_twice(ensure_absent_pp) + ensure_present_pp = <<-MANIFEST + apt_key { 'centos': + id => '#{CENTOS_GPG_KEY_LONG_ID}', + ensure => 'present', + } + MANIFEST - shell(CENTOS_KEY_CHECK_COMMAND, acceptable_exit_codes: [1]) + ensure_absent_pp = <<-MANIFEST + apt_key { 'centos': + id => '#{CENTOS_GPG_KEY_LONG_ID}', + ensure => 'absent', + } + MANIFEST - # Re-Install the key (retry because key pool may timeout) - install_key(CENTOS_GPG_KEY_FINGERPRINT) - end + it 'add an apt_key resource' do + apply_manifest_twice(ensure_present_pp) end - - context 'when absent, added with long key' do - it 'is removed' do - # Install the key first (retry because key pool may timeout) - install_key(PUPPETLABS_GPG_KEY_LONG_ID) - shell(PUPPETLABS_KEY_CHECK_COMMAND) - - # Time to remove it using Puppet - apply_manifest_twice(ensure_absent_long_key_pp) - - shell(PUPPETLABS_KEY_CHECK_COMMAND, acceptable_exit_codes: [1]) - end + it 'remove the apt_key resource' do + apply_manifest_twice(ensure_absent_pp) end end @@ -755,14 +682,14 @@ describe 'apt_key' do end apply_manifest(gpg_key_pp, catch_changes: true) - shell(PUPPETLABS_KEY_CHECK_COMMAND) + run_shell(PUPPETLABS_KEY_CHECK_COMMAND) end end context 'with multiple keys' do it 'runs without errors' do apply_manifest_twice(multiple_keys_pp) - shell(PUPPETLABS_KEY_CHECK_COMMAND) + run_shell(PUPPETLABS_KEY_CHECK_COMMAND) end end @@ -776,18 +703,6 @@ describe 'apt_key' do end describe 'server =>' do - context 'with pgp.mit.edu' do - it 'works' do - # Apply the manifest (Retry if timeout error is received from key pool) - retry_on_error_matching do - apply_manifest(hkps_pool_pp, catch_failures: true) - end - - apply_manifest(hkps_pool_pp, catch_changes: true) - shell(PUPPETLABS_KEY_CHECK_COMMAND) - end - end - context 'with hkp://pgp.mit.edu:80' do it 'works' do retry_on_error_matching do @@ -795,7 +710,7 @@ describe 'apt_key' do end apply_manifest(hkp_pool_pp, catch_changes: true) - shell(PUPPETLABS_KEY_CHECK_COMMAND) + run_shell(PUPPETLABS_KEY_CHECK_COMMAND) end end @@ -807,7 +722,7 @@ describe 'apt_key' do end apply_manifest(hkps_ubuntu_pp, catch_changes: true) - shell(PUPPETLABS_KEY_CHECK_COMMAND) + run_shell(PUPPETLABS_KEY_CHECK_COMMAND) end end end @@ -833,12 +748,12 @@ describe 'apt_key' do context 'with http://' do it 'works' do apply_manifest_twice(http_works_pp) - shell(PUPPETLABS_KEY_CHECK_COMMAND) + run_shell(PUPPETLABS_KEY_CHECK_COMMAND) end it 'works with userinfo' do apply_manifest_twice(http_works_userinfo_pp) - shell(PUPPETLABS_KEY_CHECK_COMMAND) + run_shell(PUPPETLABS_KEY_CHECK_COMMAND) end it 'fails with a 404' do @@ -857,13 +772,12 @@ describe 'apt_key' do # disabled when running in travis, security issues prevent FTP context 'with ftp://', unless: (ENV['TRAVIS'] == 'true') do before(:each) do - shell("apt-key del #{CENTOS_GPG_KEY_LONG_ID}", - acceptable_exit_codes: [0, 1, 2]) + run_shell("apt-key del #{CENTOS_GPG_KEY_LONG_ID}", expect_failures: true) end it 'works' do apply_manifest_twice(ftp_works_pp) - shell(CENTOS_KEY_CHECK_COMMAND) + run_shell(CENTOS_KEY_CHECK_COMMAND) end it 'fails with a 550' do @@ -882,12 +796,17 @@ describe 'apt_key' do context 'with https://' do it 'works' do apply_manifest_twice(https_works_pp) - shell(PUPPETLABS_KEY_CHECK_COMMAND) + run_shell(PUPPETLABS_KEY_CHECK_COMMAND) + end + + it 'works with weak ssl' do + apply_manifest_twice(https_with_weak_ssl_works_pp) + run_shell(PUPPETLABS_KEY_CHECK_COMMAND) end it 'works with userinfo' do apply_manifest_twice(https_userinfo_pp) - shell(PUPPETLABS_KEY_CHECK_COMMAND) + run_shell(PUPPETLABS_KEY_CHECK_COMMAND) end it 'fails with a 404' do @@ -905,17 +824,17 @@ describe 'apt_key' do context 'with /path/that/exists' do before(:each) do - shell("curl -o /tmp/puppetlabs-pubkey.gpg \ + run_shell("curl -o /tmp/puppetlabs-pubkey.gpg \ http://#{PUPPETLABS_APT_URL}/#{PUPPETLABS_GPG_KEY_FILE}") end after(:each) do - shell('rm /tmp/puppetlabs-pubkey.gpg') + run_shell('rm /tmp/puppetlabs-pubkey.gpg') end it 'works' do apply_manifest_twice(path_exists_pp) - shell(PUPPETLABS_KEY_CHECK_COMMAND) + run_shell(PUPPETLABS_KEY_CHECK_COMMAND) end end @@ -929,11 +848,11 @@ describe 'apt_key' do context 'with /path/that/exists/with/bogus/content' do before(:each) do - shell('echo "here be dragons" > /tmp/fake-key.gpg') + run_shell('echo "here be dragons" > /tmp/fake-key.gpg') end after(:each) do - shell('rm /tmp/fake-key.gpg') + run_shell('rm /tmp/fake-key.gpg') end it 'fails' do apply_manifest(path_bogus_content_pp, expect_failures: true) do |r| @@ -947,7 +866,7 @@ describe 'apt_key' do context 'with debug' do it 'works' do apply_manifest_twice(debug_works_pp) - shell(PUPPETLABS_KEY_CHECK_COMMAND) + run_shell(PUPPETLABS_KEY_CHECK_COMMAND) end end end @@ -969,18 +888,18 @@ describe 'apt_key' do 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 + if ['8', '14.04', '16.04'].include?(host_inventory['facter']['os']['release']['major']) + # older OSes use puppetlabs_exp_check_command let(:puppetlabs_exp_check_command) { PUPPETLABS_EXP_CHECK_COMMAND } + + else + # Set Debian Stetch and newer OSes puppetlabs_exp_check_command + let(:puppetlabs_exp_check_command) { DEBIAN_PUPPETLABS_EXP_CHECK_COMMAND } + + # Ensure dirmngr package is installed + apply_manifest(refresh_check_for_dirmngr_pp, acceptable_exit_codes: [0, 2]) 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]) - 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) @@ -989,14 +908,14 @@ describe 'apt_key' 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]) + run_shell(puppetlabs_exp_check_command.to_s) 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]) + run_shell(puppetlabs_exp_check_command.to_s, expect_failures: true) end end end diff --git a/spec/acceptance/apt_spec.rb b/spec/acceptance/apt_spec.rb index 7fe1d03..d3215a1 100644 --- a/spec/acceptance/apt_spec.rb +++ b/spec/acceptance/apt_spec.rb @@ -31,7 +31,7 @@ everything_everything_pp = <<-MANIFEST describe 'apt class' do context 'with reset' do it 'fixes the sources.list' do - shell('cp /etc/apt/sources.list /tmp') + run_shell('cp /etc/apt/sources.list /tmp') end end @@ -43,14 +43,14 @@ describe 'apt class' do end end it 'stills work' do - shell('apt-get update') - shell('apt-get -y --force-yes upgrade') + run_shell('apt-get update') + run_shell('apt-get -y --force-yes upgrade') end end context 'with reset' do it 'fixes the sources.list' do - shell('cp /tmp/sources.list /etc/apt') + run_shell('cp /tmp/sources.list /etc/apt') end end end diff --git a/spec/acceptance/init_task_spec.rb b/spec/acceptance/init_task_spec.rb index a95ef5d..f35d2fc 100644 --- a/spec/acceptance/init_task_spec.rb +++ b/spec/acceptance/init_task_spec.rb @@ -1,29 +1,29 @@ # run a test task require 'spec_helper_acceptance' -describe 'apt tasks', if: pe_install? && puppet_version =~ %r{(5\.\d\.\d)} && fact_on(master, 'osfamily') == 'Debian' do +describe 'apt tasks' do describe 'update' do it 'updates package lists' do - result = run_task(task_name: 'apt', params: 'action=update') - expect_multiple_regexes(result: result, regexes: [%r{Reading package lists}, %r{Job completed. 1/1 nodes succeeded}]) + result = run_bolt_task('apt', 'action' => 'update') + expect(result.stdout).to contain(%r{Reading package lists}) end end describe 'upgrade' do it 'upgrades packages' do - result = run_task(task_name: 'apt', params: 'action=upgrade') - expect_multiple_regexes(result: result, regexes: [%r{\d+ upgraded, \d+ newly installed, \d+ to remove and \d+ not upgraded}, %r{Job completed. 1/1 nodes succeeded}]) + result = run_bolt_task('apt', 'action' => 'upgrade') + expect(result.stdout).to contain(%r{\d+ upgraded, \d+ newly installed, \d+ to remove and \d+ not upgraded}) end end describe 'dist-upgrade' do it 'dist-upgrades packages' do - result = run_task(task_name: 'apt', params: 'action=dist-upgrade') - expect_multiple_regexes(result: result, regexes: [%r{\d+ upgraded, \d+ newly installed, \d+ to remove and \d+ not upgraded}, %r{Job completed. 1/1 nodes succeeded}]) + result = run_bolt_task('apt', 'action' => 'dist-upgrade') + expect(result.stdout).to contain(%r{\d+ upgraded, \d+ newly installed, \d+ to remove and \d+ not upgraded}) end end describe 'autoremove' do it 'autoremoves obsolete packages' do - result = run_task(task_name: 'apt', params: 'action=autoremove') - expect_multiple_regexes(result: result, regexes: [%r{\d+ upgraded, \d+ newly installed, \d+ to remove and \d+ not upgraded}, %r{Job completed. 1/1 nodes succeeded}]) + result = run_bolt_task('apt', 'action' => 'autoremove') + expect(result.stdout).to contain(%r{\d+ upgraded, \d+ newly installed, \d+ to remove and \d+ not upgraded}) end end end diff --git a/spec/acceptance/locales_spec.rb b/spec/acceptance/locales_spec.rb deleted file mode 100644 index 338e8ed..0000000 --- a/spec/acceptance/locales_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -require 'spec_helper_acceptance' -require 'beaker/i18n_helper' - -PUPPETLABS_GPG_KEY_LONG_ID = '7F438280EF8D349F'.freeze -PUPPETLABS_LONG_FINGERPRINT = '123456781274D2C8A956789A456789A456789A9A'.freeze - -id_doesnt_match_fingerprint_pp = <<-MANIFEST - apt_key { '#{PUPPETLABS_LONG_FINGERPRINT}': - ensure => 'present', - content => '123456781274D2C8A956789A456789A456789A9B', - } -MANIFEST - -location_not_specified_fail_pp = <<-MANIFEST - apt::source { 'puppetlabs': - ensure => 'present', - repos => 'main', - key => { - id => '6F6B15509CF8E59E6E469F327F438280EF8D349F', - server => 'hkps.pool.sks-keyservers.net', - }, - } -MANIFEST - -invalid_title_pp = <<-MANIFEST - apt::setting { 'test': - ensure => 'present', - content => 'test' - } -MANIFEST - -no_content_param_pp = <<-MANIFEST - apt::conf { 'test': - ensure => 'present', - } -MANIFEST - -describe 'localization', if: (fact('osfamily') == 'Debian' || fact('osfamily') == 'RedHat') && (Gem::Version.new(puppet_version) >= Gem::Version.new('4.10.5')) do - before :all do - hosts.each do |host| - on(host, "sed -i \"96i FastGettext.locale='ja'\" /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet.rb") - change_locale_on(host, 'ja_JP.utf-8') - end - end - - describe 'ruby translations' do - it 'translates an interpolated string' do - apply_manifest(id_doesnt_match_fingerprint_pp, expect_failures: true) do |r| - expect(r.stderr).to match(%r{content/sourceが正当であるかを確認してください}) - end - end - it 'translates a simple string' do - apply_manifest(location_not_specified_fail_pp, expect_failures: true) do |r| - expect(r.stderr).to match(%r{場所を指定せずにソースエントリを作成することはできません}) - end - end - end - - describe 'puppet translations' do - it 'translates a concatenated string' do - apply_manifest(invalid_title_pp, expect_failures: true) do |r| - expect(r.stderr).to match(%r{apt::settingのリソース名/タイトルの先頭は、'conf-'、'pref-'、'list-'にする必要があります}) - end - end - it 'translates a simple string' do - apply_manifest(no_content_param_pp, expect_failures: true) do |r| - expect(r.stderr).to match(%r{contentパラメータを渡す必要があります}) - end - end - end - - after :all do - hosts.each do |host| - on(host, 'sed -i "96d" /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet.rb') - change_locale_on(host, 'en_US') - end - end -end diff --git a/spec/classes/apt_backports_spec.rb b/spec/classes/apt_backports_spec.rb index 776026a..765269d 100644 --- a/spec/classes/apt_backports_spec.rb +++ b/spec/classes/apt_backports_spec.rb @@ -16,7 +16,6 @@ describe 'apt::backports', type: :class do it { is_expected.to contain_apt__source('backports').with(location: 'http://deb.debian.org/debian', - key: 'A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553', repos: 'main contrib non-free', release: 'jessie-backports', pin: { 'priority' => 200, 'release' => 'jessie-backports' }) diff --git a/spec/classes/apt_spec.rb b/spec/classes/apt_spec.rb index 15ac28c..e766c00 100644 --- a/spec/classes/apt_spec.rb +++ b/spec/classes/apt_spec.rb @@ -188,65 +188,132 @@ describe 'apt' do end context 'with entries for /etc/apt/auth.conf' do - let(:params) do - { - auth_conf_entries: [ - { machine: 'deb.example.net', - login: 'foologin', - password: 'secret' }, - { machine: 'apt.example.com', - login: 'aptlogin', - password: 'supersecret' }, - ], - } - end - - context 'with manage_auth_conf => true' do - let(:params) do - super().merge(manage_auth_conf: true) - end + facts_hash = { + 'Ubuntu 14.04' => { + os: { family: 'Debian', name: 'Ubuntu', release: { major: '14', full: '14.04' } }, + osfamily: 'Debian', + lsbdistcodename: 'trusty', + lsbdistid: 'Ubuntu', + lsbdistrelease: '14.04', + }, + 'Ubuntu 16.04' => { + os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, + osfamily: 'Debian', + lsbdistcodename: 'xenial', + lsbdistid: 'Ubuntu', + lsbdistrelease: '16.04', + }, + 'Ubuntu 18.04' => { + os: { family: 'Debian', name: 'Ubuntu', release: { major: '18', full: '18.04' } }, + osfamily: 'Debian', + lsbdistcodename: 'bionic', + lsbdistid: 'Ubuntu', + lsbdistrelease: '18.04', + }, + 'Debian 7.0' => { + os: { family: 'Debian', name: 'Debian', release: { major: '7', full: '7.0' } }, + lsbdistid: 'Debian', + osfamily: 'Debian', + lsbdistcodename: 'wheezy', + }, + 'Debian 8.0' => { + os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, + lsbdistid: 'Debian', + osfamily: 'Debian', + lsbdistcodename: 'jessie', + }, + 'Debian 9.0' => { + os: { family: 'Debian', name: 'Debian', release: { major: '9', full: '9.0' } }, + lsbdistid: 'Debian', + osfamily: 'Debian', + lsbdistcodename: 'stretch', + }, + } - auth_conf_content = "// This file is managed by Puppet. DO NOT EDIT. + facts_hash.each do |os, facts| + context "on #{os}" do + let(:facts) do + facts + end + let(:params) do + { + auth_conf_entries: [ + { + machine: 'deb.example.net', + login: 'foologin', + password: 'secret', + }, + { + machine: 'apt.example.com', + login: 'aptlogin', + password: 'supersecret', + }, + ], + } + end + + context 'with manage_auth_conf => true' do + let(:params) do + super().merge(manage_auth_conf: true) + end + + # Going forward starting with Ubuntu 16.04 and Debian 9.0 + # /etc/apt/auth.conf is owned by _apt. In previous versions it is + # root. + auth_conf_owner = case os + when 'Ubuntu 14.04', 'Debian 7.0', 'Debian 8.0' + 'root' + else + '_apt' + end + + auth_conf_content = "// This file is managed by Puppet. DO NOT EDIT. machine deb.example.net login foologin password secret machine apt.example.com login aptlogin password supersecret " - it { - is_expected.to contain_file('/etc/apt/auth.conf').with(ensure: 'present', - owner: 'root', - group: 'root', - mode: '0600', - notify: 'Class[Apt::Update]', - content: auth_conf_content) - } - end - - context 'with manage_auth_conf => false' do - let(:params) do - super().merge(manage_auth_conf: false) + it { + is_expected.to contain_file('/etc/apt/auth.conf').with(ensure: 'present', + owner: auth_conf_owner, + group: 'root', + mode: '0600', + notify: 'Class[Apt::Update]', + content: auth_conf_content) + } + end + + context 'with manage_auth_conf => false' do + let(:params) do + super().merge(manage_auth_conf: false) + end + + it { + is_expected.not_to contain_file('/etc/apt/auth.conf') + } + end end - it { - is_expected.not_to contain_file('/etc/apt/auth.conf') - } - end - end - - context 'with improperly specified entries for /etc/apt/auth.conf' do - let(:params) do - { - auth_conf_entries: [ - { machinn: 'deb.example.net', - username: 'foologin', - password: 'secret' }, - { machine: 'apt.example.com', - login: 'aptlogin', - password: 'supersecret' }, - ], - } + context 'with improperly specified entries for /etc/apt/auth.conf' do + let(:params) do + { + auth_conf_entries: [ + { + machinn: 'deb.example.net', + username: 'foologin', + password: 'secret', + }, + { + machine: 'apt.example.com', + login: 'aptlogin', + password: 'supersecret', + }, + ], + } + end + + it { is_expected.to raise_error(Puppet::Error) } + end end - - it { is_expected.to raise_error(Puppet::Error) } end context 'with sources defined on valid osfamily' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 35654b3..9ee4373 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,7 @@ +RSpec.configure do |c| + c.mock_with :rspec +end + require 'puppetlabs_spec_helper/module_spec_helper' require 'rspec-puppet-facts' @@ -19,7 +23,7 @@ default_fact_files.each do |f| next unless File.exist?(f) && File.readable?(f) && File.size?(f) begin - default_facts.merge!(YAML.safe_load(File.read(f))) + default_facts.merge!(YAML.safe_load(File.read(f), [], [], true)) rescue => e RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}" end @@ -32,8 +36,14 @@ RSpec.configure do |c| # by default Puppet runs at warning level Puppet.settings[:strict] = :warning end + c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT'] + c.after(:suite) do + RSpec::Puppet::Coverage.report!(0) + end end +# Ensures that a module is defined +# @param module_name Name of the module def ensure_module_defined(module_name) module_name.split('::').reduce(Object) do |last_module, next_module| last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module, false) diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index a6f3d85..2bb630c 100644 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -1,77 +1,58 @@ -require 'beaker-pe' -require 'beaker-puppet' -require 'beaker-rspec' -require 'beaker/puppet_install_helper' -require 'beaker/module_install_helper' -require 'beaker-task_helper' -require 'beaker/i18n_helper' -require 'beaker-task_helper' +# frozen_string_literal: true -run_puppet_install_helper -configure_type_defaults_on(hosts) -install_bolt_on(hosts) unless pe_install? -install_module_on(hosts) -install_module_dependencies_on(hosts) +require 'serverspec' +require 'puppet_litmus' +require 'spec_helper_acceptance_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_acceptance_local.rb')) +include PuppetLitmus -UNSUPPORTED_PLATFORMS = ['RedHat', 'Suse', 'windows', 'AIX', 'Solaris'].freeze -MAX_RETRY_COUNT = 12 -RETRY_WAIT = 10 -ERROR_MATCHER = %r{(no valid OpenPGP data found|keyserver timed out|keyserver receive failed)} - -# This method allows a block to be passed in and if an exception is raised -# that matches the 'error_matcher' matcher, the block will wait a set number -# of seconds before retrying. -# Params: -# - max_retry_count - Max number of retries -# - retry_wait_interval_secs - Number of seconds to wait before retry -# - error_matcher - Matcher which the exception raised must match to allow retry -# Example Usage: -# retry_on_error_matching(3, 5, /OpenGPG Error/) do -# apply_manifest(pp, :catch_failures => true) -# end -def retry_on_error_matching(max_retry_count = MAX_RETRY_COUNT, retry_wait_interval_secs = RETRY_WAIT, error_matcher = ERROR_MATCHER) - try = 0 - begin - puts "retry_on_error_matching: try #{try}" unless try.zero? - try += 1 - yield - rescue StandardError => e - raise unless try < max_retry_count && (error_matcher.nil? || e.message =~ error_matcher) - sleep retry_wait_interval_secs - retry +if ENV['TARGET_HOST'].nil? || ENV['TARGET_HOST'] == 'localhost' + puts 'Running tests against this machine !' + if Gem.win_platform? + set :backend, :cmd + else + set :backend, :exec end -end +else + # load inventory + inventory_hash = inventory_hash_from_inventory_file + node_config = config_from_node(inventory_hash, ENV['TARGET_HOST']) -RSpec.configure do |c| - File.expand_path(File.join(File.dirname(__FILE__), '..')) + if target_in_group(inventory_hash, ENV['TARGET_HOST'], 'docker_nodes') + host = ENV['TARGET_HOST'] + set :backend, :docker + set :docker_container, host + elsif target_in_group(inventory_hash, ENV['TARGET_HOST'], 'ssh_nodes') + set :backend, :ssh + options = Net::SSH::Config.for(host) + options[:user] = node_config.dig('ssh', 'user') unless node_config.dig('ssh', 'user').nil? + options[:port] = node_config.dig('ssh', 'port') unless node_config.dig('ssh', 'port').nil? + options[:keys] = node_config.dig('ssh', 'private-key') unless node_config.dig('ssh', 'private-key').nil? + options[:password] = node_config.dig('ssh', 'password') unless node_config.dig('ssh', 'password').nil? + options[:verify_host_key] = Net::SSH::Verifiers::Null.new unless node_config.dig('ssh', 'host-key-check').nil? + host = if ENV['TARGET_HOST'].include?(':') + ENV['TARGET_HOST'].split(':').first + else + ENV['TARGET_HOST'] + end + set :host, options[:host_name] || host + set :ssh_options, options + elsif target_in_group(inventory_hash, ENV['TARGET_HOST'], 'winrm_nodes') + require 'winrm' - # Readable test descriptions - c.formatter = :documentation + set :backend, :winrm + set :os, family: 'windows' + user = node_config.dig('winrm', 'user') unless node_config.dig('winrm', 'user').nil? + pass = node_config.dig('winrm', 'password') unless node_config.dig('winrm', 'password').nil? + endpoint = "http://#{ENV['TARGET_HOST']}:5985/wsman" - # Configure all nodes in nodeset - c.before :suite do - run_puppet_access_login(user: 'admin') if pe_install? && (Gem::Version.new(puppet_version) >= Gem::Version.new('5.0.0')) + opts = { + user: user, + password: pass, + endpoint: endpoint, + operation_timeout: 300, + } - hosts.each do |host| - # This will be removed, this is temporary to test localisation. - if (fact('osfamily') == 'Debian' || fact('osfamily') == 'RedHat') && - (Gem::Version.new(puppet_version) >= Gem::Version.new('4.10.5') && - Gem::Version.new(puppet_version) < Gem::Version.new('5.2.0')) - on(host, 'mkdir /opt/puppetlabs/puppet/share/locale/ja') - on(host, 'touch /opt/puppetlabs/puppet/share/locale/ja/puppet.po') - end - if fact('osfamily') == 'Debian' - # install language on debian systems - install_language_on(host, 'ja_JP.utf-8') if not_controller(host) - # This will be removed, this is temporary to test localisation. - end - # Required for binding tests. - if fact('osfamily') == 'RedHat' - if fact('operatingsystemmajrelease') =~ %r{7} || fact('operatingsystem') =~ %r{Fedora} - shell('yum install -y bzip2') - end - end - on host, puppet('module', 'install', 'stahnma/epel') - end + winrm = WinRM::Connection.new opts + Specinfra.configuration.winrm = winrm end end diff --git a/spec/spec_helper_acceptance_local.rb b/spec/spec_helper_acceptance_local.rb new file mode 100644 index 0000000..4022171 --- /dev/null +++ b/spec/spec_helper_acceptance_local.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +UNSUPPORTED_PLATFORMS = ['RedHat', 'Suse', 'windows', 'AIX', 'Solaris'].freeze +MAX_RETRY_COUNT = 5 +RETRY_WAIT = 3 +ERROR_MATCHER = %r{(no valid OpenPGP data found|keyserver timed out|keyserver receive failed)} + +# this is needed for puppet facts / apply +lsb_package = <<-MANIFEST +package { 'lsb-release': + ensure => installed, +} +MANIFEST + +include PuppetLitmus +apply_manifest(lsb_package) + +# This method allows a block to be passed in and if an exception is raised +# that matches the 'error_matcher' matcher, the block will wait a set number +# of seconds before retrying. +# Params: +# - max_retry_count - Max number of retries +# - retry_wait_interval_secs - Number of seconds to wait before retry +# - error_matcher - Matcher which the exception raised must match to allow retry +# Example Usage: +# retry_on_error_matching(3, 5, /OpenGPG Error/) do +# apply_manifest(pp, :catch_failures => true) +# end + +def retry_on_error_matching(max_retry_count = MAX_RETRY_COUNT, retry_wait_interval_secs = RETRY_WAIT, error_matcher = ERROR_MATCHER) + try = 0 + begin + puts "retry_on_error_matching: try #{try}" unless try.zero? + try += 1 + yield + rescue StandardError => e + raise('Attempted this %{value0} times. Raising %{value1}' % { value0: max_retry_count, value1: e }) unless try < max_retry_count && (error_matcher.nil? || e.message =~ error_matcher) + sleep retry_wait_interval_secs + retry + end +end diff --git a/spec/spec_helper_local.rb b/spec/spec_helper_local.rb new file mode 100644 index 0000000..2e897cb --- /dev/null +++ b/spec/spec_helper_local.rb @@ -0,0 +1,28 @@ +if ENV['COVERAGE'] == 'yes' + require 'simplecov' + require 'simplecov-console' + require 'codecov' + + SimpleCov.formatters = [ + SimpleCov::Formatter::HTMLFormatter, + SimpleCov::Formatter::Console, + SimpleCov::Formatter::Codecov, + ] + SimpleCov.start do + track_files 'lib/**/*.rb' + + add_filter '/spec' + + # do not track vendored files + add_filter '/vendor' + add_filter '/.vendor' + + # do not track gitignored files + # this adds about 4 seconds to the coverage check + # this could definitely be optimized + add_filter do |f| + # system returns true if exit status is 0, which with git-check-ignore means file is ignored + system("git check-ignore --quiet #{f.filename}") + end + end +end diff --git a/spec/unit/facter/apt_dist_has_updates_spec.rb b/spec/unit/facter/apt_dist_has_updates_spec.rb index ae67bcf..216050d 100644 --- a/spec/unit/facter/apt_dist_has_updates_spec.rb +++ b/spec/unit/facter/apt_dist_has_updates_spec.rb @@ -7,33 +7,32 @@ describe 'apt_has_dist_updates fact' do describe 'on non-Debian distro' do before(:each) do - Facter.fact(:osfamily).expects(:value).at_least(1).returns 'RedHat' + allow(Facter.fact(:osfamily)).to receive(:value).once.and_return('Redhat') end it { is_expected.to be_nil } end describe 'on Debian based distro missing apt-get' do before(:each) do - Facter.fact(:osfamily).expects(:value).at_least(1).returns 'Debian' - File.stubs(:executable?) # Stub all other calls - File.expects(:executable?).with('/usr/bin/apt-get').returns false + allow(Facter.fact(:osfamily)).to receive(:value).once.and_return('Debian') + allow(File).to receive(:executable?) # Stub all other calls + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(false) end it { is_expected.to be_nil } end describe 'on Debian based distro' do before(:each) do - 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/bin/apt-get').returns true - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns 'test' - File.expects(:executable?).with('/usr/bin/apt-get').returns true + allow(Facter.fact(:osfamily)).to receive(:value).once.and_return('Debian') + allow(File).to receive(:executable?) # Stub all other calls + allow(Facter::Util::Resolution).to receive(:exec) # Catch all other calls + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').and_return('test') apt_output = "Inst extremetuxracer [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ "Conf extremetuxracer (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ "Inst planet.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ "Conf planet.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').returns apt_output + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').and_return(apt_output) end it { is_expected.to be true } end diff --git a/spec/unit/facter/apt_dist_package_security_updates_spec.rb b/spec/unit/facter/apt_dist_package_security_updates_spec.rb index d6f0a9f..6355b79 100644 --- a/spec/unit/facter/apt_dist_package_security_updates_spec.rb +++ b/spec/unit/facter/apt_dist_package_security_updates_spec.rb @@ -7,20 +7,20 @@ describe 'apt_package_security_dist_updates fact' do describe 'when apt has no updates' do before(:each) do - Facter.fact(:apt_has_dist_updates).stubs(:value).returns false + allow(Facter.fact(:apt_has_dist_updates)).to receive(:value).and_return(false) end it { is_expected.to be nil } end describe 'when apt has updates' do before(:each) do - Facter.fact(:osfamily).stubs(:value).returns 'Debian' - File.stubs(:executable?) # Stub all other calls - Facter::Util::Resolution.stubs(:exec) # Catch all other calls - File.expects(:executable?).with('/usr/bin/apt-get').returns true - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns 'test' - File.expects(:executable?).with('/usr/bin/apt-get').returns true - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').returns apt_get_upgrade_output + allow(Facter.fact(:osfamily)).to receive(:value).and_return('Debian') + allow(File).to receive(:executable?) # Stub all other calls + allow(Facter::Util::Resolution).to receive(:exec) # Catch all other calls + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').and_return('test') + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').and_return(apt_get_upgrade_output) end describe 'on Debian' do @@ -33,11 +33,7 @@ describe 'apt_package_security_dist_updates fact' do "Conf vim (7.52.1-5+deb9u2 Debian-Security:9/stable [amd64])\n" \ end - if Facter.version < '2.0.0' - it { is_expected.to eq('vim') } - else - it { is_expected.to eq(['vim']) } - end + it { is_expected.to eq(['vim']) } end describe 'on Ubuntu' do @@ -50,11 +46,7 @@ describe 'apt_package_security_dist_updates fact' do "Conf onioncircuits (2:3.3.10-4ubuntu2.3 Ubuntu:16.04/xenial-updates [amd64])\n" end - if Facter.version < '2.0.0' - it { is_expected.to eq('extremetuxracer,vim') } - else - it { is_expected.to eq(['extremetuxracer', 'vim']) } - end + it { is_expected.to eq(['extremetuxracer', 'vim']) } end end end diff --git a/spec/unit/facter/apt_dist_package_updates_spec.rb b/spec/unit/facter/apt_dist_package_updates_spec.rb index 080e21f..bbe212e 100644 --- a/spec/unit/facter/apt_dist_package_updates_spec.rb +++ b/spec/unit/facter/apt_dist_package_updates_spec.rb @@ -7,29 +7,25 @@ describe 'apt_package_dist_updates fact' do describe 'when apt has no updates' do before(:each) do - Facter.fact(:apt_has_dist_updates).stubs(:value).returns false + allow(Facter.fact(:apt_has_dist_updates)).to receive(:value).and_return(false) end it { is_expected.to be nil } end describe 'when apt has updates' do before(:each) do - Facter.fact(:osfamily).stubs(:value).returns 'Debian' - File.stubs(:executable?) # Stub all other calls - Facter::Util::Resolution.stubs(:exec) # Catch all other calls - File.expects(:executable?).with('/usr/bin/apt-get').returns true - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns 'test' - File.expects(:executable?).with('/usr/bin/apt-get').returns true + allow(Facter.fact(:osfamily)).to receive(:value).and_return('Debian') + allow(File).to receive(:executable?) # Stub all other calls + allow(Facter::Util::Resolution).to receive(:exec) # Catch all other calls + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').and_return('test') + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) apt_output = "Inst extremetuxracer [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ "Conf extremetuxracer (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ "Inst planet.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ "Conf planet.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').returns apt_output - end - if Facter.version < '2.0.0' - it { is_expected.to eq('extremetuxracer,planet.rb') } - else - it { is_expected.to eq(['extremetuxracer', 'planet.rb']) } + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').and_return(apt_output) end + it { is_expected.to eq(['extremetuxracer', 'planet.rb']) } end end diff --git a/spec/unit/facter/apt_dist_security_updates_spec.rb b/spec/unit/facter/apt_dist_security_updates_spec.rb index 9b58b6e..8035f16 100644 --- a/spec/unit/facter/apt_dist_security_updates_spec.rb +++ b/spec/unit/facter/apt_dist_security_updates_spec.rb @@ -7,20 +7,20 @@ describe 'apt_security_updates fact' do describe 'when apt has no updates' do before(:each) do - Facter.fact(:apt_has_dist_updates).stubs(:value).returns false + allow(Facter.fact(:apt_has_dist_updates)).to receive(:value).and_return(false) end it { is_expected.to be nil } end describe 'when apt has security updates' do before(:each) do - Facter.fact(:osfamily).stubs(:value).returns 'Debian' - File.stubs(:executable?) # Stub all other calls - Facter::Util::Resolution.stubs(:exec) # Catch all other calls - File.expects(:executable?).with('/usr/bin/apt-get').returns true - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns 'test' - File.expects(:executable?).with('/usr/bin/apt-get').returns true - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').returns apt_get_upgrade_output + allow(Facter.fact(:osfamily)).to receive(:value).and_return('Debian') + allow(File).to receive(:executable?) # Stub all other calls + allow(Facter::Util::Resolution).to receive(:exec) # Catch all other calls + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').and_return('test') + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').and_return(apt_get_upgrade_output) end describe 'on Debian' do diff --git a/spec/unit/facter/apt_dist_updates_spec.rb b/spec/unit/facter/apt_dist_updates_spec.rb index 737d1b6..f9942af 100644 --- a/spec/unit/facter/apt_dist_updates_spec.rb +++ b/spec/unit/facter/apt_dist_updates_spec.rb @@ -7,24 +7,24 @@ describe 'apt_updates fact' do describe 'when apt has no updates' do before(:each) do - Facter.fact(:apt_has_dist_updates).stubs(:value).returns false + allow(Facter.fact(:apt_has_dist_updates)).to receive(:value).and_return(false) end it { is_expected.to be nil } end describe 'when apt has updates' do before(:each) do - Facter.fact(:osfamily).stubs(:value).returns 'Debian' - File.stubs(:executable?) # Stub all other calls - Facter::Util::Resolution.stubs(:exec) # Catch all other calls - File.expects(:executable?).with('/usr/bin/apt-get').returns true - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns 'test' - File.expects(:executable?).with('/usr/bin/apt-get').returns true + allow(Facter.fact(:osfamily)).to receive(:value).and_return('Debian') + allow(File).to receive(:executable?) # Stub all other calls + allow(Facter::Util::Resolution).to receive(:exec) # Catch all other calls + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').and_return('test') + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) apt_output = "Inst extremetuxracer [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ "Conf extremetuxracer (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ "Inst planet.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ "Conf planet.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').returns apt_output + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true dist-upgrade 2>&1').and_return(apt_output) end it { is_expected.to eq(2) } end diff --git a/spec/unit/facter/apt_has_updates_spec.rb b/spec/unit/facter/apt_has_updates_spec.rb index 5c06c2f..f7a1ca9 100644 --- a/spec/unit/facter/apt_has_updates_spec.rb +++ b/spec/unit/facter/apt_has_updates_spec.rb @@ -7,31 +7,31 @@ describe 'apt_has_updates fact' do describe 'on non-Debian distro' do before(:each) do - Facter.fact(:osfamily).expects(:value).at_least(1).returns 'RedHat' + allow(Facter.fact(:osfamily)).to receive(:value).once.and_return('Redhat') end it { is_expected.to be_nil } end describe 'on Debian based distro missing apt-get' do before(:each) do - Facter.fact(:osfamily).expects(:value).at_least(1).returns 'Debian' - File.stubs(:executable?) # Stub all other calls - File.expects(:executable?).with('/usr/bin/apt-get').returns false + allow(Facter.fact(:osfamily)).to receive(:value).once.and_return('Debian') + allow(File).to receive(:executable?) # Stub all other calls + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(false) end it { is_expected.to be_nil } end describe 'on Debian based distro' do before(:each) do - 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/bin/apt-get').returns true + allow(Facter.fact(:osfamily)).to receive(:value).and_return('Debian') + allow(File).to receive(:executable?) # Stub all other calls + allow(Facter::Util::Resolution).to receive(:exec) # Catch all other calls + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) apt_output = "Inst tzdata [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ "Conf tzdata (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ "Inst unhide.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ "Conf unhide.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns apt_output + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').and_return(apt_output) end it { is_expected.to be true } end diff --git a/spec/unit/facter/apt_package_security_updates_spec.rb b/spec/unit/facter/apt_package_security_updates_spec.rb index 1bc1fda..53b91bc 100644 --- a/spec/unit/facter/apt_package_security_updates_spec.rb +++ b/spec/unit/facter/apt_package_security_updates_spec.rb @@ -7,18 +7,18 @@ describe 'apt_package_security_updates fact' do describe 'when apt has no updates' do before(:each) do - Facter.fact(:apt_has_updates).stubs(:value).returns false + allow(Facter.fact(:apt_has_updates)).to receive(:value).and_return(false) end it { is_expected.to be nil } end describe 'when apt has updates' do before(:each) do - Facter.fact(:osfamily).stubs(:value).returns 'Debian' - File.stubs(:executable?) # Stub all other calls - Facter::Util::Resolution.stubs(:exec) # Catch all other calls - File.expects(:executable?).with('/usr/bin/apt-get').returns true - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns apt_get_upgrade_output + allow(Facter.fact(:osfamily)).to receive(:value).and_return('Debian') + allow(File).to receive(:executable?) # Stub all other calls + allow(Facter::Util::Resolution).to receive(:exec) # Catch all other calls + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').and_return(apt_get_upgrade_output) end describe 'on Debian' do @@ -31,11 +31,7 @@ describe 'apt_package_security_updates fact' do "Conf curl (7.52.1-5+deb9u2 Debian-Security:9/stable [amd64])\n" \ end - if Facter.version < '2.0.0' - it { is_expected.to eq('curl') } - else - it { is_expected.to eq(['curl']) } - end + it { is_expected.to eq(['curl']) } end describe 'on Ubuntu' do @@ -48,11 +44,7 @@ describe 'apt_package_security_updates fact' do "Conf procps (2:3.3.10-4ubuntu2.3 Ubuntu:16.04/xenial-updates [amd64])\n" end - if Facter.version < '2.0.0' - it { is_expected.to eq('tzdata,curl') } - else - it { is_expected.to eq(['tzdata', 'curl']) } - end + it { is_expected.to eq(['tzdata', 'curl']) } end end end diff --git a/spec/unit/facter/apt_package_updates_spec.rb b/spec/unit/facter/apt_package_updates_spec.rb index f24481a..4b3e749 100644 --- a/spec/unit/facter/apt_package_updates_spec.rb +++ b/spec/unit/facter/apt_package_updates_spec.rb @@ -7,27 +7,23 @@ describe 'apt_package_updates fact' do describe 'when apt has no updates' do before(:each) do - Facter.fact(:apt_has_updates).stubs(:value).returns false + allow(Facter.fact(:apt_has_updates)).to receive(:value).and_return(false) end it { is_expected.to be nil } end describe 'when apt has updates' do before(:each) do - Facter.fact(:osfamily).stubs(:value).returns 'Debian' - File.stubs(:executable?) # Stub all other calls - Facter::Util::Resolution.stubs(:exec) # Catch all other calls - File.expects(:executable?).with('/usr/bin/apt-get').returns true + allow(Facter.fact(:osfamily)).to receive(:value).and_return('Debian') + allow(File).to receive(:executable?) # Stub all other calls + allow(Facter::Util::Resolution).to receive(:exec) # Catch all other calls + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) apt_output = "Inst tzdata [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ "Conf tzdata (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ "Inst unhide.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ "Conf unhide.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns apt_output - end - if Facter.version < '2.0.0' - it { is_expected.to eq('tzdata,unhide.rb') } - else - it { is_expected.to eq(['tzdata', 'unhide.rb']) } + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').and_return(apt_output) end + it { is_expected.to eq(['tzdata', 'unhide.rb']) } end end diff --git a/spec/unit/facter/apt_reboot_required_spec.rb b/spec/unit/facter/apt_reboot_required_spec.rb index 356f36b..b15cb4c 100644 --- a/spec/unit/facter/apt_reboot_required_spec.rb +++ b/spec/unit/facter/apt_reboot_required_spec.rb @@ -7,18 +7,18 @@ describe 'apt_reboot_required fact' do describe 'if a reboot is required' do before(:each) do - Facter.fact(:osfamily).expects(:value).at_least(1).returns 'Debian' - File.stubs(:file?).returns true - File.expects(:file?).at_least(1).with('/var/run/reboot-required').returns true + allow(Facter.fact(:osfamily)).to receive(:value).and_return('Debian') + allow(File).to receive(:file?).and_return(true) + allow(File).to receive(:file?).once.with('/var/run/reboot-required').and_return(true) end it { is_expected.to eq true } end describe 'if a reboot is not required' do before(:each) do - Facter.fact(:osfamily).expects(:value).at_least(1).returns 'Debian' - File.stubs(:file?).returns true - File.expects(:file?).at_least(1).with('/var/run/reboot-required').returns false + allow(Facter.fact(:osfamily)).to receive(:value).and_return('Debian') + allow(File).to receive(:file?).and_return(true) + allow(File).to receive(:file?).once.with('/var/run/reboot-required').and_return(false) end it { is_expected.to eq false } end diff --git a/spec/unit/facter/apt_security_updates_spec.rb b/spec/unit/facter/apt_security_updates_spec.rb index fc93552..cde0158 100644 --- a/spec/unit/facter/apt_security_updates_spec.rb +++ b/spec/unit/facter/apt_security_updates_spec.rb @@ -7,18 +7,18 @@ describe 'apt_security_updates fact' do describe 'when apt has no updates' do before(:each) do - Facter.fact(:apt_has_updates).stubs(:value).returns false + allow(Facter.fact(:apt_has_updates)).to receive(:value).and_return(false) end it { is_expected.to be nil } end describe 'when apt has security updates' do before(:each) do - Facter.fact(:osfamily).stubs(:value).returns 'Debian' - File.stubs(:executable?) # Stub all other calls - Facter::Util::Resolution.stubs(:exec) # Catch all other calls - File.expects(:executable?).with('/usr/bin/apt-get').returns true - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns apt_get_upgrade_output + allow(Facter.fact(:osfamily)).to receive(:value).and_return('Debian') + allow(File).to receive(:executable?) # Stub all other calls + allow(Facter::Util::Resolution).to receive(:exec) # Catch all other calls + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').and_return(apt_get_upgrade_output) end describe 'on Debian' do diff --git a/spec/unit/facter/apt_update_last_success_spec.rb b/spec/unit/facter/apt_update_last_success_spec.rb index 60d7273..dc0fc54 100644 --- a/spec/unit/facter/apt_update_last_success_spec.rb +++ b/spec/unit/facter/apt_update_last_success_spec.rb @@ -8,17 +8,17 @@ describe 'apt_update_last_success fact' do describe 'on Debian based distro which has not yet created the update-success-stamp file' do it 'has a value of -1' do - Facter.fact(:osfamily).stubs(:value).returns 'Debian' - File.expects(:exist?).with('/var/lib/apt/periodic/update-success-stamp').returns false + allow(Facter.fact(:osfamily)).to receive(:value).and_return('Debian') + allow(File).to receive(:exist?).with('/var/lib/apt/periodic/update-success-stamp').and_return(false) is_expected.to eq(-1) end end describe 'on Debian based distro which has created the update-success-stamp' do it 'has the value of the mtime of the file' do - Facter.fact(:osfamily).stubs(:value).returns 'Debian' - File.stubs(:exist?).returns true - File.stubs(:mtime).returns 1_407_660_561 + allow(Facter.fact(:osfamily)).to receive(:value).and_return('Debian') + allow(File).to receive(:exist?).and_return(true) + allow(File).to receive(:mtime).and_return(1_407_660_561) is_expected.to eq(1_407_660_561) end end diff --git a/spec/unit/facter/apt_updates_spec.rb b/spec/unit/facter/apt_updates_spec.rb index d0a5dbb..e9d4c0d 100644 --- a/spec/unit/facter/apt_updates_spec.rb +++ b/spec/unit/facter/apt_updates_spec.rb @@ -7,23 +7,22 @@ describe 'apt_updates fact' do describe 'when apt has no updates' do before(:each) do - Facter.fact(:apt_has_updates).stubs(:value).returns false + allow(Facter.fact(:apt_has_updates)).to receive(:value).and_return(false) end it { is_expected.to be nil } end describe 'when apt has updates' do before(:each) do - Facter.fact(:osfamily).stubs(:value).returns 'Debian' - File.stubs(:executable?) # Stub all other calls - Facter::Util::Resolution.stubs(:exec) # Catch all other calls - File.expects(:executable?).with('/usr/bin/apt-get').returns true + allow(Facter.fact(:osfamily)).to receive(:value).and_return('Debian') + allow(File).to receive(:executable?) # Stub all other calls + allow(Facter::Util::Resolution).to receive(:exec) # Catch all other calls + allow(File).to receive(:executable?).with('/usr/bin/apt-get').and_return(true) apt_output = "Inst tzdata [2015f-0+deb8u1] (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ "Conf tzdata (2015g-0+deb8u1 Debian:stable-updates [all])\n" \ "Inst unhide.rb [13-1.1] (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" \ "Conf unhide.rb (22-2~bpo8+1 Debian Backports:jessie-backports [all])\n" - puts apt_output - Facter::Util::Resolution.expects(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').returns apt_output + allow(Facter::Util::Resolution).to receive(:exec).with('/usr/bin/apt-get -s -o Debug::NoLocking=true upgrade 2>&1').and_return(apt_output) end it { is_expected.to eq(2) } end diff --git a/spec/unit/puppet/provider/apt_key_spec.rb b/spec/unit/puppet/provider/apt_key_spec.rb new file mode 100644 index 0000000..ca35ff7 --- /dev/null +++ b/spec/unit/puppet/provider/apt_key_spec.rb @@ -0,0 +1,215 @@ +require 'spec_helper' + +describe Puppet::Type.type(:apt_key).provider(:apt_key) do + describe 'instances' do + it 'has an instance method' do + expect(described_class).to respond_to :instances + end + end + + describe 'prefetch' do + it 'has a prefetch method' do + expect(described_class).to respond_to :prefetch + end + end + + context 'self.instances no key' do + before :each do + allow(described_class).to receive(:apt_key).with( + ['adv', '--no-tty', '--list-keys', '--with-colons', '--fingerprint', '--fixed-list-mode'], + ).and_return('uid:-::::1284991450::07BEBE04F4AE4A8E885A761325717D8509D9C1DC::Ubuntu Extras Archive Automatic Signing Key ::::::::::0:') + end + it 'returns no resources' do + expect(described_class.instances.size).to eq(0) + end + end + + context 'self.instances multiple keys' do + before :each do + command_output = <<-OUTPUT +Executing: gpg --ignore-time-conflict --no-options --no-default-keyring --homedir /tmp/tmp.DU0GdRxjmE --no-auto-check-trustdb --trust-model always --keyring /etc/apt/trusted.gpg --primary-keyring /etc/apt/trusted.gpg --keyring /etc/apt/trusted.gpg.d/puppetlabs-pc1-keyring.gpg --no-tty --list-keys --with-colons --fingerprint --fixed-list-mode +tru:t:1:1549900774:0:3:1:5 +pub:-:1024:17:40976EAF437D05B5:1095016255:::-:::scESC: +fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5: +uid:-::::1095016255::B84AE656F4F5A826C273A458512EF8E282754CE1::Ubuntu Archive Automatic Signing Key : +sub:-:2048:16:251BEFF479164387:1095016263::::::e: +pub:-:1024:17:46181433FBB75451:1104433784:::-:::scSC: +fpr:::::::::C5986B4F1257FFA86632CBA746181433FBB75451: +OUTPUT + allow(described_class).to receive(:apt_key).with( + ['adv', '--no-tty', '--list-keys', '--with-colons', '--fingerprint', '--fixed-list-mode'], + ).and_return(command_output) + end + it 'returns 2 resources' do + expect(described_class.instances.size).to eq(2) + expect(described_class.instances[0].name).to eq('630239CC130E1A7FD81A27B140976EAF437D05B5') + expect(described_class.instances[0].id).to eq('40976EAF437D05B5') + expect(described_class.instances[1].name).to eq('C5986B4F1257FFA86632CBA746181433FBB75451') + expect(described_class.instances[1].id).to eq('46181433FBB75451') + end + end + + context 'create apt_key resource' do + it 'apt_key with content set and source nil' do + expect(described_class).to receive(:apt_key).with(['adv', '--no-tty', + '--keyserver', + :"keyserver.ubuntu.com", + '--recv-keys', + 'C105B9DE']) + resource = Puppet::Type::Apt_key.new(name: 'source and content nil', + id: 'C105B9DE', + ensure: 'present') + + provider = described_class.new(resource) + expect(provider).not_to be_exist + provider.create + expect(provider).to be_exist + end + + it 'apt_key content and source nil, options set' do + expect(described_class).to receive(:apt_key).with(['adv', '--no-tty', + '--keyserver', + :"keyserver.ubuntu.com", + '--keyserver-options', + 'jimno', + '--recv-keys', + 'C105B9DE']) + resource = Puppet::Type::Apt_key.new(name: 'source and content nil', + id: 'C105B9DE', + options: 'jimno', + ensure: 'present') + + provider = described_class.new(resource) + expect(provider).not_to be_exist + provider.create + expect(provider).to be_exist + end + + it 'apt_key with content set' do + expect(described_class).to receive(:apt_key).with(array_including('add', kind_of(String))) + resource = Puppet::Type::Apt_key.new(name: 'gsd', + id: 'C105B9DE', + content: 'asad', + ensure: 'present') + + provider = described_class.new(resource) + expect(provider).not_to be_exist + expect(provider).to receive(:tempfile).and_return(Tempfile.new('foo')) + provider.create + expect(provider).to be_exist + end + + it 'apt_key with source set' do + expect(described_class).to receive(:apt_key).with(array_including('add', kind_of(String))) + resource = Puppet::Type::Apt_key.new(name: 'gsd', + id: 'C105B9DE', + source: 'ftp://bla/herpderp.gpg', + ensure: 'present') + + provider = described_class.new(resource) + expect(provider).not_to be_exist + expect(provider).to receive(:source_to_file).and_return(Tempfile.new('foo')) + provider.create + expect(provider).to be_exist + end + + it 'apt_key with source and weak ssl verify set' do + expect(described_class).to receive(:apt_key).with(array_including('add', kind_of(String))) + resource = Puppet::Type::Apt_key.new(name: 'gsd', + id: 'C105B9DE', + source: 'https://bla/herpderp.gpg', + ensure: 'present', + weak_ssl: true) + + provider = described_class.new(resource) + expect(provider).not_to be_exist + expect(provider).to receive(:source_to_file).and_return(Tempfile.new('foo')) + provider.create + expect(provider).to be_exist + end + + describe 'different valid id keys' do + hash_of_keys = { + '32bit key id' => 'EF8D349F', + '64bit key id' => '7F438280EF8D349F', + '160bit key fingerprint' => '6F6B15509CF8E59E6E469F327F438280EF8D349F', + '32bit key id lowercase' => 'EF8D349F'.downcase, + '64bit key id lowercase' => '7F438280EF8D349F'.downcase, + '160bit key fingerprint lowercase' => '6F6B15509CF8E59E6E469F327F438280EF8D349F'.downcase, + '32bit key id 0x formatted' => '0xEF8D349F', + '64bit key id 0x formatted' => '0x7F438280EF8D349F', + '160bit key fingerprint 0x formatted' => '0x6F6B15509CF8E59E6E469F327F438280EF8D349F', + } + hash_of_keys.each do |key_type, value| + it "#{key_type} #{value} is valid" do + expect(described_class).to receive(:apt_key).with(array_including('adv', '--no-tty', + '--keyserver', + :"keyserver.ubuntu.com", + '--recv-keys')) + resource = Puppet::Type::Apt_key.new(name: 'source and content nil', + id: value, + ensure: 'present') + + provider = described_class.new(resource) + expect(provider).not_to be_exist + provider.create + expect(provider).to be_exist + end + end + end + + it 'apt_key with invalid key length' do + expect { + Puppet::Type::Apt_key.new(name: 'source and content nil', + id: '1', + ensure: 'present') + }.to raise_error(Puppet::ResourceError, %r{Parameter id failed on Apt_key}) + end + end + + context 'key_line_hash function' do + it 'matches rsa' do + expect(described_class.key_line_hash('pub:-:1024:1:40976EAF437D05B5:1095016255:::-:::scESC:', 'fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:')).to include( + key_expiry: nil, + key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5', + key_long: '40976EAF437D05B5', + key_short: '437D05B5', + key_size: '1024', + key_type: :rsa, + ) + end + + it 'matches dsa' do + expect(described_class.key_line_hash('pub:-:1024:17:40976EAF437D05B5:1095016255:::-:::scESC:', 'fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:')).to include( + key_expiry: nil, + key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5', + key_long: '40976EAF437D05B5', + key_short: '437D05B5', + key_size: '1024', + key_type: :dsa, + ) + end + + it 'matches ecc' do + expect(described_class.key_line_hash('pub:-:1024:18:40976EAF437D05B5:1095016255:::-:::scESC:', 'fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:')).to include( + key_expiry: nil, + key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5', + key_long: '40976EAF437D05B5', + key_short: '437D05B5', + key_size: '1024', + key_type: :ecc, + ) + end + + it 'matches ecdsa' do + expect(described_class.key_line_hash('pub:-:1024:19:40976EAF437D05B5:1095016255:::-:::scESC:', 'fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:')).to include( + key_expiry: nil, + key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5', + key_long: '40976EAF437D05B5', + key_short: '437D05B5', + key_size: '1024', + key_type: :ecdsa, + ) + end + end +end diff --git a/spec/unit/puppet/type/apt_key_spec.rb b/spec/unit/puppet/type/apt_key_spec.rb index 5b205e9..253b644 100644 --- a/spec/unit/puppet/type/apt_key_spec.rb +++ b/spec/unit/puppet/type/apt_key_spec.rb @@ -32,6 +32,10 @@ describe Puppet::Type.type(:apt_key) do it 'refresh is not set' do expect(resource[:refresh]).to eq nil end + + it 'weak_ssl is not set' do + expect(resource[:weak_ssl]).to eq nil + end end context 'with a lowercase 32bit key id' do @@ -107,6 +111,20 @@ describe Puppet::Type.type(:apt_key) do end end + context 'with source and weak_ssl' do + let(:resource) do + Puppet::Type.type(:apt_key).new( + id: 'EF8D349F', + source: 'https://apt.puppetlabs.com/pubkey.gpg', + weak_ssl: true, + ) + end + + it 'source is set to the URL' do + expect(resource[:source]).to eq 'https://apt.puppetlabs.com/pubkey.gpg' + end + end + context 'with content' do let(:resource) do Puppet::Type.type(:apt_key).new( diff --git a/tasks/init.rb b/tasks/init.rb index f8ca85e..3cd20d4 100755 --- a/tasks/init.rb +++ b/tasks/init.rb @@ -7,7 +7,7 @@ def apt_get(action) cmd = ['apt-get', action] cmd << '-y' if ['upgrade', 'dist-upgrade', 'autoremove'].include?(action) stdout, stderr, status = Open3.capture3(*cmd) - raise Puppet::Error, stderr if status != 0 # rubocop:disable GetText/DecorateFunctionMessage + raise Puppet::Error, stderr if status != 0 { status: stdout.strip } end diff --git a/types/auth_conf_entry.pp b/types/auth_conf_entry.pp index c046276..cb6f92a 100644 --- a/types/auth_conf_entry.pp +++ b/types/auth_conf_entry.pp @@ -12,9 +12,9 @@ # Specifies the password to connect with. # type Apt::Auth_conf_entry = Struct[ - { - machine => String[1], - login => String, - password => String + { + machine => String[1], + login => String, + password => String } ]