lib/ohai/plugins/network.rb in ohai-18.0.14 vs lib/ohai/plugins/network.rb in ohai-18.0.26
- old
+ new
@@ -1,186 +1,186 @@
-# frozen_string_literal: true
-#
-# Author:: Adam Jacob (<adam@chef.io>)
-# Copyright:: Copyright (c) Chef Software Inc.
-# License:: Apache License, Version 2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-Ohai.plugin(:NetworkAddresses) do
- require_relative "../mixin/network_helper"
- include Ohai::Mixin::NetworkHelper
-
- provides "ipaddress", "ip6address", "macaddress"
-
- depends "network/interfaces"
-
- # from interface data create array of hashes with ipaddress, scope, and iface
- # sorted by scope, prefixlen and then ipaddress where longest prefixes first
- def sorted_ips(family = "inet")
- raise "bad family #{family}" unless %w{inet inet6}.include? family
-
- # priority of ipv6 link scopes to sort by later
- scope_prio = [ "global", "site", "link", "host", "node", nil ]
-
- # grab ipaddress, scope, and iface for sorting later
- ipaddresses = []
- Mash[network["interfaces"]].each do |iface, iface_v|
- next if iface_v.nil? || !iface_v.key?("addresses")
-
- iface_v["addresses"].each do |addr, addr_v|
- next if addr_v.nil? || (!addr_v.key? "family") || addr_v["family"] != family
-
- ipaddresses << {
- ipaddress: addr_v["prefixlen"] ? IPAddress("#{addr}/#{addr_v["prefixlen"]}") : IPAddress("#{addr}/#{addr_v["netmask"]}"),
- scope: addr_v["scope"].nil? ? nil : addr_v["scope"].downcase,
- iface: iface,
- }
- end
- end
-
- # sort ip addresses by scope, by prefixlen and then by ip address
- # 128 - prefixlen: longest prefixes first
- ipaddresses.sort_by do |v|
- [ ( scope_prio.index(v[:scope]) || 999999 ),
- 128 - v[:ipaddress].prefix.to_i,
- v[:ipaddress].to_i,
- ]
- end
- end
-
- # finds ip address / interface for interface with default route based on
- # passed in family. returns [ipaddress, interface] uses 1st ip if no default
- # route is found
- def find_ip(family = "inet")
- ips = sorted_ips(family)
-
- # return if there aren't any #{family} addresses!
- return [ nil, nil ] if ips.empty?
-
- # shortcuts to access default #{family} interface and gateway
- int_attr = Ohai::Mixin::NetworkHelper::FAMILIES[family] + "_interface"
- gw_attr = Ohai::Mixin::NetworkHelper::FAMILIES[family] + "_gateway"
-
- if network[int_attr]
- # working with the address(es) of the default network interface
- gw_if_ips = ips.select do |v|
- v[:iface] == network[int_attr]
- end
- if gw_if_ips.empty?
- logger.warn("Plugin Network: [#{family}] no ip address on #{network[int_attr]}")
- elsif network[gw_attr] &&
- network["interfaces"][network[int_attr]] &&
- network["interfaces"][network[int_attr]]["addresses"]
- if [ "0.0.0.0", "::", /^fe80:/ ].any? { |pat| pat === network[gw_attr] } # rubocop: disable Performance/RedundantEqualityComparisonBlock
- # link level default route
- logger.trace("Plugin Network: link level default #{family} route, picking ip from #{network[gw_attr]}")
- r = gw_if_ips.first
- else
- # checking network masks
- r = gw_if_ips.find do |v|
- network_contains_address(network[gw_attr], v[:ipaddress], v[:iface])
- end
- if r.nil?
- r = gw_if_ips.first
- logger.trace("Plugin Network: [#{family}] no ipaddress/mask on #{network[int_attr]} matching the gateway #{network[gw_attr]}, picking #{r[:ipaddress]}")
- else
- logger.trace("Plugin Network: [#{family}] Using default interface #{network[int_attr]} and default gateway #{network[gw_attr]} to set the default ip to #{r[:ipaddress]}")
- end
- end
- else
- # return the first ip address on network[int_attr]
- r = gw_if_ips.first
- end
- else
- r = ips.first
- logger.trace("Plugin Network: [#{family}] no default interface, picking the first ipaddress")
- end
-
- return [ nil, nil ] if r.nil? || r.empty?
-
- [ r[:ipaddress].to_s, r[:iface] ]
- end
-
- # select mac address of first interface with family of lladdr
- def find_mac_from_iface(iface)
- r = network["interfaces"][iface]["addresses"].select { |k, v| v["family"] == "lladdr" }
- r.nil? || r.first.nil? ? nil : r.first.first
- end
-
- # address_to_match: String
- # ipaddress: IPAddress
- # iface: String
- def network_contains_address(address_to_match, ipaddress, iface)
- if ( peer = network["interfaces"][iface]["addresses"][ipaddress.to_s][:peer] )
- IPAddress(peer) == IPAddress(address_to_match)
- else
- ipaddress.include? IPAddress(address_to_match)
- end
- end
-
- # ipaddress, ip6address and macaddress are set for each interface by the
- # #{os}::network plugin. atm it is expected macaddress is set at the same
- # time as ipaddress. if ipaddress is set and macaddress is nil, that means
- # the interface ipaddress is bound to has the NOARP flag
- collect_data do
- require "ipaddress" unless defined?(IPAddress)
-
- results = {}
-
- network Mash.new unless network
- network[:interfaces] ||= Mash.new
- counters Mash.new unless counters
- counters[:network] ||= Mash.new
-
- # inet family is processed before inet6 to give ipv4 precedence
- Ohai::Mixin::NetworkHelper::FAMILIES.keys.sort.each do |family|
- r = {}
- # find the ip/interface with the default route for this family
- (r["ip"], r["iface"]) = find_ip(family)
- r["mac"] = find_mac_from_iface(r["iface"]) unless r["iface"].nil?
- # don't overwrite attributes if they've already been set by the "#{os}::network" plugin
- if (family == "inet") && ipaddress.nil?
- if r["ip"].nil?
- logger.warn("Plugin Network: unable to detect ipaddress")
- else
- ipaddress r["ip"]
- end
- elsif (family == "inet6") && ip6address.nil?
- if r["ip"].nil?
- logger.trace("Plugin Network: unable to detect ip6address")
- else
- ip6address r["ip"]
- end
- end
-
- # set the macaddress [only if we haven't already]. this allows the #{os}::network plugin to set macaddress
- # otherwise we set macaddress on a first-found basis (and we started with ipv4)
- if macaddress.nil?
- if r["mac"]
- logger.trace("Plugin Network: setting macaddress to '#{r["mac"]}' from interface '#{r["iface"]}' for family '#{family}'")
- macaddress r["mac"]
- else
- logger.trace("Plugin Network: unable to detect macaddress for family '#{family}'")
- end
- end
-
- results[family] = r
- end
-
- if results["inet"]["iface"] && results["inet6"]["iface"] &&
- (results["inet"]["iface"] != results["inet6"]["iface"])
- logger.trace("Plugin Network: ipaddress and ip6address are set from different interfaces (#{results["inet"]["iface"]} & #{results["inet6"]["iface"]})")
- end
- end
-end
+# frozen_string_literal: true
+#
+# Author:: Adam Jacob (<adam@chef.io>)
+# Copyright:: Copyright (c) Chef Software Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+Ohai.plugin(:NetworkAddresses) do
+ require_relative "../mixin/network_helper"
+ include Ohai::Mixin::NetworkHelper
+
+ provides "ipaddress", "ip6address", "macaddress"
+
+ depends "network/interfaces"
+
+ # from interface data create array of hashes with ipaddress, scope, and iface
+ # sorted by scope, prefixlen and then ipaddress where longest prefixes first
+ def sorted_ips(family = "inet")
+ raise "bad family #{family}" unless %w{inet inet6}.include? family
+
+ # priority of ipv6 link scopes to sort by later
+ scope_prio = [ "global", "site", "link", "host", "node", nil ]
+
+ # grab ipaddress, scope, and iface for sorting later
+ ipaddresses = []
+ Mash[network["interfaces"]].each do |iface, iface_v|
+ next if iface_v.nil? || !iface_v.key?("addresses")
+
+ iface_v["addresses"].each do |addr, addr_v|
+ next if addr_v.nil? || (!addr_v.key? "family") || addr_v["family"] != family
+
+ ipaddresses << {
+ ipaddress: addr_v["prefixlen"] ? IPAddress("#{addr}/#{addr_v["prefixlen"]}") : IPAddress("#{addr}/#{addr_v["netmask"]}"),
+ scope: addr_v["scope"].nil? ? nil : addr_v["scope"].downcase,
+ iface: iface,
+ }
+ end
+ end
+
+ # sort ip addresses by scope, by prefixlen and then by ip address
+ # 128 - prefixlen: longest prefixes first
+ ipaddresses.sort_by do |v|
+ [ ( scope_prio.index(v[:scope]) || 999999 ),
+ 128 - v[:ipaddress].prefix.to_i,
+ v[:ipaddress].to_i,
+ ]
+ end
+ end
+
+ # finds ip address / interface for interface with default route based on
+ # passed in family. returns [ipaddress, interface] uses 1st ip if no default
+ # route is found
+ def find_ip(family = "inet")
+ ips = sorted_ips(family)
+
+ # return if there aren't any #{family} addresses!
+ return [ nil, nil ] if ips.empty?
+
+ # shortcuts to access default #{family} interface and gateway
+ int_attr = Ohai::Mixin::NetworkHelper::FAMILIES[family] + "_interface"
+ gw_attr = Ohai::Mixin::NetworkHelper::FAMILIES[family] + "_gateway"
+
+ if network[int_attr]
+ # working with the address(es) of the default network interface
+ gw_if_ips = ips.select do |v|
+ v[:iface] == network[int_attr]
+ end
+ if gw_if_ips.empty?
+ logger.warn("Plugin Network: [#{family}] no ip address on #{network[int_attr]}")
+ elsif network[gw_attr] &&
+ network["interfaces"][network[int_attr]] &&
+ network["interfaces"][network[int_attr]]["addresses"]
+ if [ "0.0.0.0", "::", /^fe80:/ ].any? { |pat| pat === network[gw_attr] } # rubocop: disable Performance/RedundantEqualityComparisonBlock
+ # link level default route
+ logger.trace("Plugin Network: link level default #{family} route, picking ip from #{network[gw_attr]}")
+ r = gw_if_ips.first
+ else
+ # checking network masks
+ r = gw_if_ips.find do |v|
+ network_contains_address(network[gw_attr], v[:ipaddress], v[:iface])
+ end
+ if r.nil?
+ r = gw_if_ips.first
+ logger.trace("Plugin Network: [#{family}] no ipaddress/mask on #{network[int_attr]} matching the gateway #{network[gw_attr]}, picking #{r[:ipaddress]}")
+ else
+ logger.trace("Plugin Network: [#{family}] Using default interface #{network[int_attr]} and default gateway #{network[gw_attr]} to set the default ip to #{r[:ipaddress]}")
+ end
+ end
+ else
+ # return the first ip address on network[int_attr]
+ r = gw_if_ips.first
+ end
+ else
+ r = ips.first
+ logger.trace("Plugin Network: [#{family}] no default interface, picking the first ipaddress")
+ end
+
+ return [ nil, nil ] if r.nil? || r.empty?
+
+ [ r[:ipaddress].to_s, r[:iface] ]
+ end
+
+ # select mac address of first interface with family of lladdr
+ def find_mac_from_iface(iface)
+ r = network["interfaces"][iface]["addresses"].select { |k, v| v["family"] == "lladdr" }
+ r.nil? || r.first.nil? ? nil : r.first.first
+ end
+
+ # address_to_match: String
+ # ipaddress: IPAddress
+ # iface: String
+ def network_contains_address(address_to_match, ipaddress, iface)
+ if ( peer = network["interfaces"][iface]["addresses"][ipaddress.to_s][:peer] )
+ IPAddress(peer) == IPAddress(address_to_match)
+ else
+ ipaddress.include? IPAddress(address_to_match)
+ end
+ end
+
+ # ipaddress, ip6address and macaddress are set for each interface by the
+ # #{os}::network plugin. atm it is expected macaddress is set at the same
+ # time as ipaddress. if ipaddress is set and macaddress is nil, that means
+ # the interface ipaddress is bound to has the NOARP flag
+ collect_data do
+ require "ipaddress" unless defined?(IPAddress)
+
+ results = {}
+
+ network Mash.new unless network
+ network[:interfaces] ||= Mash.new
+ counters Mash.new unless counters
+ counters[:network] ||= Mash.new
+
+ # inet family is processed before inet6 to give ipv4 precedence
+ Ohai::Mixin::NetworkHelper::FAMILIES.keys.sort.each do |family|
+ r = {}
+ # find the ip/interface with the default route for this family
+ (r["ip"], r["iface"]) = find_ip(family)
+ r["mac"] = find_mac_from_iface(r["iface"]) unless r["iface"].nil?
+ # don't overwrite attributes if they've already been set by the "#{os}::network" plugin
+ if (family == "inet") && ipaddress.nil?
+ if r["ip"].nil?
+ logger.warn("Plugin Network: unable to detect ipaddress")
+ else
+ ipaddress r["ip"]
+ end
+ elsif (family == "inet6") && ip6address.nil?
+ if r["ip"].nil?
+ logger.trace("Plugin Network: unable to detect ip6address")
+ else
+ ip6address r["ip"]
+ end
+ end
+
+ # set the macaddress [only if we haven't already]. this allows the #{os}::network plugin to set macaddress
+ # otherwise we set macaddress on a first-found basis (and we started with ipv4)
+ if macaddress.nil?
+ if r["mac"]
+ logger.trace("Plugin Network: setting macaddress to '#{r["mac"]}' from interface '#{r["iface"]}' for family '#{family}'")
+ macaddress r["mac"]
+ else
+ logger.trace("Plugin Network: unable to detect macaddress for family '#{family}'")
+ end
+ end
+
+ results[family] = r
+ end
+
+ if results["inet"]["iface"] && results["inet6"]["iface"] &&
+ (results["inet"]["iface"] != results["inet6"]["iface"])
+ logger.trace("Plugin Network: ipaddress and ip6address are set from different interfaces (#{results["inet"]["iface"]} & #{results["inet6"]["iface"]})")
+ end
+ end
+end