From 627eb0b0ce674f6d47c513ba6a96c625ef9ed917 Mon Sep 17 00:00:00 2001 From: Andreas Voegele Date: Mon, 3 Dec 2018 19:49:47 +0100 Subject: [PATCH] (MODULES-8418) Add parameter $auth_conf_owner Starting from Debian 9 and Ubuntu 16.04 the user _apt owns the file /etc/apt/auth.conf. In previous versions it is owned by root. Set ownership of /etc/apt/auth.conf correctly based on OS version and add spec tests to cover managing the file's owner under Ubuntu 14.04, 16.04 and 18.04 as well as Debian 7.0, 8.0 and 9.0. --- manifests/init.pp | 38 +++++---- manifests/params.pp | 11 +++ spec/classes/apt_spec.rb | 169 +++++++++++++++++++++++++++------------ types/auth_conf_entry.pp | 8 +- 4 files changed, 154 insertions(+), 72 deletions(-) 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/params.pp b/manifests/params.pp index 52b9bca..e7bcb33 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -87,6 +87,11 @@ class apt::params { } $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 +101,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 +114,7 @@ class apt::params { $ppa_options = undef $ppa_package = undef $backports = undef + $auth_conf_owner = 'root' } } } 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/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 } ] -- 2.32.3