diff --git a/REFERENCE.md b/REFERENCE.md index 8d72878..c0436cd 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -2046,13 +2046,21 @@ Type: Ruby 3.x API Generates MAC addresses for all interfaces in the array which do not yet have an address specified. The MAC addresses are based on the domain name, network and -portgroup. The function libvirt_generate_mac is used to generate a single mac address. +portgroup or the whole interface configuration (excluding the 'filter' key, to avoid +mac changes when the firewall rules change).#{' '} +The function libvirt_generate_mac is used to generate a single mac address. +Additional remark: If the same network config is attached to a node twice +the resulting mac address is the same ! #### `libvirt_generate_mac_addresses(Any $hash)` Generates MAC addresses for all interfaces in the array which do not yet have an address specified. The MAC addresses are based on the domain name, network and -portgroup. The function libvirt_generate_mac is used to generate a single mac address. +portgroup or the whole interface configuration (excluding the 'filter' key, to avoid +mac changes when the firewall rules change).#{' '} +The function libvirt_generate_mac is used to generate a single mac address. +Additional remark: If the same network config is attached to a node twice +the resulting mac address is the same ! Returns: `Any` the interfacess with mac address diff --git a/lib/puppet/parser/functions/libvirt_generate_mac_addresses.rb b/lib/puppet/parser/functions/libvirt_generate_mac_addresses.rb index a8660ff..3769ae7 100644 --- a/lib/puppet/parser/functions/libvirt_generate_mac_addresses.rb +++ b/lib/puppet/parser/functions/libvirt_generate_mac_addresses.rb @@ -4,7 +4,11 @@ module Puppet::Parser::Functions newfunction(:libvirt_generate_mac_addresses, type: :rvalue, doc: <<-ENDHEREDOC) do |args| Generates MAC addresses for all interfaces in the array which do not yet have an address specified. The MAC addresses are based on the domain name, network and - portgroup. The function libvirt_generate_mac is used to generate a single mac address. + portgroup or the whole interface configuration (excluding the 'filter' key, to avoid + mac changes when the firewall rules change).#{' '} + The function libvirt_generate_mac is used to generate a single mac address. + Additional remark: If the same network config is attached to a node twice + the resulting mac address is the same ! @param hash of interfaces @return the interfacess with mac address @@ -21,8 +25,11 @@ module Puppet::Parser::Functions iface['mac'] = if iface['network'] function_libvirt_generate_mac([domain_name, iface['network'], iface['portgroup']]) + elsif iface['source'] && iface['source']['network'] + function_libvirt_generate_mac([domain_name, iface['source']['network'], iface['source']['portgroup']]) else - function_libvirt_generate_mac(['blah']) + function_libvirt_generate_mac([domain_name, iface.reject { |k, _v| k == 'filter' }.to_s]) + # iface.reject{|k, v| k == 'filter'} end end end diff --git a/spec/functions/libvirt_generate_mac_addresses_spec.rb b/spec/functions/libvirt_generate_mac_addresses_spec.rb index e1045b8..5cc9edc 100644 --- a/spec/functions/libvirt_generate_mac_addresses_spec.rb +++ b/spec/functions/libvirt_generate_mac_addresses_spec.rb @@ -37,10 +37,54 @@ { 'network' => 'test', 'portgroup' => 'he' }, { 'network' => 'test', 'portgroup' => 'll', 'mac' => '42:42:42:42:42:42' }, { 'network' => 'prod', 'portgroup' => 'oo' }, + { 'network' => 'nopo' }, ]).and_return([ { 'network' => 'test', 'portgroup' => 'he', 'mac' => '52:54:00:d8:54:bc' }, { 'network' => 'test', 'portgroup' => 'll', 'mac' => '42:42:42:42:42:42' }, { 'network' => 'prod', 'portgroup' => 'oo', 'mac' => '52:54:00:b8:cf:03' }, + { 'network' => 'nopo', 'mac' => '52:54:00:14:ec:f8' }, + ]) + } + end + + context 'with interface source and predefined mac' do + it { + is_expected.to run.with_params([ + { 'source' => { 'network' => 'test' }, 'mac' => '42:42::42:42:42:42' }, + ]).and_return([ + { 'source' => { 'network' => 'test' }, 'mac' => '42:42::42:42:42:42' }, + ]) + } + end + + context 'with multiple mixed source interfaces' do + it { + is_expected.to run.with_params([ + { 'source' => { 'network' => 'test', 'portgroup' => 'he' } }, + { 'source' => { 'network' => 'test', 'portgroup' => 'll' }, 'mac' => '42:42:42:42:42:42' }, + { 'source' => { 'network' => 'prod', 'portgroup' => 'oo' } }, + { 'source' => { 'network' => 'nopo' } }, + ]).and_return([ + { 'source' => { 'network' => 'test', 'portgroup' => 'he' }, 'mac' => '52:54:00:d8:54:bc' }, + { 'source' => { 'network' => 'test', 'portgroup' => 'll' }, 'mac' => '42:42:42:42:42:42' }, + { 'source' => { 'network' => 'prod', 'portgroup' => 'oo' }, 'mac' => '52:54:00:b8:cf:03' }, + { 'source' => { 'network' => 'nopo' }, 'mac' => '52:54:00:14:ec:f8' }, + ]) + } + end + + context 'with ignoring filter rules' do + it { + is_expected.to run.with_params([ + { 'interface_type' => 'bridge', 'source' => { 'bridge' => 'virbr0' } }, + { 'interface_type' => 'bridge', 'source' => { 'bridge' => 'virbr0' }, 'filter' => 'clean-traffic' }, + { 'interface_type' => 'user' }, + { 'interface_type' => 'user', 'filter' => 'clean-traffic' }, + ]).and_return([ + { 'interface_type' => 'bridge', 'source' => { 'bridge' => 'virbr0' }, 'mac' => '52:54:00:79:e5:40' }, + { 'interface_type' => 'bridge', 'source' => { 'bridge' => 'virbr0' }, 'filter' => 'clean-traffic', 'mac' => '52:54:00:79:e5:40' }, + { 'interface_type' => 'user', 'mac' => '52:54:00:12:36:36' }, + { 'interface_type' => 'user', 'filter' => 'clean-traffic', 'mac' => '52:54:00:12:36:36' }, ]) } end