Skip to content

Commit 841f5c7

Browse files
authored
Merge pull request #279 from bkuebler/feature/plugins/dns-cloudflare
Add Cloudflare DNS plugin support
2 parents 291f4b2 + fcb715d commit 841f5c7

File tree

11 files changed

+276
-4
lines changed

11 files changed

+276
-4
lines changed

REFERENCE.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
* [`letsencrypt`](#letsencrypt): Install and configure Certbot, the LetsEncrypt client
1212
* [`letsencrypt::install`](#letsencryptinstall): Installs the Let's Encrypt client.
13+
* [`letsencrypt::plugin::dns_cloudflare`](#letsencryptplugindns_cloudflare): Installs and configures the dns-cloudflare plugin
1314
* [`letsencrypt::plugin::dns_rfc2136`](#letsencryptplugindns_rfc2136): Installs and configures the dns-rfc2136 plugin
1415
* [`letsencrypt::plugin::dns_route53`](#letsencryptplugindns_route53): Installs and configures the dns-route53 plugin
1516
* [`letsencrypt::plugin::nginx`](#letsencryptpluginnginx): install and configure the Let's Encrypt nginx plugin
@@ -329,6 +330,84 @@ Name of package to use when installing the client package.
329330

330331
Default value: `$letsencrypt::package_name`
331332

333+
### <a name="letsencryptplugindns_cloudflare"></a>`letsencrypt::plugin::dns_cloudflare`
334+
335+
This class installs and configures the Let's Encrypt dns-cloudflare plugin.
336+
https://certbot-dns-cloudflare.readthedocs.io
337+
338+
#### Parameters
339+
340+
The following parameters are available in the `letsencrypt::plugin::dns_cloudflare` class:
341+
342+
* [`package_name`](#package_name)
343+
* [`api_key`](#api_key)
344+
* [`api_token`](#api_token)
345+
* [`email`](#email)
346+
* [`config_dir`](#config_dir)
347+
* [`manage_package`](#manage_package)
348+
* [`propagation_seconds`](#propagation_seconds)
349+
* [`config_path`](#config_path)
350+
351+
##### <a name="package_name"></a>`package_name`
352+
353+
Data type: `Optional[String[1]]`
354+
355+
The name of the package to install when $manage_package is true.
356+
357+
Default value: ``undef``
358+
359+
##### <a name="api_key"></a>`api_key`
360+
361+
Data type: `Optional[String[1]]`
362+
363+
Optional string, cloudflare api key value for authentication.
364+
365+
Default value: ``undef``
366+
367+
##### <a name="api_token"></a>`api_token`
368+
369+
Data type: `Optional[String[1]]`
370+
371+
Optional string, cloudflare api token value for authentication.
372+
373+
Default value: ``undef``
374+
375+
##### <a name="email"></a>`email`
376+
377+
Data type: `Optional[String[1]]`
378+
379+
Optional string, cloudflare account email address, used in conjunction with api_key.
380+
381+
Default value: ``undef``
382+
383+
##### <a name="config_dir"></a>`config_dir`
384+
385+
The path to the configuration directory.
386+
387+
##### <a name="manage_package"></a>`manage_package`
388+
389+
Data type: `Boolean`
390+
391+
Manage the plugin package.
392+
393+
Default value: ``true``
394+
395+
##### <a name="propagation_seconds"></a>`propagation_seconds`
396+
397+
Data type: `Integer`
398+
399+
Number of seconds to wait for the DNS server to propagate the DNS-01 challenge.
400+
401+
Default value: `10`
402+
403+
##### <a name="config_path"></a>`config_path`
404+
405+
Data type: `Stdlib::Absolutepath`
406+
407+
408+
409+
Default value: `"${letsencrypt::config_dir}/dns-cloudflare.ini"`
410+
332411
### <a name="letsencryptplugindns_rfc2136"></a>`letsencrypt::plugin::dns_rfc2136`
333412

334413
This class installs and configures the Let's Encrypt dns-rfc2136 plugin.

data/Debian-family.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
---
22
letsencrypt::plugin::dns_rfc2136::package_name: 'python3-certbot-dns-rfc2136'
33
letsencrypt::plugin::dns_route53::package_name: 'python3-certbot-dns-route53'
4+
letsencrypt::plugin::dns_cloudflare::package_name: 'python3-certbot-dns-cloudflare'

data/FreeBSD-family.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ letsencrypt::config_dir: '/usr/local/etc/letsencrypt'
44
letsencrypt::cron_owner_group: 'wheel'
55
letsencrypt::plugin::dns_rfc2136::package_name: 'py38-certbot-dns-rfc2136'
66
letsencrypt::plugin::dns_route53::package_name: 'py38-certbot-dns-route53'
7+
letsencrypt::plugin::dns_cloudflare::package_name: 'py38-certbot-dns-cloudflare'

data/RedHat-family.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
letsencrypt::configure_epel: true
33
letsencrypt::plugin::dns_rfc2136::package_name: 'python3-certbot-dns-rfc2136'
44
letsencrypt::plugin::dns_route53::package_name: 'python3-certbot-dns-route53'
5+
letsencrypt::plugin::dns_cloudflare::package_name: 'python3-certbot-dns-cloudflare'

data/os/CentOS/7.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
---
22
letsencrypt::plugin::dns_rfc2136::package_name: 'python2-certbot-dns-rfc2136'
33
letsencrypt::plugin::dns_route53::package_name: 'python2-certbot-dns-route53'
4+
letsencrypt::plugin::dns_cloudflare::package_name: 'python2-certbot-dns-cloudflare'
45
letsencrypt::plugin::nginx::package_name: 'python2-certbot-nginx'

data/os/RedHat/7.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
---
22
letsencrypt::plugin::dns_rfc2136::package_name: 'python2-certbot-dns-rfc2136'
33
letsencrypt::plugin::dns_route53::package_name: 'python2-certbot-dns-route53'
4+
letsencrypt::plugin::dns_cloudflare::package_name: 'python2-certbot-dns-cloudflare'
45
letsencrypt::plugin::nginx::package_name: 'python2-certbot-nginx'

manifests/certonly.pp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,17 @@
168168
$plugin_args = ["--cert-name '${cert_name}'"] + $_plugin_args
169169
}
170170

171+
'dns-cloudflare': {
172+
require letsencrypt::plugin::dns_cloudflare
173+
$_domains = join($domains, '\' -d \'')
174+
$plugin_args = [
175+
"--cert-name '${cert_name}' -d '${_domains}'",
176+
'--dns-cloudflare',
177+
"--dns-cloudflare-credentials ${letsencrypt::plugin::dns_cloudflare::config_path}",
178+
"--dns-cloudflare-propagation-seconds ${letsencrypt::plugin::dns_cloudflare::propagation_seconds}",
179+
]
180+
}
181+
171182
'dns-rfc2136': {
172183
require letsencrypt::plugin::dns_rfc2136
173184
$_domains = join($domains, '\' -d \'')
@@ -242,7 +253,8 @@
242253
$verify_domains = join(unique($domains), '\' \'')
243254

244255
if $ensure == 'present' {
245-
$exec_ensure = { 'unless' => "/usr/local/sbin/letsencrypt-domain-validation ${live_path} '${verify_domains}'" }
256+
$exec_ensure = { 'unless' => ['test ! -f /usr/local/sbin/letsencrypt-domain-validation',
257+
"/usr/local/sbin/letsencrypt-domain-validation ${live_path} '${verify_domains}'"] }
246258
} else {
247259
$exec_ensure = { 'onlyif' => "/usr/local/sbin/letsencrypt-domain-validation ${live_path} '${verify_domains}'" }
248260
}

manifests/plugin/dns_cloudflare.pp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# @summary Installs and configures the dns-cloudflare plugin
2+
#
3+
# This class installs and configures the Let's Encrypt dns-cloudflare plugin.
4+
# https://certbot-dns-cloudflare.readthedocs.io
5+
#
6+
# @param package_name The name of the package to install when $manage_package is true.
7+
# @param api_key
8+
# Optional string, cloudflare api key value for authentication.
9+
# @param api_token
10+
# Optional string, cloudflare api token value for authentication.
11+
# @param email
12+
# Optional string, cloudflare account email address, used in conjunction with api_key.
13+
# @param config_dir The path to the configuration directory.
14+
# @param manage_package Manage the plugin package.
15+
# @param propagation_seconds Number of seconds to wait for the DNS server to propagate the DNS-01 challenge.
16+
#
17+
class letsencrypt::plugin::dns_cloudflare (
18+
Optional[String[1]] $package_name = undef,
19+
Optional[String[1]] $api_key = undef,
20+
Optional[String[1]] $api_token = undef,
21+
Optional[String[1]] $email = undef,
22+
Stdlib::Absolutepath $config_path = "${letsencrypt::config_dir}/dns-cloudflare.ini",
23+
Boolean $manage_package = true,
24+
Integer $propagation_seconds = 10,
25+
) {
26+
require letsencrypt::install
27+
28+
if ! $api_key and ! $api_token {
29+
fail('No authentication method provided, please specify either api_token or api_key and api_email.')
30+
}
31+
32+
if $manage_package {
33+
if ! $package_name {
34+
fail('No package name provided for certbot dns cloudflare plugin.')
35+
}
36+
37+
package { $package_name:
38+
ensure => installed,
39+
}
40+
}
41+
42+
if $api_token {
43+
$ini_vars = {
44+
dns_cloudflare_api_token => $api_token,
45+
}
46+
}
47+
else {
48+
if ! $email {
49+
fail('Cloudflare email not provided for specified api_key.')
50+
}
51+
52+
$ini_vars = {
53+
dns_cloudflare_api_key => $api_key,
54+
dns_cloudflare_email => $email,
55+
}
56+
}
57+
58+
file { $config_path:
59+
ensure => file,
60+
owner => 'root',
61+
group => 'root',
62+
mode => '0400',
63+
content => epp('letsencrypt/ini.epp', {
64+
vars => { '' => $ini_vars },
65+
}),
66+
}
67+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper_acceptance'
4+
5+
describe 'letsencrypt::plugin::dns_cloudflare' do
6+
it_behaves_like 'an idempotent resource' do
7+
let(:manifest) do
8+
<<-PUPPET
9+
class { 'letsencrypt' :
10+
email => '[email protected]',
11+
config => {
12+
'server' => 'https://acme-staging-v02.api.letsencrypt.org/directory',
13+
},
14+
}
15+
class { 'letsencrypt::plugin::dns_cloudflare':
16+
api_token => 'dummy-cloudflare-api-token',
17+
}
18+
PUPPET
19+
end
20+
end
21+
22+
describe file('/etc/letsencrypt/dns-cloudflare.ini') do
23+
it { is_expected.to be_file }
24+
it { is_expected.to be_owned_by 'root' }
25+
it { is_expected.to be_grouped_into 'root' }
26+
it { is_expected.to be_mode 400 }
27+
end
28+
end
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
describe 'letsencrypt::plugin::dns_cloudflare' do
6+
on_supported_os.each do |os, os_facts|
7+
context "on #{os} based operating systems" do
8+
let(:facts) { os_facts }
9+
let(:params) { { 'api_token' => 'dummy-cloudflare-api-token' } }
10+
let(:pre_condition) do
11+
<<-PUPPET
12+
class { 'letsencrypt':
13+
email => '[email protected]',
14+
}
15+
PUPPET
16+
end
17+
let(:package_name) do
18+
osname = facts[:os]['name']
19+
osrelease = facts[:os]['release']['major']
20+
osfull = "#{osname}-#{osrelease}"
21+
if %w[RedHat-7 CentOS-7].include?(osfull)
22+
'python2-certbot-dns-cloudflare'
23+
elsif %w[Debian RedHat].include?(facts[:os]['family'])
24+
'python3-certbot-dns-cloudflare'
25+
elsif %w[FreeBSD].include?(facts[:os]['family'])
26+
'py38-certbot-dns-cloudflare'
27+
end
28+
end
29+
30+
context 'with required parameters' do
31+
it do
32+
if package_name.nil?
33+
is_expected.not_to compile
34+
else
35+
is_expected.to compile.with_all_deps
36+
end
37+
end
38+
39+
describe 'with manage_package => true' do
40+
let(:params) { super().merge(manage_package: true) }
41+
42+
it do
43+
if package_name.nil?
44+
is_expected.not_to compile
45+
else
46+
is_expected.to contain_class('letsencrypt::plugin::dns_cloudflare').with_package_name(package_name)
47+
is_expected.to contain_package(package_name).with_ensure('installed')
48+
end
49+
end
50+
end
51+
52+
describe 'with manage_package => false' do
53+
let(:params) { super().merge(manage_package: false, package_name: 'dns-cloudflare-package') }
54+
55+
it { is_expected.not_to contain_package('dns-cloudflare-package') }
56+
end
57+
end
58+
end
59+
end
60+
end

0 commit comments

Comments
 (0)