diff --git a/.fixtures.yml b/.fixtures.yml new file mode 100644 index 000000000..2c8302a56 --- /dev/null +++ b/.fixtures.yml @@ -0,0 +1,13 @@ +fixtures: + repositories: + concat: + repo: "https://github.com/puppetlabs/puppetlabs-concat.git" + ref: "1.2.1" + stdlib: + repo: "https://github.com/puppetlabs/puppetlabs-stdlib.git" + ref: "4.12.0" + assert: + repo: "https://github.com/binford2k/puppet-assert.git" + ref: "v0.2.1" + symlinks: + bind: "#{source_dir}" diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..14ff7f944 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.bundle +spec/fixtures/manifests +spec/fixtures/modules +.vagrant/ +log/ diff --git a/.rspec b/.rspec new file mode 100644 index 000000000..8c18f1abd --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--format documentation +--color diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..e1d798016 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,84 @@ +--- +language: ruby +sudo: false +bundler_args: --jobs=3 --retry=3 +cache: bundler +script: + - bundle exec rake test +notifications: + email: false +matrix: + fast_finish: true + include: + # On Puppet 5.x + - rvm: '2.1' + - rvm: '2.3' + sudo: required + services: docker + env: PUPPET_INSTALL_VERSION='5' PUPPET_AGENT_INSTALL_VERSION='5.3.3' PUPPET_COLLECTION=puppet5 RS_SET="centos-7-docker" + script: bundle exec rake beaker + - rvm: '2.3' + sudo: required + services: docker + env: PUPPET_INSTALL_VERSION='5' PUPPET_AGENT_INSTALL_VERSION='5.3.3' PUPPET_COLLECTION=puppet5 RS_SET="ubuntu-14.04-docker" + script: bundle exec rake beaker + - rvm: '2.3' + sudo: required + services: docker + env: PUPPET_INSTALL_VERSION='5' PUPPET_AGENT_INSTALL_VERSION='5.3.3' PUPPET_COLLECTION=puppet5 RS_SET="debian-82-docker" + script: bundle exec rake beaker + - rvm: '2.3' + - rvm: '2.4' + # On Puppet 4.x + - rvm: '1.9' + env: PUPPET_GEM_VERSION='~> 4.8.0' + - rvm: '2.0' + env: PUPPET_GEM_VERSION='~> 4.8.0' + - rvm: '2.3' + sudo: required + services: docker + env: PUPPET_INSTALL_VERSION='4' PUPPET_AGENT_INSTALL_VERSION='1.10.7' RS_SET="centos-7-docker" + script: bundle exec rake beaker + - rvm: '2.3' + sudo: required + services: docker + env: PUPPET_INSTALL_VERSION='4' PUPPET_AGENT_INSTALL_VERSION='1.10.7' RS_SET="ubuntu-14.04-docker" + script: bundle exec rake beaker + - rvm: '2.3' + sudo: required + services: docker + env: PUPPET_INSTALL_VERSION='4' PUPPET_AGENT_INSTALL_VERSION='1.10.7' RS_SET="debian-82-docker" + script: bundle exec rake beaker + - rvm: '2.1' + env: PUPPET_GEM_VERSION='~> 4' + - rvm: '2.3' + env: PUPPET_GEM_VERSION='~> 4' + - rvm: '2.4' + env: PUPPET_GEM_VERSION='~> 4' + # On Puppet 3.x + - rvm: '1.8' + env: PUPPET_GEM_VERSION='~> 3.2.0' + - rvm: '1.9' + env: PUPPET_GEM_VERSION='~> 3' + - rvm: '2.0' + env: PUPPET_GEM_VERSION='~> 3' + - rvm: '2.3' + sudo: required + services: docker + env: PUPPET_INSTALL_VERSION='3.8.7' RS_SET="ubuntu-14.04-docker" + script: bundle exec rake beaker + - rvm: '2.3' + sudo: required + services: docker + env: PUPPET_INSTALL_VERSION='3.8.7' RS_SET="debian-78-docker" + script: bundle exec rake beaker + - rvm: '2.3' + sudo: required + services: docker + env: PUPPET_INSTALL_VERSION='3.8.7' RS_SET="centos-7-docker" + script: bundle exec rake beaker + # On default Puppet 2.x + - rvm: '1.8' + env: PUPPET_GEM_VERSION='~> 2' + - rvm: '1.9' + env: PUPPET_GEM_VERSION='~> 2' diff --git a/Gemfile b/Gemfile index 4fe28936c..14b32bb1a 100644 --- a/Gemfile +++ b/Gemfile @@ -1,9 +1,23 @@ -# A sample Gemfile -source "https://rubygems.org" +source ENV['GEM_SOURCE'] || 'https://rubygems.org/' -# gem "rails" +puppet_ver = ENV['PUPPET_GEM_VERSION'] || '~> 5' + +gem 'rspec', '~> 3.1.0' gem 'rspec-puppet' gem 'rake' -gem 'puppet' +gem 'puppet', puppet_ver gem 'puppetlabs_spec_helper' -gem 'puppet-lint' \ No newline at end of file +gem 'puppet-lint' +group :acceptance do + gem 'beaker-rspec', :require => false + gem 'beaker-pe', :require => false + gem 'beaker-module_install_helper', '~> 0.1.0', :require => false + gem 'puppet-examples-helpers', :require => false + gem 'vagrant-wrapper', :require => false + gem 'vagrant-wrapper', :require => false +end if RUBY_VERSION > '2.1' + +group :development do + gem 'pry' + gem 'pry-byebug' +end if RUBY_VERSION > '2.1' diff --git a/Gemfile.lock b/Gemfile.lock index 29320b0c6..ceae1497f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,41 +1,45 @@ GEM remote: https://rubygems.org/ specs: - diff-lcs (1.2.4) + diff-lcs (1.3) facter (1.7.0) - hiera (1.2.0) - json_pure - json_pure (1.7.7) - metaclass (0.0.1) - mocha (0.13.3) + metaclass (0.0.4) + mocha (1.3.0) metaclass (~> 0.0.1) - puppet (3.1.1) - facter (~> 1.6) - hiera (~> 1.0) - puppet-lint (0.3.2) - puppetlabs_spec_helper (0.4.1) - mocha (>= 0.10.5) + puppet (2.7.26) + facter (~> 1.5) + puppet-lint (1.1.0) + puppet-syntax (2.4.1) rake - rspec (>= 2.9.0) - rspec-puppet (>= 0.1.1) - rake (10.0.4) - rspec (2.13.0) - rspec-core (~> 2.13.0) - rspec-expectations (~> 2.13.0) - rspec-mocks (~> 2.13.0) - rspec-core (2.13.1) - rspec-expectations (2.13.0) - diff-lcs (>= 1.1.3, < 2.0) - rspec-mocks (2.13.1) - rspec-puppet (0.1.6) + puppetlabs_spec_helper (1.1.1) + mocha + puppet-lint + puppet-syntax + rake + rspec-puppet + rake (10.5.0) + rspec (3.1.0) + rspec-core (~> 3.1.0) + rspec-expectations (~> 3.1.0) + rspec-mocks (~> 3.1.0) + rspec-core (3.1.7) + rspec-support (~> 3.1.0) + rspec-expectations (3.1.2) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.1.0) + rspec-mocks (3.1.3) + rspec-support (~> 3.1.0) + rspec-puppet (2.6.9) rspec + rspec-support (3.1.2) PLATFORMS ruby DEPENDENCIES - puppet + puppet (~> 2) puppet-lint puppetlabs_spec_helper rake + rspec (~> 3.1.0) rspec-puppet diff --git a/README.md b/README.md index 9f7f9690e..1c43ee826 100644 --- a/README.md +++ b/README.md @@ -7,22 +7,61 @@ and manage its DNS zone files. * `bind` : Main class to install and enable the server. * `bind::server::conf` : Main definition to configure the server. +* `bind::zone::definition` : Definition to add zone to main server configuration file and create zone file. +* `bind::zone::record` : Definition to add records into zone file. * `bind::server::file` : Definition to manage zone files. * `bind::package` : Class to install the server package (included from `bind`) * `bind::service` : Class to manage the server service (included from `bind`) + The split between `bind` and `bind::server::conf` allows to use a static file or a different template-based file for the main `named.conf` file if needed, while still using this module for the main package, service and managing zone files. This is useful if you have a large and/or complex named.conf file. Note that you may also use the `bind::package` and `bind::service` classes on their own, though you won't need to if you use the main class, which includes -them both. +them both. In order to add zone definition to already existed named.conf file and add zone file you can use `bind::zone::definition`. If you want to just add record to existed file zone use `bind::zone::record`. ## Examples -Here is a typical LAN recursive caching DNS server configuration : +Here is a typical DNS server configuration : +```puppet +include bind +bind::server::conf { '/etc/named.conf': + listen_on_addr => [ 'any' ], + listen_on_v6_addr => [ 'any' ], + forwarders => [ '8.8.8.8', '8.8.4.4' ], + allow_query => [ 'localnets' ], +} +bind::zone::definition { 'dev.internal': + definition_file => '/etc/named.conf', + zone_file => '/var/named/dev.internal.zone', + zone_type => 'master', + allow_update => 'none', + soa_nameserver => 'dev.internal', + soa_contact => 'root.localhost', + ttl => '1800', + minimum_ttl => '3H', + refresh => '1D', + retry => '1H', + expire => '1W', + serial => '20171208', # for example current date +} + +Bind::Zone::Record { target_file => '/var/named/dev.internal.zone' } + +bind::zone::record { + 'NS_server_node1.dev.internal': rname => '@', rtype => 'NS', rdata => 'node1.dev.internal', zone_name => 'dev.internal'; + 'node1.dev.internal': rname => 'node1', rtype => 'A', rdata => '192.168.33.10', zone_name => 'dev.internal'; +} + +``` +Zone definition in /etc/named.conf and zone file (i.e /var/named/dev.internal.zone) can be add with directive `bind::zone::definition`. +If named.conf file oraz zone file is not correct, then resource `assert` raise error and reload of bind service won't be done. Zone record can be add with directive `bind::zone::record`. + + +Here is anther way to set a typical LAN recursive caching DNS server configuration : ```puppet include bind bind::server::conf { '/etc/named.conf': @@ -49,6 +88,14 @@ The zone files for the above could then be managed like this : bind::server::file { 'myzone.lan': source => 'puppet:///modules/mymodule/dns/myzone.lan', } +# Here you can add new records to myzone.lan file, without changing source file +Bind::Zone::Record { target_file => '/var/named/myzone.lan' } + +bind::zone::record { + 'NS_server_node1.myzone.lan': rname => '@', rtype => 'NS', rdata => 'node1.myzone.lan', zone_name => 'myzone.lan'; + 'node1.myzone.lan': rname => 'node1', rtype => 'A', rdata => '192.168.33.10', zone_name => 'myzone.lan'; + 'node2.myzone.lan': rname => 'node2', rdata => '192.168.33.12', zone_name => 'myzone.lan'; +} bind::server::file { '1.168.192.in-addr.arpa': source => 'puppet:///modules/mymodule/dns/1.168.192.in-addr.arpa', } @@ -121,4 +168,3 @@ bind::server::conf { }, } ``` - diff --git a/Rakefile b/Rakefile index 8eb5e7250..0990f7f10 100644 --- a/Rakefile +++ b/Rakefile @@ -10,4 +10,7 @@ rescue Bundler::BundlerError => e $stderr.puts e.message $stderr.puts "Run `bundle install` to install missing gems" exit e.status_code -end \ No newline at end of file +end + +desc 'Run all tests' +task :test => [ :syntax, :lint, :spec ] diff --git a/examples/init.pp b/examples/init.pp new file mode 100644 index 000000000..bc227492b --- /dev/null +++ b/examples/init.pp @@ -0,0 +1 @@ +include bind diff --git a/examples/server/conf.pp b/examples/server/conf.pp new file mode 100644 index 000000000..5c70b0c00 --- /dev/null +++ b/examples/server/conf.pp @@ -0,0 +1,32 @@ +# Taken from the "Sample Usage :" +include bind::server +bind::server::conf { '/etc/named.conf': + recursion => 'no', + acls => { + 'rfc1918' => [ '10/8', '172.16/12', '192.168/16' ], + }, + masters => { + 'mymasters' => [ '192.0.2.1', '198.51.100.1' ], + }, + zones => { + 'example.com' => [ + 'type master', + 'file "example.com"', + ], + 'example.org' => [ + 'type slave', + 'file "slaves/example.org"', + 'masters { mymasters; }', + ], + }, +} +bind::server::file { 'example.com': + source => 'puppet:///modules/bind/named.empty', +} +Bind::Zone::Record { target_file => '/var/named/example.com' } + +bind::zone::record { + 'NS_server_world1.example.com': rname => '@', rtype => 'NS', rdata => 'world1.example.com', zone_name => 'example.com'; + 'world1.example.com': rname => 'world1', rtype => 'A', rdata => '192.168.56.110', zone_name => 'example.com'; + 'world2.example.com': rname => 'world2', rdata => '192.168.56.112', zone_name => 'example.com'; +} diff --git a/examples/zone/bad_definition.pp b/examples/zone/bad_definition.pp new file mode 100644 index 000000000..e45e0dd34 --- /dev/null +++ b/examples/zone/bad_definition.pp @@ -0,0 +1,45 @@ +# Taken from the "Sample Usage :" +# Bug in bind::zone::record. Ther is no A for dns server. Changes don't take effect, because bind service won't be reload +include bind::server +bind::server::conf { '/etc/named.conf': + acls => { + 'rfc1918' => [ '10/8', '172.16/12', '192.168/16' ], + }, + masters => { + 'mymasters' => [ '192.0.2.1', '198.51.100.1' ], + }, + zones => { + 'example.com' => [ + 'type master', + 'file "example.com"', + ], + 'example.org' => [ + 'type slave', + 'file "slaves/example.org"', + 'masters { mymasters; }', + ], + }, +} + +bind::zone::definition { 'baddev.internal': + definition_file => '/etc/named.conf', + zone_file => '/var/named/badtest_file.com', + zone_type => 'master', + allow_update => 'none', + soa_nameserver => 'world.baddev.internal', + soa_contact => 'badworld.com', + ttl => '1800', + minimum_ttl => '3H', + refresh => '1D', + retry => '1H', + expire => '1W', + serial => '20171208', # for example current date +} + +Bind::Zone::Record { target_file => '/var/named/badtest_file.com' } + +bind::zone::record { + 'NS_server_node1.baddev.internal': rname => '@', rtype => 'NS', rdata => 'node1.baddev.internal', zone_name => 'baddev.internal'; + 'node3.baddev.internal': rname => 'node3', rtype => 'A', rdata => '192.168.32.10', zone_name => 'baddev.internal'; + 'node2.baddev.internal': rname => 'node2', rdata => '192.168.32.12', zone_name => 'dev.internal'; +} diff --git a/examples/zone/definition.pp b/examples/zone/definition.pp new file mode 100644 index 000000000..8bbf953a1 --- /dev/null +++ b/examples/zone/definition.pp @@ -0,0 +1,45 @@ +# Taken from the "Sample Usage :" +include bind::server +bind::server::conf { '/etc/named.conf': + recursion => 'no', + acls => { + 'rfc1918' => [ '10/8', '172.16/12', '192.168/16' ], + }, + masters => { + 'mymasters' => [ '192.0.2.1', '198.51.100.1' ], + }, + zones => { + 'example.com' => [ + 'type master', + 'file "example.com"', + ], + 'example.org' => [ + 'type slave', + 'file "slaves/example.org"', + 'masters { mymasters; }', + ], + }, +} + +bind::zone::definition { 'dev.internal': + definition_file => '/etc/named.conf', + zone_file => '/var/named/test_file.com', + zone_type => 'master', + allow_update => 'none', + soa_nameserver => 'world.dev.internal', + soa_contact => 'world.com', + ttl => '1800', + minimum_ttl => '3H', + refresh => '1D', + retry => '1H', + expire => '1W', + serial => '20171208', # for example current date +} + +Bind::Zone::Record { target_file => '/var/named/test_file.com' } + +bind::zone::record { + 'NS_server_node1.dev.internal': rname => '@', rtype => 'NS', rdata => 'node1.dev.internal', zone_name => 'dev.internal'; + 'node1.dev.internal': rname => 'node1', rtype => 'A', rdata => '192.168.33.10', zone_name => 'dev.internal'; + 'node2.dev.internal': rname => 'node2', rdata => '192.168.33.12', zone_name => 'dev.internal'; +} diff --git a/manifests/params.pp b/manifests/params.pp index 58f9b0bc4..2879d83ea 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -8,26 +8,34 @@ $servicename = 'named' $binduser = 'root' $bindgroup = 'named' + if $::operatingsystemrelease == '7' { + $checkpath = '/sbin/' + } + else { + $checkpath = '/usr/sbin/' + } } 'Debian': { $packagenameprefix = 'bind9' $servicename = 'bind9' $binduser = 'bind' $bindgroup = 'bind' + $checkpath = '/usr/sbin/' } 'Freebsd': { $packagenameprefix = 'bind910' $servicename = 'named' $binduser = 'bind' $bindgroup = 'bind' + $checkpath = '/sbin/' } default: { $packagenameprefix = 'bind' $servicename = 'named' $binduser = 'root' $bindgroup = 'named' + $checkpath = '/sbin/' } } } - diff --git a/manifests/server/conf.pp b/manifests/server/conf.pp index 14fcbc1fc..2f696d73e 100644 --- a/manifests/server/conf.pp +++ b/manifests/server/conf.pp @@ -80,7 +80,7 @@ # 'masters { mymasters; }', # ], # } -# keys => { +# keys => { # 'example.org-tsig' => [ # 'algorithm hmac-md5', # 'secret "aaabbbcccddd"', @@ -120,10 +120,15 @@ $views = {}, ) { - # Everything is inside a single template - file { $title: - notify => Class['::bind::service'], + include ::bind + + concat { $title: + ensure => 'present', + } + concat::fragment { "${title}_01_preamble": + target => $title, content => template('bind/named.conf.erb'), + notify => Class['::bind::service'], } } diff --git a/manifests/server/file.pp b/manifests/server/file.pp index 9468a93c9..bb6cede62 100644 --- a/manifests/server/file.pp +++ b/manifests/server/file.pp @@ -21,6 +21,8 @@ # Zone file content (usually template-based). Default: none # $ensure: # Whether the zone file should be 'present' or 'absent'. Default: present. +# $order: +# Order the fragments. Default: '15' # # Sample Usage : # bind::server::file { 'example.com': @@ -31,16 +33,19 @@ define bind::server::file ( $zonedir = '/var/named', $owner = 'root', - $group = undef, $mode = '0640', $dirmode = '0750', + $order = '15', + $ensure = undef, + $group = undef, $source = undef, $source_base = undef, $content = undef, - $ensure = undef, + ) { - include '::bind::params' + include ::bind::params + include ::bind if $group { $bindgroup = $group @@ -64,20 +69,31 @@ mode => $dirmode, } } + $file_zone = "${zonedir}/${title}" - file { "${zonedir}/${title}": - ensure => $ensure, - owner => $owner, - group => $bindgroup, - mode => $mode, - source => $zone_source, - content => $content, + concat { $file_zone: + ensure => $ensure, + owner => $owner, + group => $bindgroup, + mode => $mode, + } + if $zone_source { + $content_file = $zone_source + } + elsif $content { + $content_file = $zone_source + } + else { + fail('One of $source, $source_base and $content parametres must be given') + } + concat::fragment { "${file_zone}_01_preamble": + target => $file_zone, + source => $content_file, + order => $order, notify => Class['::bind::service'], - # For the parent directory require => [ - Class['::bind::package'], - File[$zonedir], + Class['::bind::package'], + File[$zonedir], ], } - } diff --git a/manifests/service.pp b/manifests/service.pp index db91cb70c..2ed7312dc 100644 --- a/manifests/service.pp +++ b/manifests/service.pp @@ -17,5 +17,4 @@ hasstatus => true, require => Class['bind::package'], } - } diff --git a/manifests/zone/definition.pp b/manifests/zone/definition.pp new file mode 100644 index 000000000..16f2805a2 --- /dev/null +++ b/manifests/zone/definition.pp @@ -0,0 +1,82 @@ +# == Define: bind::zone::definition +# Creates definition and content preamble for DNS zone +# Define: bind::server::conf +# +# Parameters: +# $definition_file: +# full name of the /etc/named.conf.* file, +# $zone_file: +# full name of the zone file, +# $serial: +# version of zone file +# $soa_nameserver: +# domain name, default: localhost +# $soa_contact: +# contact to dns admininistrator, default: root.localhost +# $ttl: +# time to hold data in cache, default: 604800, +# $minimum_ttl: +# minimut time to hold data in cache, default: 604800, +# $refresh: +# refresh wait time, default: 604800, +# $retry: +# retry wait time, default: 86400, +# $expire: +# time after which data is outdated, default: 2419200, +# $zone_type: +# wheather zone is master or hint, default: master, +# $path: +# path to assert command, default: /sbin, +# $allow_update: +# hostnames allowed to submit dynamic updates, default: undef, +# $origin: +# name of the domain, default: undef, + +define bind::zone::definition ( + $definition_file, + $zone_file, + $serial, + $soa_nameserver = 'localhost', + $soa_contact = 'root.localhost', + $ttl = '604800', + $minimum_ttl = '604800', + $refresh = '604800', + $retry = '86400', + $expire = '2419200', + $zone_type = 'master', + $path = $::bind::params::checkpath, + $allow_update = undef, + $origin = undef, +){ + + include ::bind + include ::bind::params + case $zone_type { + 'master', 'hint': { info("Supported zone type: ${zone_type}") } + default: { fail("Unsupported zone type: ${zone_type}") } + } + + # Add zone definition in $definition_file from bind::server::conf::concat + concat::fragment { "${definition_file}_${name}": + target => $definition_file, + content => template('bind/zone_definition.erb'), + order => '99', + } + assert { "Check nameserver file-${definition_file}": + command => "${path}named-checkconf ${definition_file}", + require => [ + Concat::Fragment["${definition_file}_${name}"] + ], + before => Class['::bind::service'], + } + if $zone_type == 'master' { + # Create zone configuration file + concat { $zone_file: + ensure => 'present', + } + concat::fragment { "${zone_file}_01_preamble": + target => $zone_file, + content => template('bind/zone_preamble.erb'), + } + } +} diff --git a/manifests/zone/record.pp b/manifests/zone/record.pp new file mode 100644 index 000000000..2f8f5cac0 --- /dev/null +++ b/manifests/zone/record.pp @@ -0,0 +1,52 @@ +# == Define: bind::zone::record +# Creates a resource record in DNS zone file +# +# Parameters: +# $target_file: +# full name of the zone file, +# $rname: +# name of person or role account dealing with this zone, can be alias, +# $rdata: +# ip or name of server-record, +# $zone_name: +# Name of zone to check validyty of zone file, +# $rtype: +# type of dns record, default: A, +# $rclass +# zone class, default: IN, +# $order: +# oreder of concat fragment, default: 99, +# $path: +# path to assert command, default: /sbin, + +define bind::zone::record ( + $target_file, + $rname, + $rdata, + $zone_name, + $rtype = 'A', + $rclass = 'IN', + $order = '99', + $path = $::bind::params::checkpath, +){ + include ::bind + include ::bind::params + + $record_data = $rtype ? { + /(NS|CNAME|PTR)/ => "${rdata}.", + default => $rdata, + } + + concat::fragment { "${target_file}_${name}": + target => $target_file, + content => "${rname}\t${rclass}\t${rtype}\t${record_data}\n", + order => $order, + } + assert { "Check zone file-${target_file}-${rname}": + command => "${path}named-checkzone ${zone_name} ${target_file}", + require => [ + Concat::Fragment["${target_file}_${name}"] + ], + before => Class['::bind::service'] + } +} diff --git a/metadata.json b/metadata.json index 0e7eb6fd5..211657139 100644 --- a/metadata.json +++ b/metadata.json @@ -1,12 +1,12 @@ { - "name": "thias-bind", + "name": "thiasand-bind", "version": "0.5.3", "author": "Matthias Saou", "license": "Apache-2.0", "summary": "BIND DNS server module", - "source": "git://github.com/thias/puppet-bind", - "project_page": "https://github.com/thias/puppet-bind", - "issues_url": "https://github.com/thias/puppet-bind/issues", + "source": "https://github.com/coi-gov-pl/puppet-bind.git", + "project_page": "https://github.com/coi-gov-pl/puppet-bind.git", + "issues_url": "https://github.com/coi-gov-pl/puppet-bind/issues", "tags": [ "bind", "named", "dns" ], "operatingsystem_support": [ { @@ -29,8 +29,21 @@ "requirements": [ { "name": "puppet", - "version_requirement": ">=2.7.20 <5.0.0" + "version_requirement": ">=2.7.20 <6.0.0" } ], - "dependencies": [] + "dependencies": [ + { + "name": "puppetlabs-concat", + "version_requirement": ">=4.0.0 <5.0.0" + }, + { + "name":"puppetlabs/stdlib", + "version_requirement":">=4.0.0 <5.0.0" + }, + { + "name":"binford2k/assert", + "version_requirement":">=0.2.1 <1.0.0" + } + ] } diff --git a/spec/acceptance/init_spec.rb b/spec/acceptance/init_spec.rb new file mode 100644 index 000000000..b3482116e --- /dev/null +++ b/spec/acceptance/init_spec.rb @@ -0,0 +1,12 @@ +require 'spec_helper_acceptance' +# Tests for class bind +describe 'bind', unless: UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do + it 'should work with no errors' do + result = apply_manifest(example('init.pp'), catch_failures: true) + expect(result.exit_code).to be(2) + end + + it 'should work idempotently' do + apply_manifest(example('init.pp'), catch_changes: true) + end +end diff --git a/spec/acceptance/nodesets/centos-6-docker.yml b/spec/acceptance/nodesets/centos-6-docker.yml new file mode 100644 index 000000000..be143f017 --- /dev/null +++ b/spec/acceptance/nodesets/centos-6-docker.yml @@ -0,0 +1,20 @@ +HOSTS: + centos-6-docker: + platform: el-6-x86_64 + hypervisor: docker + image: centos:6 + docker_preserve_image: true + docker_image_commands: + - "sed -i 's/keepcache=0/keepcache=1/g' /etc/yum.conf" + - 'yum install -y crontabs wget' + mount_folders: + wget_cache: + host_path: /tmp/docker-cache/wget + container_path: /var/cache/wget + yum_cache: + host_path: /tmp/docker-cache/yum/centos-6-docker + container_path: /var/cache/yum +CONFIG: + trace_limit: 200 + type: foss + log_level: debug diff --git a/spec/acceptance/nodesets/centos-6-vagrant.yml b/spec/acceptance/nodesets/centos-6-vagrant.yml new file mode 100644 index 000000000..1de02b13b --- /dev/null +++ b/spec/acceptance/nodesets/centos-6-vagrant.yml @@ -0,0 +1,18 @@ +HOSTS: + centos-6-vagrant: + platform: el-6-x86_64 + hypervisor: vagrant + box: boxcutter-centos68 + box_url: https://artifactory.coi.gov.pl/api/vagrant/vagrant-local/boxcutter-centos68 + mount_folders: + wget_cache: + from: /tmp/vagrant-cache/wget + to: /var/cache/wget + yum_cache: + from: /tmp/vagrant-cache/yum/centos-6-vagrant + to: /var/cache/yum +CONFIG: + type: foss + log_level: debug + default_module_install_opts: + module_repository: http://forge.prs.internal/ diff --git a/spec/acceptance/nodesets/centos-7-docker.yml b/spec/acceptance/nodesets/centos-7-docker.yml new file mode 100644 index 000000000..0c3d32bc9 --- /dev/null +++ b/spec/acceptance/nodesets/centos-7-docker.yml @@ -0,0 +1,21 @@ +HOSTS: + centos-7-docker: + platform: el-7-x86_64 + hypervisor: docker + image: centos:7 + docker_preserve_image: true + docker_cmd: '["/usr/sbin/init"]' + # install various tools required to get the image up to usable levels + docker_image_commands: + - 'yum install -y crontabs tar wget openssl sysvinit-tools iproute which initscripts' + mount_folders: + wget_cache: + host_path: /tmp/docker-cache/wget + container_path: /var/cache/wget + yum_cache: + host_path: /tmp/docker-cache/yum/centos-7-docker + container_path: /var/cache/yum +CONFIG: + trace_limit: 200 + type: foss + log_level: debug \ No newline at end of file diff --git a/spec/acceptance/nodesets/centos-7-vagrant.yml b/spec/acceptance/nodesets/centos-7-vagrant.yml new file mode 100644 index 000000000..36a86c10e --- /dev/null +++ b/spec/acceptance/nodesets/centos-7-vagrant.yml @@ -0,0 +1,18 @@ +HOSTS: + centos-7-vagrant: + platform: el-7-x86_64 + hypervisor: vagrant + box: boxcutter-centos73 + box_url: https://artifactory.coi.gov.pl/api/vagrant/vagrant-local/boxcutter-centos73 + mount_folders: + wget_cache: + from: /tmp/vagrant-cache/wget + to: /var/cache/wget + yum_cache: + from: /tmp/vagrant-cache/yum/centos-7-vagrant + to: /var/cache/yum +CONFIG: + type: foss + log_level: debug + default_module_install_opts: + module_repository: http://forge.prs.internal/ diff --git a/spec/acceptance/nodesets/debian-78-docker.yml b/spec/acceptance/nodesets/debian-78-docker.yml new file mode 100644 index 000000000..80c63f79f --- /dev/null +++ b/spec/acceptance/nodesets/debian-78-docker.yml @@ -0,0 +1,19 @@ +HOSTS: + debian-78-docker: + platform: debian-7-amd64 + hypervisor : docker + image: debian:7 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get update && apt-get install -y cron locales-all net-tools wget' + mount_folders: + wget_cache: + host_path: /tmp/wget_cache + container_path: /var/cache/wget + apt_cache: + host_path: /tmp/apt_cache/debian-7-amd64 + container_path: /var/cache/apt +CONFIG: + type: foss +log_level: debug diff --git a/spec/acceptance/nodesets/debian-82-docker.yml b/spec/acceptance/nodesets/debian-82-docker.yml new file mode 100644 index 000000000..daf62b5b0 --- /dev/null +++ b/spec/acceptance/nodesets/debian-82-docker.yml @@ -0,0 +1,21 @@ +HOSTS: + debian-82-docker: + platform: debian-8-amd64 + hypervisor : docker + image: debian:8 + docker_preserve_image: true + docker_cmd: ["/bin/systemd"] + docker_preserve_image: true + docker_image_commands: + - apt-get install -y wget net-tools + - rm /lib/systemd/system/getty.target + mount_folders: + wget_cache: + host_path: /tmp/wget_cache + container_path: /var/cache/wget + apt_cache: + host_path: /tmp/apt_cache/debian-8-amd64 + container_path: /var/cache/apt +CONFIG: + type: foss +log_level: debug diff --git a/spec/acceptance/nodesets/default.yml b/spec/acceptance/nodesets/default.yml new file mode 100644 index 000000000..94b7c2a3c --- /dev/null +++ b/spec/acceptance/nodesets/default.yml @@ -0,0 +1,18 @@ +HOSTS: + default-ol-6-vagrant: + platform: el-6-x86_64 + hypervisor: vagrant + box: boxcutter-ol68 + box_url: https://artifactory.coi.gov.pl/api/vagrant/vagrant-local/boxcutter-ol68 + mount_folders: + wget_cache: + from: /tmp/vagrant-cache/wget + to: /var/cache/wget + yum_cache: + from: /tmp/vagrant-cache/wget/ol-6-vagrant + to: /var/cache/yum +CONFIG: + type: foss + log_level: info + default_module_install_opts: + module_repository: http://forge.prs.internal/ diff --git a/spec/acceptance/nodesets/ol-6-vagrant.yml b/spec/acceptance/nodesets/ol-6-vagrant.yml new file mode 100644 index 000000000..5fc1bce65 --- /dev/null +++ b/spec/acceptance/nodesets/ol-6-vagrant.yml @@ -0,0 +1,18 @@ +HOSTS: + ol-6-vagrant: + platform: el-6-x86_64 + hypervisor: vagrant + box: boxcutter-ol68 + box_url: https://artifactory.coi.gov.pl/api/vagrant/vagrant-local/boxcutter-ol68 + mount_folders: + wget_cache: + from: /tmp/vagrant-cache/wget + to: /var/cache/wget + yum_cache: + from: /tmp/vagrant-cache/yum/ol-6-vagrant + to: /var/cache/yum +CONFIG: + type: foss + log_level: debug + default_module_install_opts: + module_repository: http://forge.prs.internal/ diff --git a/spec/acceptance/nodesets/ol-7-vagrant.yml b/spec/acceptance/nodesets/ol-7-vagrant.yml new file mode 100644 index 000000000..9bf8c421e --- /dev/null +++ b/spec/acceptance/nodesets/ol-7-vagrant.yml @@ -0,0 +1,18 @@ +HOSTS: + ol-7-vagrant: + platform: el-7-x86_64 + hypervisor: vagrant + box: boxcutter-ol73 + box_url: https://artifactory.coi.gov.pl/api/vagrant/vagrant-local/boxcutter-ol73 + mount_folders: + wget_cache: + from: /tmp/vagrant-cache/wget + to: /var/cache/wget + yum_cache: + from: /tmp/vagrant-cache/yum/ol-7-vagrant + to: /var/cache/yum +CONFIG: + type: foss + log_level: debug + default_module_install_opts: + module_repository: http://forge.prs.internal/ diff --git a/spec/acceptance/nodesets/ubuntu-14.04-docker.yml b/spec/acceptance/nodesets/ubuntu-14.04-docker.yml new file mode 100644 index 000000000..dca606b07 --- /dev/null +++ b/spec/acceptance/nodesets/ubuntu-14.04-docker.yml @@ -0,0 +1,22 @@ +HOSTS: + ubuntu-1404-docker: + platform: ubuntu-14.04-amd64 + hypervisor: docker + image: ubuntu:14.04 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'rm /usr/sbin/policy-rc.d' + - 'rm /sbin/initctl; dpkg-divert --rename --remove /sbin/initctl' + - 'apt-get install -y net-tools wget' + - 'locale-gen en_US.UTF-8' + mount_folders: + wget_cache: + host_path: /tmp/docker-cache/wget + container_path: /var/cache/wget + apt_cache: + host_path: /tmp/docker-cache/apt/ubuntu-1404-docker + container_path: /var/cache/apt/archives +CONFIG: + type: foss + log_level: debug diff --git a/spec/acceptance/server/conf_spec.rb b/spec/acceptance/server/conf_spec.rb new file mode 100644 index 000000000..62ccc4a0d --- /dev/null +++ b/spec/acceptance/server/conf_spec.rb @@ -0,0 +1,18 @@ +require 'spec_helper_acceptance' + +# Tests for define bind::server::conf +describe 'bind::server::conf', unless: UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do + let(:download_pp) { example('bind::server::conf') } + + it 'should work with no errors' do + result = apply_manifest(download_pp, catch_failures: true) + expect(result.exit_code).to be(2) + end + it 'should work idempotently' do + apply_manifest(download_pp, catch_changes: true) + end + describe file('/etc/named.conf') do + it { is_expected.to exist } + it { is_expected.to contain 'acl' } + end +end diff --git a/spec/acceptance/zone/bad_definition_spec.rb b/spec/acceptance/zone/bad_definition_spec.rb new file mode 100644 index 000000000..cd425e747 --- /dev/null +++ b/spec/acceptance/zone/bad_definition_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper_acceptance' +# Tests for define flyway::migrate +describe 'bind::zone::bad_definition', unless: UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do + let(:pp) { example('bind::zone::bad_definition') } + + it 'should work with errors' do + apply_manifest(pp, expect_failures: true) + end +end diff --git a/spec/acceptance/zone/definition_spec.rb b/spec/acceptance/zone/definition_spec.rb new file mode 100644 index 000000000..840fd7c54 --- /dev/null +++ b/spec/acceptance/zone/definition_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper_acceptance' +# Tests for define flyway::migrate +describe 'bind::zone::definition', unless: UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do + let(:pp) { example('bind::zone::definition') } + + it 'should work with no errors' do + result = apply_manifest(pp, catch_failures: true) + expect(result.exit_code).to be(2) + end + it 'should work idempotently' do + apply_manifest(pp, catch_changes: true) + end + describe file('/var/named/test_file.com') do + it { should exist } + it { should contain 'world.dev.internal' } + end + describe file('/etc/named.conf') do + it { should exist } + it { should contain '/var/named/test_file.com' } + end +end diff --git a/spec/classes/bind_server_spec.rb b/spec/classes/bind_server_spec.rb index b42cf5610..b2ae54a85 100644 --- a/spec/classes/bind_server_spec.rb +++ b/spec/classes/bind_server_spec.rb @@ -1,25 +1,22 @@ require 'spec_helper' describe 'bind::server' do - it 'should compile' do - expect { should contain_class('bind::server') } - end - + it { should contain_class('bind::server') } it { should contain_package('bind').with_ensure('installed') } - it { should contain_service('named').with({ - 'hasstatus' => true, - 'enable' => true, - 'ensure' => 'running', - 'restart' => '/sbin/service named reload' - })} - it 'should create the logging directory' do - expect { should contain_file('/var/log/named').with({ - 'ensure' => 'directory', - 'owner' => 'root', - 'group' => 'named', - 'mode' => '0770', - 'seltype' => 'var_log_t' - })} - end - -end \ No newline at end of file + it { + should contain_service('named'). + with('hasstatus' => true, + 'enable' => true, + 'ensure' => 'running', + 'restart' => 'service named reload') + } + it { should contain_file('/var/log/named'). + with( + 'ensure' => 'directory', + 'owner' => 'root', + 'group' => 'named', + 'mode' => '0770', + 'seltype' => 'var_log_t' + ) + } +end diff --git a/spec/defines/bind_server_conf_spec.rb b/spec/defines/bind_server_conf_spec.rb index f271c658b..862a3fa09 100644 --- a/spec/defines/bind_server_conf_spec.rb +++ b/spec/defines/bind_server_conf_spec.rb @@ -1,10 +1,14 @@ require 'spec_helper' describe 'bind::server::conf' do + let(:facts) do { + :concat_basedir => '/root' + } + end let (:title) { '/etc/named.conf' } let (:params) { { - :acls => { - 'rfc1918' => [ '10/8', '172.16/12', '192.168/16' ] + :acls => { + 'rfc1918' => [ '10/8', '172.16/12', '192.168/16' ] }, :masters => { 'mymasters' => ['192.0.2.1', '198.51.100.1'] @@ -25,15 +29,8 @@ ], } } - it 'should generate the bind configuration' do - expect { should contain_file ('/etc/named.conf')} - content = catalogue.resource('file', '/etc/named.conf').send(:parameters)[:content] - content.should_not be_empty - content.should match('acl rfc1918') - content.should match('masters mymasters') - content.should match('zone "example.com"') - content.should match('zone "example.org"') - content.should match('include "/etc/myzones.conf"') + context 'should generate the bind configuration with concat' do + it { is_expected.to contain_file('/etc/named.conf') } + it { is_expected.to contain_concat('/etc/named.conf') } + end end - -end \ No newline at end of file diff --git a/spec/defines/bind_server_file_spec.rb b/spec/defines/bind_server_file_spec.rb index 12097295f..27e22c3b3 100644 --- a/spec/defines/bind_server_file_spec.rb +++ b/spec/defines/bind_server_file_spec.rb @@ -1,10 +1,25 @@ require 'spec_helper' describe 'bind::server::file' do - let(:title) { 'example.com' } - let (:params) {{ - :source => 'puppet:///modules/bind/named.empty' - }} - it { should contain_file('/var/named/example.com') } -end \ No newline at end of file + context 'with source parameter' do + let(:title) { 'example.com' } + let (:params) {{ + :source => 'puppet:///modules/bind/named.empty' + }} + let(:facts) do { + :concat_basedir => '/root' + } + end + + it { should contain_file('/var/named/example.com') } + end + context 'with empty $source, $source_base and $content parameters' do + let(:title) { 'example.com' } + let(:facts) do { + :concat_basedir => '/root' + } + end + it { is_expected.to raise_error(Puppet::Error) } + end +end diff --git a/spec/defines/bind_zone_definition_spec.rb b/spec/defines/bind_zone_definition_spec.rb new file mode 100644 index 000000000..fb65eb2cb --- /dev/null +++ b/spec/defines/bind_zone_definition_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe 'bind::zone::definition' do + let(:pre_condition) { 'include bind::params'} + let(:facts) do { + :concat_basedir => '/root' + } + end + let(:title) { 'localhost.org' } + let(:params) do + { + :definition_file => '/etc/bind/named.conf.unit', + :zone_file => '/etc/bind/coi/db.myzone', + :serial => '20160501' + } + end + let(:pre_condition) { "concat { '/etc/bind/named.conf.unit': + ensure => present}" } + it { should compile } + it { is_expected.to contain_file('/etc/bind/named.conf.unit') } + it { is_expected.to contain_file('/etc/bind/coi/db.myzone') } + it { is_expected.to contain_assert('Check nameserver file-/etc/bind/named.conf.unit')} +end diff --git a/spec/defines/bind_zone_record_spec.rb b/spec/defines/bind_zone_record_spec.rb new file mode 100644 index 000000000..895d8229c --- /dev/null +++ b/spec/defines/bind_zone_record_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe 'bind::zone::record' do + let(:facts) do { + :concat_basedir => '/root', + :osfamily => 'RedHat' + } + end + let(:title) { 'example.com' } + let(:params) do + { + :target_file => '/etc/bind/db.myzone', + :rname => 'host', + :rdata => '127.0.0.1', + :zone_name => 'example.com' + } + end + let(:pre_condition) { "concat { '/etc/bind/db.myzone': + ensure => present}" } + it { should compile } + it { should contain_concat__fragment('/etc/bind/db.myzone_example.com') } + it { should contain_assert('Check zone file-/etc/bind/db.myzone-host')} +end diff --git a/spec/fixtures/manifests/.empty b/spec/fixtures/manifests/.empty new file mode 100644 index 000000000..e69de29bb diff --git a/spec/fixtures/modules/.empty b/spec/fixtures/modules/.empty new file mode 100644 index 000000000..e69de29bb diff --git a/spec/fixtures/modules/bind/files b/spec/fixtures/modules/bind/files deleted file mode 120000 index 84dafe8de..000000000 --- a/spec/fixtures/modules/bind/files +++ /dev/null @@ -1 +0,0 @@ -../../../../files \ No newline at end of file diff --git a/spec/fixtures/modules/bind/manifests b/spec/fixtures/modules/bind/manifests deleted file mode 120000 index 373b99206..000000000 --- a/spec/fixtures/modules/bind/manifests +++ /dev/null @@ -1 +0,0 @@ -../../../../manifests \ No newline at end of file diff --git a/spec/fixtures/modules/bind/templates b/spec/fixtures/modules/bind/templates deleted file mode 120000 index f8a06d1d1..000000000 --- a/spec/fixtures/modules/bind/templates +++ /dev/null @@ -1 +0,0 @@ -../../../../templates \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b5b93a3dd..5ddcbf055 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,9 +2,9 @@ require 'rspec-puppet' require 'puppetlabs_spec_helper/module_spec_helper' -fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures')) - -RSpec.configure do |c| - c.module_path = File.join(fixture_path, 'modules') - c.manifest_dir = File.join(fixture_path, 'manifests') +begin + gem 'pry' + require 'pry' +rescue Gem::LoadError + # do nothing end diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb new file mode 100644 index 000000000..a538d2606 --- /dev/null +++ b/spec/spec_helper_acceptance.rb @@ -0,0 +1,28 @@ +require 'puppet' +require 'beaker-rspec' +require 'beaker/module_install_helper' +require 'puppet-examples-helpers' +require 'spec_helper' + +UNSUPPORTED_PLATFORMS = %w[Suse windows AIX Solaris].freeze + +puppet_version = ENV['PUPPET_INSTALL_VERSION'] || '4' +puppet_agent_version = ENV['PUPPET_AGENT_INSTALL_VERSION'] || '1.10.7' +opts = { + :version => puppet_version, + :puppet_agent_version => puppet_agent_version +} +opts.merge!({ + :puppet_collection => ENV['PUPPET_COLLECTION'] +}) unless ENV['PUPPET_COLLECTION'].nil? + +install_puppet opts +shell 'echo "Puppet Version: $(puppet --version)"' +install_module +install_module_dependencies + +RSpec.configure do |c| + c.include PuppetExamplesHelpers + + c.order = :defined +end diff --git a/templates/zone_definition.erb b/templates/zone_definition.erb new file mode 100644 index 000000000..fadce9166 --- /dev/null +++ b/templates/zone_definition.erb @@ -0,0 +1,5 @@ +zone "<%= @name %>" { + type <%= @zone_type %>; + file "<%= @zone_file %>"; + <% if @allow_update %>allow-update { <%= @allow_update %>; };<% end %> +}; diff --git a/templates/zone_preamble.erb b/templates/zone_preamble.erb new file mode 100644 index 000000000..d3b71daa3 --- /dev/null +++ b/templates/zone_preamble.erb @@ -0,0 +1,12 @@ +; +; This file is managed by Puppet. All changes will be overwritten. +; +<% if @origin %>$ORIGIN <%= @origin %><% end %> +$TTL <%= @ttl %> +@ IN SOA <%= @soa_nameserver %>. <%= @soa_contact %>. ( + <%= @serial %> + <%= @refresh %> + <%= @retry %> + <%= @expire %> + <%= @minimum_ttl %>) +;