summaryrefslogtreecommitdiff
path: root/puppet
diff options
context:
space:
mode:
Diffstat (limited to 'puppet')
-rw-r--r--puppet/modules/unbound/LICENSE13
-rw-r--r--puppet/modules/unbound/Modulefile10
-rw-r--r--puppet/modules/unbound/README79
-rw-r--r--puppet/modules/unbound/manifests/anchor.pp26
-rw-r--r--puppet/modules/unbound/manifests/forward.pp32
-rw-r--r--puppet/modules/unbound/manifests/init.pp117
-rw-r--r--puppet/modules/unbound/manifests/package.pp15
-rw-r--r--puppet/modules/unbound/manifests/params.pp42
-rw-r--r--puppet/modules/unbound/manifests/root_hints.pp35
-rw-r--r--puppet/modules/unbound/manifests/service.pp22
-rw-r--r--puppet/modules/unbound/manifests/service/openbsd.pp21
-rw-r--r--puppet/modules/unbound/manifests/ssl.pp25
-rw-r--r--puppet/modules/unbound/manifests/stub.pp32
-rw-r--r--puppet/modules/unbound/metadata.json50
-rw-r--r--puppet/modules/unbound/spec/spec_helper.rb17
-rw-r--r--puppet/modules/unbound/templates/unbound.conf.erb8
-rw-r--r--puppet/modules/unbound/tests/anchor.pp2
-rw-r--r--puppet/modules/unbound/tests/forward.pp7
-rw-r--r--puppet/modules/unbound/tests/init.pp26
-rw-r--r--puppet/modules/unbound/tests/package.pp2
-rw-r--r--puppet/modules/unbound/tests/params.pp1
-rw-r--r--puppet/modules/unbound/tests/root_hints.pp2
-rw-r--r--puppet/modules/unbound/tests/service.pp2
-rw-r--r--puppet/modules/unbound/tests/service/openbsd.pp1
-rw-r--r--puppet/modules/unbound/tests/ssl.pp2
-rw-r--r--puppet/modules/unbound/tests/stub.pp7
26 files changed, 596 insertions, 0 deletions
diff --git a/puppet/modules/unbound/LICENSE b/puppet/modules/unbound/LICENSE
new file mode 100644
index 00000000..b0dfc82b
--- /dev/null
+++ b/puppet/modules/unbound/LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2012 Martin Oppegaard <martin.oppegaard at gmail dot com>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/puppet/modules/unbound/Modulefile b/puppet/modules/unbound/Modulefile
new file mode 100644
index 00000000..93c593ad
--- /dev/null
+++ b/puppet/modules/unbound/Modulefile
@@ -0,0 +1,10 @@
+name 'oppegaard-unbound'
+version '0.1.0'
+author 'Martin Oppegaard'
+license 'ISC'
+summary 'The unbound module manages unbound'
+description 'This module manages unbound, the reqursive caching DNS resolver.
+ It manages the package, service, configuration file, control keys and support
+ files.'
+dependency 'puppetlabs/stdlib', '>= 3.2.0'
+dependency 'oppegaard/openbsd', '>= 0.1.0'
diff --git a/puppet/modules/unbound/README b/puppet/modules/unbound/README
new file mode 100644
index 00000000..529f37f0
--- /dev/null
+++ b/puppet/modules/unbound/README
@@ -0,0 +1,79 @@
+== Class: unbound
+
+The unbound class manages unbound, the reqursive caching DNS resolver.
+It manages the package, service, configuration file, control keys and
+support files.
+
+Supported operating systems are OpenBSD, Debian and Ubuntu. Tested on OpenBSD
+5.2 with Puppet 2.7.14 and Debian Sid with Puppet 2.7.18-2.
+
+The configuration file is concatenated from samples of server et. al.,
+stub-zone and forward-zone. The latter two are created independently
+from the server settings, by defines which can be used by other classes
+and modules.
+
+Control keys can be created with the unbound-control-setup program,
+and is enabled by default. These are neccessary to be able to control
+unbound (restart, reload etc) with the unbound-control program.
+
+The auto-trust-anchor-file 'root.key' can be created with the unbound-anchor
+program, and is enabled by default.
+
+The root-hints files named.cache can be managed, but have to be provided by
+the user. See the documentation in manifests/root_hints.pp for how to proceede.
+This functionality is not enabled by default.
+
+=== Parameters
+
+[*settings*]
+Hash containing the settings as key value pairs.
+
+[*ssl*]
+Mange unbound-control certificates? True or false, true by default.
+
+[*anchor*]
+Manage root.key? True or false, true by default.
+
+[*root_hints*]
+Manage named.cache? True or false, false by default.
+
+=== Examples
+
+class { 'unbound':
+ root_hints => true,
+ settings => {
+ server => {
+ verbosity => '1',
+ interface => [
+ '127.0.0.1',
+ '::1',
+ $::ipaddress,
+ ],
+ outgoing-interface => $::ipaddress,
+ access-control => [
+ '127.0.0.0/8 allow',
+ '::1 allow',
+ '10.0.0.0/8 allow',
+ ],
+ root-hints => '"/var/unbound/etc/named.cache"',
+ private-address => [
+ '10.0.0.0/8',
+ '172.16.0.0/12',
+ '192.168.0.0/16',
+ ],
+ private-domain => "\"$::domain\"",
+ auto-trust-anchor-file => '"/var/unbound/etc/root.key"',
+ },
+ python => { },
+ remote-control => {
+ control-enable => 'yes',
+ control-interface => [
+ '127.0.0.1',
+ '::1',
+ ],
+ },
+ }
+}
+
+See manifests/stub.pp and manifests/forward.pp for examples on how to create
+sub zones and forward zones repectively.
diff --git a/puppet/modules/unbound/manifests/anchor.pp b/puppet/modules/unbound/manifests/anchor.pp
new file mode 100644
index 00000000..e890722e
--- /dev/null
+++ b/puppet/modules/unbound/manifests/anchor.pp
@@ -0,0 +1,26 @@
+# == Class: unbound::anchor
+#
+# The unbound::anchor class manages the "root.key" file, and creates it with
+# the unbound-anchor program.
+#
+# === Examples
+#
+# include unbound::anchor
+#
+class unbound::anchor {
+ include unbound::params
+
+ file { $unbound::params::anchor:
+ owner => $unbound::params::user,
+ group => $unbound::params::group,
+ mode => '0644',
+ require => Exec[$unbound::params::unbound_anchor],
+ }
+
+ exec { $unbound::params::unbound_anchor:
+ command => "${unbound::params::unbound_anchor} -a ${unbound::params::anchor}",
+ creates => $unbound::params::anchor,
+ returns => 1,
+ before => Class['unbound::service'],
+ }
+}
diff --git a/puppet/modules/unbound/manifests/forward.pp b/puppet/modules/unbound/manifests/forward.pp
new file mode 100644
index 00000000..740c004d
--- /dev/null
+++ b/puppet/modules/unbound/manifests/forward.pp
@@ -0,0 +1,32 @@
+# == Define: unbound::forward
+#
+# Creates a forward-zone. $settings is a hash containing the settings.
+# The name of the resource is used as the 'name' of the zone.
+#
+# === Parameters
+#
+# [*settings*]
+# Hash containing the settings as key value pairs.
+#
+# === Examples
+#
+# unbound::forward { 'example.com':
+# settings => {
+# forward-addr => '10.0.0.1',
+# },
+# }
+#
+define unbound::forward (
+ $settings,
+) {
+ include unbound
+
+ $zone_name = { name => "\"${title}\"" }
+ $real_settings = { forward-zone => merge($zone_name, $settings) }
+
+ concat::fragment { "unbound ${title}":
+ target => $unbound::params::config,
+ content => template('unbound/unbound.conf.erb'),
+ order => 3,
+ }
+}
diff --git a/puppet/modules/unbound/manifests/init.pp b/puppet/modules/unbound/manifests/init.pp
new file mode 100644
index 00000000..ecb7970a
--- /dev/null
+++ b/puppet/modules/unbound/manifests/init.pp
@@ -0,0 +1,117 @@
+# == Class: unbound
+#
+# The unbound class manages unbound, the reqursive caching dns resolver.
+# It manages the package, service, configuration file, control keys and
+# support files.
+#
+# The configuration file is concatenated from samples of server et. al.,
+# stub-zone and forward-zone. The latter two are created independently
+# from the server settings, by defines which can be used by other classes
+# and modules.
+#
+# Control keys can be created with the unbound-control-setup program,
+# and is enabled by default. These are neccessary to be able to control
+# unbound (restart, reload etc) with the unbound-control program.
+#
+# The auto-trust-anchor-file 'root.key' can be created with the unbound-anchor
+# program, and is enabled by default.
+#
+# The root-hints files named.cache can be managed, but have to be provided by
+# the user. See the documentation in manifests/root_hints.pp for how to proceede.
+# This functionality is not enabled by default.
+#
+# === Parameters
+#
+# [*settings*]
+# Hash containing the settings as key value pairs.
+#
+# [*ssl*]
+# Mange unbound-control certificates? True or false, true by default.
+#
+# [*anchor*]
+# Manage root.key? True or false, true by default.
+#
+# [*root_hints*]
+# Manage named.cache? True or false, false by default.
+#
+# === Examples
+#
+# class { 'unbound':
+# root_hints => true,
+# settings => {
+# server => {
+# verbosity => '1',
+# interface => [
+# '127.0.0.1',
+# '::1',
+# $::ipaddress,
+# ],
+# outgoing-interface => $::ipaddress,
+# access-control => [
+# '127.0.0.0/8 allow',
+# '::1 allow',
+# '10.0.0.0/8 allow',
+# ],
+# root-hints => '"/var/unbound/etc/named.cache"',
+# private-address => [
+# '10.0.0.0/8',
+# '172.16.0.0/12',
+# '192.168.0.0/16',
+# ],
+# private-domain => "\"$::domain\"",
+# auto-trust-anchor-file => '"/var/unbound/etc/root.key"',
+# },
+# python => { },
+# remote-control => {
+# control-enable => 'yes',
+# control-interface => [
+# '127.0.0.1',
+# '::1',
+# ],
+# },
+# }
+# }
+#
+# See manifests/stub.pp and manifests/forward.pp for examples on how to create
+# sub zones and forward zones repectively.
+#
+class unbound (
+ $settings,
+ $anchor = true,
+ $root_hints = false,
+ $ssl = true,
+) inherits unbound::params {
+
+ include concat::setup
+ include unbound::package
+ include unbound::service
+
+ validate_hash($settings)
+ validate_bool($anchor)
+ validate_bool($root_hints)
+ validate_bool($ssl)
+
+ if $anchor {
+ include unbound::anchor
+ }
+
+ if $root_hints {
+ include unbound::root_hints
+ }
+
+ if $ssl {
+ include unbound::ssl
+ }
+
+ $real_settings = $settings
+
+ concat { $unbound::params::config:
+ require => Class['unbound::package'],
+ }
+
+ concat::fragment { 'unbound server':
+ target => $unbound::params::config,
+ content => template('unbound/unbound.conf.erb'),
+ order => 1,
+ }
+}
diff --git a/puppet/modules/unbound/manifests/package.pp b/puppet/modules/unbound/manifests/package.pp
new file mode 100644
index 00000000..b9b44f16
--- /dev/null
+++ b/puppet/modules/unbound/manifests/package.pp
@@ -0,0 +1,15 @@
+# == Class: unbound::package
+#
+# Manages the unbound package.
+#
+# === Examples
+#
+# include unbound::package
+#
+class unbound::package {
+ include unbound::params
+
+ package { $unbound::params::package:
+ ensure => installed,
+ }
+}
diff --git a/puppet/modules/unbound/manifests/params.pp b/puppet/modules/unbound/manifests/params.pp
new file mode 100644
index 00000000..fc043e24
--- /dev/null
+++ b/puppet/modules/unbound/manifests/params.pp
@@ -0,0 +1,42 @@
+class unbound::params {
+ case $::osfamily {
+ 'OpenBSD': {
+ $package = 'unbound'
+ $service = 'unbound'
+ $hasstatus = true
+ $dir = '/var/unbound/etc'
+ $logfile = '/var/unbound/dev/log'
+ $control_setup = '/usr/local/sbin/unbound-control-setup'
+ $unbound_anchor = '/usr/local/sbin/unbound-anchor'
+ $extended_service = 'unbound::service::openbsd'
+ $unbound_flags = ''
+ $user = '_unbound'
+ $group = '_unbound'
+ }
+ 'ubuntu', 'debian': {
+ $package = 'unbound'
+ $service = 'unbound'
+ $hasstatus = true
+ $dir = '/etc/unbound'
+ $logfile = ''
+ $control_setup = '/usr/sbin/unbound-control-setup'
+ $unbound_anchor = '/usr/sbin/unbound-anchor'
+ $unbound_flags = ''
+ $user = 'unbound'
+ $group = 'unbound'
+ }
+ default: {
+ fail("Class[unbound] is not supported by your operating system: ${::operatingsystem}")
+ }
+ }
+
+ $config = "${dir}/unbound.conf"
+ $control_certs = [
+ "${dir}/unbound_control.key",
+ "${dir}/unbound_control.pem",
+ "${dir}/unbound_server.key",
+ "${dir}/unbound_server.pem",
+ ]
+ $anchor = "${dir}/root.key"
+ $root_hints = "${dir}/named.cache"
+}
diff --git a/puppet/modules/unbound/manifests/root_hints.pp b/puppet/modules/unbound/manifests/root_hints.pp
new file mode 100644
index 00000000..12594956
--- /dev/null
+++ b/puppet/modules/unbound/manifests/root_hints.pp
@@ -0,0 +1,35 @@
+# == Class: unbound::root_hints
+#
+# The unbound::root_hints class manages the root-hints named.cache file.
+# The default mount point is /module_data, which should be installed
+# and populated with a the named.cache file before implementing this
+# class. See unbound.conf(5) or the default configuration file for
+# how to retrieve such a file.
+#
+# === Parameters
+#
+# [*_mount*]
+# Meta parameter for specifying an alternate mount path.
+#
+# === Examples
+#
+# class { 'unbound::root_hints':
+# $_mount = '/modules/unbound',
+# }
+#
+# include unbound::root_hints
+#
+class unbound::root_hints (
+ $_mount = "/module_data/unbound",
+) {
+ include unbound::params
+
+ file { $unbound::params::root_hints:
+ ensure => file,
+ owner => $unbound::params::user,
+ group => $unbound::params::group,
+ mode => '0644',
+ source => "puppet://${_mount}/named.cache",
+ before => Class['unbound::service'],
+ }
+}
diff --git a/puppet/modules/unbound/manifests/service.pp b/puppet/modules/unbound/manifests/service.pp
new file mode 100644
index 00000000..f96f453e
--- /dev/null
+++ b/puppet/modules/unbound/manifests/service.pp
@@ -0,0 +1,22 @@
+# == Class: unbound::service
+#
+# Manages the unbound service. If $unbound::params::extended_service
+# is true then OS specific service things are included.
+#
+# === Examples
+#
+# include unbound::service
+#
+class unbound::service {
+ include unbound::params
+
+ if $unbound::params::extended_service {
+ class { $unbound::params::extended_service: }
+ }
+
+ service { $unbound::params::service:
+ ensure => running,
+ hasstatus => $unbound::params::hasstatus,
+ subscribe => File[$unbound::params::config],
+ }
+}
diff --git a/puppet/modules/unbound/manifests/service/openbsd.pp b/puppet/modules/unbound/manifests/service/openbsd.pp
new file mode 100644
index 00000000..916a7ce9
--- /dev/null
+++ b/puppet/modules/unbound/manifests/service/openbsd.pp
@@ -0,0 +1,21 @@
+# == Class: unbound::service::openbsd
+#
+# Service things specific for OpenBSD. Sets the unbound_flags variable in
+# /etc/rc.conf.local, and appends the path to the log device to syslogd_flags.
+#
+# === Examples
+#
+# include unbound::service::openbsd
+#
+class unbound::service::openbsd {
+ rcconf { 'unbound_flags':
+ value => $unbound::params::unbound_flags,
+ }
+
+ # syslogd_flags needs one -a dir per chrooted service. Each can be a separate
+ # line, so don't use rcconf.
+ file_line { 'unbound syslogd_flags':
+ path => '/etc/rc.conf.local',
+ line => "syslogd_flags=\"\${syslogd_flags} -a ${unbound::params::logfile}\"";
+ }
+}
diff --git a/puppet/modules/unbound/manifests/ssl.pp b/puppet/modules/unbound/manifests/ssl.pp
new file mode 100644
index 00000000..e0cff172
--- /dev/null
+++ b/puppet/modules/unbound/manifests/ssl.pp
@@ -0,0 +1,25 @@
+# == Class: unbound::ssl
+#
+# unbound::ssl creates ssl certificates for controlling unbound with unbound-control,
+# using the unbound-control-setup program. Furthermore, the class manages the mode and user of the certificates themselves.
+#
+# === Examples
+#
+# include unbound::ssl
+#
+class unbound::ssl {
+ include unbound::params
+
+ file { $unbound::params::control_certs:
+ owner => $unbound::params::user,
+ group => $unbound::params::gruop,
+ mode => '0440',
+ require => Exec[$unbound::params::control_setup],
+ }
+
+ exec { $unbound::params::control_setup:
+ command => "${unbound::params::control_setup} -d ${unbound::params::dir}",
+ creates => $unbound::params::control_certs,
+ before => Class['unbound::service'],
+ }
+}
diff --git a/puppet/modules/unbound/manifests/stub.pp b/puppet/modules/unbound/manifests/stub.pp
new file mode 100644
index 00000000..02797fdb
--- /dev/null
+++ b/puppet/modules/unbound/manifests/stub.pp
@@ -0,0 +1,32 @@
+# == Define: unbound::stub
+#
+# Creates a stub-zone. $settings is a hash containing the settings.
+# The name of the resource is used as the 'name' of the zone.
+#
+# === Parameters
+#
+# [*settings*]
+# Hash containing the settings as key value pairs.
+#
+# === Examples
+#
+# unbound::stub { $::domain:
+# settings => {
+# stub-addr => '192.168.1.1',
+# },
+# }
+#
+define unbound::stub (
+ $settings,
+) {
+ include unbound::params
+
+ $zone_name = { name => "\"${title}\"" }
+ $real_settings = { stub-zone => merge($zone_name, $settings) }
+
+ concat::fragment { "unbound ${title}":
+ target => $unbound::params::config,
+ content => template('unbound/unbound.conf.erb'),
+ order => 2,
+ }
+}
diff --git a/puppet/modules/unbound/metadata.json b/puppet/modules/unbound/metadata.json
new file mode 100644
index 00000000..3c20ad4f
--- /dev/null
+++ b/puppet/modules/unbound/metadata.json
@@ -0,0 +1,50 @@
+{
+ "source": "UNKNOWN",
+ "types": [
+
+ ],
+ "project_page": "UNKNOWN",
+ "checksums": {
+ "manifests/service.pp": "baf263d0a562d6543c7418acf1e79cc2",
+ "tests/anchor.pp": "c6d270f2a0f448d7cebb6aed28b60998",
+ "LICENSE": "f8a2562cac0b3859771886422f703d27",
+ "spec/spec_helper.rb": "a55d1e6483344f8ec6963fcb2c220372",
+ "tests/service/openbsd.pp": "624a9db21c7bf277eec24186c490f4a5",
+ "Modulefile": "f1f67d825f8ef998667be8164f18744c",
+ "manifests/package.pp": "53a9d2e732f5690967f31e90d4eaaa99",
+ "manifests/init.pp": "92245e6671f2c3aef459c766c3df522d",
+ "tests/ssl.pp": "25439a06abaef7b5a2d778719a3d8c95",
+ "tests/service.pp": "106da53de4dd52a3e24d61af51263c00",
+ "tests/root_hints.pp": "7c9a9faa7350d023a00538812b9e3383",
+ "manifests/service/openbsd.pp": "fec14ed74ccf3a4c9a9d39a9870b992e",
+ "manifests/params.pp": "b949b2ac149f62130b0462a268c2a3ea",
+ "README": "6b5a94def03194686b83121ee218debd",
+ "tests/forward.pp": "29b51124459bc4fa265681cb0873afb7",
+ "manifests/root_hints.pp": "8c6879c961c8684dae69dbd13cea5efe",
+ "tests/params.pp": "f8662ff6d212159f10aac3186d010605",
+ "manifests/ssl.pp": "cc6e32a92c843bebbe5c05d7dc530c9b",
+ "tests/stub.pp": "34ca449ff833e3b1719d23f2875385d8",
+ "tests/init.pp": "9105221e2b9c942579d7e88f41a89b10",
+ "manifests/forward.pp": "07b209d883cf9ce1888a8427357a367f",
+ "tests/package.pp": "e1236eb6d345f5368f054f0e847a6a76",
+ "templates/unbound.conf.erb": "f5ee6f6444ad705c8494b8ec04e21d5b",
+ "manifests/stub.pp": "a0421e88c96df10cca872715c808ad5a",
+ "manifests/anchor.pp": "4ddf763591743e0505bf62a859e11a2d"
+ },
+ "license": "ISC",
+ "dependencies": [
+ {
+ "version_requirement": ">= 3.2.0",
+ "name": "puppetlabs/stdlib"
+ },
+ {
+ "version_requirement": ">= 0.1.0",
+ "name": "oppegaard/openbsd"
+ }
+ ],
+ "version": "0.1.0",
+ "summary": "The unbound module manages unbound",
+ "description": "This module manages unbound, the reqursive caching DNS resolver.\n It manages the package, service, configuration file, control keys and support\n files.",
+ "author": "Martin Oppegaard",
+ "name": "oppegaard-unbound"
+} \ No newline at end of file
diff --git a/puppet/modules/unbound/spec/spec_helper.rb b/puppet/modules/unbound/spec/spec_helper.rb
new file mode 100644
index 00000000..5fda5887
--- /dev/null
+++ b/puppet/modules/unbound/spec/spec_helper.rb
@@ -0,0 +1,17 @@
+dir = File.expand_path(File.dirname(__FILE__))
+$LOAD_PATH.unshift File.join(dir, 'lib')
+
+require 'mocha'
+require 'puppet'
+require 'rspec'
+require 'spec/autorun'
+
+Spec::Runner.configure do |config|
+ config.mock_with :mocha
+end
+
+# We need this because the RAL uses 'should' as a method. This
+# allows us the same behaviour but with a different method name.
+class Object
+ alias :must :should
+end
diff --git a/puppet/modules/unbound/templates/unbound.conf.erb b/puppet/modules/unbound/templates/unbound.conf.erb
new file mode 100644
index 00000000..ad93965c
--- /dev/null
+++ b/puppet/modules/unbound/templates/unbound.conf.erb
@@ -0,0 +1,8 @@
+<% @real_settings.sort.each do |section, settings| -%>
+<%= "#{section}:" %>
+<% settings.sort.each do |key, val| -%>
+<% [val].flatten.each do |val| -%>
+<%= " #{key}: #{val}" %>
+<% end -%>
+<% end %>
+<% end -%>
diff --git a/puppet/modules/unbound/tests/anchor.pp b/puppet/modules/unbound/tests/anchor.pp
new file mode 100644
index 00000000..ce73902a
--- /dev/null
+++ b/puppet/modules/unbound/tests/anchor.pp
@@ -0,0 +1,2 @@
+include unbound::params
+include unbound::anchor
diff --git a/puppet/modules/unbound/tests/forward.pp b/puppet/modules/unbound/tests/forward.pp
new file mode 100644
index 00000000..0d245e61
--- /dev/null
+++ b/puppet/modules/unbound/tests/forward.pp
@@ -0,0 +1,7 @@
+include concat::setup
+include unbound
+unbound::forward { 'example.com':
+ settings => {
+ forward-addr => '127.0.0.1',
+ },
+}
diff --git a/puppet/modules/unbound/tests/init.pp b/puppet/modules/unbound/tests/init.pp
new file mode 100644
index 00000000..89af1770
--- /dev/null
+++ b/puppet/modules/unbound/tests/init.pp
@@ -0,0 +1,26 @@
+# The baseline for module testing used by Puppet Labs is that each manifest
+# should have a corresponding test manifest that declares that class or defined
+# type.
+#
+# Tests are then run by using puppet apply --noop (to check for compilation errors
+# and view a log of events) or by fully applying the test in a virtual environment
+# (to compare the resulting system state to the desired state).
+#
+# Learn more about module testing here: http://docs.puppetlabs.com/guides/tests_smoke.html
+#
+include concat::setup
+include unbound::package
+include unbound::service
+include unbound::anchor
+include unbound::ssl
+
+class { 'unbound':
+ anchor => false,
+ root_hints => false,
+ ssl => false,
+ settings => {
+ server => { },
+ python => { },
+ remote-control => { },
+ },
+}
diff --git a/puppet/modules/unbound/tests/package.pp b/puppet/modules/unbound/tests/package.pp
new file mode 100644
index 00000000..0360b52f
--- /dev/null
+++ b/puppet/modules/unbound/tests/package.pp
@@ -0,0 +1,2 @@
+include unbound::params
+include unbound::package
diff --git a/puppet/modules/unbound/tests/params.pp b/puppet/modules/unbound/tests/params.pp
new file mode 100644
index 00000000..7cd72bd3
--- /dev/null
+++ b/puppet/modules/unbound/tests/params.pp
@@ -0,0 +1 @@
+include unbound::params
diff --git a/puppet/modules/unbound/tests/root_hints.pp b/puppet/modules/unbound/tests/root_hints.pp
new file mode 100644
index 00000000..3ce21ed1
--- /dev/null
+++ b/puppet/modules/unbound/tests/root_hints.pp
@@ -0,0 +1,2 @@
+include unbound::params
+include unbound::root_hints
diff --git a/puppet/modules/unbound/tests/service.pp b/puppet/modules/unbound/tests/service.pp
new file mode 100644
index 00000000..0fb73df1
--- /dev/null
+++ b/puppet/modules/unbound/tests/service.pp
@@ -0,0 +1,2 @@
+include unbound::params
+include unbound::service
diff --git a/puppet/modules/unbound/tests/service/openbsd.pp b/puppet/modules/unbound/tests/service/openbsd.pp
new file mode 100644
index 00000000..3e8696c0
--- /dev/null
+++ b/puppet/modules/unbound/tests/service/openbsd.pp
@@ -0,0 +1 @@
+include unbound::service::openbsd
diff --git a/puppet/modules/unbound/tests/ssl.pp b/puppet/modules/unbound/tests/ssl.pp
new file mode 100644
index 00000000..d7111977
--- /dev/null
+++ b/puppet/modules/unbound/tests/ssl.pp
@@ -0,0 +1,2 @@
+include unbound::params
+include unbound::ssl
diff --git a/puppet/modules/unbound/tests/stub.pp b/puppet/modules/unbound/tests/stub.pp
new file mode 100644
index 00000000..b1477f9d
--- /dev/null
+++ b/puppet/modules/unbound/tests/stub.pp
@@ -0,0 +1,7 @@
+include concat::setup
+include unbound::params
+unbound::stub { 'example.com':
+ settings => {
+ stub-addr => '127.0.0.1',
+ },
+}