diff --git a/manifests/init.pp b/manifests/init.pp index 18e53cb..3995534 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,324 +1,324 @@ # @summary Main class, includes all other classes. # # @see https://docs.puppetlabs.com/references/latest/function.html#createresources for the create resource function # # @param provider # 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 # hkp://). # # @param key_options # Specifies the default options for apt::key resources. # # @param ppa_options # Supplies options to be passed to the `add-apt-repository` command. # # @param ppa_package # Names the package that provides the `apt-add-repository` command. # # @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 # See apt::backports for documentation. # # @option backports [String] :repos # See apt::backports for documentation. # # @option backports [String] :key # See apt::backports for documentation. # # @param confs # Creates new `apt::conf` resources. Valid options: a hash to be passed to the create_resources function linked above. # # @param update # 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 # `apt_update` is notified). Default: 'reluctantly'. # # @option update [Integer] :loglevel # Specifies the log level of logs outputted to the console. Default: undef. # # @option update [Integer] :timeout # Specifies how long to wait for the update to complete before canceling it. Valid options: an integer, in seconds. Default: undef. # # @option update [Integer] :tries # Specifies how many times to retry the update after receiving a DNS or HTTP error. Default: undef. # # @param purge # Specifies whether to purge any existing settings that aren't managed by Puppet. Valid options: a hash made up from the following keys: # # @option purge [Boolean] :sources.list # Specifies whether to purge any unmanaged entries from sources.list. Default false. # # @option purge [Boolean] :sources.list.d # Specifies whether to purge any unmanaged entries from sources.list.d. Default false. # # @option purge [Boolean] :preferences # Specifies whether to purge any unmanaged entries from preferences. Default false. # # @option purge [Boolean] :preferences.d. # Specifies whether to purge any unmanaged entries from preferences.d. Default false. # # @param proxy # Configures Apt to connect to a proxy server. Valid options: a hash matching the locally defined type apt::proxy. # # @param sources # Creates new `apt::source` resources. Valid options: a hash to be passed to the create_resources function linked above. # # @param keys # Creates new `apt::key` resources. Valid options: a hash to be passed to the create_resources function linked above. # # @param ppas # Creates new `apt::ppa` resources. Valid options: a hash to be passed to the create_resources function linked above. # # @param pins # Creates new `apt::pin` resources. Valid options: a hash to be passed to the create_resources function linked above. # # @param settings # Creates new `apt::setting` resources. Valid options: a hash to be passed to the create_resources function linked above. # # @param manage_auth_conf # 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. # # @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 # 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. # # @param sources_list_d # Specifies the path of the sources_list.d file to use. # # @param conf_d # Specifies the path of the conf.d file to use. # # @param preferences # Specifies the path of the preferences file to use. # # @param preferences_d # 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. # class apt ( Hash $update_defaults = $apt::params::update_defaults, Hash $purge_defaults = $apt::params::purge_defaults, Hash $proxy_defaults = $apt::params::proxy_defaults, Hash $include_defaults = $apt::params::include_defaults, String $provider = $apt::params::provider, String $keyserver = $apt::params::keyserver, Optional[String] $key_options = $apt::params::key_options, Optional[String] $ppa_options = $apt::params::ppa_options, Optional[String] $ppa_package = $apt::params::ppa_package, Optional[Hash] $backports = $apt::params::backports, Hash $confs = $apt::params::confs, Hash $update = $apt::params::update, Hash $purge = $apt::params::purge, Apt::Proxy $proxy = $apt::params::proxy, Hash $sources = $apt::params::sources, Hash $keys = $apt::params::keys, Hash $ppas = $apt::params::ppas, Hash $pins = $apt::params::pins, Hash $settings = $apt::params::settings, 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, String $conf_d = $apt::params::conf_d, String $preferences = $apt::params::preferences, String $preferences_d = $apt::params::preferences_d, String $apt_conf_d = $apt::params::apt_conf_d, Hash $config_files = $apt::params::config_files, Hash $source_key_defaults = $apt::params::source_key_defaults, ) inherits apt::params { if $facts['osfamily'] != 'Debian' { fail(translate('This module only works on Debian or derivatives like Ubuntu')) } if $update['frequency'] { assert_type( Enum['always','daily','weekly','reluctantly'], $update['frequency'], ) } if $update['timeout'] { assert_type(Integer, $update['timeout']) } if $update['tries'] { assert_type(Integer, $update['tries']) } $_update = merge($::apt::update_defaults, $update) include ::apt::update if $purge['sources.list'] { assert_type(Boolean, $purge['sources.list']) } if $purge['sources.list.d'] { assert_type(Boolean, $purge['sources.list.d']) } if $purge['preferences'] { assert_type(Boolean, $purge['preferences']) } if $purge['preferences.d'] { assert_type(Boolean, $purge['preferences.d']) } if $purge['apt.conf.d'] { assert_type(Boolean, $purge['apt.conf.d']) } $_purge = merge($::apt::purge_defaults, $purge) $_proxy = merge($apt::proxy_defaults, $proxy) $confheadertmp = epp('apt/_conf_header.epp') $proxytmp = epp('apt/proxy.epp', {'proxies' => $_proxy}) $updatestamptmp = epp('apt/15update-stamp.epp') if $_proxy['ensure'] == 'absent' or $_proxy['host'] { apt::setting { 'conf-proxy': ensure => $_proxy['ensure'], priority => '01', content => "${confheadertmp}${proxytmp}", } } $sources_list_ensure = $_purge['sources.list'] ? { true => absent, default => file, } $preferences_ensure = $_purge['preferences'] ? { true => absent, default => file, } if $_update['frequency'] == 'always' { Exec <| title=='apt_update' |> { refreshonly => false, } } apt::setting { 'conf-update-stamp': priority => 15, content => "${confheadertmp}${updatestamptmp}", } file { 'sources.list': ensure => $sources_list_ensure, path => $::apt::sources_list, owner => root, group => root, - mode => '0444', + mode => '0644', notify => Class['apt::update'], } file { 'sources.list.d': ensure => directory, path => $::apt::sources_list_d, owner => root, group => root, - mode => '0555', + mode => '0644', purge => $_purge['sources.list.d'], recurse => $_purge['sources.list.d'], notify => Class['apt::update'], } file { 'preferences': ensure => $preferences_ensure, path => $::apt::preferences, owner => root, group => root, - mode => '0444', + mode => '0644', notify => Class['apt::update'], } file { 'preferences.d': ensure => directory, path => $::apt::preferences_d, owner => root, group => root, - mode => '0555', + mode => '0644', purge => $_purge['preferences.d'], recurse => $_purge['preferences.d'], notify => Class['apt::update'], } file { 'apt.conf.d': ensure => directory, path => $::apt::apt_conf_d, owner => root, group => root, mode => '0644', purge => $_purge['apt.conf.d'], recurse => $_purge['apt.conf.d'], notify => Class['apt::update'], } if $confs { create_resources('apt::conf', $confs) } # manage sources if present if $sources { create_resources('apt::source', $sources) } # manage keys if present if $keys { create_resources('apt::key', $keys) } # manage ppas if present if $ppas { create_resources('apt::ppa', $ppas) } # manage settings if present if $settings { create_resources('apt::setting', $settings) } if $manage_auth_conf { $auth_conf_ensure = $auth_conf_entries ? { [] => 'absent', default => 'present', } $auth_conf_tmp = epp('apt/auth_conf.epp') file { '/etc/apt/auth.conf': ensure => $auth_conf_ensure, owner => $auth_conf_owner, group => 'root', - mode => '0400', + mode => '0600', content => "${confheadertmp}${auth_conf_tmp}", notify => Class['apt::update'], } } # manage pins if present if $pins { create_resources('apt::pin', $pins) } # required for adding GPG keys on Debian 9 (and derivatives) ensure_packages(['gnupg']) } diff --git a/manifests/setting.pp b/manifests/setting.pp index e976c76..4729295 100644 --- a/manifests/setting.pp +++ b/manifests/setting.pp @@ -1,77 +1,77 @@ # @summary Manages Apt configuration files. # # @see https://docs.puppetlabs.com/references/latest/type.html#file-attributes for more information on source and content parameters # # @param priority # Determines the order in which Apt processes the configuration file. Files with higher priority numbers are loaded first. # # @param ensure # Specifies whether the file should exist. Valid options: 'present', 'absent', and 'file'. # # @param source # Required, unless `content` is set. Specifies a source file to supply the content of the configuration file. Cannot be used in combination # with `content`. Valid options: see link above for Puppet's native file type source attribute. # # @param content # Required, unless `source` is set. Directly supplies content for the configuration file. Cannot be used in combination with `source`. Valid # options: see link above for Puppet's native file type content attribute. # # @param notify_update # Specifies whether to trigger an `apt-get update` run. # define apt::setting ( Variant[String, Integer, Array] $priority = 50, Optional[Enum['file', 'present', 'absent']] $ensure = file, Optional[String] $source = undef, Optional[String] $content = undef, Boolean $notify_update = true, ) { if $content and $source { fail(translate('apt::setting cannot have both content and source')) } if !$content and !$source { fail(translate('apt::setting needs either of content or source')) } $title_array = split($title, '-') $setting_type = $title_array[0] $base_name = join(delete_at($title_array, 0), '-') assert_type(Pattern[/\Aconf\z/, /\Apref\z/, /\Alist\z/], $setting_type) |$a, $b| { fail(translate("apt::setting resource name/title must start with either 'conf-', 'pref-' or 'list-'")) } if $priority !~ Integer { # need this to allow zero-padded priority. assert_type(Pattern[/^\d+$/], $priority) |$a, $b| { fail(translate('apt::setting priority must be an integer or a zero-padded integer')) } } if ($setting_type == 'list') or ($setting_type == 'pref') { $_priority = '' } else { $_priority = $priority } $_path = $::apt::config_files[$setting_type]['path'] $_ext = $::apt::config_files[$setting_type]['ext'] if $notify_update { $_notify = Class['apt::update'] } else { $_notify = undef } file { "${_path}/${_priority}${base_name}${_ext}": ensure => $ensure, owner => 'root', group => 'root', - mode => '0444', + mode => '0644', content => $content, source => $source, notify => $_notify, } } diff --git a/spec/classes/apt_spec.rb b/spec/classes/apt_spec.rb index 8529af1..4421180 100644 --- a/spec/classes/apt_spec.rb +++ b/spec/classes/apt_spec.rb @@ -1,546 +1,546 @@ require 'spec_helper' sources_list = { ensure: 'file', path: '/etc/apt/sources.list', owner: 'root', group: 'root', - mode: '0444', + mode: '0644', notify: 'Class[Apt::Update]' } sources_list_d = { ensure: 'directory', path: '/etc/apt/sources.list.d', owner: 'root', group: 'root', - mode: '0555', + mode: '0644', purge: false, recurse: false, notify: 'Class[Apt::Update]' } preferences = { ensure: 'file', path: '/etc/apt/preferences', owner: 'root', group: 'root', - mode: '0444', + mode: '0644', notify: 'Class[Apt::Update]' } preferences_d = { ensure: 'directory', path: '/etc/apt/preferences.d', owner: 'root', group: 'root', - mode: '0555', + mode: '0644', purge: false, recurse: false, notify: 'Class[Apt::Update]' } apt_conf_d = { ensure: 'directory', path: '/etc/apt/apt.conf.d', owner: 'root', group: 'root', mode: '0644', purge: false, recurse: false, notify: 'Class[Apt::Update]' } describe 'apt' do let(:facts) do { os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, lsbdistid: 'Debian', osfamily: 'Debian', lsbdistcodename: 'jessie', } end context 'with defaults' do it { is_expected.to contain_file('sources.list').that_notifies('Class[Apt::Update]').only_with(sources_list) } it { is_expected.to contain_file('sources.list.d').that_notifies('Class[Apt::Update]').only_with(sources_list_d) } it { is_expected.to contain_file('preferences').that_notifies('Class[Apt::Update]').only_with(preferences) } it { is_expected.to contain_file('preferences.d').that_notifies('Class[Apt::Update]').only_with(preferences_d) } it { is_expected.to contain_file('apt.conf.d').that_notifies('Class[Apt::Update]').only_with(apt_conf_d) } it { is_expected.to contain_file('/etc/apt/auth.conf').with_ensure('absent') } it 'lays down /etc/apt/apt.conf.d/15update-stamp' do is_expected.to contain_file('/etc/apt/apt.conf.d/15update-stamp').with(group: 'root', - mode: '0444', + mode: '0644', owner: 'root').with_content( %r{APT::Update::Post-Invoke-Success {"touch /var/lib/apt/periodic/update-success-stamp 2>/dev/null || true";};}, ) end it { is_expected.to contain_exec('apt_update').with(refreshonly: 'true') } it { is_expected.not_to contain_apt__setting('conf-proxy') } end describe 'proxy=' do context 'when host=localhost' do let(:params) { { proxy: { 'host' => 'localhost' } } } it { is_expected.to contain_apt__setting('conf-proxy').with(priority: '01').with_content( %r{Acquire::http::proxy "http://localhost:8080/";}, ).without_content( %r{Acquire::https::proxy}, ) } end context 'when host=localhost and port=8180' do let(:params) { { proxy: { 'host' => 'localhost', 'port' => 8180 } } } it { is_expected.to contain_apt__setting('conf-proxy').with(priority: '01').with_content( %r{Acquire::http::proxy "http://localhost:8180/";}, ).without_content( %r{Acquire::https::proxy}, ) } end context 'when host=localhost and https=true' do let(:params) { { proxy: { 'host' => 'localhost', 'https' => true } } } it { is_expected.to contain_apt__setting('conf-proxy').with(priority: '01').with_content( %r{Acquire::http::proxy "http://localhost:8080/";}, ).with_content( %r{Acquire::https::proxy "https://localhost:8080/";}, ) } end context 'when host=localhost and direct=true' do let(:params) { { proxy: { 'host' => 'localhost', 'direct' => true } } } it { is_expected.to contain_apt__setting('conf-proxy').with(priority: '01').with_content( %r{Acquire::http::proxy "http://localhost:8080/";}, ).with_content( %r{Acquire::https::proxy "DIRECT";}, ) } end context 'when host=localhost and https=true and direct=true' do let(:params) { { proxy: { 'host' => 'localhost', 'https' => true, 'direct' => true } } } it { is_expected.to contain_apt__setting('conf-proxy').with(priority: '01').with_content( %r{Acquire::http::proxy "http://localhost:8080/";}, ).with_content( %r{Acquire::https::proxy "https://localhost:8080/";}, ) } it { is_expected.to contain_apt__setting('conf-proxy').with(priority: '01').with_content( %r{Acquire::http::proxy "http://localhost:8080/";}, ).without_content( %r{Acquire::https::proxy "DIRECT";}, ) } end context 'when ensure=absent' do let(:params) { { proxy: { 'ensure' => 'absent' } } } it { is_expected.to contain_apt__setting('conf-proxy').with(ensure: 'absent', priority: '01') } end end context 'with lots of non-defaults' do let :params do { update: { 'frequency' => 'always', 'timeout' => 1, 'tries' => 3 }, purge: { 'sources.list' => false, 'sources.list.d' => false, 'preferences' => false, 'preferences.d' => false, 'apt.conf.d' => false }, } end it { is_expected.to contain_file('sources.list').with(content: nil) } it { is_expected.to contain_file('sources.list.d').with(purge: false, recurse: false) } it { is_expected.to contain_file('preferences').with(ensure: 'file') } it { is_expected.to contain_file('preferences.d').with(purge: false, recurse: false) } it { is_expected.to contain_file('apt.conf.d').with(purge: false, recurse: false) } it { is_expected.to contain_exec('apt_update').with(refreshonly: false, timeout: 1, tries: 3) } end context 'with entries for /etc/apt/auth.conf' do 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', }, 'Debian 10.0' => { os: { family: 'Debian', name: 'Debian', release: { major: '10', full: '10.0' } }, lsbdistid: 'Debian', osfamily: 'Debian', lsbdistcodename: 'buster', }, } 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: auth_conf_owner, group: 'root', - mode: '0400', + 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 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 end context 'with sources defined on valid osfamily' do let :facts do { os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, osfamily: 'Debian', lsbdistcodename: 'xenial', lsbdistid: 'Ubuntu', lsbdistrelease: '16.04', } end let(:params) do { sources: { 'debian_unstable' => { 'location' => 'http://debian.mirror.iweb.ca/debian/', 'release' => 'unstable', 'repos' => 'main contrib non-free', 'key' => { 'id' => '150C8614919D8446E01E83AF9AA38DCD55BE302B', 'server' => 'subkeys.pgp.net' }, 'pin' => '-10', 'include' => { 'src' => true }, }, 'puppetlabs' => { 'location' => 'http://apt.puppetlabs.com', 'repos' => 'main', 'key' => { 'id' => '6F6B15509CF8E59E6E469F327F438280EF8D349F', 'server' => 'pgp.mit.edu' }, }, } } end it { is_expected.to contain_apt__setting('list-debian_unstable').with(ensure: 'present') } it { is_expected.to contain_file('/etc/apt/sources.list.d/debian_unstable.list').with_content(%r{^deb http://debian.mirror.iweb.ca/debian/ unstable main contrib non-free$}) } it { is_expected.to contain_file('/etc/apt/sources.list.d/debian_unstable.list').with_content(%r{^deb-src http://debian.mirror.iweb.ca/debian/ unstable main contrib non-free$}) } it { is_expected.to contain_apt__setting('list-puppetlabs').with(ensure: 'present') } it { is_expected.to contain_file('/etc/apt/sources.list.d/puppetlabs.list').with_content(%r{^deb http://apt.puppetlabs.com xenial main$}) } end context 'with confs defined on valid osfamily' do let :facts do { os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, osfamily: 'Debian', lsbdistcodename: 'xenial', lsbdistid: 'Ubuntu', } end let(:params) do { confs: { 'foo' => { 'content' => 'foo', }, 'bar' => { 'content' => 'bar', }, } } end it { is_expected.to contain_apt__conf('foo').with(content: 'foo') } it { is_expected.to contain_apt__conf('bar').with(content: 'bar') } end context 'with keys defined on valid osfamily' do let :facts do { os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, osfamily: 'Debian', lsbdistcodename: 'xenial', lsbdistid: 'Ubuntu', } end let(:params) do { keys: { '55BE302B' => { 'server' => 'subkeys.pgp.net', }, 'EF8D349F' => { 'server' => 'pgp.mit.edu', }, } } end it { is_expected.to contain_apt__key('55BE302B').with(server: 'subkeys.pgp.net') } it { is_expected.to contain_apt__key('EF8D349F').with(server: 'pgp.mit.edu') } end context 'with ppas defined on valid osfamily' do let :facts do { os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, osfamily: 'Debian', lsbdistcodename: 'xenial', lsbdistid: 'Ubuntu', lsbdistrelease: '16.04', } end let(:params) do { ppas: { 'ppa:drizzle-developers/ppa' => {}, 'ppa:nginx/stable' => {}, } } end it { is_expected.to contain_apt__ppa('ppa:drizzle-developers/ppa') } it { is_expected.to contain_apt__ppa('ppa:nginx/stable') } end context 'with settings defined on valid osfamily' do let :facts do { os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, osfamily: 'Debian', lsbdistcodename: 'xenial', lsbdistid: 'Ubuntu', } end let(:params) do { settings: { 'conf-banana' => { 'content' => 'banana' }, 'pref-banana' => { 'content' => 'banana' }, } } end it { is_expected.to contain_apt__setting('conf-banana') } it { is_expected.to contain_apt__setting('pref-banana') } end context 'with pins defined on valid osfamily' do let :facts do { os: { family: 'Debian', name: 'Ubuntu', release: { major: '16', full: '16.04' } }, osfamily: 'Debian', lsbdistcodename: 'xenial', lsbdistid: 'Ubuntu', } end let(:params) do { pins: { 'stable' => { 'priority' => 600, 'order' => 50 }, 'testing' => { 'priority' => 700, 'order' => 100 }, } } end it { is_expected.to contain_apt__pin('stable') } it { is_expected.to contain_apt__pin('testing') } end describe 'failing tests' do context "with purge['sources.list']=>'banana'" do let(:params) { { purge: { 'sources.list' => 'banana' } } } it do is_expected.to raise_error(Puppet::Error) end end context "with purge['sources.list.d']=>'banana'" do let(:params) { { purge: { 'sources.list.d' => 'banana' } } } it do is_expected.to raise_error(Puppet::Error) end end context "with purge['preferences']=>'banana'" do let(:params) { { purge: { 'preferences' => 'banana' } } } it do is_expected.to raise_error(Puppet::Error) end end context "with purge['preferences.d']=>'banana'" do let(:params) { { purge: { 'preferences.d' => 'banana' } } } it do is_expected.to raise_error(Puppet::Error) end end context "with purge['apt.conf.d']=>'banana'" do let(:params) { { purge: { 'apt.conf.d' => 'banana' } } } it do is_expected.to raise_error(Puppet::Error) end end end end diff --git a/spec/defines/conf_spec.rb b/spec/defines/conf_spec.rb index 3089f0c..1c0ee16 100644 --- a/spec/defines/conf_spec.rb +++ b/spec/defines/conf_spec.rb @@ -1,89 +1,89 @@ require 'spec_helper' describe 'apt::conf', type: :define do let :pre_condition do 'class { "apt": }' end let(:facts) do { os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, lsbdistid: 'Debian', osfamily: 'Debian', lsbdistcodename: 'jessie', } end let :title do 'norecommends' end describe 'when creating an apt preference' do let :default_params do { priority: '00', content: "Apt::Install-Recommends 0;\nApt::AutoRemove::InstallRecommends 1;\n", } end let :params do default_params end let :filename do '/etc/apt/apt.conf.d/00norecommends' end it { is_expected.to contain_file(filename).with('ensure' => 'present', 'content' => %r{Apt::Install-Recommends 0;\nApt::AutoRemove::InstallRecommends 1;}, 'owner' => 'root', 'group' => 'root', - 'mode' => '0444') + 'mode' => '0644') } context 'with notify_update = true (default)' do let :params do default_params end it { is_expected.to contain_apt__setting("conf-#{title}").with_notify_update(true) } end context 'with notify_update = false' do let :params do default_params.merge(notify_update: false) end it { is_expected.to contain_apt__setting("conf-#{title}").with_notify_update(false) } end end describe 'when creating a preference without content' do let :params do { priority: '00', } end it 'fails' do is_expected.to raise_error(%r{pass in content}) end end describe 'when removing an apt preference' do let :params do { ensure: 'absent', priority: '00', } end let :filename do '/etc/apt/apt.conf.d/00norecommends' end it { is_expected.to contain_file(filename).with('ensure' => 'absent', 'owner' => 'root', 'group' => 'root', - 'mode' => '0444') + 'mode' => '0644') } end end diff --git a/spec/defines/setting_spec.rb b/spec/defines/setting_spec.rb index bf55992..7e2a908 100644 --- a/spec/defines/setting_spec.rb +++ b/spec/defines/setting_spec.rb @@ -1,139 +1,139 @@ require 'spec_helper' describe 'apt::setting' do let(:pre_condition) { 'class { "apt": }' } let :facts do { os: { distro: { codename: 'jessie' }, family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, lsbdistrelease: '8.0', lsbdistcodename: 'jessie', operatingsystem: 'Debian', osfamily: 'Debian', lsbdistid: 'Debian', } end let(:title) { 'conf-teddybear' } let(:default_params) { { content: 'di' } } describe 'when using the defaults' do context 'without source or content' do it do is_expected.to raise_error(Puppet::Error, %r{needs either of }) end end context 'with title=conf-teddybear ' do let(:params) { default_params } it { is_expected.to contain_file('/etc/apt/apt.conf.d/50teddybear').that_notifies('Class[Apt::Update]') } end context 'with title=pref-teddybear' do let(:title) { 'pref-teddybear' } let(:params) { default_params } it { is_expected.to contain_file('/etc/apt/preferences.d/teddybear.pref').that_notifies('Class[Apt::Update]') } end context 'with title=list-teddybear' do let(:title) { 'list-teddybear' } let(:params) { default_params } it { is_expected.to contain_file('/etc/apt/sources.list.d/teddybear.list').that_notifies('Class[Apt::Update]') } end context 'with source' do let(:params) { { source: 'puppet:///la/die/dah' } } it { is_expected.to contain_file('/etc/apt/apt.conf.d/50teddybear').that_notifies('Class[Apt::Update]').with(ensure: 'file', owner: 'root', group: 'root', - mode: '0444', + mode: '0644', source: params[:source].to_s) } end context 'with content' do let(:params) { default_params } it { is_expected.to contain_file('/etc/apt/apt.conf.d/50teddybear').that_notifies('Class[Apt::Update]').with(ensure: 'file', owner: 'root', group: 'root', - mode: '0444', + mode: '0644', content: params[:content].to_s) } end end describe 'settings requiring settings, MODULES-769' do let(:pre_condition) do 'class { "apt": } apt::setting { "list-teddybear": content => "foo" } ' end let(:facts) do { os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } }, lsbdistid: 'Debian', osfamily: 'Debian', lsbdistcodename: 'jessie', } end let(:title) { 'conf-teddybear' } let(:default_params) { { content: 'di' } } let(:params) { default_params.merge(require: 'Apt::Setting[list-teddybear]') } it { is_expected.to compile.with_all_deps } end describe 'when trying to pull one over' do context 'with source and content' do let(:params) { default_params.merge(source: 'la') } it do is_expected.to raise_error(Puppet::Error, %r{cannot have both }) end end context 'with title=ext-teddybear' do let(:title) { 'ext-teddybear' } let(:params) { default_params } it do is_expected.to raise_error(Puppet::Error, %r{must start with either}) end end context 'with ensure=banana' do let(:params) { default_params.merge(ensure: 'banana') } it do is_expected.to raise_error(Puppet::Error, %r{Enum\['absent', 'file', 'present'\]}) end end context 'with priority=1.2' do let(:params) { default_params.merge(priority: 1.2) } it { is_expected.to compile.and_raise_error(%r{expects a value of type}) } end end describe 'with priority=100' do let(:params) { default_params.merge(priority: 100) } it { is_expected.to contain_file('/etc/apt/apt.conf.d/100teddybear').that_notifies('Class[Apt::Update]') } end describe 'with ensure=absent' do let(:params) { default_params.merge(ensure: 'absent') } it { is_expected.to contain_file('/etc/apt/apt.conf.d/50teddybear').that_notifies('Class[Apt::Update]').with(ensure: 'absent') } end end