5fff984cec
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. Change-Id: I260b18ae3479da4f5176027d4b26b3e1c6b22063 Closes-Bug: #1812938
86 lines
3.3 KiB
Ruby
86 lines
3.3 KiB
Ruby
require 'ipaddr'
|
|
|
|
# Custom function to lookup the interface which matches the subnet
|
|
# of the provided IP address.
|
|
# The function iterates over all the interfaces and chooses the
|
|
# first locally assigned interface which matches the IP.
|
|
module Puppet::Parser::Functions
|
|
newfunction(:interface_for_ip, :type => :rvalue, :doc => "Find the bind IP address for the provided subnet.") do |arg|
|
|
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 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
|
|
|
|
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
|
|
rescue IPAddr::InvalidAddressError => e
|
|
raise Puppet::ParseError, "#{e}: #{arg[0]}"
|
|
end
|
|
else
|
|
raise Puppet::ParseError, "Syntax error: #{arg[0]} must be a String"
|
|
end
|
|
return ''
|
|
end
|
|
end
|