|
42 | 42 | # [*cron_minute*] |
43 | 43 | # Optional string, integer or array, minute(s) that the renewal command should execute. |
44 | 44 | # e.g. 0 or '00' or [0,30]. Default - seeded random minute. |
| 45 | +# [*pre_hook_commands*] |
| 46 | +# Array of commands to run in a shell before attempting to obtain/renew the certificate. |
| 47 | +# [*post_hook_commands*] |
| 48 | +# Array of command(s) to run in a shell after attempting to obtain/renew the certificate. |
| 49 | +# [*deploy_hook_commands*] |
| 50 | +# Array of command(s) to run in a shell once if the certificate is successfully issued. |
| 51 | +# Two environmental variables are supplied by certbot: |
| 52 | +# - $RENEWED_LINEAGE: Points to the live directory with the cert files and key. |
| 53 | +# Example: /etc/letsencrypt/live/example.com |
| 54 | +# - $RENEWED_DOMAINS: A space-delimited list of renewed certificate domains. |
| 55 | +# Example: "example.com www.example.com" |
45 | 56 | # |
46 | 57 | define letsencrypt::certonly ( |
47 | 58 | Enum['present','absent'] $ensure = 'present', |
|
61 | 72 | Variant[Integer[0,23], String, Array] $cron_hour = fqdn_rand(24, $title), |
62 | 73 | Variant[Integer[0,59], String, Array] $cron_minute = fqdn_rand(60, fqdn_rand_string(10, $title)), |
63 | 74 | Stdlib::Unixpath $config_dir = $letsencrypt::config_dir, |
| 75 | + Variant[String[1], Array[String[1]]] $pre_hook_commands = [], |
| 76 | + Variant[String[1], Array[String[1]]] $post_hook_commands = [], |
| 77 | + Variant[String[1], Array[String[1]]] $deploy_hook_commands = [], |
64 | 78 | ) { |
65 | 79 |
|
66 | 80 | if $plugin == 'webroot' and empty($webroot_paths) { |
67 | 81 | fail("The 'webroot_paths' parameter must be specified when using the 'webroot' plugin") |
68 | 82 | } |
69 | 83 |
|
| 84 | + # Wildcard-less title for use in file paths |
| 85 | + $title_nowc = regsubst($title, '^\*\.', '') |
| 86 | + |
70 | 87 | if $ensure == 'present' { |
71 | 88 | if ($custom_plugin) { |
72 | | - $command_start = "${letsencrypt_command} --text --agree-tos --non-interactive certonly --rsa-key-size ${key_size} " |
| 89 | + $default_args = "--text --agree-tos --non-interactive certonly --rsa-key-size ${key_size}" |
73 | 90 | } else { |
74 | | - $command_start = "${letsencrypt_command} --text --agree-tos --non-interactive certonly --rsa-key-size ${key_size} -a ${plugin} " |
| 91 | + $default_args = "--text --agree-tos --non-interactive certonly --rsa-key-size ${key_size} -a ${plugin}" |
75 | 92 | } |
76 | 93 | } else { |
77 | | - $command_start = "${letsencrypt_command} --text --agree-tos --non-interactive delete " |
| 94 | + $default_args = '--text --agree-tos --non-interactive delete' |
78 | 95 | } |
79 | 96 |
|
80 | 97 | case $plugin { |
81 | 98 |
|
82 | 99 | 'webroot': { |
83 | | - $_command_domains = zip($domains, $webroot_paths).map |$domain| { |
| 100 | + $_plugin_args = zip($domains, $webroot_paths).map |$domain| { |
84 | 101 | if $domain[1] { |
85 | 102 | "--webroot-path ${domain[1]} -d ${domain[0]}" |
86 | 103 | } else { |
87 | 104 | "-d ${domain[0]}" |
88 | 105 | } |
89 | 106 | } |
90 | | - $command_domains = join([ "--cert-name ${title}", ] + $_command_domains, ' ') |
| 107 | + $plugin_args = ["--cert-name ${title}"] + $_plugin_args |
91 | 108 | } |
92 | 109 |
|
93 | 110 | 'dns-rfc2136': { |
94 | 111 | require letsencrypt::plugin::dns_rfc2136 |
95 | | - $dns_args = [ |
| 112 | + $plugin_args = [ |
96 | 113 | "--cert-name ${title} -d", |
97 | 114 | join($domains, ' -d '), |
98 | 115 | "--dns-rfc2136-credentials ${letsencrypt::plugin::dns_rfc2136::config_dir}/dns-rfc2136.ini", |
99 | 116 | "--dns-rfc2136-propagation-seconds ${letsencrypt::plugin::dns_rfc2136::propagation_seconds}", |
100 | 117 | ] |
101 | | - $command_domains = join($dns_args, ' ') |
102 | 118 | } |
103 | 119 |
|
104 | 120 | default: { |
105 | 121 | if $ensure == 'present' { |
106 | | - $_command_domains = join($domains, ' -d ') |
107 | | - $command_domains = "--cert-name ${title} -d ${_command_domains}" |
| 122 | + $_plugin_args = join($domains, ' -d ') |
| 123 | + $plugin_args = "--cert-name ${title} -d ${_plugin_args}" |
108 | 124 | } else { |
109 | | - $command_domains = "--cert-name ${title}" |
| 125 | + $plugin_args = "--cert-name ${title}" |
110 | 126 | } |
111 | 127 | } |
112 | 128 | } |
113 | 129 |
|
114 | | - if empty($additional_args) { |
115 | | - $command_end = undef |
116 | | - } else { |
117 | | - # ['',] adds an additional whitespace in the front |
118 | | - $command_end = join(['',] + $additional_args, ' ') |
| 130 | + $hook_args = ['pre', 'post', 'deploy'].map | String $type | { |
| 131 | + $commands = getvar("${type}_hook_commands") |
| 132 | + if (!empty($commands)) { |
| 133 | + $hook_file = "${config_dir}/renewal-hooks-puppet/${title_nowc}-${type}.sh" |
| 134 | + letsencrypt::hook { "${title}-${type}": |
| 135 | + type => $type, |
| 136 | + hook_file => $hook_file, |
| 137 | + commands => $commands, |
| 138 | + before => Exec["letsencrypt certonly ${title}"], |
| 139 | + } |
| 140 | + "--${type}-hook \"${hook_file}\"" |
| 141 | + } |
| 142 | + else { |
| 143 | + undef |
| 144 | + } |
119 | 145 | } |
120 | 146 |
|
121 | 147 | # certbot uses --cert-name to generate the file path |
122 | 148 | $live_path_certname = regsubst($title, '^\*\.', '') |
123 | 149 | $live_path = "${config_dir}/live/${live_path_certname}/cert.pem" |
124 | 150 |
|
| 151 | + $_command = flatten([ |
| 152 | + $letsencrypt_command, |
| 153 | + $default_args, |
| 154 | + $plugin_args, |
| 155 | + $hook_args, |
| 156 | + $additional_args, |
| 157 | + ]).filter | $arg | { $arg =~ NotUndef and $arg != [] } |
| 158 | + $command = join($_command, ' ') |
| 159 | + |
125 | 160 | $execution_environment = [ "VENV_PATH=${letsencrypt::venv_path}", ] + $environment |
126 | 161 | $verify_domains = join(unique($domains), ' ') |
127 | 162 |
|
|
132 | 167 | } |
133 | 168 |
|
134 | 169 | exec { "letsencrypt certonly ${title}": |
135 | | - command => "${command_start}${command_domains}${command_end}", |
| 170 | + command => $command, |
136 | 171 | * => $exec_ensure, |
137 | 172 | path => $facts['path'], |
138 | 173 | environment => $execution_environment, |
|
144 | 179 | } |
145 | 180 |
|
146 | 181 | if $manage_cron { |
147 | | - $maincommand = "${command_start}--keep-until-expiring ${command_domains}${command_end}" |
| 182 | + $maincommand = join($_command + ['--keep-until-expiring'], ' ') |
148 | 183 | $cron_script_ensure = $ensure ? { 'present' => 'file', default => 'absent' } |
149 | 184 | $cron_ensure = $ensure |
150 | 185 |
|
|
0 commit comments