Skip to content

Commit bf0b960

Browse files
authored
Merge pull request #1128 from puppetlabs/modern_debian_keyrings
Add support for modern keyrings
2 parents 06d5121 + 9ada844 commit bf0b960

File tree

8 files changed

+377
-42
lines changed

8 files changed

+377
-42
lines changed

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ group :development do
2222
gem "voxpupuli-puppet-lint-plugins", '~> 4.0', require: false
2323
gem "facterdb", '~> 1.18', require: false
2424
gem "metadata-json-lint", '~> 3.0', require: false
25-
gem "puppetlabs_spec_helper", '~> 6.0', require: false
25+
gem "puppetlabs_spec_helper", '~> 7.0', require: false
2626
gem "rspec-puppet-facts", '~> 2.0', require: false
2727
gem "codecov", '~> 0.2', require: false
2828
gem "dependency_checker", '~> 1.0.0', require: false

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,28 @@ include apt
6666

6767
### Add GPG keys
6868

69+
You can fetch GPG keys via HTTP, Puppet URI, or local filesystem. The key can be in GPG binary format, or ASCII armored, but the filename should have the appropriate extension (`.gpg` for keys in binary format; or `.asc` for ASCII armored keys).
70+
71+
#### Fetch via HTTP
72+
73+
```puppet
74+
apt::keyring { 'puppetlabs-keyring.gpg':
75+
source => 'https://apt.puppetlabs.com/keyring.gpg',
76+
}
77+
```
78+
79+
#### Fetch via Puppet URI
80+
81+
```puppet
82+
apt::keyring { 'puppetlabs-keyring.gpg':
83+
source => 'puppet:///modules/my_module/local_puppetlabs-keyring.gpg',
84+
}
85+
```
86+
87+
Alternatively `apt::key` can be used.
88+
89+
**Warning** `apt::key` is deprecated in the latest Debian and Ubuntu releases. Please use apt::keyring instead.
90+
6991
**Warning:** Using short key IDs presents a serious security issue, potentially leaving you open to collision attacks. We recommend you always use full fingerprints to identify your GPG keys. This module allows short keys, but issues a security warning if you use them.
7092

