Skip to content

Commit

Permalink
Merge pull request #1928 from puppetlabs/FACT-2668
Browse files Browse the repository at this point in the history
(FACT-2668) Networking fact on linux should have logic for selecting IPs
  • Loading branch information
Filipovici-Andrei authored Jun 23, 2020
2 parents 644b7a5 + 944d0df commit 93b7e1f
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 59 deletions.
1 change: 1 addition & 0 deletions lib/resolvers/macosx/networking.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def clean_up_interfaces_response(response)
def parse_interfaces_response(response)
parsed_interfaces_data = {}
interfaces_data = Hash[*response.split(/^([A-Za-z0-9_]+): /)[1..-1]]

interfaces_data.each do |interface, properties|
values = {}

Expand Down
38 changes: 8 additions & 30 deletions lib/resolvers/networking_linux_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ def retrieve_interface_info
find_dhcp!(ip_tokens, interfaces)
end

::Resolvers::Utils::Networking.expand_main_bindings(interfaces)

@fact_list[:interfaces] = interfaces
end

Expand Down Expand Up @@ -92,17 +94,10 @@ def fill_ip_v4_info!(ip_tokens, network_info)

interface_name, ip4_address, ip4_mask_length = retrieve_name_and_ip_info(ip_tokens)

binding = build_binding(ip4_address, ip4_mask_length)
build_network_info_structure!(network_info, interface_name, 'bindings')

populate_other_ipv4_facts(network_info, interface_name, binding)
end
binding = ::Resolvers::Utils::Networking.build_binding(ip4_address, ip4_mask_length)
build_network_info_structure!(network_info, interface_name, :bindings)

def populate_other_ipv4_facts(network_info, interface_name, binding)
network_info[interface_name]['bindings'] << binding
network_info[interface_name][:ip] ||= binding[:address]
network_info[interface_name][:network] ||= binding[:network]
network_info[interface_name][:netmask] ||= binding[:netmask]
network_info[interface_name][:bindings] << binding
end

def retrieve_name_and_ip_info(tokens)
Expand All @@ -119,19 +114,12 @@ def fill_io_v6_info!(ip_tokens, network_info)

interface_name, ip6_address, ip6_mask_length = retrieve_name_and_ip_info(ip_tokens)

binding = build_binding(ip6_address, ip6_mask_length)
binding = ::Resolvers::Utils::Networking.build_binding(ip6_address, ip6_mask_length)

build_network_info_structure!(network_info, interface_name, 'bindings6')
build_network_info_structure!(network_info, interface_name, :bindings6)

network_info[interface_name][:scope6] ||= ip_tokens[5]
populate_other_ipv6_facts(network_info, interface_name, binding)
end

def populate_other_ipv6_facts(network_info, interface_name, binding)
network_info[interface_name]['bindings6'] << binding
network_info[interface_name][:ip6] ||= binding[:address]
network_info[interface_name][:network6] ||= binding[:network]
network_info[interface_name][:netmask6] ||= binding[:netmask]
network_info[interface_name][:bindings6] << binding
end

def retrieve_default_interface
Expand All @@ -143,16 +131,6 @@ def retrieve_default_interface
@fact_list[:primary_interface] = default_interface
end

def build_binding(addr, mask_length)
require 'ipaddr'

ip = IPAddr.new(addr)
mask_helper = ip.ipv6? ? 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' : '255.255.255.255'
mask = IPAddr.new(mask_helper).mask(mask_length)

{ address: addr, netmask: mask.to_s, network: ip.mask(mask_length).to_s }
end

