From 5eb012b4f62615519707a926cc62528f5dc54a44 Mon Sep 17 00:00:00 2001 From: Alex Schultz Date: Tue, 22 Jan 2019 17:37:29 -0700 Subject: [PATCH] Fix interface_for_ip for newer facter versions In facter 3.x, the networking facts are in a complex hash. Previously the interface facts where flat so we would lookup the vars. This change first tries the facter 2.x lookup before falling back to the facter 3.x syntax. Closes-Bug: #1835718 Change-Id: I260b18ae3479da4f5176027d4b26b3e1c6b22063 Closes-Bug: #1812938 (cherry picked from commit 5fff984cecf68c256e60ba6017f37b9d1e76e31b) --- .../parser/functions/interface_for_ip.rb | 53 +++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/lib/puppet/parser/functions/interface_for_ip.rb b/lib/puppet/parser/functions/interface_for_ip.rb index b0963c487..b09e2fba2 100644 --- a/lib/puppet/parser/functions/interface_for_ip.rb +++ b/lib/puppet/parser/functions/interface_for_ip.rb @@ -9,23 +9,68 @@ module Puppet::Parser::Functions if arg[0].class == String begin ip1 = IPAddr.new(arg[0]) + network_facts = lookupvar('networking') Dir.foreach('/sys/class/net/') do |interface| next if interface == '.' || interface == '..' - # puppet downcases fact names, interface names can have capitals + # puppet downcases fact names, interface names can have capitals but + # in facter 2.x they were lower case. In facter 3.x they can have + # capitals iface_no_dash = interface.gsub('-', '_').downcase if ip1.ipv4? ipaddress_name = "ipaddress_#{iface_no_dash}" netmask_name = "netmask_#{iface_no_dash}" + facter_ip = 'ip' + facter_netmask = 'netmask' else ipaddress_name = "ipaddress6_#{iface_no_dash}" netmask_name = "netmask6_#{iface_no_dash}" + facter_ip = 'ip6' + facter_netmask = 'netmask6' end - interface_ip = lookupvar(ipaddress_name) - netmask = lookupvar(netmask_name) - unless interface_ip.nil? then + if network_facts.nil? or network_facts['interfaces'].nil? then + # facter 2 facts + interface_ip = lookupvar(ipaddress_name) + next if interface_ip.nil? ip2 = IPAddr.new(interface_ip) + netmask = lookupvar(netmask_name) + return interface if ip1.mask(netmask) == ip2.mask(netmask) + else + # facter 3+ syntax: + # networking => { + # ... + # interfaces => { + # br-ctlplane => { + # bindings => [ + # { + # address => "192.168.24.1", + # netmask => "255.255.255.0", + # network => "192.168.24.0" + # } + # ], + # bindings6 => [ + # { + # address => "fe80::5054:ff:fe22:bac3", + # netmask => "ffff:ffff:ffff:ffff::", + # network => "fe80::" + # } + # ], + # ip => "192.168.24.1", + # ip6 => "fe80::5054:ff:fe22:bac3", + # mac => "52:54:00:22:ba:c3", + # mtu => 1500, + # netmask => "255.255.255.0", + # netmask6 => "ffff:ffff:ffff:ffff::", + # network => "192.168.24.0", + # network6 => "fe80::" + # }, + # }, + # ... + # } + next if network_facts['interfaces'][interface].nil? or network_facts['interfaces'][interface][facter_ip].nil? + ip2 = IPAddr.new(network_facts['interfaces'][interface][facter_ip]) + netmask = network_facts['interfaces'][interface][facter_netmask] return interface if ip1.mask(netmask) == ip2.mask(netmask) end end