7193
Declare the `apt::key` defined type:
@@ -184,6 +206,22 @@ apt::source { 'puppetlabs':
184206
}
185207
```
186208

209+
### Adding name and source to the key parameter of apt::source, which then manages modern apt gpg keyrings
210+
211+
The `name` parameter of key hash should contain the filename with extension (such as `puppetlabs.gpg`).
212+
213+
```puppet
214+
apt::source { 'puppetlabs':
215+
comment => 'Puppet8',
216+
location => 'https://apt.puppetlabs.com/',
217+
repos => 'puppet8',
218+
key => {
219+
'name' => 'puppetlabs.gpg',
220+
'source' => 'https://apt.puppetlabs.com/keyring.gpg',
221+
},
222+
}
223+
```
224+
187225
<a id="configure-apt-from-hiera"></a>
188226

189227
### Configure Apt from Hiera

REFERENCE.md

Lines changed: 128 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
* [`apt::conf`](#apt--conf): Specifies a custom Apt configuration file.
2222
* [`apt::key`](#apt--key): Manages the GPG keys that Apt uses to authenticate packages.
23+
* [`apt::keyring`](#apt--keyring): Manage GPG keyrings for apt repositories
2324
* [`apt::mark`](#apt--mark): Manages apt-mark settings
2425
* [`apt::pin`](#apt--pin): Manages Apt pins. Does not trigger an apt-get update run.
2526
* [`apt::ppa`](#apt--ppa): Manages PPA repositories using `add-apt-repository`. Not supported on Debian.
@@ -73,6 +74,7 @@ The following parameters are available in the `apt` class:
7374
* [`proxy_defaults`](#-apt--proxy_defaults)
7475
* [`sources`](#-apt--sources)
7576
* [`keys`](#-apt--keys)
77+
* [`keyrings`](#-apt--keyrings)
7678
* [`ppas`](#-apt--ppas)
7779
* [`pins`](#-apt--pins)
7880
* [`settings`](#-apt--settings)
@@ -239,6 +241,14 @@ Creates new `apt::key` resources. Valid options: a hash to be passed to the crea
239241

240242
Default value: `$apt::params::keys`
241243

244+
##### <a name="-apt--keyrings"></a>`keyrings`
245+
246+
Data type: `Hash`
247+
248+
Hash of `apt::keyring` resources.
249+
250+
Default value: `{}`
251+
242252
##### <a name="-apt--ppas"></a>`ppas`
243253

244254
Data type: `Hash`
@@ -624,6 +634,101 @@ Passes additional options to `apt-key adv --keyserver-options`.
624634

625635
Default value: `$apt::key_options`
626636

637+
### <a name="apt--keyring"></a>`apt::keyring`
638+
639+
Manage GPG keyrings for apt repositories
640+
641+
#### Examples
642+
643+
##### Download the puppetlabs apt keyring
644+
645+
```puppet
646+
apt::keyring { 'puppetlabs-keyring.gpg':
647+
source => 'https://apt.puppetlabs.com/keyring.gpg',
648+
}
649+
```
650+
651+
##### Deploy the apt source and associated keyring file
652+
653+
```puppet
654+
apt::source { 'puppet8-release':
655+
location => 'http://apt.puppetlabs.com',
656+
repos => 'puppet8',
657+
key => {
658+
name => 'puppetlabs-keyring.gpg',
659+
source => 'https://apt.puppetlabs.com/keyring.gpg'
660+
}
661+
}
662+
```
663+
664+
#### Parameters
665+
666+
The following parameters are available in the `apt::keyring` defined type:
667+
668+
* [`keyring_dir`](#-apt--keyring--keyring_dir)
669+
* [`keyring_filename`](#-apt--keyring--keyring_filename)
670+
* [`keyring_file`](#-apt--keyring--keyring_file)
671+
* [`keyring_file_mode`](#-apt--keyring--keyring_file_mode)
672+
* [`source`](#-apt--keyring--source)
673+
* [`content`](#-apt--keyring--content)
674+
* [`ensure`](#-apt--keyring--ensure)
675+
676+
##### <a name="-apt--keyring--keyring_dir"></a>`keyring_dir`
677+
678+
Data type: `Stdlib::Absolutepath`
679+
680+
Path to the directory where the keyring will be stored.
681+
682+
Default value: `'/etc/apt/keyrings'`
683+
684+
##### <a name="-apt--keyring--keyring_filename"></a>`keyring_filename`
685+
686+
Data type: `String[1]`
687+
688+
Optional filename for the keyring. It should also contain extension along with the filename.
689+
690+
Default value: `$name`
691+
692+
##### <a name="-apt--keyring--keyring_file"></a>`keyring_file`
693+
694+
Data type: `Stdlib::Absolutepath`
695+
696+
File path of the keyring.
697+
698+
Default value: `"${keyring_dir}/${keyring_filename}"`
699+
700+
##### <a name="-apt--keyring--keyring_file_mode"></a>`keyring_file_mode`
701+
702+
Data type: `Stdlib::Filemode`
703+
704+
File permissions of the keyring.
705+
706+
Default value: `'0644'`
707+
708+
##### <a name="-apt--keyring--source"></a>`source`
709+
710+
Data type: `Optional[Stdlib::Filesource]`
711+
712+
Source of the keyring file. Mutually exclusive with 'content'.
713+
714+
Default value: `undef`
715+
716+
##### <a name="-apt--keyring--content"></a>`content`
717+
718+
Data type: `Optional[String[1]]`
719+
720+
Content of the keyring file. Mutually exclusive with 'source'.
721+
722+
Default value: `undef`
723+
724+
##### <a name="-apt--keyring--ensure"></a>`ensure`
725+
726+
Data type: `Enum['present','absent']`
727+
728+
Ensure presence or absence of the resource.
729+
730+
Default value: `'present'`
731+
627732
### <a name="apt--mark"></a>`apt::mark`
628733

629734
Manages apt-mark settings
@@ -925,6 +1030,20 @@ apt::source { 'puppetlabs':
9251030
}
9261031
```
9271032

1033+
##### Download key behaviour to handle modern apt gpg keyrings. The `name` parameter in the key hash should be given with
1034+
1035+
```puppet
1036+
extension. Absence of extension will result in file formation with just name and no extension.
1037+
apt::source { 'puppetlabs':
1038+
location => 'http://apt.puppetlabs.com',
1039+
comment => 'Puppet8',
1040+
key => {
1041+
'name' => 'puppetlabs.gpg',
1042+
'source' => 'https://apt.puppetlabs.com/keyring.gpg',
1043+
},
1044+
}
1045+
```
1046+
9281047
#### Parameters
9291048

9301049
The following parameters are available in the `apt::source` defined type:
@@ -1001,9 +1120,12 @@ Default value: `{}`
10011120

10021121
Data type: `Optional[Variant[String, Hash]]`
10031122

1004-
Creates a declaration of the apt::key defined type. Valid options: a string to be passed to the `id` parameter of the `apt::key`
1005-
defined type, or a hash of `parameter => value` pairs to be passed to `apt::key`'s `id`, `server`, `content`, `source`, `weak_ssl`,
1006-
and/or `options` parameters.
1123+
Creates an `apt::keyring` in `/etc/apt/keyrings` (or anywhere on disk given `filename`) Valid options:
1124+
* a hash of `parameter => value` pairs to be passed to `file`: `name` (title), `content`, `source`, `filename`
1125+
1126+
The following inputs are valid for the (deprecated) `apt::key` defined type. Valid options:
1127+
* a string to be passed to the `id` parameter of the `apt::key` defined type
1128+
* a hash of `parameter => value` pairs to be passed to `apt::key`: `id`, `server`, `content`, `source`, `weak_ssl`, `options`
10071129

10081130
Default value: `undef`
10091131

