diff --git a/lib/puppet/functions/ssh/ipaddresses.rb b/lib/puppet/functions/ssh/ipaddresses.rb index 466647a..82ea248 100644 --- a/lib/puppet/functions/ssh/ipaddresses.rb +++ b/lib/puppet/functions/ssh/ipaddresses.rb @@ -1,40 +1,56 @@ # @summary Returns ip addresses of network interfaces (except lo) found by facter. # @api private # # Returns all ip addresses of network interfaces (except lo) found by facter. # Special network interfaces (e.g. docker0) can be excluded by an exclude list. Puppet::Functions.create_function(:'ssh::ipaddresses') do dispatch :ipaddresses do # @param excluded_interfaces An array of interface names to be excluded. # @return The IP addresses found. optional_param 'Array[String[1]]', :excluded_interfaces return_type 'Array[Stdlib::IP::Address]' end def ipaddresses(excluded_interfaces = []) facts = closure_scope['facts'] # always exclude loopback interface excluded_interfaces += ['lo'] + if !facts['networking'].nil? && !facts['networking'].empty? + interfaces = facts['networking']['interfaces'] + else + interfaces = {} + facts['interfaces'].split(',').each do |iface| + next if facts["ipaddress_#{iface}"].nil? && facts["ipaddress6_#{iface}"].nil? + interfaces[iface] = {} + if !facts["ipaddress_#{iface}"].nil? && !facts["ipaddress_#{iface}"].empty? + interfaces[iface]['bindings'] = [{ 'address' => facts["ipaddress_#{iface}"] }] + end + if !facts["ipaddress6_#{iface}"].nil? && !facts["ipaddress6_#{iface}"].empty? + interfaces[iface]['bindings6'] = [{ 'address' => facts["ipaddress6_#{iface}"] }] + end + end + end + result = [] - facts['networking']['interfaces'].each do |iface, data| + interfaces.each do |iface, data| # skip excluded interfaces next if excluded_interfaces.include?(iface) %w[bindings bindings6].each do |binding_type| next unless data.key?(binding_type) data[binding_type].each do |binding| next unless binding.key?('address') result << binding['address'] end end end # Throw away any v6 link-local addresses fe8064 = IPAddr.new('fe80::/64') result.delete_if { |ip| fe8064.include? IPAddr.new(ip) } result.uniq end end diff --git a/spec/functions/ssh/ipaddresses_spec.rb b/spec/functions/ssh/ipaddresses_spec.rb index b968986..e036118 100644 --- a/spec/functions/ssh/ipaddresses_spec.rb +++ b/spec/functions/ssh/ipaddresses_spec.rb @@ -1,30 +1,59 @@ require 'spec_helper' describe 'ssh::ipaddresses', type: :puppet_function do it 'exists' do is_expected.not_to be_nil end - context 'with dummy fact data' do + context 'with dummy structured fact data' do let(:facts) do JSON.parse File.read(File.join(File.dirname(__FILE__), '../../fixtures/mock-interface-fact.json')) end describe 'without parameters' do it 'returns all IPs other than localhost' do is_expected.to run.and_return(['172.17.0.1', '10.13.42.61', '10.0.0.110', '10.0.0.104', '10.0.0.109']) end end describe 'with excluded interface' do it 'doesn\'t return the IPs of excluded interface' do is_expected.to run.with_params(['docker0']).and_return(['10.13.42.61', '10.0.0.110', '10.0.0.104', '10.0.0.109']) end end describe 'with excluded interfaces' do it 'doesn\'t return the IPs of those interfaces' do is_expected.to run.with_params(%w[docker0 eno1]).and_return([]) end end end + + context 'with dummy legacy fact data' do + let(:facts) do + { + networking: {}, + interfaces: 'lo,docker0,eno1', + ipaddress_lo: '127.0.0.1', + ipaddress_eno1: '10.13.42.61', + ipaddress_docker0: '172.17.0.1' + } + end + + describe 'without parameters' do + it 'returns all IPs other than localhost' do + is_expected.to run.and_return(['172.17.0.1', '10.13.42.61']) + end + end + + describe 'with excluded interface' do + it 'doesn\'t return the IPs of excluded interface' do + is_expected.to run.with_params(['docker0']).and_return(['10.13.42.61']) + end + end + describe 'with excluded interfaces' do + it 'doesn\'t return the IPs of those interfaces' do + is_expected.to run.with_params(%w[docker0 eno1]).and_return([]) + end + end + end end