Skip to content

Commit 83082c0

Browse files
authored
Merge pull request #1052 from puppetlabs/maint-harden_ppa
Harden PPA defined type
2 parents 8b15f6f + 3a90419 commit 83082c0

File tree

8 files changed

+185
-114
lines changed

8 files changed

+185
-114
lines changed

examples/ppa.pp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
class { 'apt': }
22

33
# Example declaration of an Apt PPA
4-
apt::ppa { 'ppa:openstack-ppa/bleeding-edge': }
4+
apt::ppa { 'ppa:ubuntuhandbook1/apps': }

lib/facter/apt_sources.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# frozen_string_literal: true
2+
3+
# This fact lists the .list filenames that are used by apt.
4+
Facter.add(:apt_sources) do
5+
confine osfamily: 'Debian'
6+
setcode do
7+
sources = ['sources.list']
8+
Dir.glob('/etc/apt/sources.list.d/*.list').each do |file|
9+
sources.push(File.basename(file))
10+
end
11+
sources
12+
end
13+
end

manifests/init.pp

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,14 @@
3737
# Configures various update settings. Valid options: a hash made up from the following keys:
3838
#
3939
# @option update [String] :frequency
40-
# Specifies how often to run `apt-get update`. If the exec resource `apt_update` is notified, `apt-get update` runs regardless of this value.
41-
# Valid options: 'always' (at every Puppet run); 'daily' (if the value of `apt_update_last_success` is less than current epoch time minus 86400);
42-
# 'weekly' (if the value of `apt_update_last_success` is less than current epoch time minus 604800); and 'reluctantly' (only if the exec resource
43-
# `apt_update` is notified). Default: 'reluctantly'.
40+
# Specifies how often to run `apt-get update`. If the exec resource `apt_update` is notified,
41+
# `apt-get update` runs regardless of this value.
42+
# Valid options:
43+
# 'always' (at every Puppet run);
44+
# daily' (if the value of `apt_update_last_success` is less than current epoch time minus 86400);
45+
# 'weekly' (if the value of `apt_update_last_success` is less than current epoch time minus 604800);
46+
# 'reluctantly' (only if the exec resource `apt_update` is notified).
47+
# Default: 'reluctantly'.
4448
#
4549
# @option update [Integer] :loglevel
4650
# Specifies the log level of logs outputted to the console. Default: undef.
@@ -122,38 +126,37 @@
122126
# Specifies whether to perform force purge or delete. Default false.
123127
#
124128
class apt (
125-
Hash $update_defaults = $apt::params::update_defaults,
126-
Hash $purge_defaults = $apt::params::purge_defaults,
127-
Hash $proxy_defaults = $apt::params::proxy_defaults,
128-
Hash $include_defaults = $apt::params::include_defaults,
129-
String $provider = $apt::params::provider,
130-
String $keyserver = $apt::params::keyserver,
131-
Optional[String] $key_options = $apt::params::key_options,
132-
Optional[String] $ppa_options = $apt::params::ppa_options,
133-
Optional[String] $ppa_package = $apt::params::ppa_package,
134-
Optional[Hash] $backports = $apt::params::backports,
135-
Hash $confs = $apt::params::confs,
136-
Hash $update = $apt::params::update,
137-
Hash $purge = $apt::params::purge,
138-
Apt::Proxy $proxy = $apt::params::proxy,
139-
Hash $sources = $apt::params::sources,
140-
Hash $keys = $apt::params::keys,
141-
Hash $ppas = $apt::params::ppas,
142-
Hash $pins = $apt::params::pins,
143-
Hash $settings = $apt::params::settings,
144-
Boolean $manage_auth_conf = $apt::params::manage_auth_conf,
145-
Array[Apt::Auth_conf_entry]
146-
$auth_conf_entries = $apt::params::auth_conf_entries,
147-
String $auth_conf_owner = $apt::params::auth_conf_owner,
148-
String $root = $apt::params::root,
149-
String $sources_list = $apt::params::sources_list,
150-
String $sources_list_d = $apt::params::sources_list_d,
151-
String $conf_d = $apt::params::conf_d,
152-
String $preferences = $apt::params::preferences,
153-
String $preferences_d = $apt::params::preferences_d,
154-
String $apt_conf_d = $apt::params::apt_conf_d,
155-
Hash $config_files = $apt::params::config_files,
156-
Boolean $sources_list_force = $apt::params::sources_list_force,
129+
Hash $update_defaults = $apt::params::update_defaults,
130+
Hash $purge_defaults = $apt::params::purge_defaults,
131+
Hash $proxy_defaults = $apt::params::proxy_defaults,
132+
Hash $include_defaults = $apt::params::include_defaults,
133+
String $provider = $apt::params::provider,
134+
String $keyserver = $apt::params::keyserver,
135+
Optional[String] $key_options = $apt::params::key_options,
136+
Optional[Array[String]] $ppa_options = $apt::params::ppa_options,
137+
Optional[String] $ppa_package = $apt::params::ppa_package,
138+
Optional[Hash] $backports = $apt::params::backports,
139+
Hash $confs = $apt::params::confs,
140+
Hash $update = $apt::params::update,
141+
Hash $purge = $apt::params::purge,
142+
Apt::Proxy $proxy = $apt::params::proxy,
143+
Hash $sources = $apt::params::sources,
144+
Hash $keys = $apt::params::keys,
145+
Hash $ppas = $apt::params::ppas,
146+
Hash $pins = $apt::params::pins,
147+
Hash $settings = $apt::params::settings,
148+
Boolean $manage_auth_conf = $apt::params::manage_auth_conf,
149+
Array[Apt::Auth_conf_entry] $auth_conf_entries = $apt::params::auth_conf_entries,
150+
String $auth_conf_owner = $apt::params::auth_conf_owner,
151+
String $root = $apt::params::root,
152+
String $sources_list = $apt::params::sources_list,
153+
String $sources_list_d = $apt::params::sources_list_d,
154+
String $conf_d = $apt::params::conf_d,
155+
String $preferences = $apt::params::preferences,
156+
String $preferences_d = $apt::params::preferences_d,
157+
String $apt_conf_d = $apt::params::apt_conf_d,
158+
Hash $config_files = $apt::params::config_files,
159+
Boolean $sources_list_force = $apt::params::sources_list_force,
157160

158161
Hash $source_key_defaults = {
159162
'server' => $keyserver,

manifests/params.pp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
'key' => '630239CC130E1A7FD81A27B140976EAF437D05B5',
9292
'repos' => 'main universe multiverse restricted',
9393
}
94-
$ppa_options = '-y'
94+
$ppa_options = ['-y']
9595
$ppa_package = 'software-properties-common'
9696
$auth_conf_owner = '_apt'
9797
}

