From 0e90dd77ed9adc82d81b014bbe47f4109c4a9bd2 Mon Sep 17 00:00:00 2001 From: Gordon Bleux <33967640+UiP9AV6Y@users.noreply.github.com> Date: Fri, 2 Oct 2026 21:59:14 +0200 Subject: [PATCH] Add support for auth management as part of source resources similar to key management, auth credentials for sources can be managed from within the resource. the resource is named after the source and can optionally be removed if needed. the configured credentials are only valid for their associated repository as the auth machine scope is set to the repo location. --- examples/auth.pp | 17 ++++++++ manifests/source.pp | 28 +++++++++++++ spec/defines/source_spec.rb | 81 +++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 examples/auth.pp diff --git a/examples/auth.pp b/examples/auth.pp new file mode 100644 index 0000000000..e395b78e19 --- /dev/null +++ b/examples/auth.pp @@ -0,0 +1,17 @@ +include 'apt' + +apt::auth { 'example': + machine => 'apt.example.com', + login => 'insecure-username', + password => 'insecure-password', +} + +apt::source { 'puppetlabs': + location => 'https://apt-enterprise.puppetlabs.com', + repos => 'main', + keyring => '/usr/share/keyrings/puppetlabs.gpg', + auth => { + login => 'insecure-username', + password => 'insecure-password', + }, +} diff --git a/manifests/source.pp b/manifests/source.pp index 05c6b07682..9f7111969d 100644 --- a/manifests/source.pp +++ b/manifests/source.pp @@ -65,6 +65,11 @@ # @option include [Boolean] :src # Specifies whether to request the distribution's uncompiled source code. # +# @param auth +# Creates an `apt::auth` resource using the `location` as machine scope. +# Valid hash keys include `login` and `password`. See `Apt::Auth_conf_entry` +# for more information. +# # @param key # Creates an `apt::keyring` in `/etc/apt/keyrings` (or anywhere on disk given `filename`) Valid options: # * a hash of `parameter => value` pairs to be passed to `file`: `name` (title), `content`, `source`, `filename` @@ -110,6 +115,7 @@ Optional[Variant[String[0], Array[String[0]]]] $release = undef, Variant[String[1], Array[String[1]]] $repos = 'main', Hash $include = {}, + Optional[Variant[String[1], Hash]] $auth = undef, Optional[Variant[String[1], Hash]] $key = undef, Optional[Stdlib::AbsolutePath] $keyring = undef, Optional[Variant[Hash, Integer, String[1]]] $pin = undef, @@ -161,6 +167,28 @@ $includes = $apt::include_defaults + $include + if $auth { + $_auth_ensure = pick($auth['ensure'], $ensure) + $_auth_login = pick_default($auth['login']) + $_auth_password = pick_default($auth['password']) + + if $_auth_ensure == 'present' and empty($_auth_login) { + fail('auth must provide a valid username') + } + + if $_auth_ensure == 'present' and empty($_auth_password) { + fail('auth must provide a valid password') + } + + apt::auth { "Add auth: ${_location} from Apt::Source ${title}": + ensure => $_auth_ensure, + name => $name, + machine => $_location, + login => $_auth_login, + password => $_auth_password, + } + } + if $keyring { if $key { fail('parameters key and keyring are mutually exclusive') diff --git a/spec/defines/source_spec.rb b/spec/defines/source_spec.rb index 4d18c7f157..e843efd5fe 100644 --- a/spec/defines/source_spec.rb +++ b/spec/defines/source_spec.rb @@ -435,6 +435,87 @@ end end + describe 'auth parameter' do + context 'with auth set' do + let :params do + { + location: 'https://apt.spec.test/debian', + auth: { + login: 'spec', + password: 'test' + } + } + end + + it { + expect(subject).to contain_apt__auth("Add auth: #{params[:location]} from Apt::Source #{title}") + .with( + ensure: 'present', + name: title, + machine: params[:location], + login: 'spec', + password: 'test', + ) + } + + it { + expect(subject).to contain_file("/etc/apt/auth.conf.d/#{title}.conf") + } + end + + context 'with ensure set' do + let :params do + { + location: 'https://apt.spec.test/debian', + auth: { + ensure: 'absent', + } + } + end + + it { + expect(subject).to contain_apt__auth("Add auth: #{params[:location]} from Apt::Source #{title}") + .with( + ensure: 'absent', + name: title, + machine: params[:location], + login: '', + password: '', + ) + } + end + + context 'with missing username' do + let :params do + { + location: 'https://apt.spec.test/debian', + auth: { + password: 'test', + } + } + end + + it { + expect(subject).to compile.and_raise_error(%r{auth must provide a valid username}) + } + end + + context 'with missing password' do + let :params do + { + location: 'https://apt.spec.test/debian', + auth: { + login: 'spec', + } + } + end + + it { + expect(subject).to compile.and_raise_error(%r{auth must provide a valid password}) + } + end + end + describe 'deb822 sources' do context 'suite contains a slash but does not end with slash (should require Components)' do let :params do