From ea4fd867017083119a41f3a35a4b8ed6ad9fdbdc Mon Sep 17 00:00:00 2001 From: Raphaël Pinson Date: Thu, 11 Apr 2013 12:08:13 +0200 Subject: Prepare for rspec tests --- spec/.rspec | 6 ++++++ spec/fixtures/manifests/site.pp | 6 ++++++ spec/spec_helper.rb | 4 ++++ 3 files changed, 16 insertions(+) create mode 100644 spec/.rspec create mode 100644 spec/fixtures/manifests/site.pp create mode 100644 spec/spec_helper.rb (limited to 'spec') diff --git a/spec/.rspec b/spec/.rspec new file mode 100644 index 0000000..91cd642 --- /dev/null +++ b/spec/.rspec @@ -0,0 +1,6 @@ +--format +s +--colour +--loadby +mtime +--backtrace diff --git a/spec/fixtures/manifests/site.pp b/spec/fixtures/manifests/site.pp new file mode 100644 index 0000000..0380291 --- /dev/null +++ b/spec/fixtures/manifests/site.pp @@ -0,0 +1,6 @@ +# Fake $::concat_basedir fact +$concat_basedir = '/var/lib/puppet/concat' + +# Default node to test defines +node default { +} diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..4edc964 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,4 @@ +require 'mocha' +require 'rspec-puppet' +require 'puppetlabs_spec_helper/module_spec_helper' + -- cgit v1.2.3 From 4cc54cff2d04eedb672c7cc6b92a5edcccac63c9 Mon Sep 17 00:00:00 2001 From: Raphaël Pinson Date: Thu, 11 Apr 2013 12:34:23 +0200 Subject: Add spec tests for the dhcp class --- manifests/hosts.pp | 2 +- manifests/params.pp | 2 +- spec/classes/dhcp_spec.rb | 73 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 spec/classes/dhcp_spec.rb (limited to 'spec') diff --git a/manifests/hosts.pp b/manifests/hosts.pp index b159449..426d661 100644 --- a/manifests/hosts.pp +++ b/manifests/hosts.pp @@ -42,7 +42,7 @@ define dhcp::hosts ( $template = 'dhcp/host.conf.erb', ) { - include dhcp::params + include ::dhcp::params concat::fragment {"dhcp.host.${name}": target => "${dhcp::params::config_dir}/hosts.d/${subnet}.conf", diff --git a/manifests/params.pp b/manifests/params.pp index 925f3f5..0938e4a 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -27,7 +27,7 @@ class dhcp::params { } default: { - fail "${name} is not available for ${::operatingsystem}/${::lsbdistcodename}" + fail "Unsupported OS ${::operatingsystem}/${::lsbdistcodename}" } } diff --git a/spec/classes/dhcp_spec.rb b/spec/classes/dhcp_spec.rb new file mode 100644 index 0000000..c833c52 --- /dev/null +++ b/spec/classes/dhcp_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper' + +describe 'dhcp' do + context 'When on an unsupported OS' do + let (:facts) { { + :operatingsystem => 'RedHat', + :osfamily => 'Redhat', + :lsbdistcodename => 'Santiago' + } } + + it 'should fail' do + expect { + should contain_package('dhcp-server') + }.to raise_error(Puppet::Error, /Unsupported OS RedHat\/Santiago/) + end + end + + context 'When on Debian lenny' do + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'lenny' + } } + + # Package + it { should contain_package('dhcp-server').with( + :name => 'dhcp3-server' + ) } + + # Config + it { should contain_concat('/etc/dhcp3/dhcpd.conf').with( + :owner => 'root', + :group => 'root', + :mode => '0644' + ) } + + # Service + it { should contain_service('dhcpd').with( + :ensure => 'running', + :name => 'dhcp3-server', + :enable => true, + :pattern => '/usr/sbin/dhcpd3' + ) } + end + + context 'When on Debian squeeze' do + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'squeeze' + } } + + # Package + it { should contain_package('dhcp-server').with( + :name => 'isc-dhcp-server' + ) } + + # Config + it { should contain_concat('/etc/dhcp/dhcpd.conf').with( + :owner => 'root', + :group => 'root', + :mode => '0644' + ) } + + # Service + it { should contain_service('dhcpd').with( + :ensure => 'running', + :name => 'isc-dhcp-server', + :enable => true, + :pattern => '/usr/sbin/dhcpd' + ) } + end +end -- cgit v1.2.3 From 65bea20e0d8e61de7519bb1ab0677597500aaac7 Mon Sep 17 00:00:00 2001 From: Raphaël Pinson Date: Thu, 11 Apr 2013 14:25:15 +0200 Subject: Get rid of unscoped variables in dhcp::server, fix template --- manifests/init.pp | 9 +++++- manifests/server.pp | 20 +++++++----- manifests/server/config.pp | 4 +++ spec/classes/dhcp_spec.rb | 68 +++++++++++++++++++++++++++++++++++++++++ templates/dhcpd.conf.debian.erb | 16 +++------- 5 files changed, 97 insertions(+), 20 deletions(-) (limited to 'spec') diff --git a/manifests/init.pp b/manifests/init.pp index 8a14b13..e1e05b3 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,7 +1,14 @@ class dhcp ( $server = true, + $server_ddns_update = undef, + $server_authoritative = undef, + $server_opts = undef, ) { if $server { - class { '::dhcp::server': } + class { '::dhcp::server': + ddns_update => $server_ddns_update, + authoritative => $server_authoritative, + opts => $server_opts, + } } } diff --git a/manifests/server.pp b/manifests/server.pp index ceffa14..d83c26f 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -5,15 +5,17 @@ # module "common": git://github.com/camptocamp/puppet-common.git # # facultative argument: -# *$dhcpd_ddns_update* : ddns-update-style option (default to none) -# *$dhcpd_authoritative* : set it if you want that your DHCP server is -# authoritative (default to no) -# *$dhcpd_opts* : any other DHCPD valid options +# *$ddns_update* : ddns-update-style option (default to none) +# *$authoritative* : set it if you want that your DHCP server is +# authoritative (default to no) +# *$opts* : any other DHCPD valid options # # Example: # node "dhcp.toto.ltd" { -# $dhcpd_opts = ['domain-name "toto.ltd"', "domain-name-servers 192.168.21.1"] -# include dhcp::server +# class { 'dhcp::server': +# opts => ['domain-name "toto.ltd"', +# 'domain-name-servers 192.168.21.1'], +# } # # dhcp::subnet {"10.27.20.0": # ensure => present, @@ -29,7 +31,11 @@ # } # } # -class dhcp::server { +class dhcp::server ( + $ddns_update = 'none', + $authoritative = false, + $opts = [], +) { class { '::dhcp::server::packages': } -> class { '::dhcp::server::config': } ~> class { '::dhcp::server::service': } diff --git a/manifests/server/config.pp b/manifests/server/config.pp index 4898a60..0c1a74a 100644 --- a/manifests/server/config.pp +++ b/manifests/server/config.pp @@ -11,6 +11,10 @@ class dhcp::server::config { validate_string($dhcp::params::server_template) validate_re($dhcp::params::server_template, '^\S+$') + validate_string($dhcp::server::ddns_update) + validate_bool($dhcp::server::authoritative) + validate_array($dhcp::server::opts) + concat {"${dhcp::params::config_dir}/dhcpd.conf": owner => root, group => root, diff --git a/spec/classes/dhcp_spec.rb b/spec/classes/dhcp_spec.rb index c833c52..ce9228e 100644 --- a/spec/classes/dhcp_spec.rb +++ b/spec/classes/dhcp_spec.rb @@ -34,6 +34,13 @@ describe 'dhcp' do :mode => '0644' ) } + it { should contain_concat__fragment('00.dhcp.server.base').with( + :ensure => 'present', + :target => '/etc/dhcp3/dhcpd.conf', + :content => /log-facility/ + ).with_content(/ddns-update-style none;/).with_content(/#authoritative/) + } + # Service it { should contain_service('dhcpd').with( :ensure => 'running', @@ -62,6 +69,13 @@ describe 'dhcp' do :mode => '0644' ) } + it { should contain_concat__fragment('00.dhcp.server.base').with( + :ensure => 'present', + :target => '/etc/dhcp/dhcpd.conf', + :content => /log-facility/ + ).with_content(/ddns-update-style none;/).with_content(/#authoritative/) + } + # Service it { should contain_service('dhcpd').with( :ensure => 'running', @@ -70,4 +84,58 @@ describe 'dhcp' do :pattern => '/usr/sbin/dhcpd' ) } end + + context 'When passing ddns_update' do + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'squeeze' + } } + let (:params) { { + :server_ddns_update => 'foo' + } } + + it { should contain_concat__fragment('00.dhcp.server.base').with( + :ensure => 'present', + :target => '/etc/dhcp/dhcpd.conf', + :content => /log-facility/ + ).with_content(/ddns-update-style foo;/).with_content(/#authoritative/) + } + end + + context 'When passing authoritative' do + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'squeeze' + } } + let (:params) { { + :server_authoritative => true + } } + + it { should contain_concat__fragment('00.dhcp.server.base').with( + :ensure => 'present', + :target => '/etc/dhcp/dhcpd.conf', + :content => /log-facility/ + ).with_content(/ddns-update-style none;/).with_content(/[^#]authoritative/) + } + end + + context 'When passing opts' do + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'squeeze' + } } + let (:params) { { + :server_opts => ['foo', 'bar', 'baz'] + } } + + it { should contain_concat__fragment('00.dhcp.server.base').with( + :ensure => 'present', + :target => '/etc/dhcp/dhcpd.conf', + :content => /log-facility/ + ).with_content(/ddns-update-style none;/).with_content(/#authoritative/).with_content(/foo;\nbar;\nbaz;\n/) + } + end end diff --git a/templates/dhcpd.conf.debian.erb b/templates/dhcpd.conf.debian.erb index ee95bee..7dfd168 100644 --- a/templates/dhcpd.conf.debian.erb +++ b/templates/dhcpd.conf.debian.erb @@ -4,22 +4,14 @@ # attempt to do a DNS update when a lease is confirmed. We default to the # behavior of the version 2 packages ('none', since DHCP v2 didn't # have support for DDNS.) -<% if has_variable?('dhcpd_ddns_update') -%> -ddns-update-style <%=dhcpd_ddns_update%>; -<% else -%> -ddns-update-style none; -<% end -%> +ddns-update-style <%= @ddns_update %>; # If this DHCP server is the official DHCP server for the local # network, the authoritative directive should be uncommented. -<% if has_variable?('dhcpd_authoritative') -%> -authoritative; -<% else -%> -#authoritative; -<% end -%> +<% unless @authoritative -%>#<%- end -%>authoritative; -<% if has_variable?('dhcpd_opts') and not dhcpd_opts.empty? -%> -<%= dhcpd_opts.join(";\n") %> +<% unless @opts.empty? -%> +<%= @opts.join(";\n") %>; <% end -%> # Use this to send dhcp log messages to a different log file (you also -- cgit v1.2.3 From d7efc5772d475e3ad374e6000f2e706be42c85da Mon Sep 17 00:00:00 2001 From: Raphaël Pinson Date: Thu, 11 Apr 2013 14:31:39 +0200 Subject: Check param validation in dhcp::server::config --- spec/classes/dhcp_spec.rb | 141 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 99 insertions(+), 42 deletions(-) (limited to 'spec') diff --git a/spec/classes/dhcp_spec.rb b/spec/classes/dhcp_spec.rb index ce9228e..5eb7172 100644 --- a/spec/classes/dhcp_spec.rb +++ b/spec/classes/dhcp_spec.rb @@ -86,56 +86,113 @@ describe 'dhcp' do end context 'When passing ddns_update' do - let (:facts) { { - :operatingsystem => 'Debian', - :osfamily => 'Debian', - :lsbdistcodename => 'squeeze' - } } - let (:params) { { - :server_ddns_update => 'foo' - } } + context 'When passing wrong type' do + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'squeeze' + } } + let (:params) { { + :server_ddns_update => true + } } + + it 'should fail' do + expect { + should contain_concat__fragment('00.dhcp.server.base') + }.to raise_error(Puppet::Error, /true is not a string./) + end + end - it { should contain_concat__fragment('00.dhcp.server.base').with( - :ensure => 'present', - :target => '/etc/dhcp/dhcpd.conf', - :content => /log-facility/ - ).with_content(/ddns-update-style foo;/).with_content(/#authoritative/) - } + context 'When passing valid value' do + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'squeeze' + } } + let (:params) { { + :server_ddns_update => 'foo' + } } + + it { should contain_concat__fragment('00.dhcp.server.base').with( + :ensure => 'present', + :target => '/etc/dhcp/dhcpd.conf', + :content => /log-facility/ + ).with_content(/ddns-update-style foo;/).with_content(/#authoritative/) + } + end end context 'When passing authoritative' do - let (:facts) { { - :operatingsystem => 'Debian', - :osfamily => 'Debian', - :lsbdistcodename => 'squeeze' - } } - let (:params) { { - :server_authoritative => true - } } + context 'When passing wrong type' do + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'squeeze' + } } + let (:params) { { + :server_authoritative => 'foo' + } } + + it 'should fail' do + expect { + should contain_concat__fragment('00.dhcp.server.base') + }.to raise_error(Puppet::Error, /"foo" is not a boolean./) + end + end - it { should contain_concat__fragment('00.dhcp.server.base').with( - :ensure => 'present', - :target => '/etc/dhcp/dhcpd.conf', - :content => /log-facility/ - ).with_content(/ddns-update-style none;/).with_content(/[^#]authoritative/) - } + context 'When passing valid value' do + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'squeeze' + } } + let (:params) { { + :server_authoritative => true + } } + + it { should contain_concat__fragment('00.dhcp.server.base').with( + :ensure => 'present', + :target => '/etc/dhcp/dhcpd.conf', + :content => /log-facility/ + ).with_content(/ddns-update-style none;/).with_content(/[^#]authoritative/) + } + end end context 'When passing opts' do - let (:facts) { { - :operatingsystem => 'Debian', - :osfamily => 'Debian', - :lsbdistcodename => 'squeeze' - } } - let (:params) { { - :server_opts => ['foo', 'bar', 'baz'] - } } + context 'When passing wrong type' do + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'squeeze' + } } + let (:params) { { + :server_opts => 'foo' + } } + + it 'should fail' do + expect { + should contain_concat__fragment('00.dhcp.server.base') + }.to raise_error(Puppet::Error, /"foo" is not an Array./) + end + end - it { should contain_concat__fragment('00.dhcp.server.base').with( - :ensure => 'present', - :target => '/etc/dhcp/dhcpd.conf', - :content => /log-facility/ - ).with_content(/ddns-update-style none;/).with_content(/#authoritative/).with_content(/foo;\nbar;\nbaz;\n/) - } + context 'When passing valid value' do + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'squeeze' + } } + let (:params) { { + :server_opts => ['foo', 'bar', 'baz'] + } } + + it { should contain_concat__fragment('00.dhcp.server.base').with( + :ensure => 'present', + :target => '/etc/dhcp/dhcpd.conf', + :content => /log-facility/ + ).with_content(/ddns-update-style none;/).with_content(/#authoritative/).with_content(/foo;\nbar;\nbaz;\n/) + } + end end end -- cgit v1.2.3 From 0689631b833d5683bdef5885de5893450f4928ca Mon Sep 17 00:00:00 2001 From: Raphaël Pinson Date: Fri, 12 Apr 2013 08:52:01 +0200 Subject: small letters --- spec/classes/dhcp_spec.rb | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'spec') diff --git a/spec/classes/dhcp_spec.rb b/spec/classes/dhcp_spec.rb index 5eb7172..9db478c 100644 --- a/spec/classes/dhcp_spec.rb +++ b/spec/classes/dhcp_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'dhcp' do - context 'When on an unsupported OS' do + context 'when on an unsupported OS' do let (:facts) { { :operatingsystem => 'RedHat', :osfamily => 'Redhat', @@ -15,7 +15,7 @@ describe 'dhcp' do end end - context 'When on Debian lenny' do + context 'when on Debian lenny' do let (:facts) { { :operatingsystem => 'Debian', :osfamily => 'Debian', @@ -50,7 +50,7 @@ describe 'dhcp' do ) } end - context 'When on Debian squeeze' do + context 'when on Debian squeeze' do let (:facts) { { :operatingsystem => 'Debian', :osfamily => 'Debian', @@ -85,8 +85,8 @@ describe 'dhcp' do ) } end - context 'When passing ddns_update' do - context 'When passing wrong type' do + context 'when passing ddns_update' do + context 'when passing wrong type' do let (:facts) { { :operatingsystem => 'Debian', :osfamily => 'Debian', @@ -103,7 +103,7 @@ describe 'dhcp' do end end - context 'When passing valid value' do + context 'when passing valid value' do let (:facts) { { :operatingsystem => 'Debian', :osfamily => 'Debian', @@ -122,8 +122,8 @@ describe 'dhcp' do end end - context 'When passing authoritative' do - context 'When passing wrong type' do + context 'when passing authoritative' do + context 'when passing wrong type' do let (:facts) { { :operatingsystem => 'Debian', :osfamily => 'Debian', @@ -140,7 +140,7 @@ describe 'dhcp' do end end - context 'When passing valid value' do + context 'when passing valid value' do let (:facts) { { :operatingsystem => 'Debian', :osfamily => 'Debian', @@ -159,8 +159,8 @@ describe 'dhcp' do end end - context 'When passing opts' do - context 'When passing wrong type' do + context 'when passing opts' do + context 'when passing wrong type' do let (:facts) { { :operatingsystem => 'Debian', :osfamily => 'Debian', @@ -177,7 +177,7 @@ describe 'dhcp' do end end - context 'When passing valid value' do + context 'when passing valid value' do let (:facts) { { :operatingsystem => 'Debian', :osfamily => 'Debian', -- cgit v1.2.3 From f4e7bdf477586e34e47a972172c15809ac92fe3c Mon Sep 17 00:00:00 2001 From: Raphaël Pinson Date: Fri, 12 Apr 2013 10:38:14 +0200 Subject: Improve template host.conf.erb with validations and add spec for dhcp::hosts --- manifests/hosts.pp | 26 ++- spec/defines/dhcp_hosts_spec.rb | 411 ++++++++++++++++++++++++++++++++++++++++ templates/host.conf.erb | 32 ++-- 3 files changed, 451 insertions(+), 18 deletions(-) create mode 100644 spec/defines/dhcp_hosts_spec.rb (limited to 'spec') diff --git a/manifests/hosts.pp b/manifests/hosts.pp index 426d661..f8e5faf 100644 --- a/manifests/hosts.pp +++ b/manifests/hosts.pp @@ -1,4 +1,4 @@ -# = Definition: dhcp::hosts +# Definition: dhcp::hosts # # Creates a dhcp configuration for given hosts # @@ -38,15 +38,27 @@ define dhcp::hosts ( $hash_data, $subnet, - $global_options = false, - $template = 'dhcp/host.conf.erb', + $ensure = present, + $global_options = [], + $template = "${module_name}/host.conf.erb", ) { include ::dhcp::params - concat::fragment {"dhcp.host.${name}": - target => "${dhcp::params::config_dir}/hosts.d/${subnet}.conf", - content => template($template), - notify => Service['dhcpd'], + validate_string($ensure) + validate_re($ensure, ['present', 'absent'], + "\$ensure must be either 'present' or 'absent', got '${ensure}'") + validate_hash($hash_data) + validate_string($subnet) + validate_re($subnet, '^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$') + validate_array($global_options) + validate_string($template) + + if ($ensure == 'present') { + concat::fragment {"dhcp.host.${name}": + target => "${dhcp::params::config_dir}/hosts.d/${subnet}.conf", + content => template($template), + notify => Service['dhcpd'], + } } } diff --git a/spec/defines/dhcp_hosts_spec.rb b/spec/defines/dhcp_hosts_spec.rb new file mode 100644 index 0000000..658be20 --- /dev/null +++ b/spec/defines/dhcp_hosts_spec.rb @@ -0,0 +1,411 @@ +require 'spec_helper' + +describe 'dhcp::hosts' do + let (:title) { 'My hosts' } + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'squeeze', + } } + + context 'when passing wrong value for ensure' do + let (:params) { { + :hash_data => {}, + :subnet => '1.2.3.4', + :ensure => 'running' + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /\$ensure must be either 'present' or 'absent', got 'running'/) + end + end + + context 'when hash_data is not passed' do + let (:params) { { + :subnet => '1.2.3.4', + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /Must pass hash_data to Dhcp::Hosts/) + end + end + + context 'when passing wrong type for hash_data' do + let (:params) { { + :hash_data => 'foo', + :subnet => '1.2.3.4', + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /"foo" is not a Hash\./) + end + end + + context 'when subnet is not passed' do + let (:params) { { + :hash_data => {}, + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /Must pass subnet to Dhcp::Hosts/) + end + end + + context 'when passing wrong type for subnet' do + let (:params) { { + :hash_data => {}, + :subnet => true + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /true is not a string\./) + end + end + + context 'when passing wrong value for subnet' do + let (:params) { { + :hash_data => {}, + :subnet => 'foo' + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /"foo" does not match/) + end + end + + context 'when passing wrong type for global_options' do + let (:params) { { + :hash_data => {}, + :subnet => '1.2.3.4', + :global_options => 'foo' + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /"foo" is not an Array\./) + end + end + + context 'when passing wrong type for template' do + let (:params) { { + :hash_data => {}, + :subnet => '1.2.3.4', + :template => true + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /true is not a string\./) + end + end + + context 'when passing one entry in hash_data' do + context 'when passing wrong type for an host data' do + let (:params) { { + :hash_data => { + 'host1' => true, + }, + :subnet => '1.2.3.4' + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /true is not a Hash/) + end + end + + context 'when interfaces is not passed' do + let (:params) { { + :hash_data => { + 'host1' => { + }, + }, + :subnet => '1.2.3.4' + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /Missing interfaces hash for host 'host1'/) + end + end + + context 'when passing wrong value for an interface' do + let (:params) { { + :hash_data => { + 'host1' => { + 'interfaces' => { + 'eth 0' => '00:11:22:33:44:55', + }, + }, + }, + :subnet => '1.2.3.4' + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /"eth 0" does not match/) + end + end + + context 'when passing wrong type for a mac address' do + let (:params) { { + :hash_data => { + 'host1' => { + 'interfaces' => { + 'eth0' => true, + }, + }, + }, + :subnet => '1.2.3.4' + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /true is not a string\./) + end + end + + context 'when passing wrong value for a mac address' do + let (:params) { { + :hash_data => { + 'host1' => { + 'interfaces' => { + 'eth0' => 'my mac', + }, + }, + }, + :subnet => '1.2.3.4' + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /"my mac" does not match/) + end + end + + context 'when passing wrong type for fixed_address' do + let (:params) { { + :hash_data => { + 'host1' => { + 'interfaces' => { + 'eth0' => '00:11:22:33:44:55', + }, + 'fixed_address' => true, + }, + }, + :subnet => '1.2.3.4' + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /true is not a string/) + end + end + + context 'when passing wrong value for fixed_address' do + let (:params) { { + :hash_data => { + 'host1' => { + 'interfaces' => { + 'eth0' => '00:11:22:33:44:55', + }, + 'fixed_address' => 'my wrong value', + }, + }, + :subnet => '1.2.3.4' + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /"my wrong value" does not match/) + end + end + + context 'when not passing fixed_address' do + let (:params) { { + :hash_data => { + 'host1' => { + 'interfaces' => { + 'eth0' => '00:11:22:33:44:55', + }, + }, + }, + :subnet => '1.2.3.4' + } } + + it { should contain_concat__fragment('dhcp.host.My hosts').with( + :content => /fixed-address host1;/ + ) } + end + + context 'when not passing options' do + let (:params) { { + :hash_data => { + 'host1' => { + 'interfaces' => { + 'eth0' => '00:11:22:33:44:55', + }, + }, + }, + :subnet => '1.2.3.4', + :global_options => ['foo', 'bar'], + } } + + it { should contain_concat__fragment('dhcp.host.My hosts').with( + :content => /foo;\nbar;\n/ + ) } + end + + context 'when overriding options' do + let (:params) { { + :hash_data => { + 'host1' => { + 'interfaces' => { + 'eth0' => '00:11:22:33:44:55', + }, + 'options' => ['baz'], + }, + }, + :subnet => '1.2.3.4', + :global_options => ['foo', 'bar'], + } } + + it { should contain_concat__fragment('dhcp.host.My hosts').with( + :content => /baz;\n/ + ) } + end + + context 'when passing wrong type for options' do + let (:params) { { + :hash_data => { + 'host1' => { + 'interfaces' => { + 'eth0' => '00:11:22:33:44:55', + }, + 'options' => true, + }, + }, + :subnet => '1.2.3.4', + :global_options => ['foo', 'bar'], + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /true is not an Array\./) + end + end + + context 'when passing wrong value for fixed_address' do + let (:params) { { + :hash_data => { + 'host1' => { + 'interfaces' => { + 'eth0' => '00:11:22:33:44:55', + }, + 'fixed_address' => 'my wrong value', + }, + }, + :subnet => '1.2.3.4' + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /"my wrong value" does not match/) + end + end + + context 'when not passing fixed_address' do + let (:params) { { + :hash_data => { + 'host1' => { + 'interfaces' => { + 'eth0' => '00:11:22:33:44:55', + }, + }, + }, + :subnet => '1.2.3.4' + } } + + it { should contain_concat__fragment('dhcp.host.My hosts').with( + :content => /fixed-address host1;/ + ) } + end + + context 'when not passing options' do + let (:params) { { + :hash_data => { + 'host1' => { + 'interfaces' => { + 'eth0' => '00:11:22:33:44:55', + }, + }, + }, + :subnet => '1.2.3.4', + :global_options => ['foo', 'bar'], + } } + + it { should contain_concat__fragment('dhcp.host.My hosts').with( + :content => /foo;\nbar;\n/ + ) } + end + + context 'when passing two hosts' do + let (:params) { { + :hash_data => { + 'host1' => { + 'interfaces' => { + 'eth0' => '00:11:22:33:44:55', + 'wlan0' => '00:aa:bb:44:55:ff', + }, + }, + 'host2' => { + 'interfaces' => { + 'eth1' => '00:11:af:33:44:55', + }, + 'fixed_address' => 'foo.example.com', + 'options' => ['opt1'], + }, + }, + :subnet => '1.2.3.4' + } } + + it { should contain_concat__fragment('dhcp.host.My hosts').with_content( + /host host1-eth0 \{\n hardware ethernet 00:11:22:33:44:55;\n fixed-address host1;\n\}/).with_content( + /host host1-wlan0 \{\n hardware ethernet 00:aa:bb:44:55:ff;\n fixed-address host1;\n\}/).with_content( + /host host2-eth1 \{\n hardware ethernet 00:11:af:33:44:55;\n fixed-address foo\.example\.com;\n opt1;\n\}/) + } + end + end + + context 'when passing two entries in hash_data' do + end + + context 'when passing global_options' do + end + + context 'when overriding template' do + end +end diff --git a/templates/host.conf.erb b/templates/host.conf.erb index e6a7073..398d798 100644 --- a/templates/host.conf.erb +++ b/templates/host.conf.erb @@ -1,16 +1,26 @@ -<%- @hash_data.sort.each do |host, datas| -%> -<%- datas.fetch('interfaces').sort.each do |if_name, if_mac| -%> +<%- @hash_data.sort.each do |host, data| + scope.function_validate_hash([data]) -%> +<%- + raise Puppet::ParseError, "Missing interfaces hash for host '#{host}'" unless data.has_key? 'interfaces' + data.fetch('interfaces').sort.each do |if_name, if_mac| + scope.function_validate_re([if_name, '^\S+$']) + scope.function_validate_string([if_mac]) + scope.function_validate_re([if_mac, '^[a-f0-9:.]+$']) + -%> host <%= host %>-<%= if_name %> { hardware ethernet <%= if_mac %>; -<% if datas.fetch('fixed_address', false) -%> - fixed-address <%= datas.fetch('fixed_address') %>; -<% else -%> - fixed-address <%= host %>; -<% end -%> -<% if datas.fetch('option', false) -%> - <%= datas.fetch('option') %> -<% elsif @global_options -%> - <%= @global_options %> +<% + fixed_address = data.fetch('fixed_address', nil) || host + scope.function_validate_string([fixed_address]) + scope.function_validate_re([fixed_address, '^\S+$']) + -%> + fixed-address <%= fixed_address %>; +<% + options = data.fetch('options', nil) || @global_options + scope.function_validate_array([options]) + unless options.empty? + -%> + <%= options.join(";\n") %>; <% end -%> } <% end -%> -- cgit v1.2.3 From 53346e4314aed349290661cbe70c97ab573ea9bc Mon Sep 17 00:00:00 2001 From: Raphaël Pinson Date: Fri, 12 Apr 2013 10:45:55 +0200 Subject: Remove duplicated tests, test template override --- spec/defines/dhcp_hosts_spec.rb | 54 +++++++++-------------------------------- 1 file changed, 11 insertions(+), 43 deletions(-) (limited to 'spec') diff --git a/spec/defines/dhcp_hosts_spec.rb b/spec/defines/dhcp_hosts_spec.rb index 658be20..c8face6 100644 --- a/spec/defines/dhcp_hosts_spec.rb +++ b/spec/defines/dhcp_hosts_spec.rb @@ -317,43 +317,6 @@ describe 'dhcp::hosts' do end end - context 'when passing wrong value for fixed_address' do - let (:params) { { - :hash_data => { - 'host1' => { - 'interfaces' => { - 'eth0' => '00:11:22:33:44:55', - }, - 'fixed_address' => 'my wrong value', - }, - }, - :subnet => '1.2.3.4' - } } - - it 'should fail' do - expect { - should contain_concat__fragment('dhcp.host.My hosts') - }.to raise_error(Puppet::Error, /"my wrong value" does not match/) - end - end - - context 'when not passing fixed_address' do - let (:params) { { - :hash_data => { - 'host1' => { - 'interfaces' => { - 'eth0' => '00:11:22:33:44:55', - }, - }, - }, - :subnet => '1.2.3.4' - } } - - it { should contain_concat__fragment('dhcp.host.My hosts').with( - :content => /fixed-address host1;/ - ) } - end - context 'when not passing options' do let (:params) { { :hash_data => { @@ -400,12 +363,17 @@ describe 'dhcp::hosts' do end end - context 'when passing two entries in hash_data' do - end - - context 'when passing global_options' do - end - context 'when overriding template' do + let (:params) { { + :hash_data => {}, + :subnet => '1.2.3.4', + :template => 'wrong/path', + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp.host.My hosts') + }.to raise_error(Puppet::Error, /Could not find template 'wrong\/path'/) + end end end -- cgit v1.2.3 From f7025518512c0bf8d63f413f7be78347fedee9f4 Mon Sep 17 00:00:00 2001 From: Raphaël Pinson Date: Fri, 12 Apr 2013 10:50:24 +0200 Subject: Test target for concat::fragment in dhcp::hosts --- manifests/hosts.pp | 8 +++----- spec/defines/dhcp_hosts_spec.rb | 7 ++++++- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'spec') diff --git a/manifests/hosts.pp b/manifests/hosts.pp index f8e5faf..676d507 100644 --- a/manifests/hosts.pp +++ b/manifests/hosts.pp @@ -4,15 +4,14 @@ # # Arguments # $template: dhcp host template - default: 'dhcp/host.conf.erb' -# $global_options: global options for the whole bunch of hosts. +# $global_options: an array of global options for the whole bunch of hosts. # you may override it per host, setting the host "options" # directly in the hash. # $subnet: targeted subnet # $hash_data: hash containing data - default form: # { # => { -# options => false, -# fixed_address => false, +# options => ['opt1', 'opt2'], # interfaces => { # eth0 => 'mac-address', # eth1 => 'mac-address', @@ -22,8 +21,7 @@ # } # }, # => { -# options => false, -# fixed_address => false, +# fixed_address => 'foo.example.com', # interfaces => { # eth0 => 'mac-address', # eth1 => 'mac-address', diff --git a/spec/defines/dhcp_hosts_spec.rb b/spec/defines/dhcp_hosts_spec.rb index c8face6..f5f44ca 100644 --- a/spec/defines/dhcp_hosts_spec.rb +++ b/spec/defines/dhcp_hosts_spec.rb @@ -255,6 +255,7 @@ describe 'dhcp::hosts' do } } it { should contain_concat__fragment('dhcp.host.My hosts').with( + :target => '/etc/dhcp/hosts.d/1.2.3.4.conf', :content => /fixed-address host1;/ ) } end @@ -273,6 +274,7 @@ describe 'dhcp::hosts' do } } it { should contain_concat__fragment('dhcp.host.My hosts').with( + :target => '/etc/dhcp/hosts.d/1.2.3.4.conf', :content => /foo;\nbar;\n/ ) } end @@ -292,6 +294,7 @@ describe 'dhcp::hosts' do } } it { should contain_concat__fragment('dhcp.host.My hosts').with( + :target => '/etc/dhcp/hosts.d/1.2.3.4.conf', :content => /baz;\n/ ) } end @@ -331,6 +334,7 @@ describe 'dhcp::hosts' do } } it { should contain_concat__fragment('dhcp.host.My hosts').with( + :target => '/etc/dhcp/hosts.d/1.2.3.4.conf', :content => /foo;\nbar;\n/ ) } end @@ -355,7 +359,8 @@ describe 'dhcp::hosts' do :subnet => '1.2.3.4' } } - it { should contain_concat__fragment('dhcp.host.My hosts').with_content( + it { should contain_concat__fragment('dhcp.host.My hosts').with( + :target => '/etc/dhcp/hosts.d/1.2.3.4.conf').with_content( /host host1-eth0 \{\n hardware ethernet 00:11:22:33:44:55;\n fixed-address host1;\n\}/).with_content( /host host1-wlan0 \{\n hardware ethernet 00:aa:bb:44:55:ff;\n fixed-address host1;\n\}/).with_content( /host host2-eth1 \{\n hardware ethernet 00:11:af:33:44:55;\n fixed-address foo\.example\.com;\n opt1;\n\}/) -- cgit v1.2.3 From b35e1322d0a791ab22cb2c385ec913492c75026d Mon Sep 17 00:00:00 2001 From: Raphaël Pinson Date: Fri, 12 Apr 2013 11:10:45 +0200 Subject: Rename dhcp::shared-network to dhcp::shared_network, add specs --- manifests/shared_network.pp | 15 ++++--- spec/defines/dhcp_shared_network_spec.rb | 71 ++++++++++++++++++++++++++++++++ templates/shared-network.erb | 9 ++-- 3 files changed, 87 insertions(+), 8 deletions(-) create mode 100644 spec/defines/dhcp_shared_network_spec.rb (limited to 'spec') diff --git a/manifests/shared_network.pp b/manifests/shared_network.pp index 9a02a5b..38f14fb 100644 --- a/manifests/shared_network.pp +++ b/manifests/shared_network.pp @@ -8,17 +8,22 @@ # - subnets must exists # - subnets must have $is_shared set to true (default is false) # -define dhcp::shared-network( +define dhcp::shared_network( $ensure = present, - $subnets = [] + $subnets = [], ) { - include dhcp::params + include ::dhcp::params - concat::fragment {"shared-${name}": + validate_string($ensure) + validate_re($ensure, ['present', 'absent'], + "\$ensure must be either 'present' or 'absent', got '${ensure}'") + validate_array($subnets) + + concat::fragment {"dhcp-shared-${name}": ensure => $ensure, target => "${dhcp::params::config_dir}/dhcpd.conf", - content => template('dhcp/shared-network.erb'), + content => template("${module_name}/shared-network.erb"), require => Dhcp::Subnet[$subnets], } diff --git a/spec/defines/dhcp_shared_network_spec.rb b/spec/defines/dhcp_shared_network_spec.rb new file mode 100644 index 0000000..ff5a2c5 --- /dev/null +++ b/spec/defines/dhcp_shared_network_spec.rb @@ -0,0 +1,71 @@ +require 'spec_helper' + +describe 'dhcp::shared_network' do + let (:title) { 'My network' } + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'squeeze' + } } + + context 'when passing wrong value for ensure' do + let (:params) { { + :ensure => 'running', + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp-shared-My network') + }.to raise_error(Puppet::Error, /\$ensure must be either 'present' or 'absent', got 'running'/) + end + end + + context 'when passing wrong type for subnets' do + let (:params) { { + :subnets => true, + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp-shared-My network') + }.to raise_error(Puppet::Error, /true is not an Array\./) + end + end + + context 'when passing no parameters' do + it { should contain_concat__fragment('dhcp-shared-My network').with( + :ensure => 'present', + :target => '/etc/dhcp/dhcpd.conf' + ).with_content( + /shared-network My network/ + ) + } + end + + context 'when passing wrong type for a subnet' do + let (:params) { { + :subnets => [true], + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp-shared-My network') + }.to raise_error(Puppet::Error, /true is not a string\./) + end + end + + context 'when passing wrong value for a subnet' do + let (:params) { { + :subnets => ['wrong value'], + } } + + it 'should fail' do + expect { + should contain_concat__fragment('dhcp-shared-My network') + }.to raise_error(Puppet::Error, /"wrong value" does not match/) + end + end + + context 'when passing subnets' do + end +end diff --git a/templates/shared-network.erb b/templates/shared-network.erb index 99a7aca..407106a 100644 --- a/templates/shared-network.erb +++ b/templates/shared-network.erb @@ -1,6 +1,9 @@ -#### dhcp::shared-network <%= name %> -shared-network <%= name %> { -<% subnets.each do |subnet| -%> +#### dhcp::shared_network <%= @name %> +shared-network <%= @name %> { +<% @subnets.each do |subnet| + scope.function_validate_string([subnet]) + scope.function_validate_re([subnet, '^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$']) +-%> include "<%= scope.lookupvar("dhcp::params::config_dir") %>/subnets/<%= subnet %>.conf"; <% end -%> } -- cgit v1.2.3 From e7cdc4e685a73d05be05ea9d6d0f854c4a3a6ab2 Mon Sep 17 00:00:00 2001 From: Raphaël Pinson Date: Fri, 12 Apr 2013 11:18:56 +0200 Subject: Test working dhcp::shared_network --- spec/defines/dhcp_shared_network_spec.rb | 12 +++++++++++- templates/shared-network.erb | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'spec') diff --git a/spec/defines/dhcp_shared_network_spec.rb b/spec/defines/dhcp_shared_network_spec.rb index ff5a2c5..d59f73c 100644 --- a/spec/defines/dhcp_shared_network_spec.rb +++ b/spec/defines/dhcp_shared_network_spec.rb @@ -37,7 +37,7 @@ describe 'dhcp::shared_network' do :ensure => 'present', :target => '/etc/dhcp/dhcpd.conf' ).with_content( - /shared-network My network/ + /shared-network My network \{\n\}/ ) } end @@ -67,5 +67,15 @@ describe 'dhcp::shared_network' do end context 'when passing subnets' do + let (:params) { { + :subnets => ['1.2.3.4', '5.6.7.8'], + } } + + it { should contain_concat__fragment('dhcp-shared-My network').with( + :ensure => 'present', + :target => '/etc/dhcp/dhcpd.conf' + ).with_content( + /shared-network My network \{\n include "\/etc\/dhcp\/subnets\/1\.2\.3\.4\.conf";\n include "\/etc\/dhcp\/subnets\/5\.6\.7\.8\.conf";\n\}/) + } end end diff --git a/templates/shared-network.erb b/templates/shared-network.erb index 407106a..33810b8 100644 --- a/templates/shared-network.erb +++ b/templates/shared-network.erb @@ -7,4 +7,4 @@ shared-network <%= @name %> { include "<%= scope.lookupvar("dhcp::params::config_dir") %>/subnets/<%= subnet %>.conf"; <% end -%> } -#### END <%= name %> +#### END <%= @name %> -- cgit v1.2.3 From eda301b7ba8f8827d1c9973ffaba0c1c7a029d98 Mon Sep 17 00:00:00 2001 From: Raphaël Pinson Date: Fri, 12 Apr 2013 12:29:45 +0200 Subject: Add spec for dhcp::subnet and improve template and definition --- manifests/subnet.pp | 57 +++++---- spec/defines/dhcp_subnet_spec.rb | 252 +++++++++++++++++++++++++++++++++++++++ templates/subnet.conf.erb | 49 ++++---- 3 files changed, 307 insertions(+), 51 deletions(-) create mode 100644 spec/defines/dhcp_subnet_spec.rb (limited to 'spec') diff --git a/manifests/subnet.pp b/manifests/subnet.pp index 18ffdc5..b9826da 100644 --- a/manifests/subnet.pp +++ b/manifests/subnet.pp @@ -27,16 +27,29 @@ # define dhcp::subnet( $broadcast, - $ensure=present, - $netmask=false, - $routers=false, - $subnet_mask=false, - $domain_name=false, - $other_opts=false, - $is_shared=false + $ensure = present, + $netmask = undef, + $routers = [], + $subnet_mask = undef, + $domain_name = undef, + $other_opts = [], + $is_shared = false ) { - include dhcp::params + include ::dhcp::params + + $ip_re = '^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$' + + validate_string($ensure) + validate_re($ensure, ['present', 'absent'], + "\$ensure must be either 'present' or 'absent', got '${ensure}'") + validate_string($broadcast) + validate_re($broadcast, $ip_re) + validate_string($netmask) + validate_array($routers) + validate_string($subnet_mask) + validate_string($domain_name) + validate_bool($is_shared) concat {"${dhcp::params::config_dir}/hosts.d/${name}.conf": owner => root, @@ -48,34 +61,30 @@ define dhcp::subnet( ensure => $ensure, owner => root, group => root, - content => template('dhcp/subnet.conf.erb'), + content => template("${module_name}/subnet.conf.erb"), notify => Service['dhcpd'], } - if ! $is_shared { - concat::fragment {"dhcp.${name}": - ensure => $ensure, - target => "${dhcp::params::config_dir}/dhcpd.conf", - content => "include \"${dhcp::params::config_dir}/subnets/${name}.conf\";\n", - } - } else { - concat::fragment {"dhcp.${name}": - ensure => absent, - target => "${dhcp::params::config_dir}/dhcpd.conf", - content => "include \"${dhcp::params::config_dir}/subnets/${name}.conf\";\n", - } - + $ensure_shared = $is_shared ? { + true => $ensure, + false => 'absent', + } + concat::fragment {"dhcp.subnet.${name}": + ensure => $ensure_shared, + target => "${dhcp::params::config_dir}/dhcpd.conf", + content => "include \"${dhcp::params::config_dir}/subnets/${name}.conf\";\n", } - concat::fragment {"subnet.${name}.hosts": + concat::fragment {"dhcp.subnet.${name}.hosts": ensure => $ensure, target => "${dhcp::params::config_dir}/dhcpd.conf", content => "include \"${dhcp::params::config_dir}/hosts.d/${name}.conf\";\n", } - concat::fragment {"00.dhcp.${name}.base": + concat::fragment {"dhcp.subnet.${name}.base": ensure => $ensure, target => "${dhcp::params::config_dir}/hosts.d/${name}.conf", content => "# File managed by puppet\n", + order => '00', } } diff --git a/spec/defines/dhcp_subnet_spec.rb b/spec/defines/dhcp_subnet_spec.rb new file mode 100644 index 0000000..48ab71b --- /dev/null +++ b/spec/defines/dhcp_subnet_spec.rb @@ -0,0 +1,252 @@ +require 'spec_helper' + +describe 'dhcp::subnet' do + let (:title) { '1.2.3.4' } + let (:facts) { { + :operatingsystem => 'Debian', + :osfamily => 'Debian', + :lsbdistcodename => 'squeeze', + :netmask_eth0 => '255.255.255.0', + :domain => 'example.com', + } } + + context 'when passing wrong value for ensure' do + let (:params) { { + :ensure => 'running', + :broadcast => '1.2.3.4', + } } + + it 'should fail' do + expect { + should contain_concat('/etc/dhcp/hosts.d/1.2.3.4.conf') + }.to raise_error(Puppet::Error, /\$ensure must be either 'present' or 'absent', got 'running'/) + end + end + + context 'when not passing broadcast' do + it 'should fail' do + expect { + should contain_concat('/etc/dhcp/hosts.d/1.2.3.4.conf') + }.to raise_error(Puppet::Error, /Must pass broadcast to Dhcp::Subnet/) + end + end + + context 'when passing wrong type for broadcast' do + let (:params) { { + :broadcast => true, + } } + + it 'should fail' do + expect { + should contain_concat('/etc/dhcp/hosts.d/1.2.3.4.conf') + }.to raise_error(Puppet::Error, /true is not a string\./) + end + end + + context 'when passing wrong value for broadcast' do + let (:params) { { + :broadcast => 'foo', + } } + + it 'should fail' do + expect { + should contain_concat('/etc/dhcp/hosts.d/1.2.3.4.conf') + }.to raise_error(Puppet::Error, /"foo" does not match/) + end + end + + context 'when passing wrong type for netmask' do + let (:params) { { + :broadcast => '1.2.3.4', + :netmask => true, + } } + + it 'should fail' do + expect { + should contain_concat('/etc/dhcp/hosts.d/1.2.3.4.conf') + }.to raise_error(Puppet::Error, /true is not a string\./) + end + end + + context 'when passing wrong value for netmask' do + let (:params) { { + :broadcast => '1.2.3.4', + :netmask => 'foo', + } } + + it 'should fail' do + expect { + should contain_concat('/etc/dhcp/hosts.d/1.2.3.4.conf') + }.to raise_error(Puppet::Error, /"foo" does not match/) + end + end + + context 'when passing wrong type for routers' do + let (:params) { { + :broadcast => '1.2.3.4', + :routers => true, + } } + + it 'should fail' do + expect { + should contain_concat('/etc/dhcp/hosts.d/1.2.3.4.conf') + }.to raise_error(Puppet::Error, /true is not an Array\./) + end + end + + context 'when passing wrong type for subnet_mask' do + let (:params) { { + :broadcast => '1.2.3.4', + :subnet_mask => true, + } } + + it 'should fail' do + expect { + should contain_concat('/etc/dhcp/hosts.d/1.2.3.4.conf') + }.to raise_error(Puppet::Error, /true is not a string\./) + end + end + + context 'when passing wrong type for domain_name' do + let (:params) { { + :broadcast => '1.2.3.4', + :domain_name => true, + } } + + it 'should fail' do + expect { + should contain_concat('/etc/dhcp/hosts.d/1.2.3.4.conf') + }.to raise_error(Puppet::Error, /true is not a string\./) + end + end + + context 'when passing wrong type for is_shared' do + let (:params) { { + :broadcast => '1.2.3.4', + :is_shared => 'foo', + } } + + it 'should fail' do + expect { + should contain_concat('/etc/dhcp/hosts.d/1.2.3.4.conf') + }.to raise_error(Puppet::Error, /"foo" is not a boolean\./) + end + end + + context 'when using defaults' do + let (:params) { { + :broadcast => '1.2.3.4', + } } + + it { should contain_concat('/etc/dhcp/hosts.d/1.2.3.4.conf').with( + :owner => 'root', + :group => 'root', + :mode => '0644' + ) } + + it { should contain_file('/etc/dhcp/subnets/1.2.3.4.conf').with( + :ensure => 'present', + :owner => 'root', + :group => 'root' + ).with_content( + /subnet 1\.2\.3\.4 netmask 255\.255\.255\.0 \{\n/ + ).with_content( + /option routers 255\.255\.255\.0;\n/ + ).with_content( + /option subnet-mask 255\.255\.255\.0;\n/ + ).with_content( + /option broadcast-address 1\.2\.3\.4;\n/ + ).with_content( + /option domain-name "example\.com";\n/ + ) } + + it { should contain_concat__fragment('dhcp.subnet.1.2.3.4').with( + :ensure => 'absent' + ) } + + it { should contain_concat__fragment('dhcp.subnet.1.2.3.4.hosts').with( + :ensure => 'present', + :target => '/etc/dhcp/dhcpd.conf', + :content => "include \"/etc/dhcp/hosts.d/1\.2\.3\.4\.conf\";\n" + ) } + + it { should contain_concat__fragment('dhcp.subnet.1.2.3.4.base').with( + :ensure => 'present', + :target => '/etc/dhcp/hosts.d/1.2.3.4.conf', + :content => "# File managed by puppet\n", + :order => '00' + ) } + end + + context 'when is_shared is true' do + let (:params) { { + :broadcast => '1.2.3.4', + :is_shared => true, + } } + + it { should contain_concat__fragment('dhcp.subnet.1.2.3.4').with( + :ensure => 'present', + :target => '/etc/dhcp/dhcpd.conf', + :content => "include \"/etc/dhcp/subnets/1.2.3.4.conf\";\n" + ) } + end + + context 'when passing other_opts as array' do + let (:params) { { + :broadcast => '1.2.3.4', + :other_opts => ['foo', 'bar'], + } } + + it { should contain_file('/etc/dhcp/subnets/1.2.3.4.conf').with( + :ensure => 'present', + :owner => 'root', + :group => 'root' + ).with_content( + / foo;\n bar;\n/ + ) } + end + + context 'when passing other_opts as string' do + let (:params) { { + :broadcast => '1.2.3.4', + :other_opts => 'bar', + } } + + it { should contain_file('/etc/dhcp/subnets/1.2.3.4.conf').with( + :ensure => 'present', + :owner => 'root', + :group => 'root' + ).with_content( + / bar;\n/ + ) } + end + + context 'when overriding all parameters' do + let (:params) { { + :broadcast => '1.2.3.4', + :netmask => '255.1.2.0', + :routers => ['2.3.4.5', '3.4.5.6'], + :subnet_mask => '255.255.1.0', + :domain_name => 'foo.io', + :other_opts => ['foo', 'bar'], + } } + + it { should contain_file('/etc/dhcp/subnets/1.2.3.4.conf').with( + :ensure => 'present', + :owner => 'root', + :group => 'root' + ).with_content( + /subnet 1\.2\.3\.4 netmask 255\.1\.2\.0 \{\n/ + ).with_content( + /option routers 2\.3\.4\.5,3\.4\.5\.6;\n/ + ).with_content( + /option subnet-mask 255\.255\.1\.0;\n/ + ).with_content( + /option broadcast-address 1\.2\.3\.4;\n/ + ).with_content( + /option domain-name "foo\.io";\n/ + ).with_content( + / foo;\n bar;\n/ + ) } + end +end diff --git a/templates/subnet.conf.erb b/templates/subnet.conf.erb index 89ca82f..11f9ed4 100644 --- a/templates/subnet.conf.erb +++ b/templates/subnet.conf.erb @@ -1,33 +1,28 @@ # File managed by puppet -<% if netmask -%> -subnet <%=name%> netmask <%=netmask%> { -<% else -%> -subnet <%=name%> netmask <%=netmask_eth0%> { -<% end -%> -<% if routers and not routers.empty? -%> - option routers <%= routers.collect! {|i| "#{i}" }.join(",") %>; -<% else -%> - option routers <%=network_eth0%>; -<% end -%> -<% if subnet_mask -%> - option subnet-mask <%=subnet_mask%>; -<% elsif netmask -%> - option subnet-mask <%=netmask%>; -<% else -%> - option subnet-mask <%=netmask_eth0%>; -<% end -%> - option broadcast-address <%=broadcast%>; -<% if domain_name -%> - option domain-name "<%=domain_name%>"; -<% else -%> - option domain-name "<%=domain%>"; -<% end -%> -<% if other_opts and not other_opts.empty? -%> - <% if other_opts.is_a?(Array) -%> -<%= other_opts.collect! {|i| " #{i};"}.join("\n") %> +<%- + _netmask = @netmask || scope.lookupvar('::netmask_eth0') + scope.function_validate_re([_netmask, @ip_re]) -%> +subnet <%= @name %> netmask <%= _netmask %> { +<%- + _routers = @routers unless @routers.empty? + _routers ||= [scope.lookupvar('::netmask_eth0')] + scope.function_validate_array([_routers]) -%> + option routers <%= _routers.collect! {|i| "#{i}" }.join(',') %>; +<%- + _subnet_mask = @subnet_mask || _netmask + scope.function_validate_re([_subnet_mask, @ip_re]) -%> + option subnet-mask <%= _subnet_mask %>; + option broadcast-address <%= @broadcast %>; +<%- + _domain_name = @domain_name || scope.lookupvar('::domain') + scope.function_validate_re([_domain_name, '^\S+$']) -%> + option domain-name "<%= _domain_name %>"; +<% unless @other_opts.empty? -%> + <% if @other_opts.is_a?(Array) -%> +<%= @other_opts.collect! {|i| " #{i};"}.join("\n") %> <% else -%> - <%=other_opts%>; + <%= @other_opts %>; <% end -%> <% end -%> } -- cgit v1.2.3 From 1ad8359dc57c99c1671d7cb41b961c451fb1c22f Mon Sep 17 00:00:00 2001 From: Raphaël Pinson Date: Fri, 12 Apr 2013 14:27:05 +0200 Subject: capital letters are valid in mac addresses --- spec/defines/dhcp_hosts_spec.rb | 4 ++-- templates/host.conf.erb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'spec') diff --git a/spec/defines/dhcp_hosts_spec.rb b/spec/defines/dhcp_hosts_spec.rb index f5f44ca..8170ed5 100644 --- a/spec/defines/dhcp_hosts_spec.rb +++ b/spec/defines/dhcp_hosts_spec.rb @@ -350,7 +350,7 @@ describe 'dhcp::hosts' do }, 'host2' => { 'interfaces' => { - 'eth1' => '00:11:af:33:44:55', + 'eth1' => '00:11:AF:33:44:55', }, 'fixed_address' => 'foo.example.com', 'options' => ['opt1'], @@ -363,7 +363,7 @@ describe 'dhcp::hosts' do :target => '/etc/dhcp/hosts.d/1.2.3.4.conf').with_content( /host host1-eth0 \{\n hardware ethernet 00:11:22:33:44:55;\n fixed-address host1;\n\}/).with_content( /host host1-wlan0 \{\n hardware ethernet 00:aa:bb:44:55:ff;\n fixed-address host1;\n\}/).with_content( - /host host2-eth1 \{\n hardware ethernet 00:11:af:33:44:55;\n fixed-address foo\.example\.com;\n opt1;\n\}/) + /host host2-eth1 \{\n hardware ethernet 00:11:AF:33:44:55;\n fixed-address foo\.example\.com;\n opt1;\n\}/) } end end diff --git a/templates/host.conf.erb b/templates/host.conf.erb index 1c690b4..c483d62 100644 --- a/templates/host.conf.erb +++ b/templates/host.conf.erb @@ -4,7 +4,7 @@ data.fetch('interfaces').sort.each do |if_name, if_mac| scope.function_validate_re([if_name, '^\S+$']) scope.function_validate_string([if_mac]) - scope.function_validate_re([if_mac, '^[a-f0-9:.]+$']) + scope.function_validate_re([if_mac, '^[A-Fa-f0-9:.]+$']) -%> host <%= host %>-<%= if_name %> { hardware ethernet <%= if_mac %>; -- cgit v1.2.3 From c0f46562b70777b9a4a39429d94c49e869150c64 Mon Sep 17 00:00:00 2001 From: Raphaël Pinson Date: Fri, 12 Apr 2013 15:14:55 +0200 Subject: Fix inverted logic for $is_shared in dhcp::subnet --- manifests/subnet.pp | 4 ++-- spec/defines/dhcp_subnet_spec.rb | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'spec') diff --git a/manifests/subnet.pp b/manifests/subnet.pp index b70a233..e7c72dd 100644 --- a/manifests/subnet.pp +++ b/manifests/subnet.pp @@ -64,8 +64,8 @@ define dhcp::subnet( } $ensure_shared = $is_shared ? { - true => $ensure, - false => 'absent', + true => 'absent', + false => $ensure, } concat::fragment {"dhcp.subnet.${name}": ensure => $ensure_shared, diff --git a/spec/defines/dhcp_subnet_spec.rb b/spec/defines/dhcp_subnet_spec.rb index 48ab71b..b679551 100644 --- a/spec/defines/dhcp_subnet_spec.rb +++ b/spec/defines/dhcp_subnet_spec.rb @@ -161,7 +161,9 @@ describe 'dhcp::subnet' do ) } it { should contain_concat__fragment('dhcp.subnet.1.2.3.4').with( - :ensure => 'absent' + :ensure => 'present', + :target => '/etc/dhcp/dhcpd.conf', + :content => "include \"/etc/dhcp/subnets/1.2.3.4.conf\";\n" ) } it { should contain_concat__fragment('dhcp.subnet.1.2.3.4.hosts').with( @@ -185,9 +187,7 @@ describe 'dhcp::subnet' do } } it { should contain_concat__fragment('dhcp.subnet.1.2.3.4').with( - :ensure => 'present', - :target => '/etc/dhcp/dhcpd.conf', - :content => "include \"/etc/dhcp/subnets/1.2.3.4.conf\";\n" + :ensure => 'absent' ) } end -- cgit v1.2.3