manifests/ppa.pp

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424
# Specifies whether Puppet should manage the package that provides `apt-add-repository`.
2525
#
2626
define apt::ppa (
27-
String $ensure = 'present',
28-
Optional[String] $options = $::apt::ppa_options,
29-
Optional[String] $release = fact('os.distro.codename'),
30-
Optional[String] $dist = $facts['os']['name'],
31-
Optional[String] $package_name = $::apt::ppa_package,
32-
Boolean $package_manage = false,
27+
String $ensure = 'present',
28+
Optional[Array[String]] $options = $::apt::ppa_options,
29+
Optional[String] $release = fact('os.distro.codename'),
30+
Optional[String] $dist = $facts['os']['name'],
31+
Optional[String] $package_name = $::apt::ppa_package,
32+
Boolean $package_manage = false,
3333
) {
3434
unless $release {
3535
fail('os.distro.codename fact not available: release parameter required')
@@ -39,6 +39,11 @@
3939
fail('apt::ppa is not currently supported on Debian.')
4040
}
4141

42+
# Validate the resource name
43+
if $name !~ /^ppa:([a-zA-Z0-9\-_]+)\/([a-zA-z0-9\-_]+)$/ {
44+
fail("Invalid PPA name: ${name}")
45+
}
46+
4247
if versioncmp($facts['os']['release']['full'], '14.10') >= 0 {
4348
$distid = downcase($dist)
4449
$dash_filename = regsubst($name, '^ppa:([^/]+)/(.+)$', "\\1-${distid}-\\2")
@@ -62,6 +67,9 @@
6267
$trusted_gpg_d_filename = "${dash_filename_no_specialchars}.gpg"
6368
}
6469

70+
# This is the location of our main exec script
71+
$script_path = "/opt/puppetlabs/puppet/cache/add-apt-repository-${dash_filename_no_specialchars}-${release}.sh"
72+
6573
if $ensure == 'present' {
6674
if $package_manage {
6775
ensure_packages($package_name)
@@ -81,24 +89,36 @@
8189
$_proxy_env = []
8290
}
8391

84-
exec { "add-apt-repository-${name}":
85-
environment => $_proxy_env,
86-
command => "/usr/bin/add-apt-repository ${options} ${name} || (rm ${::apt::sources_list_d}/${sources_list_d_filename} && false)",
87-
unless => "/usr/bin/test -f ${::apt::sources_list_d}/${sources_list_d_filename} && /usr/bin/test -f ${::apt::trusted_gpg_d}/${trusted_gpg_d_filename}",
88-
user => 'root',
89-
logoutput => 'on_failure',
90-
notify => Class['apt::update'],
91-
require => $_require,
92-
}
92+
unless $sources_list_d_filename in $facts['apt_sources'] {
93+
$script_content = epp('apt/add-apt-repository.sh.epp', {
94+
command => ['/usr/bin/add-apt-repository', shell_join($options), $name],
95+
sources_list_d_path => $::apt::sources_list_d,
96+
sources_list_d_filename => $sources_list_d_filename,
97+
})
9398

94-
file { "${::apt::sources_list_d}/${sources_list_d_filename}":
95-
ensure => file,
96-
require => Exec["add-apt-repository-${name}"],
99+
file { "add-apt-repository-script-${name}":
100+
ensure => 'file',
101+
path => $script_path,
102+
content => $script_content,
103+
mode => '0755',
104+
}
105+
106+
exec { "add-apt-repository-${name}":
107+
environment => $_proxy_env,
108+
command => $script_path,
109+
logoutput => 'on_failure',
110+
notify => Class['apt::update'],
111+
require => $_require,
112+
}
97113
}
98114
}
99115
else {
100-
file { "${::apt::sources_list_d}/${sources_list_d_filename}":
101-
ensure => 'absent',
116+
tidy { "remove-apt-repository-script-${name}":
117+
path => $script_path,
118+
}
119+
120+
tidy { "remove-apt-repository-${name}":
121+
path => "${::apt::sources_list_d}/${sources_list_d_filename}",
102122
notify => Class['apt::update'],
103123
}
104124
}

0 commit comments

Comments
 (0)