Merge pull request #936 from puppetlabs/pdksync_IAC-746
[puppet-modules/puppetlabs-apt.git] / manifests / source.pp
1 # @summary Manages the Apt sources in /etc/apt/sources.list.d/.
2 #
3 # @example Install the puppetlabs apt source
4 #   apt::source { 'puppetlabs':
5 #     location => 'http://apt.puppetlabs.com',
6 #     repos    => 'main',
7 #     key      => {
8 #       id     => '6F6B15509CF8E59E6E469F327F438280EF8D349F',
9 #       server => 'hkps.pool.sks-keyservers.net',
10 #     },
11 #   }
12 #
13 # @param location
14 #   Required, unless ensure is set to 'absent'. Specifies an Apt repository. Valid options: a string containing a repository URL.
15 #
16 # @param comment
17 #   Supplies a comment for adding to the Apt source file.
18 #
19 # @param ensure
20 #   Specifies whether the Apt source file should exist. Valid options: 'present' and 'absent'.
21 #
22 # @param release
23 #   Specifies a distribution of the Apt repository.
24 #
25 # @param repos
26 #   Specifies a component of the Apt repository.
27 #
28 # @param include
29 #   Configures include options. Valid options: a hash of available keys.
30
31 # @option include [Boolean] :deb
32 #   Specifies whether to request the distribution's compiled binaries. Default true.
33 #
34 # @option include [Boolean] :src
35 #   Specifies whether to request the distribution's uncompiled source code. Default false.
36 #
37 # @param key
38 #   Creates a declaration of the apt::key defined type. Valid options: a string to be passed to the `id` parameter of the `apt::key` 
39 #   defined type, or a hash of `parameter => value` pairs to be passed to `apt::key`'s `id`, `server`, `content`, `source`, and/or 
40 #   `options` parameters.
41 #
42 # @param pin
43 #   Creates a declaration of the apt::pin defined type. Valid options: a number or string to be passed to the `id` parameter of the 
44 #   `apt::pin` defined type, or a hash of `parameter => value` pairs to be passed to `apt::pin`'s corresponding parameters.
45 #
46 # @param architecture
47 #   Tells Apt to only download information for specified architectures. Valid options: a string containing one or more architecture names, 
48 #   separated by commas (e.g., 'i386' or 'i386,alpha,powerpc'). Default: undef (if unspecified, Apt downloads information for all architectures 
49 #   defined in the Apt::Architectures option).
50 #
51 # @param allow_unsigned
52 #   Specifies whether to authenticate packages from this release, even if the Release file is not signed or the signature can't be checked.
53 #
54 # @param notify_update
55 #   Specifies whether to trigger an `apt-get update` run.
56 #
57 define apt::source(
58   Optional[String] $location                    = undef,
59   String $comment                               = $name,
60   String $ensure                                = present,
61   Optional[String] $release                     = undef,
62   String $repos                                 = 'main',
63   Optional[Variant[Hash]] $include              = {},
64   Optional[Variant[String, Hash]] $key          = undef,
65   Optional[Variant[Hash, Numeric, String]] $pin = undef,
66   Optional[String] $architecture                = undef,
67   Boolean $allow_unsigned                       = false,
68   Boolean $notify_update                        = true,
69 ) {
70
71   include ::apt
72
73   $_before = Apt::Setting["list-${title}"]
74
75   if !$release {
76     if $facts['lsbdistcodename'] {
77       $_release = $facts['lsbdistcodename']
78     } else {
79       fail(translate('lsbdistcodename fact not available: release parameter required'))
80     }
81   } else {
82     $_release = $release
83   }
84
85   if $ensure == 'present' {
86     if ! $location {
87       fail(translate('cannot create a source entry without specifying a location'))
88     }
89     # Newer oses, do not need the package for HTTPS transport.
90     $_transport_https_releases = [ 'wheezy', 'jessie', 'stretch', 'trusty', 'xenial' ]
91     if ($facts['lsbdistcodename'] in $_transport_https_releases) and $location =~ /(?i:^https:\/\/)/ {
92       ensure_packages('apt-transport-https')
93     }
94   }
95
96   $includes = merge($::apt::include_defaults, $include)
97
98   if $key {
99     if $key =~ Hash {
100       unless $key['id'] {
101         fail(translate('key hash must contain at least an id entry'))
102       }
103       $_key = merge($::apt::source_key_defaults, $key)
104     } else {
105       $_key = { 'id' => assert_type(String[1], $key) }
106     }
107   }
108
109   $header = epp('apt/_header.epp')
110
111   $sourcelist = epp('apt/source.list.epp', {
112     'comment'          => $comment,
113     'includes'         => $includes,
114     'opt_architecture' => $architecture,
115     'allow_unsigned'   => $allow_unsigned,
116     'location'         => $location,
117     'release'          => $_release,
118     'repos'            => $repos,
119   })
120
121   apt::setting { "list-${name}":
122     ensure        => $ensure,
123     content       => "${header}${sourcelist}",
124     notify_update => $notify_update,
125   }
126
127   if $pin {
128     if $pin =~ Hash {
129       $_pin = merge($pin, { 'ensure' => $ensure, 'before' => $_before })
130     } elsif ($pin =~ Numeric or $pin =~ String) {
131       $url_split = split($location, '[:\/]+')
132       $host      = $url_split[1]
133       $_pin = {
134         'ensure'   => $ensure,
135         'priority' => $pin,
136         'before'   => $_before,
137         'origin'   => $host,
138       }
139     } else {
140       fail(translate('Received invalid value for pin parameter'))
141     }
142     create_resources('apt::pin', { "${name}" => $_pin })
143   }
144
145   # We do not want to remove keys when the source is absent.
146   if $key and ($ensure == 'present') {
147     if $_key =~ Hash {
148       if $_key['ensure'] != undef {
149         $_ensure = $_key['ensure']
150       } else {
151         $_ensure = $ensure
152       }
153
154       apt::key { "Add key: ${$_key['id']} from Apt::Source ${title}":
155         ensure  => $_ensure,
156         id      => $_key['id'],
157         server  => $_key['server'],
158         content => $_key['content'],
159         source  => $_key['source'],
160         options => $_key['options'],
161         before  => $_before,
162       }
163     }
164   }
165 }