diff --git a/README.md b/README.md
index 5e2e461..5401e50 100644
--- a/README.md
+++ b/README.md
@@ -43,6 +43,29 @@ class { 'powerdns':
recursor => true,
}
```
+### YAML config format
+
+Starting from Recursor `5.0` YAML syntax is supported. From release `5.2` `recursor.conf` file is parsed as YAML, unless `--enable-old-settings` flag is provided. The old configuration can be converted:
+
+```
+$ rec_control show-yaml path/to/recursor.conf
+```
+
+For detailed changes in syntax see [the official documentation](https://doc.powerdns.com/recursor/appendices/yamlconversion.html).
+```yaml
+powerdns::recursor_version: '5.3'
+powerdns::recursor_use_yaml: true
+powerdns::recursor::config:
+ dnssec:
+ validation: 'off'
+ incoming:
+ allow_from:
+ - 0.0.0.0/0
+ distributor_threads: 1
+ listen:
+ - 0.0.0.0:53
+```
+
### Recursor forward zones
diff --git a/REFERENCE.md b/REFERENCE.md
index bf12e7a..d7209b5 100644
--- a/REFERENCE.md
+++ b/REFERENCE.md
@@ -19,7 +19,8 @@
### Defined types
-* [`powerdns::config`](#powerdns--config): Manage powerdns settings
+* [`powerdns::config`](#powerdns--config): Manage powerdns settings in old configuration format.
+Supported up to recursor version 5.2.
### Resource types
@@ -107,6 +108,9 @@ The following parameters are available in the `powerdns` class:
* [`authoritative_group`](#-powerdns--authoritative_group)
* [`authoritative_file_owner`](#-powerdns--authoritative_file_owner)
* [`authoritative_file_group`](#-powerdns--authoritative_file_group)
+* [`recursor_use_yaml`](#-powerdns--recursor_use_yaml)
+* [`recursor_local_config_file`](#-powerdns--recursor_local_config_file)
+* [`recursor_local_config`](#-powerdns--recursor_local_config)
##### `authoritative_package_name`
@@ -152,7 +156,7 @@ Authoritative config file path
##### `authoritative_version`
-Data type: `Pattern[/4\.[0-9]+/]`
+Data type: `Pattern[/[4,5]\.[0-9]+/]`
Authoritative server version
@@ -491,11 +495,11 @@ Default value: `false`
##### `forward_zones`
-Data type: `Hash`
+Data type: `Optional[Variant[Hash,Tuple]]`
Configures recursor forward_zones
-Default value: `{}`
+Default value: `undef`
##### `autoprimaries`
@@ -545,6 +549,30 @@ Group of authoritative config files
Default value: `$authoritative_group`
+##### `recursor_use_yaml`
+
+Data type: `Boolean`
+
+
+
+Default value: `false`
+
+##### `recursor_local_config_file`
+
+Data type: `Optional[Stdlib::Absolutepath]`
+
+
+
+Default value: `undef`
+
+##### `recursor_local_config`
+
+Data type: `Optional[Hash]`
+
+
+
+Default value: `undef`
+
### `powerdns::authoritative`
powerdns::authoritative
@@ -577,20 +605,60 @@ sqlite backend for powerdns
powerdns recursor
+* **See also**
+ * https://doc.powerdns.com/recursor/yamlsettings.html
+
#### Parameters
The following parameters are available in the `powerdns::recursor` class:
* [`forward_zones`](#-powerdns--recursor--forward_zones)
+* [`config`](#-powerdns--recursor--config)
+* [`forward_zones_file`](#-powerdns--recursor--forward_zones_file)
+* [`include`](#-powerdns--recursor--include)
+* [`config_includedir`](#-powerdns--recursor--config_includedir)
##### `forward_zones`
-Data type: `Hash`
+Data type: `Optional[Variant[Hash,Tuple]]`
Hash containing zone => dns servers pairs
Default value: `$powerdns::forward_zones`
+##### `config`
+
+Data type: `Hash`
+
+recursor config (will be converted to YAML)
+when powerdns::recursor_use_yaml is set to `true`
+
+Default value: `{}`
+
+##### `forward_zones_file`
+
+Data type: `String`
+
+filename
+
+Default value: `'forward_zones.conf'`
+
+##### `include`
+
+Data type: `Hash`
+
+Key as filename and its contents as value
+
+Default value: `{}`
+
+##### `config_includedir`
+
+Data type: `Stdlib::Absolutepath`
+
+
+
+Default value: `"${powerdns::recursor_configdir}/recursor.d"`
+
### `powerdns::repo`
powerdns::repo
@@ -599,7 +667,11 @@ powerdns::repo
### `powerdns::config`
-Manage powerdns settings
+Manage powerdns settings in old configuration format.
+Supported up to recursor version 5.2.
+
+* **See also**
+ * https://doc.powerdns.com/recursor/settings.html
#### Parameters
diff --git a/data/common.yaml b/data/common.yaml
index 5e00312..c3401aa 100644
--- a/data/common.yaml
+++ b/data/common.yaml
@@ -1,4 +1,7 @@
---
+lookup_options:
+ powerdns::recursor_local_config:
+ merge: deep
powerdns::authoritative_package_ensure: installed
powerdns::authoritative_extra_packages_ensure: installed
powerdns::authoritative_version: '4.9'
@@ -8,3 +11,4 @@ powerdns::recursor_user: pdns
powerdns::recursor_group: pdns
powerdns::recursor_file_owner: root
powerdns::recursor_file_group: "%{lookup('powerdns::recursor_group')}"
+powerdns::recursor_use_yaml: false
diff --git a/data/os/Debian.yaml b/data/os/Debian.yaml
index c6c06c8..6830a08 100644
--- a/data/os/Debian.yaml
+++ b/data/os/Debian.yaml
@@ -1,5 +1,5 @@
---
-powerdns::db_file: "/var/lib/powerdns/powerdns.sqlite3"
+powerdns::db_file: /var/lib/powerdns/powerdns.sqlite3
powerdns::mysql_schema_file: /usr/share/doc/pdns-backend-mysql/schema.mysql.sql
powerdns::pgsql_schema_file: /usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql
powerdns::sqlite_schema_file: /usr/share/doc/pdns-backend-sqlite3/schema.sqlite3.sql
diff --git a/data/os/Debian/12.yaml b/data/os/Debian/12.yaml
new file mode 100644
index 0000000..fe7e462
--- /dev/null
+++ b/data/os/Debian/12.yaml
@@ -0,0 +1,3 @@
+---
+powerdns::mysql_charset: utf8mb3
+powerdns::mysql_collate: utf8mb3_general_ci
diff --git a/data/os/FreeBSD.yaml b/data/os/FreeBSD.yaml
index 3adf1fa..11cc58c 100644
--- a/data/os/FreeBSD.yaml
+++ b/data/os/FreeBSD.yaml
@@ -1,5 +1,5 @@
---
-powerdns::db_file: "/var/db/powerdns/powerdns.sqlite3"
+powerdns::db_file: /var/db/powerdns/powerdns.sqlite3
powerdns::mysql_schema_file: /usr/local/share/doc/powerdns/schema.mysql.sql
powerdns::pgsql_schema_file: /usr/local/share/doc/powerdns/schema.pgsql.sql
powerdns::sqlite_schema_file: /usr/local/share/doc/powerdns/schema.sqlite3.sql
diff --git a/data/os/RedHat.yaml b/data/os/RedHat.yaml
index 11dfe60..b806938 100644
--- a/data/os/RedHat.yaml
+++ b/data/os/RedHat.yaml
@@ -1,5 +1,5 @@
---
-powerdns::db_file: "/var/lib/powerdns/powerdns.sqlite3"
+powerdns::db_file: /var/lib/powerdns/powerdns.sqlite3
powerdns::mysql_schema_file: /usr/share/doc/pdns-backend-mysql/schema.mysql.sql
powerdns::pgsql_schema_file: /usr/share/doc/pdns-backend-postgresql/schema.pgsql.sql
powerdns::sqlite_schema_file: /usr/share/doc/pdns-backend-sqlite/schema.sqlite.sql
diff --git a/manifests/config.pp b/manifests/config.pp
index e2960b9..3fffe20 100644
--- a/manifests/config.pp
+++ b/manifests/config.pp
@@ -1,4 +1,6 @@
-# @summary Manage powerdns settings
+# @summary Manage powerdns settings in old configuration format.
+# Supported up to recursor version 5.2.
+# @see https://doc.powerdns.com/recursor/settings.html
#
# @param setting
# The setting you want to change
diff --git a/manifests/init.pp b/manifests/init.pp
index 61ebc6f..6f6dbbf 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -132,7 +132,7 @@
String[1] $authoritative_service_name,
Stdlib::Absolutepath $authoritative_configdir,
Stdlib::Absolutepath $authoritative_config,
- Pattern[/4\.[0-9]+/] $authoritative_version,
+ Pattern[/[4,5]\.[0-9]+/] $authoritative_version,
Stdlib::Absolutepath $db_file,
Stdlib::Absolutepath $mysql_schema_file,
Stdlib::Absolutepath $pgsql_schema_file,
@@ -157,6 +157,9 @@
Optional[String[1]] $mysql_collate = undef,
Boolean $authoritative = true,
Boolean $recursor = false,
+ Boolean $recursor_use_yaml = false,
+ Optional[Stdlib::Absolutepath] $recursor_local_config_file = undef,
+ Optional[Hash] $recursor_local_config = undef,
Powerdns::Backends $backend = 'mysql',
Boolean $backend_install = true,
Boolean $backend_create_tables = true,
@@ -178,7 +181,7 @@
Powerdns::LmdbSyncMode $lmdb_sync_mode = undef,
Boolean $custom_repo = false,
Boolean $custom_epel = false,
- Hash $forward_zones = {},
+ Optional[Variant[Hash,Tuple]] $forward_zones = undef,
Powerdns::Autoprimaries $autoprimaries = {},
Boolean $purge_autoprimaries = false,
String[1] $authoritative_user = 'pdns',
@@ -223,10 +226,12 @@
if $recursor {
contain powerdns::recursor
- # Set up Hiera for the recursor.
- $powerdns_recursor_config = lookup('powerdns::recursor::config', Hash, 'deep', {})
- $powerdns_recursor_defaults = { 'type' => 'recursor' }
- create_resources(powerdns::config, $powerdns_recursor_config, $powerdns_recursor_defaults)
+ # old config format
+ unless $recursor_use_yaml {
+ $powerdns_recursor_config = lookup('powerdns::recursor::config', Hash, 'deep', {})
+ $powerdns_recursor_defaults = { 'type' => 'recursor' }
+ create_resources(powerdns::config, $powerdns_recursor_config, $powerdns_recursor_defaults)
+ }
}
if $purge_autoprimaries {
diff --git a/manifests/recursor.pp b/manifests/recursor.pp
index 26fdd6c..8c482ff 100644
--- a/manifests/recursor.pp
+++ b/manifests/recursor.pp
@@ -2,37 +2,97 @@
#
# @param forward_zones
# Hash containing zone => dns servers pairs
+# @param config recursor config (will be converted to YAML)
+# when powerdns::recursor_use_yaml is set to `true`
+# @see https://doc.powerdns.com/recursor/yamlsettings.html
+# @param forward_zones_file filename
+# @param include Key as filename and its contents as value
#
class powerdns::recursor (
- Hash $forward_zones = $powerdns::forward_zones,
+ Optional[Variant[Hash,Tuple]] $forward_zones = $powerdns::forward_zones,
+ Hash $config = {},
+ String $forward_zones_file = 'forward_zones.conf',
+ Stdlib::Absolutepath $config_includedir = "${powerdns::recursor_configdir}/recursor.d",
+ Hash $include = {},
) inherits powerdns {
package { $powerdns::recursor_package_name:
ensure => $powerdns::recursor_package_ensure,
}
+ $zone_config = "${powerdns::recursor_configdir}/${forward_zones_file}"
- file { $powerdns::recursor_config:
- ensure => file,
- owner => $powerdns::recursor_file_owner,
- group => $powerdns::recursor_file_group,
- require => Package[$powerdns::recursor_package_name],
- }
+ if $powerdns::recursor_use_yaml {
+ ## Use New YAML based configuration
+ $forward_block = empty($forward_zones) ? {
+ true => {},
+ false => { 'forward_zones_file' => $zone_config },
+ }
+
+ $recursor_config = deep_merge({
+ 'recursor' => {
+ 'include_dir' => $config_includedir,
+ } + $forward_block,
+ }, $config)
+
+ file { $config_includedir:
+ ensure => directory,
+ owner => $powerdns::recursor_file_owner,
+ group => $powerdns::recursor_file_group,
+ require => Package[$powerdns::recursor_package_name],
+ }
- if !empty($forward_zones) {
- $zone_config = "${powerdns::recursor_configdir}/forward_zones.conf"
file { $zone_config:
ensure => file,
owner => $powerdns::recursor_file_owner,
group => $powerdns::recursor_file_group,
- content => template('powerdns/forward_zones.conf.erb'),
+ content => stdlib::to_yaml($forward_zones),
+ require => Package[$powerdns::recursor_package_name],
notify => Service['pdns-recursor'],
}
- powerdns::config { 'forward-zones-file':
- value => $zone_config,
- type => 'recursor',
+ file { $powerdns::recursor_config:
+ ensure => file,
+ owner => $powerdns::recursor_file_owner,
+ group => $powerdns::recursor_file_group,
+ content => stdlib::to_yaml($recursor_config),
+ require => Package[$powerdns::recursor_package_name],
+ notify => Service['pdns-recursor'],
}
- }
+ $include.each |String $filename, Hash $content| {
+ file { "${config_includedir}/${filename}":
+ ensure => file,
+ owner => $powerdns::recursor_file_owner,
+ group => $powerdns::recursor_file_group,
+ content => stdlib::to_yaml($content),
+ require => Package[$powerdns::recursor_package_name],
+ notify => Service['pdns-recursor'],
+ }
+ }
+ } else {
+ ## Use Old INI based configuration
+
+ file { $powerdns::recursor_config:
+ ensure => file,
+ owner => $powerdns::recursor_file_owner,
+ group => $powerdns::recursor_file_group,
+ require => Package[$powerdns::recursor_package_name],
+ }
+
+ if !empty($forward_zones) {
+ file { $zone_config:
+ ensure => file,
+ owner => $powerdns::recursor_file_owner,
+ group => $powerdns::recursor_file_group,
+ content => template('powerdns/forward_zones.conf.erb'),
+ notify => Service['pdns-recursor'],
+ }
+
+ powerdns::config { 'forward-zones-file':
+ value => $zone_config,
+ type => 'recursor',
+ }
+ }
+ }
service { 'pdns-recursor':
ensure => running,
name => $powerdns::recursor_service_name,
diff --git a/metadata.json b/metadata.json
index a5de57d..56383de 100644
--- a/metadata.json
+++ b/metadata.json
@@ -51,16 +51,16 @@
]
},
{
- "operatingsystem": "Ubuntu",
+ "operatingsystem": "Debian",
"operatingsystemrelease": [
- "24.04"
+ "11",
+ "12"
]
},
{
- "operatingsystem": "Debian",
+ "operatingsystem": "Ubuntu",
"operatingsystemrelease": [
- "11",
- "12"
+ "24.04"
]
}
],
diff --git a/spec/acceptance/class_spec.rb b/spec/acceptance/class_spec.rb
index 69b5449..7bda8f4 100644
--- a/spec/acceptance/class_spec.rb
+++ b/spec/acceptance/class_spec.rb
@@ -46,7 +46,7 @@ class { 'powerdns':
end
describe command('/usr/bin/pdns_control version') do
- its(:stdout) { is_expected.to match %r{^4\.9} }
+ its(:stdout) { is_expected.to match %r{^(4\.9|5\.\d)} }
end
end
diff --git a/spec/classes/powerdns_init_spec.rb b/spec/classes/powerdns_init_spec.rb
index df310b0..f50b4a2 100644
--- a/spec/classes/powerdns_init_spec.rb
+++ b/spec/classes/powerdns_init_spec.rb
@@ -27,6 +27,7 @@
sqlite_binary_package_name = 'sqlite'
recursor_package_name = 'pdns-recursor'
recursor_service_name = 'pdns-recursor'
+ recursor_dir = '/etc/pdns-recursor'
when 'Debian'
authoritative_package_name = 'pdns-server'
authoritative_service_name = 'pdns'
@@ -39,6 +40,7 @@
sqlite_binary_package_name = 'sqlite3'
recursor_package_name = 'pdns-recursor'
recursor_service_name = 'pdns-recursor'
+ recursor_dir = '/etc/powerdns'
when 'Archlinux'
authoritative_package_name = 'powerdns'
authoritative_service_name = 'pdns'
@@ -121,9 +123,7 @@
it { is_expected.to contain_apt__keyring('powerdns.asc') }
it { is_expected.to contain_apt__pin('powerdns') }
it { is_expected.to contain_apt__source('powerdns') }
- it { is_expected.to contain_apt__source('powerdns').with_release(%r{auth-49}) }
it { is_expected.to contain_apt__source('powerdns-recursor') }
- it { is_expected.to contain_apt__source('powerdns-recursor').with_release(%r{rec-50}) }
it { is_expected.to contain_package('dirmngr') }
end
@@ -632,11 +632,98 @@
it { is_expected.to contain_package(authoritative_package_name).with('ensure' => 'installed') }
end
+ # if a yaml OS, test the yaml style forward zones
+ context 'powerdns class with the recursor with yaml forward zones' do
+ let(:params) do
+ {
+ recursor: true,
+ authoritative: false,
+ recursor_version: '5.3',
+ recursor_use_yaml: true,
+ forward_zones: [
+ {
+ 'zone' => 'example.com',
+ 'forwarders' => ['192.0.2.1:5300'],
+ },
+ {
+ 'zone' => 'example.net',
+ 'forwarders' => ['198.51.100.1', '198.51.100.2', '198.51.100.3', '198.51.100.4'],
+ 'recurse' => true,
+ },
+ {
+ 'zone' => 'example.org',
+ 'forwarders' => ['203.0.113.5', '203.0.113.6'],
+ },
+ {
+ 'zone' => '2.0.192.in-addr.arpa', # reverse for 192.0.2.0/24
+ 'forwarders' => ['192.0.2.53', '192.0.2.54'],
+ 'recurse' => true,
+ },
+ {
+ 'zone' => '100.51.198.in-addr.arpa', # reverse for 198.51.100.0/24
+ 'forwarders' => ['198.51.100.53', '198.51.100.54'],
+ 'recurse' => true,
+ },
+ ]
+ }
+ end
+
+ it { is_expected.to compile.with_all_deps }
+
+ # Check forward zones
+ it { is_expected.to contain_class('powerdns::recursor') }
+
+ it 'renders forward zones yaml correctly' do
+ is_expected.to contain_file("#{recursor_dir}/recursor.conf").with('ensure' => 'file').
+ with_content(<<~EOS
+ ---
+ recursor:
+ include_dir: "#{recursor_dir}/recursor.d"
+ forward_zones_file: "#{recursor_dir}/forward_zones.conf"
+ EOS
+ )
+ end
+
+ it 'includes forward_zones config in yaml format' do
+ is_expected.to contain_file("#{recursor_dir}/forward_zones.conf").with('ensure' => 'file').
+ with_content(<<~EOS
+ ---
+ - zone: example.com
+ forwarders:
+ - 192.0.2.1:5300
+ - zone: example.net
+ forwarders:
+ - 198.51.100.1
+ - 198.51.100.2
+ - 198.51.100.3
+ - 198.51.100.4
+ recurse: true
+ - zone: example.org
+ forwarders:
+ - 203.0.113.5
+ - 203.0.113.6
+ - zone: 2.0.192.in-addr.arpa
+ forwarders:
+ - 192.0.2.53
+ - 192.0.2.54
+ recurse: true
+ - zone: 100.51.198.in-addr.arpa
+ forwarders:
+ - 198.51.100.53
+ - 198.51.100.54
+ recurse: true
+ EOS
+ )
+ end
+ end
+
+ # if not a yaml OS, test the old style forward zones
context 'powerdns class with the recursor with forward zones' do
let(:params) do
{
recursor: true,
authoritative: false,
+ recursor_version: '4.9', # without yaml support
forward_zones: {
'example.com': '1.1.1.1',
'+.': '8.8.8.8'
@@ -644,16 +731,9 @@
}
end
- case facts[:os]['family']
- when 'RedHat'
- recursor_dir = '/etc/pdns-recursor'
- when 'Debian'
- recursor_dir = '/etc/powerdns'
- end
-
it { is_expected.to compile.with_all_deps }
- # Check the authoritative server
+ # Check forward zones
it { is_expected.to contain_class('powerdns::recursor') }
it { is_expected.to contain_file("#{recursor_dir}/forward_zones.conf").with_ensure('file') }
diff --git a/spec/classes/powerdns_recursor_spec.rb b/spec/classes/powerdns_recursor_spec.rb
new file mode 100644
index 0000000..c90f820
--- /dev/null
+++ b/spec/classes/powerdns_recursor_spec.rb
@@ -0,0 +1,96 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'powerdns::recursor' do
+ context 'supported operating systems' do
+ on_supported_os.each do |os, facts|
+ context "on #{os}" do
+ let(:pre_condition) do
+ <<-EOS
+ class { 'powerdns':
+ db_root_password => 'foobar',
+ db_username => 'foo',
+ db_password => 'bar',
+ recursor_use_yaml => true,
+ }
+ EOS
+ end
+ let(:facts) do
+ facts
+ end
+
+ recursor_dir = case facts[:os]['family']
+ when 'RedHat'
+ '/etc/pdns-recursor'
+ else
+ '/etc/powerdns'
+ end
+
+ it { is_expected.to compile.with_all_deps }
+
+ context 'custom config' do
+ let(:params) do
+ {
+ include: {
+ '00-defaults.yml': {
+ logging: {
+ loglevel: 6
+ }
+ }
+ }
+ }
+ end
+
+ it 'checks file resource based on hiera value' do
+ is_expected.to contain_file("#{recursor_dir}/recursor.d/00-defaults.yml").with('ensure' => 'file')
+ end
+ end
+
+ context 'with forward zones' do
+ let(:params) do
+ {
+ config: {
+ recursor: {
+ threads: 2,
+ }
+ },
+ forward_zones_file: 'forward_zones.yml',
+ forward_zones: [
+ {
+ 'zone' => '.',
+ 'forwarders' => ['1.1.1.1'],
+ 'recurse' => true,
+ },
+ ]
+ }
+ end
+
+ it 'includes main config in yaml format' do
+ is_expected.to contain_file("#{recursor_dir}/recursor.conf").with('ensure' => 'file').
+ with_content(<<~EOS
+ ---
+ recursor:
+ include_dir: "#{recursor_dir}/recursor.d"
+ forward_zones_file: "#{recursor_dir}/forward_zones.yml"
+ threads: 2
+ EOS
+ )
+ end
+
+ it 'includes forward_zones config in yaml format' do
+ is_expected.to contain_file("#{recursor_dir}/forward_zones.yml").with('ensure' => 'file').
+ with_content(<<~EOS
+ ---
+ - zone: "."
+ forwarders:
+ - 1.1.1.1
+ recurse: true
+ EOS
+ )
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/defines/powerdns_config_spec.rb b/spec/defines/powerdns_config_spec.rb
index ca4f5dd..6453476 100644
--- a/spec/defines/powerdns_config_spec.rb
+++ b/spec/defines/powerdns_config_spec.rb
@@ -5,6 +5,7 @@
}
require 'spec_helper'
+
describe 'powerdns::config' do
context 'supported operating systems' do
on_supported_os.each do |os, facts|
@@ -18,11 +19,14 @@
end
let(:pre_condition) do
- 'class { "::powerdns":
+ 'class { "powerdns":
db_root_password => "foobar",
db_username => "foo",
db_password => "bar",
recursor => true,
+ recursor_use_yaml => false, # <- force INI mode
+ authoritative_version => "4.9",
+ recursor_version => "5.0",
}'
end
@@ -53,15 +57,12 @@
end
context 'powerdns::config with recursor type' do
- let(:params) do
- {
- setting: 'foo',
- value: 'bar',
- type: 'recursor'
- }
- end
+ let(:params) { { setting: 'foo', value: 'bar', type: 'recursor' } }
- it { is_expected.to contain_file_line(format('powerdns-config-foo-%{config}', config: recursor_config)) }
+ it do
+ # Only assert in INI mode
+ is_expected.to contain_file_line("powerdns-config-foo-#{recursor_config}") unless catalogue.resource('Class', 'Powerdns')[:recursor_use_yaml]
+ end
end
context 'powerdns::config with integers' do
diff --git a/spec/defines/powerdns_config_yaml_spec.rb b/spec/defines/powerdns_config_yaml_spec.rb
new file mode 100644
index 0000000..4298c14
--- /dev/null
+++ b/spec/defines/powerdns_config_yaml_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'powerdns::config', type: :define do
+ on_supported_os.each do |os, facts|
+ context "on #{os} with recursor_use_yaml => true" do
+ let(:facts) { facts.merge(root_home: '/root') }
+ let(:pre_condition) do
+ <<-PUPPET
+ class { 'powerdns':
+ authoritative => true,
+ recursor => true,
+ authoritative_version => '5.0',
+ recursor_version => '5.3',
+ recursor_use_yaml => true,
+ db_root_password => 'rootpass',
+ db_username => 'pdns',
+ db_password => 'secret',
+ }
+ PUPPET
+ end
+ let(:title) { 'foo' }
+
+ case facts[:os]['family']
+ when 'RedHat'
+ authoritative_config = '/etc/pdns/pdns.conf'
+ recursor_dir = '/etc/pdns-recursor'
+ else
+ authoritative_config = '/etc/powerdns/pdns.conf'
+ recursor_dir = '/etc/powerdns'
+ end
+ recursor_config = "#{recursor_dir}/recursor.conf"
+
+ context 'recursor type uses YAML file (with include_dir stanza)' do
+ let(:params) { { setting: 'foo', value: 'bar', type: 'recursor' } }
+
+ it { is_expected.to contain_file(recursor_config).with_ensure('file') }
+
+ it 'includes the include_dir stanza in the YAML content' do
+ is_expected.to contain_file(recursor_config).
+ with_content(%r{include_dir:\s*"?#{Regexp.escape(recursor_dir)}/recursor\.d"?})
+ end
+ end
+
+ context 'authoritative still writes to pdns.conf via file_line' do
+ let(:params) { { setting: 'foo', value: 'bar' } }
+
+ it do
+ is_expected.to contain_file_line("powerdns-config-foo-#{authoritative_config}").
+ with_path(authoritative_config)
+ end
+ end
+ end
+ end
+end