Fix direct_networks to handle overridden endpoints

Handle non-hash values of network's scheme endpoints which is being
injected for override/remove action.

Change-Id: I44c5f867a9fb7e6147e5fb42a10e0d5b6553a180
Related-Bug: #1588934
This commit is contained in:
Michael Polenchuk 2016-06-17 17:49:15 +03:00
parent b4ac09e45a
commit cfad4ec3da
2 changed files with 82 additions and 29 deletions

View File

@ -1,12 +1,23 @@
Puppet::Parser::Functions::newfunction(:direct_networks, :type => :rvalue, :doc => <<-EOS
parses network scheme and returns networks
directly attached to the host
Puppet::Parser::Functions::newfunction(:direct_networks, :arity => -2, :type => :rvalue, :doc => <<-EOS
Parses network endpoints scheme and returns networks
directly attached to the host
EOS
) do |argv|
endpoints = argv[0]
filter = argv[1]
netmask = argv[2]
networks = []
) do |args|
endpoints, filter, netmask = args
allowed_netmask = ['cidr', 'netmask']
netmask ||= allowed_netmask.first
raise(
ArgumentError,
'direct_networks(): Requires hash as first argument'
) unless endpoints.is_a? Hash
raise(
ArgumentError,
"direct_networks(): Expected a string with one of (#{allowed_netmask.join ','}), got #{netmask}"
) unless allowed_netmask.include? netmask
class IPAddr
def mask_length
@ -27,26 +38,16 @@ EOS
end
end
endpoints.each do |interface, parameters|
next unless parameters.has_key? 'IP' and parameters['IP'].is_a? Array
next if filter and interface != filter
parameters['IP'].each do |ip|
next unless ip
if netmask and netmask == 'netmask'
networks << IPAddr.new(ip).netmask
else
networks << IPAddr.new(ip).cidr
end
end
next unless parameters.has_key? 'routes' and parameters['routes'].is_a? Array
parameters['routes'].each do |route|
next unless route.has_key? 'net'
if netmask and netmask == 'netmask'
networks << IPAddr.new(route['net']).netmask
else
networks << IPAddr.new(route['net']).cidr
end
end
networks = []
get_network = lambda {|ip| networks << IPAddr.new(ip).send(netmask) rescue ''}
endpoints.each do |interface, opts|
next unless opts.is_a? Hash
next if filter && filter != interface
Array(opts.fetch('IP', [])).each(&get_network)
Array(opts.fetch('routes', [])).map {|route| route.fetch('net', nil)}.each(&get_network)
end
return networks.join(' ')
networks.join(' ')
end

View File

@ -0,0 +1,52 @@
require 'spec_helper'
describe 'direct_networks' do
let(:endpoints) do
{
'br-ex' => {
'IP' => 'none',
'gateway' => '',
'vendor_specific' => {}
},
'br-fw-admin' => {
'IP' => ['10.109.0.7/24'],
'vendor_specific' => {'provider_gateway' => '10.109.0.2'}
},
'br-mgmt' => {
'IP' => ['10.109.1.3/24'],
'gateway' => '10.109.1.1',
'gateway-metric' => 100,
'routes' => [
{
'net' => '10.109.242.0/24',
'via' => '10.109.1.1',
},
]
},
'br-storage' => {
'IP' => ['10.109.2.1/24']
},
'br-ex-lnx' => {
'IP' => ['10.109.3.4/24'],
'gateway' => '10.109.3.1',
'vendor_specific' => {'provider_gateway' => '10.109.3.1'}
},
'br-aux' => {
'IP' => 'none'
},
'br-prv' => '',
'br-floating' => '',
}
end
it { is_expected.not_to eq(nil) }
it { is_expected.to run.with_params().and_raise_error(ArgumentError, /Wrong number of arguments given/) }
it { is_expected.to run.with_params([{'br-ex' => 'routes'}]).and_raise_error(ArgumentError, /Requires hash/) }
it { is_expected.to run.with_params(endpoints, 'br-ex', 'cidra').and_raise_error(ArgumentError, /Expected a string with one of/) }
it { is_expected.to run.with_params(endpoints).and_return('10.109.0.0/24 10.109.1.0/24 10.109.242.0/24 10.109.2.0/24 10.109.3.0/24')}
it { is_expected.to run.with_params(endpoints, 'br-mgmt').and_return('10.109.1.0/24 10.109.242.0/24')}
it { is_expected.to run.with_params(endpoints, 'br-mgmt', 'netmask').and_return('10.109.1.0/255.255.255.0 10.109.242.0/255.255.255.0')}
end