aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md29
-rw-r--r--manifests/failover.pp41
-rw-r--r--spec/defines/dhcp_failover_spec.rb204
-rw-r--r--templates/failover.conf.erb14
4 files changed, 288 insertions, 0 deletions
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
+-%>
+}