facter 4.0.47 → 4.0.48
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/facter.rb +0 -1
- data/lib/facter/config.rb +1 -2
- data/lib/facter/custom_facts/util/fact.rb +19 -1
- data/lib/facter/custom_facts/util/resolution.rb +1 -1
- data/lib/facter/facts/aix/disks.rb +1 -1
- data/lib/facter/facts/aix/ssh.rb +1 -1
- data/lib/facter/facts/aix/sshalgorithmkey.rb +1 -1
- data/lib/facter/facts/aix/sshfp_algorithm.rb +1 -1
- data/lib/facter/facts/freebsd/ssh.rb +1 -1
- data/lib/facter/facts/freebsd/sshalgorithmkey.rb +1 -1
- data/lib/facter/facts/freebsd/sshfp_algorithm.rb +1 -1
- data/lib/facter/facts/linux/disks.rb +1 -1
- data/lib/facter/facts/linux/os/family.rb +4 -2
- data/lib/facter/facts/linux/ssh.rb +1 -1
- data/lib/facter/facts/linux/sshalgorithmkey.rb +1 -1
- data/lib/facter/facts/linux/sshfp_algorithm.rb +1 -1
- data/lib/facter/facts/macosx/ssh.rb +1 -1
- data/lib/facter/facts/macosx/sshalgorithmkey.rb +1 -1
- data/lib/facter/facts/macosx/sshfp_algorithm.rb +1 -1
- data/lib/facter/facts/solaris/disks.rb +1 -1
- data/lib/facter/facts/solaris/ssh.rb +1 -1
- data/lib/facter/facts/solaris/sshalgorithmkey.rb +1 -1
- data/lib/facter/facts/solaris/sshfp_algorithm.rb +1 -1
- data/lib/facter/facts/windows/networking/fqdn.rb +1 -1
- data/lib/facter/framework/core/options/option_store.rb +3 -1
- data/lib/facter/framework/detector/os_detector.rb +1 -0
- data/lib/facter/resolvers/aix/{architecture_resolver.rb → architecture.rb} +0 -0
- data/lib/facter/resolvers/aix/{filesystem_resolver.rb → filesystem.rb} +0 -0
- data/lib/facter/resolvers/aix/{hardware_resolver.rb → hardware.rb} +0 -0
- data/lib/facter/resolvers/aix/{load_averages_resolver.rb → load_averages.rb} +0 -0
- data/lib/facter/resolvers/aix/{networking_resolver.rb → networking.rb} +0 -0
- data/lib/facter/resolvers/{augeas_resolver.rb → augeas.rb} +0 -0
- data/lib/facter/resolvers/{disk_resolver.rb → disk.rb} +0 -0
- data/lib/facter/resolvers/{dmi_resolver.rb → dmi.rb} +0 -0
- data/lib/facter/resolvers/{eos_release_resolver.rb → eos_release.rb} +0 -0
- data/lib/facter/resolvers/{facterversion_resolver.rb → facterversion.rb} +0 -0
- data/lib/facter/resolvers/{filesystems_resolver.rb → filesystems.rb} +0 -0
- data/lib/facter/resolvers/{fips_enabled_resolver.rb → fips_enabled.rb} +0 -0
- data/lib/facter/resolvers/freebsd/{dmi_resolver.rb → dmi.rb} +0 -0
- data/lib/facter/resolvers/freebsd/{freebsd_version_resolver.rb → freebsd_version.rb} +0 -0
- data/lib/facter/resolvers/freebsd/{geom_resolver.rb → geom.rb} +0 -0
- data/lib/facter/resolvers/freebsd/{swap_memory_resolver.rb → swap_memory.rb} +0 -0
- data/lib/facter/resolvers/freebsd/{system_memory_resolver.rb → system_memory.rb} +0 -0
- data/lib/facter/resolvers/freebsd/{virtual_resolver.rb → virtual.rb} +0 -0
- data/lib/facter/resolvers/{hostname_resolver.rb → hostname.rb} +0 -0
- data/lib/facter/resolvers/{identity_resolver.rb → identity.rb} +0 -0
- data/lib/facter/resolvers/{lpar_resolver.rb → lpar.rb} +0 -0
- data/lib/facter/resolvers/{lsb_release_resolver.rb → lsb_release.rb} +0 -0
- data/lib/facter/resolvers/macosx/{dmi_resolver.rb → dmi.rb} +0 -0
- data/lib/facter/resolvers/macosx/{filesystems_resolver.rb → filesystems.rb} +0 -0
- data/lib/facter/resolvers/macosx/{load_averages_resolver.rb → load_averages.rb} +0 -0
- data/lib/facter/resolvers/macosx/{mountpoints_resolver.rb → mountpoints.rb} +0 -0
- data/lib/facter/resolvers/macosx/{processor_resolver.rb → processor.rb} +0 -0
- data/lib/facter/resolvers/macosx/{swap_memory_resolver.rb → swap_memory.rb} +0 -0
- data/lib/facter/resolvers/macosx/{system_memory_resolver.rb → system_memory.rb} +0 -0
- data/lib/facter/resolvers/macosx/{system_profiler_resolver.rb → system_profiler.rb} +0 -0
- data/lib/facter/resolvers/{memory_resolver.rb → memory.rb} +0 -0
- data/lib/facter/resolvers/{mountpoints_resolver.rb → mountpoints.rb} +0 -0
- data/lib/facter/resolvers/{networking_resolver.rb → networking.rb} +0 -0
- data/lib/facter/resolvers/networking_linux.rb +296 -0
- data/lib/facter/resolvers/{os_release_resolver.rb → os_release.rb} +0 -0
- data/lib/facter/resolvers/{path_resolver.rb → path.rb} +0 -0
- data/lib/facter/resolvers/{processors_resolver.rb → processors.rb} +0 -0
- data/lib/facter/resolvers/{redhat_release_resolver.rb → redhat_release.rb} +0 -0
- data/lib/facter/resolvers/{ruby_resolver.rb → ruby.rb} +0 -0
- data/lib/facter/resolvers/{selinux_resolver.rb → selinux.rb} +0 -0
- data/lib/facter/resolvers/{ssh_resolver.rb → ssh.rb} +1 -1
- data/lib/facter/resolvers/{suse_release_resolver.rb → suse_release.rb} +0 -0
- data/lib/facter/resolvers/{sw_vers_resolver.rb → sw_vers.rb} +0 -0
- data/lib/facter/resolvers/{timezone_resolver.rb → timezone.rb} +0 -0
- data/lib/facter/resolvers/{uname_resolver.rb → uname.rb} +0 -0
- data/lib/facter/resolvers/{uptime_resolver.rb → uptime.rb} +0 -0
- data/lib/facter/resolvers/windows/{dmi_bios_resolver.rb → dmi_bios.rb} +0 -0
- data/lib/facter/resolvers/windows/{dmi_computersystem_resolver.rb → dmi_computersystem.rb} +0 -0
- data/lib/facter/resolvers/windows/{fips_resolver.rb → fips.rb} +0 -0
- data/lib/facter/resolvers/windows/{hardware_architecture_resolver.rb → hardware_architecture.rb} +0 -0
- data/lib/facter/resolvers/windows/{identity_resolver.rb → identity.rb} +0 -0
- data/lib/facter/resolvers/windows/{kernel_resolver.rb → kernel.rb} +0 -0
- data/lib/facter/resolvers/windows/{memory_resolver.rb → memory.rb} +0 -0
- data/lib/facter/resolvers/windows/{netkvm_resolver.rb → netkvm.rb} +0 -0
- data/lib/facter/resolvers/windows/{networking_resolver.rb → networking.rb} +13 -0
- data/lib/facter/resolvers/windows/{processors_resolver.rb → processors.rb} +0 -0
- data/lib/facter/resolvers/windows/{product_release_resolver.rb → product_release.rb} +0 -0
- data/lib/facter/resolvers/windows/{system32_resolver.rb → system32.rb} +0 -0
- data/lib/facter/resolvers/windows/{uptime_resolver.rb → uptime.rb} +0 -0
- data/lib/facter/resolvers/windows/{virtualization_resolver.rb → virtualization.rb} +0 -0
- data/lib/facter/resolvers/windows/{win_os_description_resolver.rb → win_os_description.rb} +0 -0
- data/lib/facter/resolvers/{wpar_resolver.rb → wpar.rb} +0 -0
- data/lib/facter/util/facts/facts_utils.rb +16 -0
- data/lib/facter/version.rb +1 -1
- metadata +78 -79
- data/lib/facter/resolvers/networking_linux_resolver.rb +0 -258
- data/lib/facter/util/resolvers/networking.rb +0 -90
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a97076330c5a6ac8a2d8ba6a5a36ecc3b8b3d5661d46057a444f0bafc1fe1e35
|
4
|
+
data.tar.gz: b84fcccd87ee9e7554e99342bf3722f383f23481480b9090e1cdba1ed26021ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: beba9d7a66f00a6914558d54df18438a64e0e78f9d5109f5a5657f605480a26519a8c5a3b5b12e31c6c312a48c43066fadf302e433f6e57f129ba9214277e266
|
7
|
+
data.tar.gz: 73348a9dd6e2b68f50c7b73f543b0e90153b4753d2f7641ff078ee58860229af32c2f4a3871c25fc7da011308cb5ce20d2c6e455645b6c1e8ae2c59f9092b3b9
|
data/lib/facter.rb
CHANGED
@@ -381,7 +381,6 @@ module Facter
|
|
381
381
|
# @api public
|
382
382
|
def values(options, user_queries)
|
383
383
|
init_cli_options(options, user_queries)
|
384
|
-
Options[:show_legacy] = true
|
385
384
|
log_blocked_facts
|
386
385
|
resolved_facts = Facter::FactManager.instance.resolve_facts(user_queries)
|
387
386
|
resolved_facts.reject! { |fact| fact.type == :custom && fact.value.nil? }
|
data/lib/facter/config.rb
CHANGED
@@ -43,6 +43,8 @@ module Facter
|
|
43
43
|
@used_resolution_weight = 0
|
44
44
|
|
45
45
|
@value = nil
|
46
|
+
|
47
|
+
@log = Facter::Log.new(self)
|
46
48
|
end
|
47
49
|
|
48
50
|
# Adds a new {Facter::Util::Resolution resolution}. This requires a
|
@@ -201,11 +203,27 @@ module Facter
|
|
201
203
|
break
|
202
204
|
end
|
203
205
|
@used_resolution_weight = resolve.weight
|
204
|
-
|
206
|
+
next if value.nil?
|
207
|
+
|
208
|
+
log_fact_path(resolve)
|
209
|
+
|
210
|
+
return value
|
205
211
|
end
|
206
212
|
nil
|
207
213
|
end
|
208
214
|
|
215
|
+
def log_fact_path(resolve)
|
216
|
+
fact_type, resolved_from = if resolve.instance_of?(Facter::Core::Aggregate)
|
217
|
+
['aggregate', resolve.instance_variable_get(:@aggregate).source_location[0]]
|
218
|
+
elsif resolve.fact_type == :external
|
219
|
+
['external', resolve.file]
|
220
|
+
else
|
221
|
+
['custom', resolve.last_evaluated]
|
222
|
+
end
|
223
|
+
|
224
|
+
@log.debug("#{fact_type} fact #{resolve.fact.name} got resolved from: #{resolved_from}")
|
225
|
+
end
|
226
|
+
|
209
227
|
def announce_when_no_suitable_resolution(resolutions)
|
210
228
|
return unless resolutions.empty?
|
211
229
|
|
data/lib/facter/facts/aix/ssh.rb
CHANGED
@@ -8,7 +8,7 @@ module Facts
|
|
8
8
|
|
9
9
|
def call_the_resolver
|
10
10
|
facts = []
|
11
|
-
result = Facter::Resolvers::
|
11
|
+
result = Facter::Resolvers::Ssh.resolve(:ssh)
|
12
12
|
result.each { |ssh| facts << Facter::ResolvedFact.new("ssh#{ssh.name.to_sym}key", ssh.key, :legacy) }
|
13
13
|
facts
|
14
14
|
end
|
@@ -8,7 +8,7 @@ module Facts
|
|
8
8
|
|
9
9
|
def call_the_resolver
|
10
10
|
facts = []
|
11
|
-
result = Facter::Resolvers::
|
11
|
+
result = Facter::Resolvers::Ssh.resolve(:ssh)
|
12
12
|
result.each do |ssh|
|
13
13
|
facts << Facter::ResolvedFact.new("sshfp_#{ssh.name.to_sym}",
|
14
14
|
"#{ssh.fingerprint.sha1}\n#{ssh.fingerprint.sha256}", :legacy)
|
@@ -6,7 +6,7 @@ module Facts
|
|
6
6
|
FACT_NAME = 'ssh'
|
7
7
|
|
8
8
|
def call_the_resolver
|
9
|
-
result = Facter::Resolvers::
|
9
|
+
result = Facter::Resolvers::Ssh.resolve(:ssh)
|
10
10
|
ssh_facts = {}
|
11
11
|
result.each { |ssh| ssh_facts.merge!(create_ssh_fact(ssh)) }
|
12
12
|
Facter::ResolvedFact.new(FACT_NAME, ssh_facts)
|
@@ -8,7 +8,7 @@ module Facts
|
|
8
8
|
|
9
9
|
def call_the_resolver
|
10
10
|
facts = []
|
11
|
-
result = Facter::Resolvers::
|
11
|
+
result = Facter::Resolvers::Ssh.resolve(:ssh)
|
12
12
|
result.each { |ssh| facts << Facter::ResolvedFact.new("ssh#{ssh.name.to_sym}key", ssh.key, :legacy) }
|
13
13
|
facts
|
14
14
|
end
|
@@ -8,7 +8,7 @@ module Facts
|
|
8
8
|
|
9
9
|
def call_the_resolver
|
10
10
|
facts = []
|
11
|
-
result = Facter::Resolvers::
|
11
|
+
result = Facter::Resolvers::Ssh.resolve(:ssh)
|
12
12
|
result.each do |ssh|
|
13
13
|
facts << Facter::ResolvedFact.new("sshfp_#{ssh.name.to_sym}",
|
14
14
|
"#{ssh.fingerprint.sha1}\n#{ssh.fingerprint.sha256}", :legacy)
|
@@ -4,7 +4,7 @@ module Facts
|
|
4
4
|
module Linux
|
5
5
|
class Disks
|
6
6
|
FACT_NAME = 'disks'
|
7
|
-
ALIASES = %w[blockdevices blockdevice_.*_model blockdevice_.*_size blockdevice_.*_vendor
|
7
|
+
ALIASES = %w[blockdevices blockdevice_.*_model blockdevice_.*_size blockdevice_.*_vendor].freeze
|
8
8
|
|
9
9
|
def call_the_resolver
|
10
10
|
facts = []
|
@@ -8,8 +8,10 @@ module Facts
|
|
8
8
|
ALIASES = 'osfamily'
|
9
9
|
|
10
10
|
def call_the_resolver
|
11
|
-
|
12
|
-
|
11
|
+
id = Facter::Resolvers::OsRelease.resolve(:id_like)
|
12
|
+
id ||= Facter::Resolvers::OsRelease.resolve(:id)
|
13
|
+
|
14
|
+
fact_value = Facter::Util::Facts.discover_family(id)
|
13
15
|
|
14
16
|
[Facter::ResolvedFact.new(FACT_NAME, fact_value.capitalize),
|
15
17
|
Facter::ResolvedFact.new(ALIASES, fact_value.capitalize, :legacy)]
|
@@ -8,7 +8,7 @@ module Facts
|
|
8
8
|
|
9
9
|
def call_the_resolver
|
10
10
|
facts = []
|
11
|
-
result = Facter::Resolvers::
|
11
|
+
result = Facter::Resolvers::Ssh.resolve(:ssh)
|
12
12
|
result.each { |ssh| facts << Facter::ResolvedFact.new("ssh#{ssh.name.to_sym}key", ssh.key, :legacy) }
|
13
13
|
facts
|
14
14
|
end
|
@@ -8,7 +8,7 @@ module Facts
|
|
8
8
|
|
9
9
|
def call_the_resolver
|
10
10
|
facts = []
|
11
|
-
result = Facter::Resolvers::
|
11
|
+
result = Facter::Resolvers::Ssh.resolve(:ssh)
|
12
12
|
result.each do |ssh|
|
13
13
|
facts << Facter::ResolvedFact.new("sshfp_#{ssh.name.to_sym}",
|
14
14
|
"#{ssh.fingerprint.sha1}\n#{ssh.fingerprint.sha256}", :legacy)
|
@@ -8,7 +8,7 @@ module Facts
|
|
8
8
|
|
9
9
|
def call_the_resolver
|
10
10
|
facts = []
|
11
|
-
result = Facter::Resolvers::
|
11
|
+
result = Facter::Resolvers::Ssh.resolve(:ssh)
|
12
12
|
result.each { |ssh| facts << Facter::ResolvedFact.new("ssh#{ssh.name.to_sym}key", ssh.key, :legacy) }
|
13
13
|
facts
|
14
14
|
end
|
@@ -8,7 +8,7 @@ module Facts
|
|
8
8
|
|
9
9
|
def call_the_resolver
|
10
10
|
facts = []
|
11
|
-
result = Facter::Resolvers::
|
11
|
+
result = Facter::Resolvers::Ssh.resolve(:ssh)
|
12
12
|
result.each do |ssh|
|
13
13
|
facts << Facter::ResolvedFact.new("sshfp_#{ssh.name.to_sym}",
|
14
14
|
"#{ssh.fingerprint.sha1}\n#{ssh.fingerprint.sha256}", :legacy)
|
@@ -8,7 +8,7 @@ module Facts
|
|
8
8
|
|
9
9
|
def call_the_resolver
|
10
10
|
facts = []
|
11
|
-
result = Facter::Resolvers::
|
11
|
+
result = Facter::Resolvers::Ssh.resolve(:ssh)
|
12
12
|
result.each { |ssh| facts << Facter::ResolvedFact.new("ssh#{ssh.name.to_sym}key", ssh.key, :legacy) }
|
13
13
|
facts
|
14
14
|
end
|
@@ -8,7 +8,7 @@ module Facts
|
|
8
8
|
|
9
9
|
def call_the_resolver
|
10
10
|
facts = []
|
11
|
-
result = Facter::Resolvers::
|
11
|
+
result = Facter::Resolvers::Ssh.resolve(:ssh)
|
12
12
|
result.each do |ssh|
|
13
13
|
facts << Facter::ResolvedFact.new("sshfp_#{ssh.name.to_sym}",
|
14
14
|
"#{ssh.fingerprint.sha1}\n#{ssh.fingerprint.sha256}", :legacy)
|
@@ -12,7 +12,7 @@ module Facts
|
|
12
12
|
hostname = Facter::Resolvers::Hostname.resolve(:hostname)
|
13
13
|
return Facter::ResolvedFact.new(FACT_NAME, nil) if !hostname || hostname.empty?
|
14
14
|
|
15
|
-
fact_value = [hostname, domain].compact.join('.')
|
15
|
+
fact_value = domain && !domain.empty? ? [hostname, domain].compact.join('.') : hostname
|
16
16
|
|
17
17
|
[Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)]
|
18
18
|
end
|
@@ -34,6 +34,7 @@ module Facter
|
|
34
34
|
@timing = false
|
35
35
|
@external_dir = []
|
36
36
|
@custom_dir = []
|
37
|
+
@hocon = false
|
37
38
|
|
38
39
|
class << self
|
39
40
|
attr_reader :debug, :verbose, :log_level, :show_legacy,
|
@@ -42,7 +43,7 @@ module Facter
|
|
42
43
|
attr_accessor :config, :user_query, :strict, :json,
|
43
44
|
:cache, :yaml, :puppet, :ttls, :block, :cli, :config_file_custom_dir,
|
44
45
|
:config_file_external_dir, :default_external_dir, :fact_groups,
|
45
|
-
:block_list, :color, :trace, :sequential, :timing
|
46
|
+
:block_list, :color, :trace, :sequential, :timing, :hocon
|
46
47
|
|
47
48
|
attr_writer :external_dir
|
48
49
|
|
@@ -171,6 +172,7 @@ module Facter
|
|
171
172
|
@ruby = true
|
172
173
|
@user_query = []
|
173
174
|
@json = false
|
175
|
+
@hocon = false
|
174
176
|
@cache = true
|
175
177
|
@yaml = false
|
176
178
|
@puppet = false
|
@@ -45,6 +45,7 @@ class OsDetector
|
|
45
45
|
if hierarchy.empty?
|
46
46
|
@log.debug("Could not detect hierarchy using os identifier: #{identifier} , trying with family")
|
47
47
|
|
48
|
+
# https://www.commandlinux.com/man-page/man5/os-release.5.html
|
48
49
|
detect_family.to_s.split.each do |family|
|
49
50
|
hierarchy = @os_hierarchy.construct_hierarchy(family)
|
50
51
|
return hierarchy unless hierarchy.empty?
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,296 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Facter
|
4
|
+
module Resolvers
|
5
|
+
class NetworkingLinux < BaseResolver
|
6
|
+
init_resolver
|
7
|
+
|
8
|
+
DIRS = ['/var/lib/dhclient/', '/var/lib/dhcp/', '/var/lib/dhcp3/', '/var/lib/NetworkManager/', '/var/db/'].freeze
|
9
|
+
ROUTE_TYPES = %w[anycast
|
10
|
+
unicast
|
11
|
+
broadcast
|
12
|
+
local
|
13
|
+
nat
|
14
|
+
unreachable
|
15
|
+
prohibit
|
16
|
+
blackhole
|
17
|
+
throw].freeze
|
18
|
+
|
19
|
+
class << self
|
20
|
+
private
|
21
|
+
|
22
|
+
def post_resolve(fact_name)
|
23
|
+
@fact_list.fetch(fact_name) { retrieve_network_info(fact_name) }
|
24
|
+
|
25
|
+
@fact_list[fact_name]
|
26
|
+
end
|
27
|
+
|
28
|
+
def retrieve_network_info(fact_name)
|
29
|
+
mtu_and_indexes = interfaces_mtu_and_index
|
30
|
+
retrieve_interfaces_with_socket(mtu_and_indexes)
|
31
|
+
add_info_from_routing_table
|
32
|
+
retrieve_primary_interface
|
33
|
+
Facter::Util::Resolvers::Networking.expand_main_bindings(@fact_list)
|
34
|
+
@fact_list[fact_name]
|
35
|
+
end
|
36
|
+
|
37
|
+
def interfaces_mtu_and_index
|
38
|
+
mtu_and_indexes = {}
|
39
|
+
output = Facter::Core::Execution.execute('ip link show', logger: log)
|
40
|
+
output.each_line do |line|
|
41
|
+
next unless line.include?('mtu')
|
42
|
+
|
43
|
+
parse_ip_command_line(line, mtu_and_indexes)
|
44
|
+
end
|
45
|
+
log.debug("Associated MTU and index in ip command: #{mtu_and_indexes}")
|
46
|
+
mtu_and_indexes
|
47
|
+
end
|
48
|
+
|
49
|
+
def parse_ip_command_line(line, mtu_and_indexes)
|
50
|
+
mtu = line.match(/mtu (\d+)/)&.captures&.first&.to_i
|
51
|
+
index_tokens = line.split(':')
|
52
|
+
index = index_tokens[0].strip
|
53
|
+
# vlans are displayed as <vlan_name>@<physical_interface>
|
54
|
+
name = index_tokens[1].split('@').first.strip
|
55
|
+
mtu_and_indexes[name] = { index: index, mtu: mtu }
|
56
|
+
end
|
57
|
+
|
58
|
+
def retrieve_interfaces_with_socket(mtu_and_indexes)
|
59
|
+
require 'socket'
|
60
|
+
interfaces = {}
|
61
|
+
Socket.getifaddrs.each do |ifaddr|
|
62
|
+
populate_interface_info(ifaddr, interfaces, mtu_and_indexes)
|
63
|
+
end
|
64
|
+
|
65
|
+
@fact_list[:interfaces] = interfaces
|
66
|
+
end
|
67
|
+
|
68
|
+
def populate_interface_info(ifaddr, interfaces, mtu_and_indexes)
|
69
|
+
interface_name = ifaddr.name
|
70
|
+
interfaces[interface_name] = {} if interfaces[interface_name].nil?
|
71
|
+
interface_data = interfaces[interface_name]
|
72
|
+
|
73
|
+
mac(ifaddr, interfaces)
|
74
|
+
mtu(ifaddr, interfaces, mtu_and_indexes)
|
75
|
+
ip, netmask, ipv4_type = ip_info_of(ifaddr)
|
76
|
+
add_binding(interface_data, interface_name, ip, netmask, ipv4_type)
|
77
|
+
dhcp(interface_name, mtu_and_indexes[interface_name], interface_data) if interface_data[:dhcp].nil?
|
78
|
+
log.debug("Found interface #{interface_name} with #{interface_data}")
|
79
|
+
end
|
80
|
+
|
81
|
+
def mac(ifaddr, interfaces)
|
82
|
+
return unless interfaces[ifaddr.name][:mac].nil?
|
83
|
+
|
84
|
+
mac = search_for_mac(ifaddr)
|
85
|
+
interfaces[ifaddr.name][:mac] = mac if mac
|
86
|
+
end
|
87
|
+
|
88
|
+
def search_for_mac(ifaddr)
|
89
|
+
mac = mac_from_bonded_interface(ifaddr.name)
|
90
|
+
mac ||= mac_from(ifaddr)
|
91
|
+
mac if !mac.nil? && mac != '00:00:00:00:00:00' && mac =~ /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/
|
92
|
+
end
|
93
|
+
|
94
|
+
def mac_from_bonded_interface(interface_name)
|
95
|
+
master = bond_master_of(interface_name)
|
96
|
+
return unless master
|
97
|
+
|
98
|
+
output = Facter::Util::FileHelper.safe_read("/proc/net/bonding/#{master}", nil)
|
99
|
+
return unless output
|
100
|
+
|
101
|
+
found_match = false
|
102
|
+
output.each_line do |line|
|
103
|
+
if line.strip == "Slave Interface: #{interface_name}"
|
104
|
+
found_match = true
|
105
|
+
elsif line.include? 'Slave Interface'
|
106
|
+
# if we reached the data block of another interface belonging to the bonded interface
|
107
|
+
found_match = false
|
108
|
+
end
|
109
|
+
return Regexp.last_match(1) if found_match && line =~ /Permanent HW addr: (\S*)/
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def bond_master_of(interface_name)
|
114
|
+
content = Facter::Core::Execution.execute("ip link show #{interface_name}", logger: log)
|
115
|
+
content.match(/master (\S*) /)&.captures&.first
|
116
|
+
end
|
117
|
+
|
118
|
+
def mac_from(ifaddr)
|
119
|
+
if Socket.const_defined? :PF_LINK
|
120
|
+
ifaddr.addr&.getnameinfo&.first # sometimes it returns localhost or ip
|
121
|
+
elsif Socket.const_defined? :PF_PACKET
|
122
|
+
return if ifaddr.addr.nil?
|
123
|
+
|
124
|
+
search_mac_in_sockaddr(ifaddr)
|
125
|
+
end
|
126
|
+
rescue StandardError => e
|
127
|
+
log.debug("Could not read mac, got #{e}")
|
128
|
+
end
|
129
|
+
|
130
|
+
def search_mac_in_sockaddr(ifaddr)
|
131
|
+
result = ifaddr.addr.inspect_sockaddr
|
132
|
+
result&.match(/hwaddr=([\h:]+)/)&.captures&.first
|
133
|
+
end
|
134
|
+
|
135
|
+
def mtu(ifaddr, interfaces, mtu_and_indexes)
|
136
|
+
return unless interfaces[ifaddr.name][:mtu].nil?
|
137
|
+
|
138
|
+
mtu = mtu_and_indexes.dig(ifaddr.name, :mtu)
|
139
|
+
interfaces[ifaddr.name][:mtu] = mtu unless mtu.nil?
|
140
|
+
end
|
141
|
+
|
142
|
+
def ip_info_of(ifaddr)
|
143
|
+
return if ifaddr.addr.nil? || ifaddr.netmask.nil?
|
144
|
+
|
145
|
+
# ipv6 ips are retrieved as <ip>%<interface_name>
|
146
|
+
ip = ifaddr.addr.ip_address.split('%').first
|
147
|
+
netmask = ifaddr.netmask.ip_address
|
148
|
+
[ip, netmask, ifaddr.addr.ipv4?]
|
149
|
+
rescue StandardError => e
|
150
|
+
log.debug("Could not read binding data, got #{e}")
|
151
|
+
end
|
152
|
+
|
153
|
+
def add_binding(interface_data, interface_name, ip, netmask, ip_v4_type)
|
154
|
+
binding = Facter::Util::Resolvers::Networking.build_binding(ip, netmask)
|
155
|
+
return if binding.nil?
|
156
|
+
|
157
|
+
log.debug("Adding to interface #{interface_name}, binding:\n#{binding}")
|
158
|
+
binding_key = ip_v4_type == true ? :bindings : :bindings6
|
159
|
+
interface_data[binding_key] = [] if interface_data[binding_key].nil?
|
160
|
+
interface_data[binding_key] << binding
|
161
|
+
end
|
162
|
+
|
163
|
+
def add_info_from_routing_table
|
164
|
+
routes4, routes6 = read_routing_table
|
165
|
+
compare_ips(routes4, :bindings)
|
166
|
+
compare_ips(routes6, :bindings6)
|
167
|
+
end
|
168
|
+
|
169
|
+
def read_routing_table
|
170
|
+
ipv4_output = Facter::Core::Execution.execute('ip route show', logger: log)
|
171
|
+
ipv6_output = Facter::Core::Execution.execute('ip -6 route show', logger: log)
|
172
|
+
routes4 = parse_routes(ipv4_output, true)
|
173
|
+
routes6 = parse_routes(ipv6_output, false)
|
174
|
+
[routes4, routes6]
|
175
|
+
end
|
176
|
+
|
177
|
+
def parse_routes(output, ipv4_type)
|
178
|
+
routes = []
|
179
|
+
output.each_line do |line|
|
180
|
+
parts = line.split(' ').compact
|
181
|
+
next if parts.include?('linkdown')
|
182
|
+
|
183
|
+
delete_invalid_route_type(parts)
|
184
|
+
next if !ipv4_type && !parts[0].include?(':')
|
185
|
+
|
186
|
+
route = construct_route(parts)
|
187
|
+
routes << route unless route[:ip].nil?
|
188
|
+
end
|
189
|
+
routes.uniq
|
190
|
+
end
|
191
|
+
|
192
|
+
def delete_invalid_route_type(parts)
|
193
|
+
route_type = parts[0]
|
194
|
+
parts.delete_at(0) if ROUTE_TYPES.include?(route_type)
|
195
|
+
end
|
196
|
+
|
197
|
+
def construct_route(parts)
|
198
|
+
route = {}
|
199
|
+
dev_index = parts.find_index { |elem| elem == 'dev' }
|
200
|
+
src_index = parts.find_index { |elem| elem == 'src' }
|
201
|
+
route[:interface] = parts[dev_index + 1] if dev_index
|
202
|
+
route[:ip] = parts[src_index + 1] if src_index
|
203
|
+
route
|
204
|
+
end
|
205
|
+
|
206
|
+
def compare_ips(routes, binding_key)
|
207
|
+
routes.each do |route|
|
208
|
+
next unless @fact_list[:interfaces].key?(route[:interface])
|
209
|
+
|
210
|
+
interface_data = @fact_list[:interfaces][route[:interface]]
|
211
|
+
add_binding_if_missing(interface_data, binding_key, route)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def add_binding_if_missing(interface_data, binding_key, route)
|
216
|
+
interface_binding = interface_data[binding_key]
|
217
|
+
|
218
|
+
if interface_binding.nil?
|
219
|
+
interface_data[binding_key] = [{ address: route[:ip] }]
|
220
|
+
elsif interface_binding.none? { |binding| binding[:address] == route[:ip] }
|
221
|
+
interface_binding << { address: route[:ip] }
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def dhcp(interface_name, index_and_mtu, interface_data)
|
226
|
+
log.debug("Get DHCP for interface #{interface_name}")
|
227
|
+
|
228
|
+
search_systemd_netif_leases(interface_data, index_and_mtu)
|
229
|
+
search_dhclient_leases(interface_data, interface_name)
|
230
|
+
search_internal_leases(interface_data, interface_name)
|
231
|
+
search_with_dhcpcd_command(interface_data, interface_name)
|
232
|
+
end
|
233
|
+
|
234
|
+
def search_systemd_netif_leases(interface_data, index_and_mtu)
|
235
|
+
return if index_and_mtu.nil?
|
236
|
+
|
237
|
+
index = index_and_mtu[:index]
|
238
|
+
file_content = Facter::Util::FileHelper.safe_read("/run/systemd/netif/leases/#{index}", nil)
|
239
|
+
dhcp = file_content.match(/SERVER_ADDRESS=(.*)/) if file_content
|
240
|
+
interface_data[:dhcp] = dhcp[1] if dhcp
|
241
|
+
end
|
242
|
+
|
243
|
+
def search_dhclient_leases(interface_data, interface_name)
|
244
|
+
return unless interface_data[:dhcp].nil?
|
245
|
+
|
246
|
+
DIRS.each do |dir|
|
247
|
+
next unless File.readable?(dir)
|
248
|
+
|
249
|
+
lease_files = Dir.entries(dir).select { |file| file =~ /dhclient.*\.lease/ }
|
250
|
+
next if lease_files.empty?
|
251
|
+
|
252
|
+
lease_files.select do |file|
|
253
|
+
content = Facter::Util::FileHelper.safe_read("#{dir}#{file}", nil)
|
254
|
+
next unless content =~ /interface.*#{interface_name}/
|
255
|
+
|
256
|
+
dhcp = content.match(/dhcp-server-identifier ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/)
|
257
|
+
return interface_data[:dhcp] = dhcp[1] if dhcp
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def search_internal_leases(interface_data, interface_name)
|
263
|
+
return if !interface_data[:dhcp].nil? || !File.readable?('/var/lib/NetworkManager/')
|
264
|
+
|
265
|
+
files = Dir.entries('/var/lib/NetworkManager/').reject { |dir| dir =~ /^\.+$/ }
|
266
|
+
lease_file = files.find { |file| file =~ /internal.*#{interface_name}\.lease/ }
|
267
|
+
return unless lease_file
|
268
|
+
|
269
|
+
dhcp = Facter::Util::FileHelper.safe_read("/var/lib/NetworkManager/#{lease_file}", nil)
|
270
|
+
|
271
|
+
return unless dhcp
|
272
|
+
|
273
|
+
dhcp = dhcp.match(/SERVER_ADDRESS=(.*)/)
|
274
|
+
interface_data[:dhcp] = dhcp[1] if dhcp
|
275
|
+
end
|
276
|
+
|
277
|
+
def search_with_dhcpcd_command(interface_data, interface_name)
|
278
|
+
return unless interface_data[:dhcp].nil?
|
279
|
+
|
280
|
+
output = Facter::Core::Execution.execute("dhcpcd -U #{interface_name}", logger: log)
|
281
|
+
dhcp = output.match(/dhcp_server_identifier='(.*)'/)
|
282
|
+
interface_data[:dhcp] = dhcp[1] if dhcp
|
283
|
+
end
|
284
|
+
|
285
|
+
def retrieve_primary_interface
|
286
|
+
primary_helper = Facter::Util::Resolvers::Networking::PrimaryInterface
|
287
|
+
primary_interface = primary_helper.read_from_proc_route
|
288
|
+
primary_interface ||= primary_helper.read_from_ip_route
|
289
|
+
primary_interface ||= primary_helper.find_in_interfaces(@fact_list[:interfaces])
|
290
|
+
|
291
|
+
@fact_list[:primary_interface] = primary_interface
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|