From 7573dce19395f00763be7f4b8d548532f98cf7b1 Mon Sep 17 00:00:00 2001 From: Roberto Valentini Date: Tue, 9 Jul 2024 16:28:34 +0200 Subject: [PATCH] Add shared-network configuration --- manifests/init.pp | 7 ++++++ manifests/sharednet.pp | 22 ++++++++++++++++++ manifests/subnet.pp | 7 ++++-- spec/acceptance/shared_spec.rb | 41 ++++++++++++++++++++++++++++++++++ spec/classes/init_spec.rb | 14 ++++++++++++ 5 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 manifests/sharednet.pp create mode 100644 spec/acceptance/shared_spec.rb diff --git a/manifests/init.pp b/manifests/init.pp index 3360f97..d740086 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -2,6 +2,8 @@ # # @param option_static_route # When enabled it sets the options rfc3442-classless-static-routes and ms-classless-static-routes +# @param shared_network +# When used it configure subnet in shared-network statement, it is used to inform the DHCP server that it share the same physical network class dhcp ( Array[String] $dnsdomain = $dhcp::params::dnsdomain, Array[String] $nameservers = [], @@ -46,6 +48,7 @@ Hash[String, Hash] $hosts = {}, Variant[Array[String], Optional[String]] $includes = undef, String $config_comment = 'dhcpd.conf', + Optional[Hash[String, Hash]] $shared_networks = undef, ) inherits dhcp::params { # In case people set interface instead of interfaces work around # that. If they set both, use interfaces and the user is a unwise @@ -157,6 +160,10 @@ order => '01', } + if $shared_networks { + create_resources('dhcp::sharednet', $shared_networks) + } + create_resources('dhcp::subnet', $subnets) create_resources('dhcp::pool', $pools) create_resources('dhcp::host', $hosts) diff --git a/manifests/sharednet.pp b/manifests/sharednet.pp new file mode 100644 index 0000000..0928a2b --- /dev/null +++ b/manifests/sharednet.pp @@ -0,0 +1,22 @@ +# @summary +# Define a DHCP shared-network +# @param subnets +# subnets to include in the shared-network statement +# @param order +# Fragment order in the dhcpd.conf +define dhcp::sharednet ( + Hash[String,Hash] $subnets = {}, + Integer[1] $order = 75, +) { + concat::fragment { "dhcp.conf+${order}-start_${name}.dhcp": + target => "${dhcp::dhcp_dir}/dhcpd.conf", + content => "shared-network ${name} {\n", + order => "${order}-0start", + } + concat::fragment { "dhcp.conf+${order}-end_${name}.dhcp": + target => "${dhcp::dhcp_dir}/dhcpd.conf", + content => "}\n", + order => "${order}-9end", + } + create_resources('dhcp::subnet', $subnets, { order => $order }) +} diff --git a/manifests/subnet.pp b/manifests/subnet.pp index c8908b6..dd25bdf 100644 --- a/manifests/subnet.pp +++ b/manifests/subnet.pp @@ -45,6 +45,8 @@ # Partial that is appended to the dhcpd.conf (before the final `}`) # @param raw_prepend # Partial that is prepended to the dhcpd.conf (after the first `{`) +# @param order +# Fragment order in the dhcpd.conf define dhcp::subnet ( Stdlib::IP::Address::Nosubnet $network, Stdlib::IP::Address::Nosubnet $mask, @@ -61,10 +63,11 @@ Variant[Array[String], Optional[String]] $search_domains = undef, Optional[String] $raw_append = undef, Optional[String] $raw_prepend = undef, + Integer[1] $order = 70, ) { - concat::fragment { "dhcp.conf+70_${name}.dhcp": + concat::fragment { "dhcp.conf+${order}_${name}.dhcp": target => "${dhcp::dhcp_dir}/dhcpd.conf", content => template('dhcp/dhcpd.subnet.erb'), - order => "70-${name}", + order => "${order}-${name}", } } diff --git a/spec/acceptance/shared_spec.rb b/spec/acceptance/shared_spec.rb new file mode 100644 index 0000000..4323c50 --- /dev/null +++ b/spec/acceptance/shared_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper_acceptance' + +describe 'Simple installation' do + interface = 'eth0' + config_file = fact('os.family') == 'Archlinux' ? '/etc/dhcpd.conf' : '/etc/dhcp/dhcpd.conf' + + it_behaves_like 'an idempotent resource' do + let(:manifest) do + <<-EOS + $interface = $facts['networking']['interfaces']['#{interface}'] + + class { 'dhcp': + interfaces => ['#{interface}'], + shared_networks => { + 'shared' => { + subnets => { + $interface['network'] => { + network => $interface['network'], + mask => $interface['netmask'], + pools => [], + }, + '172.20.0.0' => { + network => '172.20.0.0', + mask => '255.255.255.0', + pools => [], + } + } + } + }, + } + EOS + end + end + + it_behaves_like 'a DHCP server' + + describe file(config_file) do + it { is_expected.to be_file } + its(:content) { should match(/shared-network shared/) } + end +end diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index dc825c3..15e5e5b 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -534,6 +534,20 @@ it { is_expected.to compile.and_raise_error(%r{dnsupdateserver or nameservers parameter is required to enable ddns}) } end end + + describe "with shared_network" do + let(:params) { super().merge(shared_network: "shared") } + + let(:expected_content) do + <<~CONTENT + shared-network shared { + CONTENT + end + + it do + is_expected.to contain_concat__fragment('dhcp.conf+75-start_shared.dhcp').with_content(expected_content) + end + end end end end