Skip to content

Commit

Permalink
(FACT-2901) Rewrite and refactor linux networking resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
Filipovici-Andrei committed Jan 15, 2021
1 parent f90af03 commit a8fce6f
Show file tree
Hide file tree
Showing 61 changed files with 1,125 additions and 862 deletions.
7 changes: 3 additions & 4 deletions .rubocop.yml
Expand Up @@ -89,7 +89,6 @@ Metrics/ClassLength:
- 'lib/facter/custom_facts/util/collection.rb'
- 'lib/facter/framework/core/options/option_store.rb'
- 'lib/facter/framework/cli/cli.rb'
- 'lib/facter/resolvers/networking_linux.rb'
- 'lib/facter/framework/core/cache_manager.rb'
- 'install.rb'
- 'scripts/generate_changelog.rb'
Expand Down Expand Up @@ -171,10 +170,10 @@ Style/ModuleFunction:
- 'lib/facter/custom_facts/core/logging.rb'

Style/HashEachMethods:
Enabled: false # not implemted in ruby 2.3
Enabled: false # not implemented in ruby 2.3

Style/HashTransformKeys:
Enabled: false # not implemted in ruby 2.3
Enabled: false # not implemented in ruby 2.3

Style/HashTransformValues:
Enabled: false # not implemted in ruby 2.3
Enabled: false # not implemented in ruby 2.3
5 changes: 2 additions & 3 deletions .rubocop_todo.yml
@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config --exclude-limit 1000`
# on 2020-12-16 14:46:37 +0200 using RuboCop version 0.81.0.
# on 2021-01-14 13:30:11 +0200 using RuboCop version 0.81.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
Expand All @@ -16,7 +16,7 @@ Metrics/CyclomaticComplexity:
Metrics/PerceivedComplexity:
Max: 10

# Offense count: 72
# Offense count: 71
# Configuration parameters: CustomTransform, IgnoreMethods, SpecSuffixOnly.
RSpec/FilePath:
Exclude:
Expand Down Expand Up @@ -51,7 +51,6 @@ RSpec/FilePath:
- 'spec/facter/resolvers/freebsd/ffi_helper_spec.rb'
- 'spec/facter/resolvers/identity_spec.rb'
- 'spec/facter/resolvers/macosx/dmi_spec.rb'
- 'spec/facter/resolvers/macosx/utils/system_profile_executor_spec.rb'
- 'spec/facter/resolvers/memory_spec.rb'
- 'spec/facter/resolvers/processors_spec.rb'
- 'spec/facter/resolvers/redhat_release_spec.rb'
Expand Down
2 changes: 1 addition & 1 deletion check.sh
Expand Up @@ -11,5 +11,5 @@ bundle exec rspec --default-path spec_integration --order random
echo "<------------- Running rubocop ------------->"
bundle exec rubocop --parallel

# It will be disabled untill we rewrite it's rules
# It will be disabled until we rewrite it's rules
# rubycritic --no-browser -f console
4 changes: 2 additions & 2 deletions lib/facter/facts/linux/dhcp_servers.rb
Expand Up @@ -15,8 +15,8 @@ def call_the_resolver
private

def construct_addresses_hash
primary_dhcp = Facter::Resolvers::NetworkingLinux.resolve(:dhcp)
interfaces = Facter::Resolvers::NetworkingLinux.resolve(:interfaces)
primary_dhcp = Facter::Resolvers::Linux::Networking.resolve(:dhcp)
interfaces = Facter::Resolvers::Linux::Networking.resolve(:interfaces)
return unless interfaces

servers = { system: primary_dhcp }
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/interfaces.rb
Expand Up @@ -7,7 +7,7 @@ class Interfaces
TYPE = :legacy

def call_the_resolver
fact_value = Facter::Resolvers::NetworkingLinux.resolve(:interfaces)
fact_value = Facter::Resolvers::Linux::Networking.resolve(:interfaces)

Facter::ResolvedFact.new(FACT_NAME, fact_value && !fact_value.empty? ? fact_value.keys.sort.join(',') : nil,
:legacy)
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/ipaddress6_interfaces.rb
Expand Up @@ -8,7 +8,7 @@ class Ipaddress6Interfaces

def call_the_resolver
arr = []
interfaces = Facter::Resolvers::NetworkingLinux.resolve(:interfaces)
interfaces = Facter::Resolvers::Linux::Networking.resolve(:interfaces)
interfaces&.each do |interface_name, info|
arr << Facter::ResolvedFact.new("ipaddress6_#{interface_name}", info[:ip6], :legacy) if info[:ip6]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/ipaddress_interfaces.rb
Expand Up @@ -8,7 +8,7 @@ class IpaddressInterfaces

def call_the_resolver
arr = []
interfaces = Facter::Resolvers::NetworkingLinux.resolve(:interfaces)
interfaces = Facter::Resolvers::Linux::Networking.resolve(:interfaces)
interfaces&.each do |interface_name, info|
arr << Facter::ResolvedFact.new("ipaddress_#{interface_name}", info[:ip], :legacy) if info[:ip]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/macaddress_interfaces.rb
Expand Up @@ -8,7 +8,7 @@ class MacaddressInterfaces

def call_the_resolver
arr = []
interfaces = Facter::Resolvers::NetworkingLinux.resolve(:interfaces)
interfaces = Facter::Resolvers::Linux::Networking.resolve(:interfaces)
interfaces&.each do |interface_name, info|
arr << Facter::ResolvedFact.new("macaddress_#{interface_name}", info[:mac], :legacy) if info[:mac]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/mtu_interfaces.rb
Expand Up @@ -8,7 +8,7 @@ class MtuInterfaces

def call_the_resolver
arr = []
interfaces = Facter::Resolvers::NetworkingLinux.resolve(:interfaces)
interfaces = Facter::Resolvers::Linux::Networking.resolve(:interfaces)
interfaces&.each do |interface_name, info|
arr << Facter::ResolvedFact.new("mtu_#{interface_name}", info[:mtu], :legacy) if info[:mtu]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/netmask6_interfaces.rb
Expand Up @@ -8,7 +8,7 @@ class Netmask6Interfaces

def call_the_resolver
arr = []
interfaces = Facter::Resolvers::NetworkingLinux.resolve(:interfaces)
interfaces = Facter::Resolvers::Linux::Networking.resolve(:interfaces)
interfaces&.each do |interface_name, info|
arr << Facter::ResolvedFact.new("netmask6_#{interface_name}", info[:netmask6], :legacy) if info[:netmask6]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/netmask_interfaces.rb
Expand Up @@ -8,7 +8,7 @@ class NetmaskInterfaces

def call_the_resolver
arr = []
interfaces = Facter::Resolvers::NetworkingLinux.resolve(:interfaces)
interfaces = Facter::Resolvers::Linux::Networking.resolve(:interfaces)
interfaces&.each do |interface_name, info|
arr << Facter::ResolvedFact.new("netmask_#{interface_name}", info[:netmask], :legacy) if info[:netmask]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/network6_interfaces.rb
Expand Up @@ -8,7 +8,7 @@ class Network6Interfaces

def call_the_resolver
arr = []
interfaces = Facter::Resolvers::NetworkingLinux.resolve(:interfaces)
interfaces = Facter::Resolvers::Linux::Networking.resolve(:interfaces)
interfaces&.each do |interface_name, info|
arr << Facter::ResolvedFact.new("network6_#{interface_name}", info[:network6], :legacy) if info[:network6]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/network_interfaces.rb
Expand Up @@ -8,7 +8,7 @@ class NetworkInterfaces

def call_the_resolver
arr = []
interfaces = Facter::Resolvers::NetworkingLinux.resolve(:interfaces)
interfaces = Facter::Resolvers::Linux::Networking.resolve(:interfaces)
interfaces&.each do |interface_name, info|
arr << Facter::ResolvedFact.new("network_#{interface_name}", info[:network], :legacy) if info[:network]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/networking/dhcp.rb
Expand Up @@ -7,7 +7,7 @@ class Dhcp
FACT_NAME = 'networking.dhcp'

def call_the_resolver
fact_value = Facter::Resolvers::NetworkingLinux.resolve(:dhcp)
fact_value = Facter::Resolvers::Linux::Networking.resolve(:dhcp)

Facter::ResolvedFact.new(FACT_NAME, fact_value)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/networking/interfaces.rb
Expand Up @@ -7,7 +7,7 @@ class Interfaces
FACT_NAME = 'networking.interfaces'

def call_the_resolver
fact_value = Facter::Resolvers::NetworkingLinux.resolve(:interfaces)
fact_value = Facter::Resolvers::Linux::Networking.resolve(:interfaces)

Facter::ResolvedFact.new(FACT_NAME, fact_value)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/networking/ip.rb
Expand Up @@ -8,7 +8,7 @@ class Ip
ALIASES = 'ipaddress'

def call_the_resolver
fact_value = Facter::Resolvers::NetworkingLinux.resolve(:ip)
fact_value = Facter::Resolvers::Linux::Networking.resolve(:ip)

[Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/networking/ip6.rb
Expand Up @@ -8,7 +8,7 @@ class Ip6
ALIASES = 'ipaddress6'

def call_the_resolver
fact_value = Facter::Resolvers::NetworkingLinux.resolve(:ip6)
fact_value = Facter::Resolvers::Linux::Networking.resolve(:ip6)

[Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/networking/mac.rb
Expand Up @@ -8,7 +8,7 @@ class Mac
ALIASES = 'macaddress'

def call_the_resolver
fact_value = Facter::Resolvers::NetworkingLinux.resolve(:mac)
fact_value = Facter::Resolvers::Linux::Networking.resolve(:mac)

[Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/networking/mtu.rb
Expand Up @@ -7,7 +7,7 @@ class Mtu
FACT_NAME = 'networking.mtu'

def call_the_resolver
fact_value = Facter::Resolvers::NetworkingLinux.resolve(:mtu)
fact_value = Facter::Resolvers::Linux::Networking.resolve(:mtu)

Facter::ResolvedFact.new(FACT_NAME, fact_value)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/networking/netmask.rb
Expand Up @@ -8,7 +8,7 @@ class Netmask
ALIASES = 'netmask'

def call_the_resolver
fact_value = Facter::Resolvers::NetworkingLinux.resolve(:netmask)
fact_value = Facter::Resolvers::Linux::Networking.resolve(:netmask)

[Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/networking/netmask6.rb
Expand Up @@ -8,7 +8,7 @@ class Netmask6
ALIASES = 'netmask6'

def call_the_resolver
fact_value = Facter::Resolvers::NetworkingLinux.resolve(:netmask6)
fact_value = Facter::Resolvers::Linux::Networking.resolve(:netmask6)

[Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/networking/network.rb
Expand Up @@ -8,7 +8,7 @@ class Network
ALIASES = 'network'

def call_the_resolver
fact_value = Facter::Resolvers::NetworkingLinux.resolve(:network)
fact_value = Facter::Resolvers::Linux::Networking.resolve(:network)

[Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/networking/network6.rb
Expand Up @@ -8,7 +8,7 @@ class Network6
ALIASES = 'network6'

def call_the_resolver
fact_value = Facter::Resolvers::NetworkingLinux.resolve(:network6)
fact_value = Facter::Resolvers::Linux::Networking.resolve(:network6)

[Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/networking/primary.rb
Expand Up @@ -7,7 +7,7 @@ class Primary
FACT_NAME = 'networking.primary'

def call_the_resolver
fact_value = Facter::Resolvers::NetworkingLinux.resolve(:primary_interface)
fact_value = Facter::Resolvers::Linux::Networking.resolve(:primary_interface)

Facter::ResolvedFact.new(FACT_NAME, fact_value)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/networking/scope6.rb
Expand Up @@ -8,7 +8,7 @@ class Scope6
ALIASES = 'scope6'

def call_the_resolver
fact_value = Facter::Resolvers::NetworkingLinux.resolve(:scope6)
fact_value = Facter::Resolvers::Linux::Networking.resolve(:scope6)

[Facter::ResolvedFact.new(FACT_NAME, fact_value),
Facter::ResolvedFact.new('scope6', fact_value, :legacy)]
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/facts/linux/scope6_interfaces.rb
Expand Up @@ -8,7 +8,7 @@ class Scope6Interfaces

def call_the_resolver
resolved_facts = []
interfaces = Facter::Resolvers::NetworkingLinux.resolve(:interfaces)
interfaces = Facter::Resolvers::Linux::Networking.resolve(:interfaces)

interfaces&.each do |interface_name, info|
if info[:scope6]
Expand Down
106 changes: 106 additions & 0 deletions lib/facter/resolvers/linux/networking.rb
@@ -0,0 +1,106 @@
# frozen_string_literal: true

module Facter
module Resolvers
module Linux
class Networking < BaseResolver
init_resolver

class << self
private

def post_resolve(fact_name)
@fact_list.fetch(fact_name) { retrieve_network_info(fact_name) }

@fact_list[fact_name]
end

def retrieve_network_info(fact_name)
add_info_from_socket_reader
add_info_from_routing_table
retrieve_primary_interface
Facter::Util::Resolvers::Networking.expand_main_bindings(@fact_list)
@fact_list[fact_name]
end

def add_info_from_socket_reader
@fact_list[:interfaces] = Facter::Util::Linux::SocketParser.retrieve_interfaces(log)
mtu_and_indexes = interfaces_mtu_and_index

@fact_list[:interfaces].keys.each do |interface_name|
mtu(interface_name, mtu_and_indexes)
dhcp(interface_name, mtu_and_indexes)

@log.debug("Found interface #{interface_name} with #{@fact_list[:interfaces][interface_name]}")
end
end

def interfaces_mtu_and_index
mtu_and_indexes = {}
output = Facter::Core::Execution.execute('ip link show', logger: log)
output.each_line do |line|
next unless line.include?('mtu')

parse_ip_command_line(line, mtu_and_indexes)
end
log.debug("Associated MTU and index in ip command: #{mtu_and_indexes}")
mtu_and_indexes
end

def parse_ip_command_line(line, mtu_and_indexes)
mtu = line.match(/mtu (\d+)/)&.captures&.first&.to_i
index_tokens = line.split(':')
index = index_tokens[0].strip
# vlans are displayed as <vlan_name>@<physical_interface>
name = index_tokens[1].split('@').first.strip
mtu_and_indexes[name] = { index: index, mtu: mtu }
end

def mtu(interface_name, mtu_and_indexes)
mtu = mtu_and_indexes.dig(interface_name, :mtu)
@fact_list[:interfaces][interface_name][:mtu] = mtu unless mtu.nil?
end

def dhcp(interface_name, mtu_and_indexes)
dhcp = Facter::Util::Linux::Dhcp.dhcp(interface_name, mtu_and_indexes.dig(interface_name, :index), log)
@fact_list[:interfaces][interface_name][:dhcp] = dhcp unless dhcp.nil?
end

def add_info_from_routing_table
routes4, routes6 = Facter::Util::Linux::RoutingTable.read_routing_table(log)
compare_ips(routes4, :bindings)
compare_ips(routes6, :bindings6)
end

def compare_ips(routes, binding_key)
routes.each do |route|
next unless @fact_list[:interfaces].key?(route[:interface])

interface_data = @fact_list[:interfaces][route[:interface]]
add_binding_if_missing(interface_data, binding_key, route)
end
end

def add_binding_if_missing(interface_data, binding_key, route)
interface_binding = interface_data[binding_key]

if interface_binding.nil?
interface_data[binding_key] = [{ address: route[:ip] }]
elsif interface_binding.none? { |binding| binding[:address] == route[:ip] }
interface_binding << { address: route[:ip] }
end
end

def retrieve_primary_interface
primary_helper = Facter::Util::Resolvers::Networking::PrimaryInterface
primary_interface = primary_helper.read_from_proc_route
primary_interface ||= primary_helper.read_from_ip_route
primary_interface ||= primary_helper.find_in_interfaces(@fact_list[:interfaces])

@fact_list[:primary_interface] = primary_interface
end
end
end
end
end
end

0 comments on commit a8fce6f

Please sign in to comment.