Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cron time parameters #122

Merged
merged 1 commit into from
Dec 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,21 @@ letsencrypt::certonly { 'foo':
}
```

To automatically renew a certificate, you can pass the `manage_cron` parameter.
You can optionally add a shell command to be run on success using the `cron_success_command` parameter.
You can optionally add a shell command to be run on before using the `cron_before_command` parameter.
You can optionally specify one or multiple days of the month when to run the cron using the `cron_monthday` parameter (default is every day).
You can disable output (and resulting emails) generated by the cron command using the `suppress_cron_output` parameter.
* `manage_cron` can be used to automatically renew the certificate
* `cron_success_command` can be used to run a shell command on a successful renewal
* `cron_before_command` can be used to run a shell command before a renewal
* `cron_monthday` can be used to specify one or multiple days of the month to run the cron job (defaults to every day)
* `cron_hour` can be used to specify hour(s) to run the cron job (defaults to a seeded random hour)
* `cron_minute` can be used to specify minute(s) to run the cron job (defaults to a seeded random minute)
* `suppress_cron_output` can be used to disable output (and resulting emails) generated by the cron command

```puppet
letsencrypt::certonly { 'foo':
domains => ['foo.example.com', 'bar.example.com'],
manage_cron => true,
cron_before_command => 'service nginx stop',
domains => ['foo.example.com', 'bar.example.com'],
manage_cron => true,
cron_hour => [0,12],
cron_minute => '30',
cron_before_command => 'service nginx stop',
cron_success_command => '/bin/systemctl reload nginx.service',
suppress_cron_output => true,
}
Expand Down
10 changes: 8 additions & 2 deletions manifests/certonly.pp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
# [*cron_success_command*]
# String representation of a command that should be run if the renewal command
# succeeds.
# [*cron_hour*]
# Optional string, integer or array, hour(s) that the renewal command should execute.
# e.g. '[0,12]' execute at midnight and midday. Default - seeded random hour.
# [*cron_minute*]
# Optional string, integer or array, minute(s) that the renewal command should execute.
# e.g. 0 or '00' or [0,30]. Default - seeded random minute.
#
define letsencrypt::certonly (
Array[String[1]] $domains = [$title],
Expand All @@ -45,6 +51,8 @@
Optional[String[1]] $cron_before_command = undef,
Optional[String[1]] $cron_success_command = undef,
Array[Variant[Integer[0, 59], String[1]]] $cron_monthday = ['*'],
Variant[Integer[0,23], String, Array] $cron_hour = fqdn_rand(24, $title),
Variant[Integer[0,59], String, Array] $cron_minute = fqdn_rand(60, fqdn_rand_string(10, $title)),
Stdlib::Unixpath $config_dir = $letsencrypt::config_dir,
) {

Expand Down Expand Up @@ -109,8 +117,6 @@
} else {
$cron_cmd = $renewcommand
}
$cron_hour = fqdn_rand(24, $title) # 0 - 23, seed is title plus fqdn
$cron_minute = fqdn_rand(60, fqdn_rand_string(10,$title)) # 0 - 59, seed is title plus fqdn
file { "${::letsencrypt::cron_scripts_path}/renew-${title}.sh":
ensure => 'file',
mode => '0755',
Expand Down
106 changes: 104 additions & 2 deletions spec/defines/letsencrypt_certonly_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command 'letsencrypt --text --agree-tos --non-interactive certonly -a apache --cert-name foo.example.com -d foo.example.com' }
end

context 'with custom plugin and manage cron' do
context 'with custom plugin and manage_cron' do
let(:title) { 'foo.example.com' }
let(:params) do
{
Expand All @@ -87,6 +87,108 @@
it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_content "#!/bin/sh\nexport VENV_PATH=/opt/letsencrypt/.venv\nletsencrypt --text --agree-tos --non-interactive certonly -a apache --keep-until-expiring --cert-name foo.example.com -d foo.example.com\n" }
end

context 'with manage_cron and defined cron_hour (integer)' do
let(:title) { 'foo.example.com' }
let(:params) do
{
cron_hour: 13,
manage_cron: true
}
end

