diff --git a/README.md b/README.md index 7c88898..b1627fe 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,15 @@ file will not be overwritten. Only the `zone_type` is required. If `domain` is unspecified, the title of the `bind::zone` declaration will be used as the domain. +A master zone with a zone file managed directly by Puppet: + + bind::zone { 'example.org': + zone_type => 'master', + dynamic => false, + source => 'puppet:///dns/db.example.org', + allow_transfers => [ 'secondary-dns', ], + } + A master zone with DNSSec disabled which allows updates using a TSIG key and zone transfers to servers matching an acl: diff --git a/manifests/zone.pp b/manifests/zone.pp index 6522960..097441e 100644 --- a/manifests/zone.pp +++ b/manifests/zone.pp @@ -3,6 +3,7 @@ define bind::zone ( $zone_type, $domain = '', + $dynamic = true, $masters = '', $transfer_source = '', $allow_updates = '', @@ -16,74 +17,120 @@ define bind::zone ( $forward = '', $source = '', ) { - $cachedir = $bind::cachedir + # where there is a zone, there is a server + include bind + $cachedir = $::bind::cachedir + $_domain = pick($domain, $name) - if $domain == '' { - $_domain = $name - } else { - $_domain = $domain + unless !($masters != '' and ! member(['slave', 'stub'], $zone_type)) { + fail("masters may only be provided for bind::zone resources with zone_type 'slave' or 'stub'") } - $has_zone_file = $zone_type ? { - 'master' => true, - 'slave' => true, - 'hint' => true, - 'stub' => true, - default => false, + unless !($transfer_source != '' and ! member(['slave', 'stub'], $zone_type)) { + fail("transfer_source may only be provided for bind::zone resources with zone_type 'slave' or 'stub'") } - if $has_zone_file { - if $zone_type == 'master' and $source != '' { - $_source = $source - } else { - $_source = 'puppet:///modules/bind/db.empty' - } + unless !($allow_update != '' and ! $dynamic) { + fail("allow_update may only be provided for bind::zone resources with dynamic set to true") + } + unless !($dnssec and ! $dynamic) { + fail("dnssec may only be true for bind::zone resources with dynamic set to true") + } + + unless !($key_directory != '' and ! $dnssec) { + fail("key_directory may only be provided for bind::zone resources with dnssec set to true") + } + + unless !($allow_notify != '' and ! member(['slave', 'stub'], $zone_type)) { + fail("allow_notify may only be provided for bind::zone resources with zone_type 'slave' or 'stub'") + } + + unless !($forwarders != '' and $zone_type != 'forward') { + fail("forwarders may only be provided for bind::zone resources with zone_type 'forward'") + } + + unless !($forward != '' and $zone_type != 'forward') { + fail("forward may only be provided for bind::zone resources with zone_type 'forward'") + } + + unless !($source != '' and ! member(['master', 'hint'], $zone_type)) { + fail("source may only be provided for bind::zone resources with zone_type 'master' or 'hint'") + } + + $zone_file_mode = $zone_type ? { + 'master' => $dynamic ? { + true => 'init', + false => 'managed', + }, + 'slave' => 'allowed', + 'hint' => 'managed', + 'stub' => 'allowed', + default => 'absent', + } + + if member(['init', 'managed', 'allowed'], $zone_file_mode) { file { "${cachedir}/${name}": ensure => directory, - owner => $bind::params::bind_user, - group => $bind::params::bind_group, + owner => $::bind::params::bind_user, + group => $::bind::params::bind_group, mode => '0755', require => Package['bind'], } - file { "${cachedir}/${name}/${_domain}": - ensure => present, - owner => $bind::params::bind_user, - group => $bind::params::bind_group, - mode => '0644', - replace => false, - source => $_source, - audit => [ content ], + if member(['init', 'managed'], $zone_file_mode) { + file { "${cachedir}/${name}/${_domain}": + ensure => present, + owner => $::bind::params::bind_user, + group => $::bind::params::bind_group, + mode => '0644', + replace => ($zone_file_mode == 'managed'), + source => pick($source, 'puppet:///modules/bind/db.empty'), + audit => [ content ], + } } - if $dnssec { - exec { "dnssec-keygen-${name}": - command => "/usr/local/bin/dnssec-init '${cachedir}' '${name}'\ - '${_domain}' '${key_directory}'", - cwd => $cachedir, - user => $bind::params::bind_user, - creates => "${cachedir}/${name}/${_domain}.signed", - timeout => 0, # crypto is hard - require => [ - File['/usr/local/bin/dnssec-init'], - File["${cachedir}/${name}/${_domain}"] - ], - } - - file { "${cachedir}/${name}/${_domain}.signed": - owner => $bind::params::bind_user, - group => $bind::params::bind_group, - mode => '0644', - audit => [ content ], + if $zone_file_mode == 'managed' { + exec { "rndc reload ${_domain}": + command => "/usr/sbin/rndc reload ${_domain}", + user => $::bind::params::bind_user, + refreshonly => true, + require => Service['bind'], + subscribe => File["${cachedir}/${name}/${_domain}"], } } + } elsif $zone_file_mode == 'absent' { + file { "${cachedir}/${name}": + ensure => absent, + } } - file { "${bind::confdir}/zones/${name}.conf": + if $dnssec { + exec { "dnssec-keygen-${name}": + command => "/usr/local/bin/dnssec-init '${cachedir}' '${name}'\ + '${_domain}' '${key_directory}'", + cwd => $cachedir, + user => $::bind::params::bind_user, + creates => "${cachedir}/${name}/${_domain}.signed", + timeout => 0, # crypto is hard + require => [ + File['/usr/local/bin/dnssec-init'], + File["${cachedir}/${name}/${_domain}"] + ], + } + + file { "${cachedir}/${name}/${_domain}.signed": + owner => $::bind::params::bind_user, + group => $::bind::params::bind_group, + mode => '0644', + audit => [ content ], + } + } + + file { "${::bind::confdir}/zones/${name}.conf": ensure => present, owner => 'root', - group => $bind::params::bind_group, + group => $::bind::params::bind_group, mode => '0644', content => template('bind/zone.conf.erb'), notify => Service['bind'], diff --git a/metadata.json b/metadata.json index 8d00a00..d825440 100644 --- a/metadata.json +++ b/metadata.json @@ -27,6 +27,7 @@ } ], "dependencies": [ + { "name": "puppetlabs/stdlib" }, { "name": "puppetlabs/concat", "version_requirement": ">=1.0.0 <2.0.0" }, { "name": "ripienaar/module_data" } ] diff --git a/templates/zone.conf.erb b/templates/zone.conf.erb index 98a4fcf..4be5f17 100644 --- a/templates/zone.conf.erb +++ b/templates/zone.conf.erb @@ -2,35 +2,33 @@ # This file managed by puppet - changes will be lost zone "<%= @_domain %>" { type <%= @zone_type %>; -<%- if @has_zone_file -%> -<%- if @dnssec -%> +<%- if @dnssec -%> auto-dnssec maintain; -<%- if @key_directory and @key_directory != '' -%> +<%- if @key_directory and @key_directory != '' -%> key-directory "<%= @key_directory %>"; -<%- else -%> - key-directory "<%= @cachedir %>/<%= @name %>"; -<%- end -%> - file "<%= @cachedir %>/<%= @name %>/<%= @_domain %>.signed"; <%- else -%> + key-directory "<%= @cachedir %>/<%= @name %>"; +<%- end -%> + file "<%= @cachedir %>/<%= @name %>/<%= @_domain %>.signed"; +<%- elsif %w(init managed allowed).include? @zone_file_mode -%> file "<%= @cachedir %>/<%= @name %>/<%= @_domain %>"; -<%- end -%> -<%- unless @zone_type == 'stub' -%> +<%- end -%> +<%- if %w(master slave).include? @zone_type -%> notify <%= @ns_notify ? 'yes' : 'no' %>; -<%- end -%> -<%- if @also_notify and @also_notify != '' -%> +<%- end -%> +<%- if @also_notify and @also_notify != '' -%> also-notify { -<%- Array(@also_notify).each do |server| -%> +<%- Array(@also_notify).each do |server| -%> <%= server %>; -<%- end -%> - }; <%- end -%> -<%- if @allow_notify and @allow_notify != '' -%> + }; +<%- end -%> +<%- if @allow_notify and @allow_notify != '' -%> allow-notify { -<%- Array(@allow_notify).each do |server| -%> +<%- Array(@allow_notify).each do |server| -%> <%= server %>; -<%- end -%> - }; <%- end -%> + }; <%- end -%> <%- if @masters and @masters != '' -%> masters {