def build_network_info_structure!(network_info, interface_name, binding)
network_info[interface_name] = {} unless network_info.dig(interface_name)
network_info[interface_name][binding] = [] unless network_info.dig(interface_name, binding)
Expand Down
109 changes: 80 additions & 29 deletions spec/facter/resolvers/networking_linux_resolver_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,42 +45,81 @@
let(:result) do
{
'lo' => {
'bindings' =>
[
{ address: '127.0.0.1', netmask: '255.0.0.0', network: '127.0.0.0' }
],
'bindings6' =>
[
{ address: '::1', netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', network: '::1' }
],
:dhcp => '10.32.22.9',
:ip => '127.0.0.1',
:ip6 => '::1',
:mtu => 65_536,
:netmask => '255.0.0.0',
:netmask6 => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
:network => '127.0.0.0',
:network6 => '::1',
:scope6 => 'host'
bindings: [
{ address: '127.0.0.1', netmask: '255.0.0.0', network: '127.0.0.0' }
],
bindings6: [
{ address: '::1', netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', network: '::1' }
],
dhcp: '10.32.22.9',
ip: '127.0.0.1',
ip6: '::1',
mtu: 65_536,
netmask: '255.0.0.0',
netmask6: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
network: '127.0.0.0',
network6: '::1',
scope6: 'host'
},
'ens160' => {
'bindings' => [
bindings: [
{ address: '10.16.119.155', netmask: '255.255.240.0', network: '10.16.112.0' },
{ address: '10.16.127.70', netmask: '255.255.240.0', network: '10.16.112.0' }
],
'bindings6' => [
bindings6: [
{ address: 'fe80::250:56ff:fe9a:8481', netmask: 'ffff:ffff:ffff:ffff::', network: 'fe80::' }
],
:dhcp => '10.32.22.10',
:ip => '10.16.119.155',
:ip6 => 'fe80::250:56ff:fe9a:8481',
:mac => '00:50:56:9a:61:46',
:mtu => 1500,
:netmask => '255.255.240.0',
:netmask6 => 'ffff:ffff:ffff:ffff::',
:network => '10.16.112.0',
:network6 => 'fe80::',
:scope6 => 'link'
dhcp: '10.32.22.10',
ip: '10.16.119.155',
ip6: 'fe80::250:56ff:fe9a:8481',
mac: '00:50:56:9a:61:46',
mtu: 1500,
netmask: '255.255.240.0',
netmask6: 'ffff:ffff:ffff:ffff::',
network: '10.16.112.0',
network6: 'fe80::',
scope6: 'link'
}
}
end

let(:result_with_127_first) do
{
'lo' => {
bindings: [
{ address: '127.0.0.1', netmask: '255.0.0.0', network: '127.0.0.0' }
],
bindings6: [
{ address: '::1', netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', network: '::1' }
],
dhcp: '10.32.22.9',
ip: '127.0.0.1',
ip6: '::1',
mtu: 65_536,
netmask: '255.0.0.0',
netmask6: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
network: '127.0.0.0',
network6: '::1',
scope6: 'host'
},
'ens160' => {
bindings: [
{ address: '127.0.0.1', netmask: '255.0.0.0', network: '127.0.0.0' },
{ address: '10.16.127.70', netmask: '255.255.240.0', network: '10.16.112.0' }
],
bindings6: [
{ address: 'fe80::250:56ff:fe9a:8481', netmask: 'ffff:ffff:ffff:ffff::', network: 'fe80::' }
],
dhcp: '10.32.22.10',
ip: '10.16.127.70',
ip6: 'fe80::250:56ff:fe9a:8481',
mac: '00:50:56:9a:61:46',
mtu: 1500,
netmask: '255.255.240.0',
netmask6: 'ffff:ffff:ffff:ffff::',
network: '10.16.112.0',
network6: 'fe80::',
scope6: 'link'
}
}
end
Expand Down Expand Up @@ -110,5 +149,17 @@
.with('ip route get 1', logger: log_spy).twice
end
end

context 'when 127.0.0.1 is first ip' do
before do
allow(Facter::Core::Execution).to receive(:execute)
.with('ip -o address', logger: log_spy)
.and_return(load_fixture('ip_o_address_linux_with_127_first').read)
end

it 'is ignored and the next ip is used' do
expect(networking_linux.resolve(:interfaces)).to eq(result_with_127_first)
end
end
end
end
5 changes: 5 additions & 0 deletions spec/fixtures/ip_o_address_linux_with_127_first
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
1: lo inet 127.0.0.1/8 scope host lo\ valid_lft forever preferred_lft forever
1: lo inet6 ::1/128 scope host \ valid_lft forever preferred_lft forever
2: ens160 inet 127.0.0.1/8 scope global dynamic ens160\ valid_lft 732sec preferred_lft 732sec
2: ens160 inet 10.16.127.70/20 brd 10.16.127.255 scope global secondary ens160\ valid_lft forever preferred_lft forever
2: ens160 inet6 fe80::250:56ff:fe9a:8481/64 scope link \ valid_lft forever preferred_lft forever

0 comments on commit 93b7e1f

Please sign in to comment.