From ef876ed48fe121fa72c61c8dea3c79d8b81d34a7 Mon Sep 17 00:00:00 2001 From: Martijn de Gouw Date: Thu, 22 Jun 2023 17:14:13 +0200 Subject: [PATCH] Add support for specifying key type Defaults to rsa for backwards compatibility --- REFERENCE.md | 36 ++++++++++++++++ manifests/certonly.pp | 14 +++++- manifests/init.pp | 4 ++ spec/defines/letsencrypt_certonly_spec.rb | 52 +++++++++++------------ 4 files changed, 78 insertions(+), 28 deletions(-) diff --git a/REFERENCE.md b/REFERENCE.md index 727f6f89..f2ed2bbd 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -75,7 +75,9 @@ The following parameters are available in the `letsencrypt` class: * [`agree_tos`](#-letsencrypt--agree_tos) * [`unsafe_registration`](#-letsencrypt--unsafe_registration) * [`config_dir`](#-letsencrypt--config_dir) +* [`key_type`](#-letsencrypt--key_type) * [`key_size`](#-letsencrypt--key_size) +* [`elliptic_curve`](#-letsencrypt--elliptic_curve) * [`certificates`](#-letsencrypt--certificates) * [`renew_pre_hook_commands`](#-letsencrypt--renew_pre_hook_commands) * [`renew_post_hook_commands`](#-letsencrypt--renew_post_hook_commands) @@ -210,6 +212,14 @@ The path to the configuration directory. Default value: `'/etc/letsencrypt'` +##### `key_type` + +Data type: `Enum['rsa', 'ecdsa']` + +Type of private key + +Default value: `'rsa'` + ##### `key_size` Data type: `Integer[2048]` @@ -218,6 +228,14 @@ Size for the RSA public key Default value: `4096` +##### `elliptic_curve` + +Data type: `String[1]` + +The SECG elliptic curve name to use + +Default value: `'secp256r1'` + ##### `certificates` Data type: `Hash[String[1],Hash]` @@ -752,7 +770,9 @@ The following parameters are available in the `letsencrypt::certonly` defined ty * [`letsencrypt_command`](#-letsencrypt--certonly--letsencrypt_command) * [`additional_args`](#-letsencrypt--certonly--additional_args) * [`environment`](#-letsencrypt--certonly--environment) +* [`key_type`](#-letsencrypt--certonly--key_type) * [`key_size`](#-letsencrypt--certonly--key_size) +* [`elliptic_curve`](#-letsencrypt--certonly--elliptic_curve) * [`manage_cron`](#-letsencrypt--certonly--manage_cron) * [`cron_output`](#-letsencrypt--certonly--cron_output) * [`cron_before_command`](#-letsencrypt--certonly--cron_before_command) @@ -835,6 +855,14 @@ An optional array of environment variables Default value: `[]` +##### `key_type` + +Data type: `Enum['rsa', 'ecdsa']` + +Type of private key + +Default value: `$letsencrypt::key_type` + ##### `key_size` Data type: `Integer[2048]` @@ -843,6 +871,14 @@ Size for the RSA public key Default value: `$letsencrypt::key_size` +##### `elliptic_curve` + +Data type: `String[1]` + +The SECG elliptic curve name to use + +Default value: `$letsencrypt::elliptic_curve` + ##### `manage_cron` Data type: `Boolean` diff --git a/manifests/certonly.pp b/manifests/certonly.pp index 1c17ecc8..d04e77e7 100644 --- a/manifests/certonly.pp +++ b/manifests/certonly.pp @@ -87,7 +87,9 @@ # @param letsencrypt_command Command to run letsencrypt # @param additional_args An array of additional command line arguments to pass to the `letsencrypt` command. # @param environment An optional array of environment variables +# @param key_type Type of private key # @param key_size Size for the RSA public key +# @param elliptic_curve The SECG elliptic curve name to use # @param manage_cron # Indicating whether or not to schedule cron job for renewal. # Runs daily but only renews if near expiration, e.g. within 10 days. @@ -128,7 +130,9 @@ Letsencrypt::Plugin $plugin = 'standalone', Array[Stdlib::Unixpath] $webroot_paths = [], String[1] $letsencrypt_command = $letsencrypt::command, + Enum['rsa', 'ecdsa'] $key_type = $letsencrypt::key_type, Integer[2048] $key_size = $letsencrypt::key_size, + String[1] $elliptic_curve = $letsencrypt::elliptic_curve, Array[String[1]] $additional_args = [], Array[String[1]] $environment = [], Boolean $manage_cron = false, @@ -153,10 +157,16 @@ $title_nowc = regsubst($title, '^\*\.', '') if $ensure == 'present' { + if $key_type == 'rsa' { + $key_args = "--rsa-key-size ${key_size}" + } else { + $key_args = "--elliptic-curve ${elliptic_curve}" + } + if ($custom_plugin) { - $default_args = "--text --agree-tos --non-interactive certonly --rsa-key-size ${key_size}" + $default_args = "--text --agree-tos --non-interactive certonly --key-type ${key_type} ${key_args}" } else { - $default_args = "--text --agree-tos --non-interactive certonly --rsa-key-size ${key_size} -a ${plugin}" + $default_args = "--text --agree-tos --non-interactive certonly --key-type ${key_type} ${key_args} -a ${plugin}" } } else { $default_args = '--text --agree-tos --non-interactive delete' diff --git a/manifests/init.pp b/manifests/init.pp index 9c37d08a..390b5c4c 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -27,7 +27,9 @@ # @param agree_tos A flag to agree to the Let's Encrypt Terms of Service. # @param unsafe_registration A flag to allow using the 'register-unsafely-without-email' flag. # @param config_dir The path to the configuration directory. +# @param key_type Type of private key # @param key_size Size for the RSA public key +# @param elliptic_curve The SECG elliptic curve name to use # @param certificates A hash containing certificates. Each key is the title and each value is a hash, both passed to letsencrypt::certonly. # @param renew_pre_hook_commands Array of commands to run in a shell before obtaining/renewing any certificates. # @param renew_post_hook_commands Array of commands to run in a shell after attempting to obtain/renew certificates. @@ -76,7 +78,9 @@ Boolean $manage_install = true, Boolean $agree_tos = true, Boolean $unsafe_registration = false, + Enum['rsa', 'ecdsa'] $key_type = 'rsa', Integer[2048] $key_size = 4096, + String[1] $elliptic_curve = 'secp256r1', Hash[String[1],Hash] $certificates = {}, # $renew_* should only be used in letsencrypt::renew (blame rspec) Variant[String[1], Array[String[1]]] $renew_pre_hook_commands = [], diff --git a/spec/defines/letsencrypt_certonly_spec.rb b/spec/defines/letsencrypt_certonly_spec.rb index b1de6934..e34a4e47 100644 --- a/spec/defines/letsencrypt_certonly_spec.rb +++ b/spec/defines/letsencrypt_certonly_spec.rb @@ -60,7 +60,7 @@ let(:params) { { domains: ['foo.example.com', 'bar.example.com', '*.example.com'] } } it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_exec('letsencrypt certonly foo').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name 'foo' -d 'foo.example.com' -d 'bar.example.com' -d '*.example.com'" } + it { is_expected.to contain_exec('letsencrypt certonly foo').with_command "letsencrypt --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name 'foo' -d 'foo.example.com' -d 'bar.example.com' -d '*.example.com'" } end context 'with custom cert-name' do @@ -68,7 +68,7 @@ let(:params) { { cert_name: 'bar.example.com' } } it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_exec('letsencrypt certonly foo').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name 'bar.example.com' -d 'foo'" } + it { is_expected.to contain_exec('letsencrypt certonly foo').with_command "letsencrypt --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name 'bar.example.com' -d 'foo'" } end context 'with custom command' do @@ -76,7 +76,7 @@ let(:params) { { letsencrypt_command: '/usr/lib/letsencrypt/letsencrypt-auto' } } it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command '/usr/lib/letsencrypt/letsencrypt-auto --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name \'foo.example.com\' -d \'foo.example.com\'' } + it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command '/usr/lib/letsencrypt/letsencrypt-auto --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name \'foo.example.com\' -d \'foo.example.com\'' } end context 'with webroot plugin' do @@ -87,7 +87,7 @@ end it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a webroot --cert-name 'foo.example.com' --webroot-path /var/www/foo -d 'foo.example.com'" } + it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a webroot --cert-name 'foo.example.com' --webroot-path /var/www/foo -d 'foo.example.com'" } end context 'with webroot plugin and multiple domains' do @@ -99,7 +99,7 @@ end it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_exec('letsencrypt certonly foo').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a webroot --cert-name 'foo' --webroot-path /var/www/foo -d 'foo.example.com' --webroot-path /var/www/bar -d 'bar.example.com'" } + it { is_expected.to contain_exec('letsencrypt certonly foo').with_command "letsencrypt --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a webroot --cert-name 'foo' --webroot-path /var/www/foo -d 'foo.example.com' --webroot-path /var/www/bar -d 'bar.example.com'" } end context 'with webroot plugin, one webroot, and multiple domains' do @@ -111,7 +111,7 @@ end it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_exec('letsencrypt certonly foo').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a webroot --cert-name 'foo' --webroot-path /var/www/foo -d 'foo.example.com' -d 'bar.example.com'" } + it { is_expected.to contain_exec('letsencrypt certonly foo').with_command "letsencrypt --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a webroot --cert-name 'foo' --webroot-path /var/www/foo -d 'foo.example.com' -d 'bar.example.com'" } end context 'with webroot plugin and no webroot_paths' do @@ -142,7 +142,7 @@ class { 'letsencrypt::plugin::dns_rfc2136': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_class('letsencrypt::plugin::dns_rfc2136') } - it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a dns-rfc2136 --cert-name 'foo.example.com' -d 'foo.example.com' --dns-rfc2136-credentials /etc/letsencrypt/dns-rfc2136.ini --dns-rfc2136-propagation-seconds 10" } + it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a dns-rfc2136 --cert-name 'foo.example.com' -d 'foo.example.com' --dns-rfc2136-credentials /etc/letsencrypt/dns-rfc2136.ini --dns-rfc2136-propagation-seconds 10" } end context 'with dns-route53 plugin' do @@ -162,7 +162,7 @@ class { 'letsencrypt::plugin::dns_route53': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_class('letsencrypt::plugin::dns_route53') } - it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a dns-route53 --cert-name 'foo.example.com' -d 'foo.example.com' --dns-route53-propagation-seconds 10" } + it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a dns-route53 --cert-name 'foo.example.com' -d 'foo.example.com' --dns-route53-propagation-seconds 10" } end context 'with nginx plugin' do @@ -182,7 +182,7 @@ class { 'letsencrypt::plugin::nginx': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_class('letsencrypt::plugin::nginx') } - it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a nginx --cert-name 'foo.example.com' -d 'foo.example.com'" } + it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a nginx --cert-name 'foo.example.com' -d 'foo.example.com'" } end context 'with dns-cloudflare plugin' do @@ -203,7 +203,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_class('letsencrypt::plugin::dns_cloudflare') } - it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a dns-cloudflare --cert-name 'foo.example.com' -d 'foo.example.com' --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/dns-cloudflare.ini --dns-cloudflare-propagation-seconds 10" } + it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a dns-cloudflare --cert-name 'foo.example.com' -d 'foo.example.com' --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/dns-cloudflare.ini --dns-cloudflare-propagation-seconds 10" } end context 'with custom plugin' do @@ -211,7 +211,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': let(:params) { { plugin: 'apache' } } it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a apache --cert-name 'foo.example.com' -d 'foo.example.com'" } + it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a apache --cert-name 'foo.example.com' -d 'foo.example.com'" } end context 'with custom plugin and manage_cron' do @@ -225,7 +225,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_command('"/var/lib/puppet/letsencrypt/renew-foo.example.com.sh"').with_ensure('present') } - it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a apache --cert-name 'foo.example.com' -d 'foo.example.com'\n") } + it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a apache --cert-name 'foo.example.com' -d 'foo.example.com'\n") } end context 'with hook' do @@ -281,7 +281,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_hour(13).with_ensure('present') } - it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } + it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } end context 'with manage_cron and out of range defined cron_hour (integer)' do @@ -308,7 +308,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_hour('00').with_ensure('present') } - it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } + it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } end context 'with manage_cron and defined cron_hour (array)' do @@ -322,7 +322,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_hour([1, 13]).with_ensure('present') } - it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } + it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } end context 'with manage_cron and defined cron_minute (integer)' do @@ -336,7 +336,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_minute(15).with_ensure('present') } - it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } + it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } end context 'with manage_cron and defined cron_minute (string)' do @@ -350,7 +350,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_minute('15').with_ensure('present') } - it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } + it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } end context 'with manage_cron and defined cron_minute (array)' do @@ -364,7 +364,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_minute([0, 30]).with_ensure('present') } - it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } + it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } end context 'with manage_cron and ensure absent' do @@ -394,7 +394,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_file('/tmp/custom_vardir/letsencrypt').with_ensure('directory') } it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_command '"/tmp/custom_vardir/letsencrypt/renew-foo.example.com.sh"' } - it { is_expected.to contain_file('/tmp/custom_vardir/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a apache --cert-name 'foo.example.com' -d 'foo.example.com'\n") } + it { is_expected.to contain_file('/tmp/custom_vardir/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a apache --cert-name 'foo.example.com' -d 'foo.example.com'\n") } end context 'with custom plugin and manage cron and cron_success_command' do @@ -410,14 +410,14 @@ class { 'letsencrypt::plugin::dns_cloudflare': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_command '"/var/lib/puppet/letsencrypt/renew-foo.example.com.sh"' } - it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\n(echo before) && letsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a apache --cert-name 'foo.example.com' -d 'foo.example.com' && (echo success)\n") } + it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\n(echo before) && letsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a apache --cert-name 'foo.example.com' -d 'foo.example.com' && (echo success)\n") } end context 'without plugin' do let(:title) { 'foo.example.com' } let(:params) { { custom_plugin: true } } - it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 --cert-name 'foo.example.com' -d 'foo.example.com'" } + it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 --cert-name 'foo.example.com' -d 'foo.example.com'" } end context 'with invalid plugin' do @@ -433,7 +433,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': let(:params) { { additional_args: ['--foo bar', '--baz quux'] } } it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com' --foo bar --baz quux" } + it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com' --foo bar --baz quux" } end describe 'when specifying custom environment variables' do @@ -449,7 +449,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': let(:params) { { environment: ['FOO=bar', 'FIZZ=buzz'], manage_cron: true } } it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_content "#!/bin/sh\nexport FOO=bar\nexport FIZZ=buzz\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n" } + it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_content "#!/bin/sh\nexport FOO=bar\nexport FIZZ=buzz\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n" } end context 'with manage cron and cron_output=suppress' do \ @@ -461,7 +461,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_command('"/var/lib/puppet/letsencrypt/renew-foo.example.com.sh"').with_ensure('present') } - it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com' > /dev/null 2>&1\n") } + it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com' > /dev/null 2>&1\n") } end context 'with manage cron and cron_output=log' do \ @@ -473,7 +473,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with_command('"/var/lib/puppet/letsencrypt/renew-foo.example.com.sh"').with_ensure('present') } - it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com' 2>&1 | logger -t letsencrypt-renew\n") } + it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com' 2>&1 | logger -t letsencrypt-renew\n") } end context 'with manage cron and custom day of month' do @@ -485,7 +485,7 @@ class { 'letsencrypt::plugin::dns_cloudflare': it { is_expected.to compile.with_all_deps } it { is_expected.to contain_cron('letsencrypt renew cron foo.example.com').with(monthday: [1, 15]).with_ensure('present') } - it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } + it { is_expected.to contain_file('/var/lib/puppet/letsencrypt/renew-foo.example.com.sh').with_ensure('file').with_content("#!/bin/sh\nletsencrypt --keep-until-expiring --text --agree-tos --non-interactive certonly --key-type rsa --rsa-key-size 4096 -a standalone --cert-name 'foo.example.com' -d 'foo.example.com'\n") } end context 'with custom config_dir' do