From ca9bfad600ffaa0eb37533c9d86c9912ad35d833 Mon Sep 17 00:00:00 2001 From: Cédric Jeanneret Date: Fri, 30 Oct 2015 13:57:27 +0100 Subject: added new dhcp::failover, related unit-test and updated doc --- README.md | 29 ++++++ manifests/failover.pp | 41 ++++++++ spec/defines/dhcp_failover_spec.rb | 204 +++++++++++++++++++++++++++++++++++++ templates/failover.conf.erb | 14 +++ 4 files changed, 288 insertions(+) create mode 100644 manifests/failover.pp create mode 100644 spec/defines/dhcp_failover_spec.rb create mode 100644 templates/failover.conf.erb diff --git a/README.md b/README.md index a5f323e..f083591 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ Installs a DHCP server: * dhcp::hosts * dhcp::shared\_network * dhcp::subnet +* dhcp::failover ### dhcp::hosts @@ -74,6 +75,34 @@ Creates a subnet: other_opts => ['filename "pxelinux.0";', 'next-server 10.27.10.1;'], } +## dhcp::failover + +Creates a failover peer: + + dhcp::failover {'my-failover-peer': + ensure => present, + peer_address => '1.2.3.4', + options => { + 'max-response-delay' => 30, + 'max-unacked-updates' => 10, + 'load balance max seconds' => 3, + 'mclt' => 1800, + 'split' => 128, + } + } + dhcp::subnet {"10.27.20.0": + ensure => present, + broadcast => "10.27.20.255", + other_opts => [ + 'pool {', + 'failover peer "my-failover-peer";', + 'max-lease-time 1800;', + 'range 10.27.20.100 10.27.20.250;', + '}', + ], + } + + ## Contributing Please report bugs and feature request using [GitHub issue diff --git a/manifests/failover.pp b/manifests/failover.pp new file mode 100644 index 0000000..6b465f2 --- /dev/null +++ b/manifests/failover.pp @@ -0,0 +1,41 @@ +define dhcp::failover( + $peer_address, + $ensure = present, + $address = $::ipaddress, + $peer_port = 647, + $port = 647, + $options = {}, + $role = 'primary', +) { + + validate_re($ensure, ['present', 'absent']) + validate_ipv4_address($address) + validate_ipv4_address($peer_address) + validate_integer($port) + validate_integer($peer_port) + validate_hash($options) + validate_re($role, ['primary', 'secondary']) + + include ::dhcp::params + + $_ensure = $ensure? { + 'present' => 'file', + default => $ensure, + } + + file {"${dhcp::params::config_dir}/failover/${name}.conf": + ensure => $_ensure, + content => template("${module_name}/failover.conf.erb"), + group => 'root', + mode => '0644', + notify => Service['dhcpd'], + owner => 'root', + } + + concat::fragment {"dhcp.failover.${name}": + ensure => $ensure, + content => "include \"${dhcp::params::config_dir}/failover/${name}.conf\";\n", + target => "${dhcp::params::config_dir}/dhcpd.conf", + } + +} diff --git a/spec/defines/dhcp_failover_spec.rb b/spec/defines/dhcp_failover_spec.rb new file mode 100644 index 0000000..d8400b0 --- /dev/null +++ b/spec/defines/dhcp_failover_spec.rb @@ -0,0 +1,204 @@ +require 'spec_helper' + +describe 'dhcp::failover' do + let (:title) { 'failover-dhcp' } + + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) do + facts.merge({ + :concat_basedir => '/var/lib/puppet/concat', + :domain => 'example.com', + :ipaddress => '1.2.3.3', + }) + end + + context 'when passing wrong value for ensure' do + let (:params) { { + :ensure => 'foo', + :peer_address => '1.2.3.4', + } } + + it 'should fail' do + expect { + should contain_file('/etc/dhcp/failover/failover-dhcp.conf') + }.to raise_error(Puppet::Error, /"foo" does not match \["present", "absent"\]/) + end + end + + context 'when passing wrong type for address' do + let (:params) { { + :address => true, + :peer_address => '1.2.3.4', + } } + + it 'should fail' do + expect { + should contain_file('/etc/dhcp/failover/failover-dhcp.conf') + }.to raise_error(Puppet::Error, /true is not a string\./) + end + end + + context 'when passing wrong value for address' do + let (:params) { { + :address => 'foo', + :peer_address => '1.2.3.4', + } } + + it 'should fail' do + expect { + should contain_file('/etc/dhcp/failover/failover-dhcp.conf') + }.to raise_error(Puppet::Error, /is not a valid IPv4 address\./) + end + end + + context 'when not passing peer_address' do + it 'should fail' do + expect { + should contain_file('/etc/dhcp/failover/failover-dhcp.conf') + }.to raise_error(Puppet::Error, /Must pass peer_address to Dhcp::Failover/) + end + end + + context 'when passing wrong type for peer_address' do + let (:params) { { + :peer_address => true, + } } + + it 'should fail' do + expect { + should contain_file('/etc/dhcp/failover/failover-dhcp.conf') + }.to raise_error(Puppet::Error, /true is not a string\./) + end + end + + context 'when passing wrong value for peer_address' do + let (:params) { { + :peer_address => 'foo', + } } + + it 'should fail' do + expect { + should contain_file('/etc/dhcp/failover/failover-dhcp.conf') + }.to raise_error(Puppet::Error, /is not a valid IPv4 address\./) + end + end + + context 'when passing wrong type for peer_port' do + let (:params) { { + :peer_port => 'foo', + :peer_address => '1.2.3.4', + } } + + it 'should fail' do + expect { + should contain_file('/etc/dhcp/failover/failover-dhcp.conf') + }.to raise_error(Puppet::Error, /Expected first argument to be an Integer/) + end + end + + context 'when passing wrong type for port' do + let (:params) { { + :peer_address => '1.2.3.4', + :port => 'foo', + } } + + it 'should fail' do + expect { + should contain_file('/etc/dhcp/failover/failover-dhcp.conf') + }.to raise_error(Puppet::Error, /Expected first argument to be an Integer/) + end + end + + + + context 'when using defaults' do + let (:params) { { + :peer_address => '1.2.3.4', + } } + + it { should contain_file('/etc/dhcp/failover/failover-dhcp.conf').with( + :ensure => 'file', + :owner => 'root', + :group => 'root' + ).with_content( + /failover peer "failover-dhcp" \{\n/ + ).with_content( + /primary;\n/ + ).with_content( + /address 1.2.3.3;\n/ + ).with_content( + /port 647;\n/ + ).with_content( + /peer address 1.2.3.4;\n/ + ).with_content( + /peer port 647;\n/ + ) } + it { should contain_concat__fragment('dhcp.failover.failover-dhcp').with({ + :content => "include \"/etc/dhcp/failover/failover-dhcp.conf\";\n", + :target => '/etc/dhcp/dhcpd.conf', + })} + end + + context 'when passing options as a hash' do + let (:params) { { + :peer_address => '1.2.3.4', + :options => { + 'max-response-delay' => '30', + 'max-unacked-updates' => '10', + 'load balance max seconds' => '3', + 'mclt' => '1800', + 'split' => '128', + }, + } } + + it { should contain_file('/etc/dhcp/failover/failover-dhcp.conf').with({ + :ensure => 'file', + :owner => 'root', + :group => 'root' + }).with_content( + /failover peer "failover-dhcp" \{\n/ + ).with_content( + / load balance max seconds 3;\n/ + ).with_content( + / max-response-delay 30;\n/ + ).with_content( + / max-unacked-updates 10;\n/ + ).with_content( + / mclt 1800;\n/ + ).with_content( + / split 128;\n/ + ) } + end + + context 'when overriding all parameters' do + let (:params) { { + :peer_address => '1.2.3.4', + :address => '1.2.3.5', + :peer_port => 847, + :port => 847, + :options => { + 'mclt' => 1800, + }, + :role => 'secondary', + } } + + it { should contain_file('/etc/dhcp/failover/failover-dhcp.conf').with({ + :ensure => 'file', + :owner => 'root', + :group => 'root' + }).with_content( + /secondary;\n/ + ).with_content( + /address 1.2.3.5;\n/ + ).with_content( + /port 847;\n/ + ).with_content( + /peer port 847;\n/ + ).with_content( + /mclt 1800;\n/ + ) } + end + end + end +end diff --git a/templates/failover.conf.erb b/templates/failover.conf.erb new file mode 100644 index 0000000..3b9441f --- /dev/null +++ b/templates/failover.conf.erb @@ -0,0 +1,14 @@ +failover peer "<%=@name%>" { + <%=@role%>; + address <%=@address%>; + port <%=@port%>; + peer address <%=@peer_address%>; + peer port <%=@peer_port%>; +<%- + @options.sort.each do |k,v| +-%> + <%=k%> <%=v%>; +<%- +end +-%> +} -- cgit v1.2.3