Skip to content

Commit

Permalink
Merge pull request #332 from bastelfreak/timer
Browse files Browse the repository at this point in the history
Add systemd timer to update root.hints file
  • Loading branch information
bastelfreak authored Feb 9, 2024
2 parents 70e36a7 + 26a15f7 commit 084e16b
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 41 deletions.
1 change: 1 addition & 0 deletions .fixtures.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ fixtures:
repositories:
concat: "https://github.com/puppetlabs/puppetlabs-concat.git"
stdlib: "https://github.com/puppetlabs/puppetlabs-stdlib.git"
systemd: "https://github.com/voxpupuli/puppet-systemd.git"
13 changes: 10 additions & 3 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

### Classes

* [`unbound`](#unbound): Class: unbound Installs and configures Unbound, the caching DNS resolver from NLnet Labs
* [`unbound`](#unbound): Installs and configures Unbound, the caching DNS resolver from NLnet Labs
* [`unbound::remote`](#unbound--remote): Class: unbound::remote Configure remote control of the unbound daemon process === Parameters: [*enable*] (optional) The option is used t

### Defined types
Expand Down Expand Up @@ -36,8 +36,6 @@

### <a name="unbound"></a>`unbound`

Class: unbound

Installs and configures Unbound, the caching DNS resolver from NLnet Labs

#### Parameters
Expand All @@ -47,6 +45,7 @@ The following parameters are available in the `unbound` class:
* [`hints_file`](#-unbound--hints_file)
* [`hints_file_content`](#-unbound--hints_file_content)
* [`unbound_version`](#-unbound--unbound_version)
* [`update_root_hints`](#-unbound--update_root_hints)
* [`manage_service`](#-unbound--manage_service)
* [`verbosity`](#-unbound--verbosity)
* [`statistics_interval`](#-unbound--statistics_interval)
Expand Down Expand Up @@ -274,6 +273,14 @@ the version of the installed unbound instance. defaults to the fact, but you can

Default value: `$facts['unbound_version']`

##### <a name="-unbound--update_root_hints"></a>`update_root_hints`

Data type: `Enum['absent','present','unmanaged']`

If set to true (and hints_file isn't set to 'builtin') a systemd timer will be configured to update the root hints file every month

Default value: `fact('systemd') ? { true => 'present', default => 'unmanaged'`

##### <a name="-unbound--manage_service"></a>`manage_service`

Data type: `Boolean`
Expand Down
11 changes: 11 additions & 0 deletions files/roothints.timer
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# THIS FILE IS MANAGED BY PUPPET
# BASED ON https://wiki.archlinux.org/title/Unbound#Roothints_systemd_timer
[Unit]
Description=Run root.hints monthly

[Timer]
OnCalendar=monthly
Persistent=true

[Install]
WantedBy=timers.target
22 changes: 19 additions & 3 deletions manifests/init.pp
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# Class: unbound
#
# Installs and configures Unbound, the caching DNS resolver from NLnet Labs
# @summary Installs and configures Unbound, the caching DNS resolver from NLnet Labs
#
# @param hints_file
# File path to the root-hints. Set to 'builtin' to remove root-hint option from unbound.conf and use built-in hints.
# @param hints_file_content
# Contents of the root hints file, if it's not remotely fetched.
# @param unbound_version
# the version of the installed unbound instance. defaults to the fact, but you can overwrite it. this reduces the initial puppet runs from two to one
# @param update_root_hints
# If set to true (and hints_file isn't set to 'builtin') a systemd timer will be configured to update the root hints file every month
#
class unbound (
Boolean $manage_service = true,
Integer[0,5] $verbosity = 1,
Expand Down Expand Up @@ -135,7 +137,7 @@
Optional[Integer] $key_cache_slabs = undef,
Optional[Unbound::Size] $neg_cache_size = undef,
Boolean $unblock_lan_zones = false,
Boolean $insecure_lan_zones = false, # version 1.5.8
Boolean $insecure_lan_zones = false, # version 1.5.8
Unbound::Local_zone $local_zone = {},
Array[String[1]] $local_data = [],
Array[String[1]] $local_data_ptr = [],
Expand Down Expand Up @@ -212,6 +214,7 @@
Integer[1] $redis_timeout = 100,
Stdlib::Absolutepath $unbound_conf_d = "${confdir}/unbound.conf.d",
Unbound::Hints_file $hints_file = "${confdir}/root.hints",
Enum['absent','present','unmanaged'] $update_root_hints = fact('systemd') ? { true => 'present', default => 'unmanaged' },
Optional[String[1]] $hints_file_content = undef,
Hash[String[1], Unbound::Rpz] $rpzs = {},
Optional[String[1]] $unbound_version = $facts['unbound_version'],
Expand Down Expand Up @@ -316,6 +319,19 @@
mode => '0444',
content => $hints_file_content,
}
if $update_root_hints == 'present' {
systemd::timer { 'roothints.timer':
timer_content => file("${module_name}/roothints.timer"),
service_content => epp("${module_name}/roothints.service.epp", { 'hints_file' => $hints_file, 'root_hints_url' => $root_hints_url, 'fetch_client' => $fetch_client }),
active => true,
enable => true,
}
}
}
if $update_root_hints == 'absent' {
systemd::timer { 'roothints.timer':
ensure => 'absent',
}
}

# purge unmanaged files in configuration directory
Expand Down
4 changes: 4 additions & 0 deletions metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@
{
"name": "puppetlabs/stdlib",
"version_requirement": ">= 4.25.0 < 10.0.0"
},
{
"name": "puppet/systemd",
"version_requirement": ">= 6.3.0 < 7.0.0"
}
]
}
113 changes: 78 additions & 35 deletions spec/classes/init_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,6 @@

pidfile = nil

if facts.dig(:os, 'family').nil?
if facts[:osfamily]
puts "Skipping tests on on platform #{facts[:osfamily]} due to missing facts[:os][:family]"
else
puts "Skipping tests on on platform #{facts[:kernel]} due to missing facts[:os][:family]"
end
next
end

case facts[:os]['family']
when 'Debian'
pidfile = '/run/unbound.pid'
Expand Down Expand Up @@ -67,6 +58,10 @@
it { is_expected.to contain_file(keys_d_dir) }
it { is_expected.to contain_file(hints_file) }

context 'on Linux', if: facts[:kernel] == 'Linux' do
it { is_expected.to contain_systemd__timer('roothints.timer') }
end

it do
expect(subject).to contain_file(unbound_conf_d).with(
'ensure' => 'directory',
Expand Down Expand Up @@ -1038,41 +1033,89 @@
end
end

context 'no root hints in config' do
let(:params) do
{
hints_file: 'builtin'
}
context 'roothints' do
context 'no root hints in config' do
let(:params) do
{
hints_file: 'builtin'
}
end

it do
expect(subject).to contain_concat__fragment(
'unbound-header'
).without_content(%r{root-hints})
end

it { is_expected.not_to contain_systemd__timer('roothints.timer') }
end

it do
expect(subject).to contain_concat__fragment(
'unbound-header'
).without_content(%r{root-hints})
context 'no root hints in config and update_root_hints=unmanaged' do
let(:params) do
{
hints_file: 'builtin',
update_root_hints: 'unmanaged'
}
end

it do
expect(subject).to contain_concat__fragment(
'unbound-header'
).without_content(%r{root-hints})
end

it { is_expected.not_to contain_systemd__timer('roothints.timer') }
end
end

context 'hieradata root hints' do
let(:params) do
{
skip_roothints_download: true,
hints_file_content: File.read('spec/classes/expected/hieradata-root-hint.conf'),
}
context 'no root hints in config and update_root_hints=absent' do
let(:params) do
{
hints_file: 'builtin',
update_root_hints: 'absent'
}
end

it do
expect(subject).to contain_concat__fragment(
'unbound-header'
).without_content(%r{root-hints})
end

it { is_expected.to contain_systemd__timer('roothints.timer').with_ensure('absent') }
end

it do
expect(subject).to contain_file(hints_file).with(
'ensure' => 'file',
'mode' => '0444',
'content' => File.read('spec/classes/expected/hieradata-root-hint.conf')
)
context 'update_root_hints=absent' do
let(:params) do
{
update_root_hints: 'absent'
}
end

it { is_expected.to contain_systemd__timer('roothints.timer').with_ensure('absent') }
end
end

context 'with File defaults' do
let(:pre_condition) { "File { mode => '0644', owner => 'root', group => 'root' }" }
context 'hieradata root hints' do
let(:params) do
{
skip_roothints_download: true,
hints_file_content: File.read('spec/classes/expected/hieradata-root-hint.conf'),
}
end

it { is_expected.to compile.with_all_deps }
it do
expect(subject).to contain_file(hints_file).with(
'ensure' => 'file',
'mode' => '0444',
'content' => File.read('spec/classes/expected/hieradata-root-hint.conf')
)
end
end

context 'with File defaults' do
let(:pre_condition) { "File { mode => '0644', owner => 'root', group => 'root' }" }

it { is_expected.to compile.with_all_deps }
end
end

context 'RPZs config' do
Expand Down
9 changes: 9 additions & 0 deletions templates/roothints.service.epp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<%- | Stdlib::Absolutepath $hints_file, Stdlib::HTTPSUrl $root_hints_url, String[1] $fetch_client | -%>
# THIS FILE IS MANAGED BY PUPPET
# BASED ON https://wiki.archlinux.org/title/Unbound#Roothints_systemd_timer
[Unit]
Description=Update root hints for unbound
After=network.target

[Service]
ExecStart=<%= $fetch_client %> <%= $hints_file %> <%= $root_hints_url %>

0 comments on commit 084e16b

Please sign in to comment.