@@ -1012,6 +1134,7 @@ Default value: `undef`
10121134
Data type: `Optional[Stdlib::AbsolutePath]`
10131135

10141136
Absolute path to a file containing the PGP keyring used to sign this repository. Value is used to set signed-by on the source entry.
1137+
This is not necessary if the key is installed with `key` param above.
10151138
See https://wiki.debian.org/DebianRepository/UseThirdParty for details.
10161139

10171140
Default value: `undef`
@@ -1030,8 +1153,8 @@ Default value: `undef`
10301153
Data type: `Optional[String]`
10311154

10321155
Tells Apt to only download information for specified architectures. Valid options: a string containing one or more architecture names,
1033-
separated by commas (e.g., 'i386' or 'i386,alpha,powerpc'). Default: undef (if unspecified, Apt downloads information for all architectures
1034-
defined in the Apt::Architectures option).
1156+
separated by commas (e.g., 'i386' or 'i386,alpha,powerpc').
1157+
(if unspecified, Apt downloads information for all architectures defined in the Apt::Architectures option)
10351158

10361159
Default value: `undef`
10371160

manifests/init.pp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@
8888
# @param keys
8989
# Creates new `apt::key` resources. Valid options: a hash to be passed to the create_resources function linked above.
9090
#
91+
# @param keyrings
92+
# Hash of `apt::keyring` resources.
93+
#
9194
# @param ppas
9295
# Creates new `apt::ppa` resources. Valid options: a hash to be passed to the create_resources function linked above.
9396
#
@@ -159,6 +162,7 @@
159162
Apt::Proxy $proxy = $apt::params::proxy,
160163
Hash $sources = $apt::params::sources,
161164
Hash $keys = $apt::params::keys,
165+
Hash $keyrings = {},
162166
Hash $ppas = $apt::params::ppas,
163167
Hash $pins = $apt::params::pins,
164168
Hash $settings = $apt::params::settings,
@@ -347,6 +351,12 @@
347351
if $keys {
348352
create_resources('apt::key', $keys)
349353
}
354+
# manage keyrings if present
355+
$keyrings.each |$key, $data| {
356+
apt::keyring { $key:
357+
* => $data,
358+
}
359+
}
350360
# manage ppas if present
351361
if $ppas {
352362
create_resources('apt::ppa', $ppas)

manifests/keyring.pp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# @summary Manage GPG keyrings for apt repositories
2+
#
3+
# @example Download the puppetlabs apt keyring
4+
# apt::keyring { 'puppetlabs-keyring.gpg':
5+
# source => 'https://apt.puppetlabs.com/keyring.gpg',
6+
# }
7+
# @example Deploy the apt source and associated keyring file
8+
# apt::source { 'puppet8-release':
9+
# location => 'http://apt.puppetlabs.com',
10+
# repos => 'puppet8',
11+
# key => {
12+
# name => 'puppetlabs-keyring.gpg',
13+
# source => 'https://apt.puppetlabs.com/keyring.gpg'
14+
# }
15+
# }
16+
#
17+
# @param keyring_dir
18+
# Path to the directory where the keyring will be stored.
19+
#
20+
# @param keyring_filename
21+
# Optional filename for the keyring. It should also contain extension along with the filename.
22+
#
23+
# @param keyring_file
24+
# File path of the keyring.
25+
#
26+
# @param keyring_file_mode
27+
# File permissions of the keyring.
28+
#
29+
# @param source
30+
# Source of the keyring file. Mutually exclusive with 'content'.
31+
#
32+
# @param content
33+
# Content of the keyring file. Mutually exclusive with 'source'.
34+
#
35+
# @param ensure
36+
# Ensure presence or absence of the resource.
37+
#
38+
define apt::keyring (
39+
Stdlib::Absolutepath $keyring_dir = '/etc/apt/keyrings',
40+
String[1] $keyring_filename = $name,
41+
Stdlib::Absolutepath $keyring_file = "${keyring_dir}/${keyring_filename}",
42+
Stdlib::Filemode $keyring_file_mode = '0644',
43+
Optional[Stdlib::Filesource] $source = undef,
44+
Optional[String[1]] $content = undef,
45+
Enum['present','absent'] $ensure = 'present',
46+
) {
47+
ensure_resource('file', $keyring_dir, { ensure => 'directory', mode => '0755', })
48+
if $source and $content {
49+
fail("Parameters 'source' and 'content' are mutually exclusive")
50+
} elsif ! $source and ! $content {
51+
fail("One of 'source' or 'content' parameters are required")
52+
}
53+
54+
case $ensure {
55+
'present': {
56+
file { $keyring_file:
57+
ensure => 'file',
58+
mode => $keyring_file_mode,
59+
owner => 'root',
60+
group => 'root',
61+
source => $source,
62+
content => $content,
63+
}
64+
}
65+
'absent': {
66+
file { $keyring_file:
67+
ensure => $ensure,
68+
}
69+
}
70+
default: {
71+
fail("Invalid 'ensure' value '${ensure}' for apt::keyring")
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)