diff --git a/REFERENCE.md b/REFERENCE.md
index 3936bc75..5c3db159 100644
--- a/REFERENCE.md
+++ b/REFERENCE.md
@@ -10,6 +10,7 @@
* [`letsencrypt`](#letsencrypt): Install and configure Certbot, the LetsEncrypt client
* [`letsencrypt::plugin::dns_cloudflare`](#letsencrypt--plugin--dns_cloudflare): Installs and configures the dns-cloudflare plugin
+* [`letsencrypt::plugin::dns_linode`](#letsencrypt--plugin--dns_linode): Installs and configures the dns-linode plugin
* [`letsencrypt::plugin::dns_rfc2136`](#letsencrypt--plugin--dns_rfc2136): Installs and configures the dns-rfc2136 plugin
* [`letsencrypt::plugin::dns_route53`](#letsencrypt--plugin--dns_route53): Installs and configures the dns-route53 plugin
* [`letsencrypt::plugin::nginx`](#letsencrypt--plugin--nginx): install and configure the Let's Encrypt nginx plugin
@@ -411,6 +412,68 @@ Number of seconds to wait for the DNS server to propagate the DNS-01 challenge.
Default value: `10`
+### `letsencrypt::plugin::dns_linode`
+
+This class installs and configures the Let's Encrypt dns-linode plugin.
+https://certbot-dns-linode.readthedocs.io
+
+#### Parameters
+
+The following parameters are available in the `letsencrypt::plugin::dns_linode` class:
+
+* [`package_name`](#-letsencrypt--plugin--dns_linode--package_name)
+* [`api_key`](#-letsencrypt--plugin--dns_linode--api_key)
+* [`version`](#-letsencrypt--plugin--dns_linode--version)
+* [`config_path`](#-letsencrypt--plugin--dns_linode--config_path)
+* [`manage_package`](#-letsencrypt--plugin--dns_linode--manage_package)
+* [`propagation_seconds`](#-letsencrypt--plugin--dns_linode--propagation_seconds)
+
+##### `package_name`
+
+Data type: `Optional[String[1]]`
+
+The name of the package to install when $manage_package is true.
+
+Default value: `undef`
+
+##### `api_key`
+
+Data type: `String[1]`
+
+Optional string, linode api key value for authentication.
+
+##### `version`
+
+Data type: `String[1]`
+
+string, linode api version.
+
+Default value: `'4'`
+
+##### `config_path`
+
+Data type: `Stdlib::Absolutepath`
+
+The path to the configuration directory.
+
+Default value: `"${letsencrypt::config_dir}/dns-linode.ini"`
+
+##### `manage_package`
+
+Data type: `Boolean`
+
+Manage the plugin package.
+
+Default value: `true`
+
+##### `propagation_seconds`
+
+Data type: `Integer`
+
+Number of seconds to wait for the DNS server to propagate the DNS-01 challenge.
+
+Default value: `120`
+
### `letsencrypt::plugin::dns_rfc2136`
This class installs and configures the Let's Encrypt dns-rfc2136 plugin.
@@ -1072,5 +1135,5 @@ Variant[Integer[0,31], String[1], Array[
List of accepted plugins
-Alias of `Enum['apache', 'standalone', 'webroot', 'nginx', 'dns-azure', 'dns-route53', 'dns-google', 'dns-cloudflare', 'dns-rfc2136', 'manual']`
+Alias of `Enum['apache', 'standalone', 'webroot', 'nginx', 'dns-azure', 'dns-route53', 'dns-google', 'dns-cloudflare', 'dns-linode', 'dns-rfc2136', 'manual']`
diff --git a/data/Debian-family.yaml b/data/Debian-family.yaml
index c52a03b6..a4242b73 100644
--- a/data/Debian-family.yaml
+++ b/data/Debian-family.yaml
@@ -2,3 +2,4 @@
letsencrypt::plugin::dns_rfc2136::package_name: 'python3-certbot-dns-rfc2136'
letsencrypt::plugin::dns_route53::package_name: 'python3-certbot-dns-route53'
letsencrypt::plugin::dns_cloudflare::package_name: 'python3-certbot-dns-cloudflare'
+letsencrypt::plugin::dns_linode::package_name: 'python3-certbot-dns-linode'
diff --git a/data/FreeBSD-family.yaml b/data/FreeBSD-family.yaml
index 46a0d2e7..42bc65c1 100644
--- a/data/FreeBSD-family.yaml
+++ b/data/FreeBSD-family.yaml
@@ -5,3 +5,4 @@ letsencrypt::cron_owner_group: 'wheel'
letsencrypt::plugin::dns_rfc2136::package_name: 'py311-certbot-dns-rfc2136'
letsencrypt::plugin::dns_route53::package_name: 'py311-certbot-dns-route53'
letsencrypt::plugin::dns_cloudflare::package_name: 'py311-certbot-dns-cloudflare'
+letsencrypt::plugin::dns_linode::package_name: 'py311-certbot-dns-linode'
diff --git a/data/RedHat-family.yaml b/data/RedHat-family.yaml
index 35f52041..c8a02590 100644
--- a/data/RedHat-family.yaml
+++ b/data/RedHat-family.yaml
@@ -3,3 +3,4 @@ letsencrypt::configure_epel: true
letsencrypt::plugin::dns_rfc2136::package_name: 'python3-certbot-dns-rfc2136'
letsencrypt::plugin::dns_route53::package_name: 'python3-certbot-dns-route53'
letsencrypt::plugin::dns_cloudflare::package_name: 'python3-certbot-dns-cloudflare'
+letsencrypt::plugin::dns_linode::package_name: 'python3-certbot-dns-linode'
diff --git a/data/os/Fedora.yaml b/data/os/Fedora.yaml
index 56c3cd56..6541eac1 100644
--- a/data/os/Fedora.yaml
+++ b/data/os/Fedora.yaml
@@ -2,3 +2,4 @@
letsencrypt::configure_epel: false
letsencrypt::plugin::dns_rfc2136::package_name: 'python3-certbot-dns-rfc2136'
letsencrypt::plugin::dns_route53::package_name: 'python3-certbot-dns-route53'
+letsencrypt::plugin::dns_linode::package_name: 'python3-certbot-dns-linode'
diff --git a/manifests/certonly.pp b/manifests/certonly.pp
index b04f94b5..c9106a1c 100644
--- a/manifests/certonly.pp
+++ b/manifests/certonly.pp
@@ -205,6 +205,17 @@
]
}
+ 'dns-linode': {
+ require letsencrypt::plugin::dns_linode
+ $_domains = join($domains, '\' -d \'')
+ $plugin_args = [
+ "--cert-name '${cert_name}' -d '${_domains}'",
+ '--dns-linode',
+ "--dns-linode-credentials ${letsencrypt::plugin::dns_linode::config_path}",
+ "--dns-linode-propagation-seconds ${letsencrypt::plugin::dns_linode::propagation_seconds}",
+ ]
+ }
+
'nginx': {
require letsencrypt::plugin::nginx
diff --git a/manifests/plugin/dns_linode.pp b/manifests/plugin/dns_linode.pp
new file mode 100644
index 00000000..250406bd
--- /dev/null
+++ b/manifests/plugin/dns_linode.pp
@@ -0,0 +1,57 @@
+# @summary Installs and configures the dns-linode plugin
+#
+# This class installs and configures the Let's Encrypt dns-linode plugin.
+# https://certbot-dns-linode.readthedocs.io
+#
+# @param package_name The name of the package to install when $manage_package is true.
+# @param api_key
+# Optional string, linode api key value for authentication.
+# @param version
+# string, linode api version.
+# @param config_path The path to the configuration directory.
+# @param manage_package Manage the plugin package.
+# @param propagation_seconds Number of seconds to wait for the DNS server to propagate the DNS-01 challenge.
+#
+class letsencrypt::plugin::dns_linode (
+ String[1] $api_key,
+ Optional[String[1]] $package_name = undef,
+ String[1] $version = '4',
+ Stdlib::Absolutepath $config_path = "${letsencrypt::config_dir}/dns-linode.ini",
+ Boolean $manage_package = true,
+ Integer $propagation_seconds = 120,
+) {
+ include letsencrypt
+
+ if $manage_package {
+ if ! $package_name {
+ fail('No package name provided for certbot dns linode plugin.')
+ }
+
+ $requirement = if $letsencrypt::configure_epel {
+ Class['epel']
+ } else {
+ undef
+ }
+
+ package { $package_name:
+ ensure => $letsencrypt::package_ensure,
+ require => $requirement,
+ }
+ }
+
+ $ini_vars = {
+ dns_linode_key => $api_key,
+ dns_linode_version => $version,
+ }
+
+ file { $config_path:
+ ensure => file,
+ owner => 'root',
+ group => 0,
+ mode => '0400',
+ content => epp('letsencrypt/ini.epp', {
+ vars => { '' => $ini_vars },
+ },
+ ),
+ }
+}
diff --git a/spec/acceptance/letsencrypt_plugin_dns_linode_spec.rb b/spec/acceptance/letsencrypt_plugin_dns_linode_spec.rb
new file mode 100644
index 00000000..79909831
--- /dev/null
+++ b/spec/acceptance/letsencrypt_plugin_dns_linode_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper_acceptance'
+
+describe 'letsencrypt::plugin::dns_linode' do
+ it_behaves_like 'an idempotent resource' do
+ let(:manifest) do
+ <<-PUPPET
+ include letsencrypt
+ class { 'letsencrypt::plugin::dns_linode':
+ api_key => 'dummy-linode-api-key',
+ }
+ PUPPET
+ end
+ end
+
+ describe file('/etc/letsencrypt/dns-linode.ini') do
+ it { is_expected.to be_file }
+ it { is_expected.to be_owned_by 'root' }
+ it { is_expected.to be_grouped_into 'root' }
+ it { is_expected.to be_mode 400 }
+ end
+end
diff --git a/spec/classes/plugin/dns_linode_spec.rb b/spec/classes/plugin/dns_linode_spec.rb
new file mode 100644
index 00000000..8f297d36
--- /dev/null
+++ b/spec/classes/plugin/dns_linode_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'letsencrypt::plugin::dns_linode' do
+ on_supported_os.each do |os, os_facts|
+ context "on #{os} based operating systems" do
+ let(:facts) { os_facts }
+ let(:params) { { 'api_key' => 'dummy-linode-api-token' } }
+ let(:pre_condition) do
+ <<-PUPPET
+ class { 'letsencrypt':
+ email => 'foo@example.com',
+ }
+ PUPPET
+ end
+ let(:package_name) do
+ if %w[Debian RedHat].include?(facts['os']['family'])
+ 'python3-certbot-dns-linode'
+ elsif %w[FreeBSD].include?(facts['os']['family'])
+ 'py311-certbot-dns-linode'
+ 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_linode').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-linode-package') }
+
+ it { is_expected.not_to contain_package('dns-linode-package') }
+ end
+ end
+ end
+ end
+end
diff --git a/spec/defines/letsencrypt_certonly_spec.rb b/spec/defines/letsencrypt_certonly_spec.rb
index 6ded37de..3456b017 100644
--- a/spec/defines/letsencrypt_certonly_spec.rb
+++ b/spec/defines/letsencrypt_certonly_spec.rb
@@ -206,6 +206,27 @@ 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" }
end
+ context 'with dns-linode plugin' do
+ let(:title) { 'foo.example.com' }
+ let(:params) { { plugin: 'dns-linode', letsencrypt_command: 'letsencrypt' } }
+ let(:pre_condition) do
+ <<-PUPPET
+ class { 'letsencrypt':
+ email => 'foo@example.com',
+ config_dir => '/etc/letsencrypt',
+ }
+ class { 'letsencrypt::plugin::dns_linode':
+ package_name => 'irrelevant',
+ api_key => 'dummy-linode-api-key',
+ }
+ PUPPET
+ end
+
+ it { is_expected.to compile.with_all_deps }
+ it { is_expected.to contain_class('letsencrypt::plugin::dns_linode') }
+ 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-linode --cert-name 'foo.example.com' -d 'foo.example.com' --dns-linode --dns-linode-credentials /etc/letsencrypt/dns-linode.ini --dns-linode-propagation-seconds 120" }
+ end
+
context 'with custom plugin' do
let(:title) { 'foo.example.com' }
let(:params) { { plugin: 'apache' } }
diff --git a/spec/type_aliases/plugin_spec.rb b/spec/type_aliases/plugin_spec.rb
index 0891edfe..f5df70b5 100644
--- a/spec/type_aliases/plugin_spec.rb
+++ b/spec/type_aliases/plugin_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe 'Letsencrypt::Plugin' do
- it { is_expected.to allow_values('apache', 'standalone', 'webroot', 'nginx', 'dns-azure', 'dns-route53', 'dns-google', 'dns-cloudflare', 'dns-rfc2136') }
+ it { is_expected.to allow_values('apache', 'standalone', 'webroot', 'nginx', 'dns-azure', 'dns-route53', 'dns-google', 'dns-cloudflare', 'dns-rfc2136', 'dns-linode') }
it { is_expected.not_to allow_value(nil) }
it { is_expected.not_to allow_value('foo') }
it { is_expected.not_to allow_value('custom') }
diff --git a/types/plugin.pp b/types/plugin.pp
index 56dffb61..6083293a 100644
--- a/types/plugin.pp
+++ b/types/plugin.pp
@@ -8,6 +8,7 @@
'dns-route53',
'dns-google',
'dns-cloudflare',
+ 'dns-linode',
'dns-rfc2136',
'manual',
]