lib/facter/util/resolvers/networking/primary_interface.rb
# frozen_string_literal: true
module Facter
module Util
module Resolvers
module Networking
module PrimaryInterface
@log ||= Log.new(self)
class << self
ROUTE_TABLE_MAPPING = {
'Iface' => 0,
'Destination' => 1,
'Gateway' => 2,
'Flags' => 3,
'RefCnt' => 4,
'Use' => 5,
'Metric' => 6,
'Mask' => 7,
'MTU' => 8,
'Window' => 9,
'IRTT' => 10
}.freeze
def read_from_route
return if Facter::Core::Execution.which('route').nil?
result = Facter::Core::Execution.execute('route -n get default', logger: @log)
result.match(/interface: (.+)/)&.captures&.first
end
def read_from_proc_route
content = Facter::Util::FileHelper.safe_read('/proc/net/route', '')
content.each_line.with_index do |line, index|
next if index.zero?
route = line.strip.split("\t")
return route[ROUTE_TABLE_MAPPING['Iface']] if valid_default_route?(route)
end
nil
end
def read_from_ip_route
return if Facter::Core::Execution.which('ip').nil?
output = Facter::Core::Execution.execute('ip route show default', logger: @log)
primary_interface = nil
output.each_line do |line|
primary_interface = line.strip.split(' ')[4] if line.start_with?('default')
end
primary_interface
end
def find_in_interfaces(interfaces)
return if interfaces.nil?
interfaces.each do |iface_name, interface|
interface[:bindings]&.each do |binding|
return iface_name unless Facter::Util::Resolvers::Networking.ignored_ip_address(binding[:address])
end
next unless interface[:bindings6]
interface[:bindings6].each do |binding|
return iface_name unless Facter::Util::Resolvers::Networking.ignored_ip_address(binding[:address])
end
end
nil
end
private
def valid_default_route?(route)
route.count > 7 &&
route[ROUTE_TABLE_MAPPING['Destination']] == '00000000' &&
route[ROUTE_TABLE_MAPPING['Mask']] == '00000000' &&
route[ROUTE_TABLE_MAPPING['Iface']] != '*' # `*` represents blackhole and not a valid interface
end
end
end
end
end
end
end