Puppet Function: interface_for_ip

Defined in:
lib/puppet/parser/functions/interface_for_ip.rb
Function type:
Ruby 3.x API

Overview

interface_for_ip()Any

Find the bind IP address for the provided subnet.

Returns:

  • (Any)


8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/puppet/parser/functions/interface_for_ip.rb', line 8

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