diff --git a/README.md b/README.md index ff1c5635..2c682d51 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,18 @@ letsencrypt::certonly { 'foo': } ``` +#### Nginx authenticator + +To request a certificate for `foo.example.com` and `bar.example.com` with the +`certonly` installer and the `nginx` authenticator: + +```puppet +letsencrypt::certonly { 'foo': + domains => ['foo.example.com', 'bar.example.com'], + plugin => 'nginx', +} +``` + #### Webroot plugin To request a certificate using the `webroot` plugin, the paths to the webroots diff --git a/REFERENCE.md b/REFERENCE.md index 3da1d460..fba14aa5 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -12,6 +12,7 @@ * [`letsencrypt::install`](#letsencryptinstall): Installs the Let's Encrypt client. * [`letsencrypt::plugin::dns_rfc2136`](#letsencryptplugindns_rfc2136): Installs and configures the dns-rfc2136 plugin * [`letsencrypt::plugin::dns_route53`](#letsencryptplugindns_route53): Installs and configures the dns-route53 plugin +* [`letsencrypt::plugin::nginx`](#letsencryptpluginnginx): install and configure the Let's Encrypt nginx plugin * [`letsencrypt::renew`](#letsencryptrenew): Configures renewal of Let's Encrypt certificates using Certbot #### Private Classes @@ -436,6 +437,33 @@ Data type: `String[1]` The name of the package to install when $manage_package is true. +### `letsencrypt::plugin::nginx` + +install and configure the Let's Encrypt nginx plugin + +#### Parameters + +The following parameters are available in the `letsencrypt::plugin::nginx` class: + +* [`manage_package`](#manage_package) +* [`package_name`](#package_name) + +##### `manage_package` + +Data type: `Boolean` + +Manage the plugin package. + +Default value: ``true`` + +##### `package_name` + +Data type: `String` + +The name of the package to install when $manage_package is true. + +Default value: `'python3-certbot-nginx'` + ### `letsencrypt::renew` Configures renewal of Let's Encrypt certificates using the certbot renew command. diff --git a/data/os/CentOS/7.yaml b/data/os/CentOS/7.yaml index e18cad3a..1aba5e01 100644 --- a/data/os/CentOS/7.yaml +++ b/data/os/CentOS/7.yaml @@ -1,3 +1,4 @@ --- letsencrypt::plugin::dns_rfc2136::package_name: 'python2-certbot-dns-rfc2136' letsencrypt::plugin::dns_route53::package_name: 'python2-certbot-dns-route53' +letsencrypt::plugin::nginx::package_name: 'python2-certbot-nginx' diff --git a/data/os/RedHat/7.yaml b/data/os/RedHat/7.yaml index e18cad3a..1aba5e01 100644 --- a/data/os/RedHat/7.yaml +++ b/data/os/RedHat/7.yaml @@ -1,3 +1,4 @@ --- letsencrypt::plugin::dns_rfc2136::package_name: 'python2-certbot-dns-rfc2136' letsencrypt::plugin::dns_route53::package_name: 'python2-certbot-dns-route53' +letsencrypt::plugin::nginx::package_name: 'python2-certbot-nginx' diff --git a/manifests/certonly.pp b/manifests/certonly.pp index 2b46b843..6db2220b 100644 --- a/manifests/certonly.pp +++ b/manifests/certonly.pp @@ -117,6 +117,17 @@ ] } + 'nginx': { + require letsencrypt::plugin::nginx + + if $ensure == 'present' { + $_domains = join($domains, '\' -d \'') + $plugin_args = "--cert-name '${cert_name}' -d '${_domains}'" + } else { + $plugin_args = "--cert-name '${cert_name}'" + } + } + default: { if $ensure == 'present' { $_domains = join($domains, '\' -d \'') diff --git a/manifests/plugin/nginx.pp b/manifests/plugin/nginx.pp new file mode 100644 index 00000000..0e6b6ce1 --- /dev/null +++ b/manifests/plugin/nginx.pp @@ -0,0 +1,14 @@ +# @summary install and configure the Let's Encrypt nginx plugin +# +# @param manage_package Manage the plugin package. +# @param package_name The name of the package to install when $manage_package is true. +class letsencrypt::plugin::nginx ( + Boolean $manage_package = true, + String $package_name = 'python3-certbot-nginx', +) { + if $manage_package { + package { $package_name: + ensure => installed, + } + } +} diff --git a/spec/acceptance/letsencrypt_plugin_nginx_spec.rb b/spec/acceptance/letsencrypt_plugin_nginx_spec.rb new file mode 100644 index 00000000..358689e0 --- /dev/null +++ b/spec/acceptance/letsencrypt_plugin_nginx_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper_acceptance' + +describe 'letsencrypt::plugin::nginx' do + context 'with default values' do + pp = <<-PUPPET + class { 'letsencrypt' : + email => 'letsregister@example.com', + config => { + 'server' => 'https://acme-staging.api.letsencrypt.org/directory', + }, + } + class { 'letsencrypt::plugin::nginx': + } + PUPPET + + it 'installs letsencrypt and nginx plugin without error' do + apply_manifest(pp, catch_failures: true) + end + it 'installs letsencrypt and nginx idempotently' do + apply_manifest(pp, catch_changes: true) + end + end +end diff --git a/spec/classes/plugin/nginx_spec.rb b/spec/classes/plugin/nginx_spec.rb new file mode 100644 index 00000000..6288927d --- /dev/null +++ b/spec/classes/plugin/nginx_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' + +describe 'letsencrypt::plugin::nginx' 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 + + context 'with default parameters' do + it { is_expected.to compile.with_all_deps } + + package_name = + if facts[:os]['family'] == 'RedHat' && facts[:os]['release']['major'] == '7' + 'python2-certbot-nginx' + else + 'python3-certbot-nginx' + end + it 'installs the certbot nginx plugin' do + is_expected.to contain_class('letsencrypt::plugin::nginx') + is_expected.to contain_package(package_name).with_ensure('installed') + end + + describe 'with manage_package => false' do + let(:params) { super().merge(manage_package: false, package_name: 'nginx-package') } + + it { is_expected.not_to contain_package('nginx-package') } + end + end + end + end +end diff --git a/spec/defines/letsencrypt_certonly_spec.rb b/spec/defines/letsencrypt_certonly_spec.rb index b4e61bcc..63f184c5 100644 --- a/spec/defines/letsencrypt_certonly_spec.rb +++ b/spec/defines/letsencrypt_certonly_spec.rb @@ -153,6 +153,26 @@ 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" } end + context 'with nginx plugin' do + let(:title) { 'foo.example.com' } + let(:params) { { plugin: 'nginx', letsencrypt_command: 'letsencrypt' } } + let(:pre_condition) do + <<-PUPPET + class { 'letsencrypt': + email => 'foo@example.com', + config_dir => '/etc/letsencrypt', + } + class { 'letsencrypt::plugin::nginx': + package_name => 'irrelevant', + } + PUPPET + end + + 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'" } + end + context 'with custom plugin' do let(:title) { 'foo.example.com' } let(:params) { { plugin: 'apache' } }