it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_hour 13 }
it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_content "#!/bin/sh\nexport VENV_PATH=/opt/letsencrypt/.venv\nletsencrypt --text --agree-tos --non-interactive certonly -a standalone --keep-until-expiring --cert-name foo.example.com -d foo.example.com\n" }
end

context 'with manage_cron and out of range defined cron_hour (integer)' do
let(:title) { 'foo.example.com' }
let(:params) do
{
cron_hour: 24,
manage_cron: true
}
end

it { is_expected.to raise_error Puppet::Error }
end

context 'with manage_cron and defined cron_hour (string)' do
let(:title) { 'foo.example.com' }
let(:params) do
{
cron_hour: '00',
manage_cron: true
}
end

it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_hour '00' }
it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_content "#!/bin/sh\nexport VENV_PATH=/opt/letsencrypt/.venv\nletsencrypt --text --agree-tos --non-interactive certonly -a standalone --keep-until-expiring --cert-name foo.example.com -d foo.example.com\n" }
end

context 'with manage_cron and defined cron_hour (array)' do
let(:title) { 'foo.example.com' }
let(:params) do
{
cron_hour: [1, 13],
manage_cron: true
}
end

it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_hour [1, 13] }
it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_content "#!/bin/sh\nexport VENV_PATH=/opt/letsencrypt/.venv\nletsencrypt --text --agree-tos --non-interactive certonly -a standalone --keep-until-expiring --cert-name foo.example.com -d foo.example.com\n" }
end

context 'with manage_cron and defined cron_minute (integer)' do
let(:title) { 'foo.example.com' }
let(:params) do
{
cron_minute: 15,
manage_cron: true
}
end

it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_minute 15 }
it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_content "#!/bin/sh\nexport VENV_PATH=/opt/letsencrypt/.venv\nletsencrypt --text --agree-tos --non-interactive certonly -a standalone --keep-until-expiring --cert-name foo.example.com -d foo.example.com\n" }
end

context 'with manage_cron and out of range defined cron_hour (integer)' do
let(:title) { 'foo.example.com' }
let(:params) do
{
cron_hour: 66,
manage_cron: true
}
end

it { is_expected.to raise_error Puppet::Error }
end

context 'with manage_cron and defined cron_minute (string)' do
let(:title) { 'foo.example.com' }
let(:params) do
{
cron_minute: '15',
manage_cron: true
}
end

it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_minute '15' }
it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_content "#!/bin/sh\nexport VENV_PATH=/opt/letsencrypt/.venv\nletsencrypt --text --agree-tos --non-interactive certonly -a standalone --keep-until-expiring --cert-name foo.example.com -d foo.example.com\n" }
end

context 'with manage_cron and defined cron_minute (array)' do
let(:title) { 'foo.example.com' }
let(:params) do
{
cron_minute: [0, 30],
manage_cron: true
}
end

it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_minute [0, 30] }
it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_content "#!/bin/sh\nexport VENV_PATH=/opt/letsencrypt/.venv\nletsencrypt --text --agree-tos --non-interactive certonly -a standalone --keep-until-expiring --cert-name foo.example.com -d foo.example.com\n" }
end

context 'with custom puppet_vardir path and manage_cron' do
let(:facts) { { osfamily: osfamily, operatingsystem: osfamily, operatingsystemrelease: osversion, operatingsystemmajrelease: osversion.split('.').first, path: '/usr/bin', puppet_vardir: '/tmp/custom_vardir' } }
let(:title) { 'foo.example.com' }
Expand Down Expand Up @@ -142,7 +244,7 @@
it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_environment(['VENV_PATH=/opt/letsencrypt/.venv', 'FOO=bar', 'FIZZ=buzz']) }
end

context 'with custom environment variables and manage cron' do
context 'with custom environment variables and manage_cron' do
let(:title) { 'foo.example.com' }
let(:params) { { environment: ['FOO=bar', 'FIZZ=buzz'], manage_cron: true } }

Expand Down