diff --git a/data/FreeBSD-family.yaml b/data/FreeBSD-family.yaml index 5e7cf81..61e057e 100644 --- a/data/FreeBSD-family.yaml +++ b/data/FreeBSD-family.yaml @@ -1,4 +1,4 @@ --- -letsencrypt::package_name: 'py27-certbot' +letsencrypt::package_name: 'py38-certbot' letsencrypt::config_dir: '/usr/local/etc/letsencrypt' letsencrypt::cron_owner_group: 'wheel' diff --git a/data/os/Debian/11.yaml b/data/os/Debian/11.yaml new file mode 100644 index 0000000..d0641b2 --- /dev/null +++ b/data/os/Debian/11.yaml @@ -0,0 +1,3 @@ +--- +letsencrypt::plugin::dns_rfc2136::package_name: 'python3-certbot-dns-rfc2136' +letsencrypt::plugin::dns_route53::package_name: 'python3-certbot-dns-route53' diff --git a/metadata.json b/metadata.json index 8211833..4128533 100644 --- a/metadata.json +++ b/metadata.json @@ -1,84 +1,83 @@ { "name": "puppet-letsencrypt", "version": "6.0.1-rc0", "author": "Vox Pupuli", "summary": "Manages lets-encrypt and certbot + related certs", "license": "Apache-2.0", "source": "https://github.com/voxpupuli/puppet-letsencrypt", "project_page": "https://github.com/voxpupuli/puppet-letsencrypt", "issues_url": "https://github.com/voxpupuli/puppet-letsencrypt/issues", "tags": [ "letsencrypt", "let's encrypt", "certbot", "acme" ], "operatingsystem_support": [ { "operatingsystem": "CentOS", "operatingsystemrelease": [ "7" ] }, { "operatingsystem": "RedHat", "operatingsystemrelease": [ "7" ] }, { "operatingsystem": "Fedora", "operatingsystemrelease": [ "32" ] }, { "operatingsystem": "Ubuntu", "operatingsystemrelease": [ - "16.04", "18.04", "20.04" ] }, { "operatingsystem": "Debian", "operatingsystemrelease": [ - "9", - "10" + "10", + "11" ] }, { "operatingsystem": "OpenBSD", "operatingsystemrelease": [ "6.2" ] }, { "operatingsystem": "FreeBSD", "operatingsystemrelease": [ - "11", - "12" + "12", + "13" ] } ], "requirements": [ { "name": "puppet", "version_requirement": ">= 6.1.0 < 8.0.0" } ], "dependencies": [ { "name": "puppetlabs/stdlib", "version_requirement": ">= 4.13.1 < 9.0.0" }, { "name": "puppetlabs/inifile", "version_requirement": ">= 2.0.0 < 6.0.0" }, { "name": "puppet/epel", "version_requirement": ">= 3.0.1 < 4.0.0" } ] } diff --git a/spec/classes/letsencrypt_spec.rb b/spec/classes/letsencrypt_spec.rb index 1b59164..6142541 100644 --- a/spec/classes/letsencrypt_spec.rb +++ b/spec/classes/letsencrypt_spec.rb @@ -1,255 +1,255 @@ require 'spec_helper' describe 'letsencrypt' do on_supported_os.each do |os, facts| context "on #{os}" do let :facts do facts end context 'when specifying an email address with the email parameter' do let(:params) { additional_params.merge(default_params) } let(:default_params) { { email: 'foo@example.com' } } let(:additional_params) { {} } describe 'with defaults' do it { is_expected.to compile } epel = facts[:osfamily] == 'RedHat' && facts[:operatingsystem] != 'Fedora' it 'contains File[/usr/local/sbin/letsencrypt-domain-validation]' do is_expected.to contain_file('/usr/local/sbin/letsencrypt-domain-validation'). with_ensure('file'). with_owner('root'). with_group('root'). with_mode('0500'). with_source('puppet:///modules/letsencrypt/domain-validation.sh') end it 'contains the correct resources' do is_expected.to contain_class('letsencrypt::install'). with(configure_epel: epel). that_notifies('Exec[initialize letsencrypt]'). that_comes_before('Class[letsencrypt::renew]') is_expected.to contain_exec('initialize letsencrypt').with_command('certbot -h') is_expected.to contain_class('letsencrypt::config').that_comes_before('Exec[initialize letsencrypt]') is_expected.to contain_class('letsencrypt::renew'). with(pre_hook_commands: [], post_hook_commands: [], deploy_hook_commands: [], additional_args: [], cron_ensure: 'absent', cron_monthday: ['*']) is_expected.to contain_cron('letsencrypt-renew').with_ensure('absent') if facts[:osfamily] == 'FreeBSD' is_expected.to contain_ini_setting('/usr/local/etc/letsencrypt/cli.ini email foo@example.com') is_expected.to contain_ini_setting('/usr/local/etc/letsencrypt/cli.ini server https://acme-v02.api.letsencrypt.org/directory') is_expected.to contain_file('letsencrypt-renewal-hooks-puppet'). with(ensure: 'directory', path: '/usr/local/etc/letsencrypt/renewal-hooks-puppet', owner: 'root', group: 'root', mode: '0755', recurse: true, purge: true) else is_expected.to contain_ini_setting('/etc/letsencrypt/cli.ini email foo@example.com') is_expected.to contain_ini_setting('/etc/letsencrypt/cli.ini server https://acme-v02.api.letsencrypt.org/directory') is_expected.to contain_file('letsencrypt-renewal-hooks-puppet').with_path('/etc/letsencrypt/renewal-hooks-puppet') end if facts[:osfamily] == 'RedHat' if epel is_expected.to contain_class('epel').that_comes_before('Package[letsencrypt]') else is_expected.not_to contain_class('epel') end is_expected.to contain_class('letsencrypt::install').with(package_name: 'certbot') is_expected.to contain_class('letsencrypt').with(package_command: 'certbot') is_expected.to contain_package('letsencrypt').with(name: 'certbot') is_expected.to contain_file('/etc/letsencrypt').with(ensure: 'directory') elsif facts[:osfamily] == 'Debian' is_expected.to contain_class('letsencrypt::install').with(package_name: 'certbot') is_expected.to contain_file('/etc/letsencrypt').with(ensure: 'directory') elsif facts[:operatingsystem] == 'Gentoo' is_expected.to contain_class('letsencrypt::install').with(package_name: 'app-crypt/certbot') is_expected.to contain_class('letsencrypt').with(package_command: 'certbot') is_expected.to contain_package('letsencrypt').with(name: 'app-crypt/certbot') is_expected.to contain_file('/etc/letsencrypt').with(ensure: 'directory') elsif facts[:operatingsystem] == 'OpenBSD' is_expected.to contain_class('letsencrypt::install').with(package_name: 'certbot') is_expected.to contain_class('letsencrypt').with(package_command: 'certbot') is_expected.to contain_package('letsencrypt').with(name: 'certbot') is_expected.to contain_file('/etc/letsencrypt').with(ensure: 'directory') elsif facts[:operatingsystem] == 'FreeBSD' - is_expected.to contain_class('letsencrypt::install').with(package_name: 'py27-certbot') + is_expected.to contain_class('letsencrypt::install').with(package_name: 'py38-certbot') is_expected.to contain_class('letsencrypt').with(package_command: 'certbot') - is_expected.to contain_package('letsencrypt').with(name: 'py27-certbot') + is_expected.to contain_package('letsencrypt').with(name: 'py38-certbot') is_expected.to contain_file('/usr/local/etc/letsencrypt').with(ensure: 'directory') else is_expected.to contain_class('letsencrypt::install') is_expected.to contain_file('/etc/letsencrypt').with(ensure: 'directory') end end end # describe 'with defaults' describe 'with custom environment variables' do let(:additional_params) { { environment: ['FOO=bar', 'FIZZ=buzz'] } } it { is_expected.to contain_exec('initialize letsencrypt').with_environment(['FOO=bar', 'FIZZ=buzz']) } end describe 'with custom package_ensure' do let(:additional_params) { { package_ensure: '0.3.0-1.el7' } } it { is_expected.to contain_class('letsencrypt::install').with_package_ensure('0.3.0-1.el7') } end describe 'with custom config file' do let(:additional_params) { { config_file: '/etc/letsencrypt/custom_config.ini' } } it { is_expected.to contain_ini_setting('/etc/letsencrypt/custom_config.ini server https://acme-v02.api.letsencrypt.org/directory') } end describe 'with custom config' do let(:additional_params) { { config: { 'foo' => 'bar' } } } case facts[:operatingsystem] when 'FreeBSD' it { is_expected.to contain_ini_setting('/usr/local/etc/letsencrypt/cli.ini foo bar') } else it { is_expected.to contain_ini_setting('/etc/letsencrypt/cli.ini foo bar') } end end describe 'with manage_config set to false' do let(:additional_params) { { manage_config: false } } it { is_expected.not_to contain_class('letsencrypt::config') } end describe 'with manage_install set to false' do let(:additional_params) { { manage_install: false } } it { is_expected.not_to contain_class('letsencrypt::install') } end describe 'with custom config directory' do let(:additional_params) { { config_dir: '/foo/bar/baz' } } it { is_expected.to contain_file('/foo/bar/baz').with(ensure: 'directory') } end context 'when not agreeing to the TOS' do let(:params) { { agree_tos: false } } it { is_expected.to raise_error Puppet::Error, %r{You must agree to the Let's Encrypt Terms of Service} } end context 'with renew' do describe 'pre hook' do let(:additional_params) { { config_dir: '/etc/letsencrypt', renew_pre_hook_commands: ['FooBar'] } } it { is_expected.to contain_letsencrypt__hook('renew-pre').with_hook_file('/etc/letsencrypt/renewal-hooks-puppet/renew-pre.sh') } end describe 'post hook' do let(:additional_params) { { config_dir: '/etc/letsencrypt', renew_post_hook_commands: ['FooBar'] } } it { is_expected.to contain_letsencrypt__hook('renew-post').with_hook_file('/etc/letsencrypt/renewal-hooks-puppet/renew-post.sh') } end describe 'deploy hook' do let(:additional_params) { { config_dir: '/etc/letsencrypt', renew_deploy_hook_commands: ['FooBar'] } } it { is_expected.to contain_letsencrypt__hook('renew-deploy').with_hook_file('/etc/letsencrypt/renewal-hooks-puppet/renew-deploy.sh') } end describe 'renew_cron_ensure' do let(:additional_params) do { renew_cron_ensure: 'present', renew_cron_hour: 0, renew_cron_minute: 0 } end it do is_expected.to contain_cron('letsencrypt-renew'). with(ensure: 'present', command: 'certbot renew -q', hour: 0, minute: 0, monthday: '*') end end describe 'renew_cron_ensure and renew_cron_monthday' do let(:additional_params) { { renew_cron_ensure: 'present', renew_cron_monthday: [1, 15] } } it { is_expected.to contain_cron('letsencrypt-renew').with_ensure('present').with_monthday([1, 15]) } end describe 'renew_cron_ensure and hooks' do let(:additional_params) do { config_dir: '/etc/letsencrypt', renew_cron_ensure: 'present', renew_pre_hook_commands: ['PreBar'], renew_post_hook_commands: ['PostBar'], renew_deploy_hook_commands: ['DeployBar'] } end it do is_expected.to contain_cron('letsencrypt-renew'). with(ensure: 'present', command: 'certbot renew -q --pre-hook "/etc/letsencrypt/renewal-hooks-puppet/renew-pre.sh" --post-hook "/etc/letsencrypt/renewal-hooks-puppet/renew-post.sh" --deploy-hook "/etc/letsencrypt/renewal-hooks-puppet/renew-deploy.sh"') end end describe 'renew_cron_ensure and additional args' do let(:additional_params) do { renew_cron_ensure: 'present', renew_additional_args: ['AdditionalBar'] } end it do is_expected.to contain_cron('letsencrypt-renew'). with(ensure: 'present', command: 'certbot renew -q AdditionalBar') end end end # context 'with renew' end # context 'when specifying an email address with the email parameter' context 'when specifying an email in $config' do let(:params) { { config: { 'email' => 'foo@example.com' } } } it { is_expected.to compile.with_all_deps } case facts[:operatingsystem] when 'FreeBSD' it { is_expected.to contain_ini_setting('/usr/local/etc/letsencrypt/cli.ini email foo@example.com') } else it { is_expected.to contain_ini_setting('/etc/letsencrypt/cli.ini email foo@example.com') } end end context 'when not specifying the email parameter or an email key in $config' do context 'with unsafe_registration set to false' do it { is_expected.to raise_error Puppet::Error, %r{Please specify an email address} } end context 'with unsafe_registration set to true' do let(:params) { { unsafe_registration: true } } case facts[:operatingsystem] when 'FreeBSD' it { is_expected.not_to contain_ini_setting('/usr/local/etc/letsencrypt/cli.ini email foo@example.com') } it { is_expected.to contain_ini_setting('/usr/local/etc/letsencrypt/cli.ini register-unsafely-without-email true') } else it { is_expected.not_to contain_ini_setting('/etc/letsencrypt/cli.ini email foo@example.com') } it { is_expected.to contain_ini_setting('/etc/letsencrypt/cli.ini register-unsafely-without-email true') } end end end end end end diff --git a/spec/classes/plugin/dns_rfc2136_spec.rb b/spec/classes/plugin/dns_rfc2136_spec.rb index 240d9af..28885ee 100644 --- a/spec/classes/plugin/dns_rfc2136_spec.rb +++ b/spec/classes/plugin/dns_rfc2136_spec.rb @@ -1,76 +1,76 @@ require 'spec_helper' describe 'letsencrypt::plugin::dns_rfc2136' do on_supported_os.each do |os, facts| context "on #{os} based operating systems" do let(:facts) { facts } let(:params) { {} } let(:pre_condition) do <<-PUPPET class { 'letsencrypt': email => 'foo@example.com', } PUPPET end let(:package_name) do osname = facts[:os]['name'] osrelease = facts[:os]['release']['major'] osfull = "#{osname}-#{osrelease}" case osfull - when 'Debian-10', 'Ubuntu-20.04', 'Ubuntu-18.04', 'Fedora-30', 'Fedora-31' + when 'Debian-10', 'Debian-11', 'Ubuntu-20.04', 'Ubuntu-18.04', 'Fedora-30', 'Fedora-31' 'python3-certbot-dns-rfc2136' when 'RedHat-7', 'CentOS-7' 'python2-certbot-dns-rfc2136' end end context 'without required parameters' do it { is_expected.not_to compile } end context 'with required parameters' do let(:params) do super().merge( server: '192.0.2.1', key_name: 'certbot', key_secret: 'secret' ) end it do if package_name.nil? is_expected.not_to compile else is_expected.to compile.with_all_deps is_expected.to contain_file('/etc/letsencrypt/dns-rfc2136.ini'). with_ensure('file'). with_owner('root'). with_group('root'). with_mode('0400'). with_content(%r{^.*dns_rfc2136_server.*$}) end end describe 'with manage_package => true' do let(:params) { super().merge(manage_package: true) } it do if package_name.nil? is_expected.not_to compile else is_expected.to contain_class('letsencrypt::plugin::dns_rfc2136').with_package_name(package_name) is_expected.to contain_package(package_name).with_ensure('installed') end end end describe 'with manage_package => false' do let(:params) { super().merge(manage_package: false, package_name: 'dns-rfc2136-package') } it { is_expected.not_to contain_package('dns-rfc2136-package') } end end end end end diff --git a/spec/classes/plugin/dns_route53_spec.rb b/spec/classes/plugin/dns_route53_spec.rb index 84957a1..ec88d5d 100644 --- a/spec/classes/plugin/dns_route53_spec.rb +++ b/spec/classes/plugin/dns_route53_spec.rb @@ -1,57 +1,57 @@ require 'spec_helper' describe 'letsencrypt::plugin::dns_route53' do on_supported_os.each do |os, facts| context "on #{os} based operating systems" do let(:facts) { facts } let(:params) { {} } let(:pre_condition) do <<-PUPPET class { 'letsencrypt': email => 'foo@example.com', } PUPPET end let(:package_name) do osname = facts[:os]['name'] osrelease = facts[:os]['release']['major'] osfull = "#{osname}-#{osrelease}" case osfull - when 'Debian-10', 'Ubuntu-20.04', 'Ubuntu-18.04', 'Fedora-30', 'Fedora-31' + when 'Debian-10', 'Debian-11', 'Ubuntu-20.04', 'Ubuntu-18.04', 'Fedora-30', 'Fedora-31' 'python3-certbot-dns-route53' when 'RedHat-7', 'CentOS-7' 'python2-certbot-dns-route53' end end context 'with required parameters' do it do if package_name.nil? is_expected.not_to compile else is_expected.to compile.with_all_deps end end describe 'with manage_package => true' do let(:params) { super().merge(manage_package: true) } it do if package_name.nil? is_expected.not_to compile else is_expected.to contain_class('letsencrypt::plugin::dns_route53').with_package_name(package_name) is_expected.to contain_package(package_name).with_ensure('installed') end end end describe 'with manage_package => false' do let(:params) { super().merge(manage_package: false, package_name: 'dns-route53-package') } it { is_expected.not_to contain_package('dns-route53-package') } end end end end end