facter 4.0.46 → 4.0.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. checksums.yaml +4 -4
  2. data/lib/docs/generate.rb +32 -0
  3. data/lib/docs/template.erb +34 -0
  4. data/lib/facter.rb +38 -6
  5. data/lib/facter/config.rb +32 -1
  6. data/lib/facter/custom_facts/util/collection.rb +1 -2
  7. data/lib/facter/custom_facts/util/directory_loader.rb +1 -1
  8. data/lib/facter/custom_facts/util/fact.rb +18 -1
  9. data/lib/facter/custom_facts/util/loader.rb +1 -1
  10. data/lib/facter/custom_facts/util/resolution.rb +1 -1
  11. data/lib/facter/facts/aix/interfaces.rb +1 -0
  12. data/lib/facter/facts/aix/memory/swap/available.rb +1 -1
  13. data/lib/facter/facts/aix/memory/swap/available_bytes.rb +1 -1
  14. data/lib/facter/facts/aix/memory/swap/total.rb +1 -1
  15. data/lib/facter/facts/aix/memory/swap/total_bytes.rb +1 -1
  16. data/lib/facter/facts/aix/memory/swap/used.rb +1 -1
  17. data/lib/facter/facts/aix/memory/system/available.rb +1 -1
  18. data/lib/facter/facts/aix/memory/system/available_bytes.rb +1 -1
  19. data/lib/facter/facts/aix/memory/system/total.rb +1 -1
  20. data/lib/facter/facts/aix/memory/system/total_bytes.rb +1 -1
  21. data/lib/facter/facts/aix/memory/system/used.rb +1 -1
  22. data/lib/facter/facts/aix/processors/speed.rb +1 -1
  23. data/lib/facter/facts/bsd/processors/speed.rb +1 -1
  24. data/lib/facter/facts/freebsd/is_virtual.rb +25 -0
  25. data/lib/facter/facts/freebsd/memory/swap/available.rb +1 -1
  26. data/lib/facter/facts/freebsd/memory/swap/available_bytes.rb +1 -1
  27. data/lib/facter/facts/freebsd/memory/swap/total.rb +1 -1
  28. data/lib/facter/facts/freebsd/memory/swap/total_bytes.rb +1 -1
  29. data/lib/facter/facts/freebsd/memory/swap/used.rb +1 -1
  30. data/lib/facter/facts/freebsd/memory/system/available.rb +1 -1
  31. data/lib/facter/facts/freebsd/memory/system/available_bytes.rb +1 -1
  32. data/lib/facter/facts/freebsd/memory/system/total.rb +1 -1
  33. data/lib/facter/facts/freebsd/memory/system/total_bytes.rb +1 -1
  34. data/lib/facter/facts/freebsd/memory/system/used.rb +1 -1
  35. data/lib/facter/facts/freebsd/processors/speed.rb +1 -1
  36. data/lib/facter/facts/freebsd/virtual.rb +22 -0
  37. data/lib/facter/facts/linux/dhcp_servers.rb +1 -0
  38. data/lib/facter/facts/linux/ec2_metadata.rb +1 -1
  39. data/lib/facter/facts/linux/ec2_userdata.rb +1 -1
  40. data/lib/facter/facts/linux/hypervisors/kvm.rb +1 -1
  41. data/lib/facter/facts/linux/hypervisors/xen.rb +1 -1
  42. data/lib/facter/facts/linux/interfaces.rb +1 -0
  43. data/lib/facter/facts/linux/is_virtual.rb +2 -2
  44. data/lib/facter/facts/linux/memory/swap/available.rb +1 -1
  45. data/lib/facter/facts/linux/memory/swap/available_bytes.rb +1 -1
  46. data/lib/facter/facts/linux/memory/swap/total.rb +1 -1
  47. data/lib/facter/facts/linux/memory/swap/total_bytes.rb +1 -1
  48. data/lib/facter/facts/linux/memory/swap/used.rb +1 -1
  49. data/lib/facter/facts/linux/memory/system/available.rb +1 -1
  50. data/lib/facter/facts/linux/memory/system/available_bytes.rb +1 -1
  51. data/lib/facter/facts/linux/memory/system/total.rb +1 -1
  52. data/lib/facter/facts/linux/memory/system/total_bytes.rb +1 -1
  53. data/lib/facter/facts/linux/memory/system/used.rb +1 -1
  54. data/lib/facter/facts/linux/processors/speed.rb +1 -1
  55. data/lib/facter/facts/linux/virtual.rb +1 -1
  56. data/lib/facter/facts/macosx/dhcp_servers.rb +1 -0
  57. data/lib/facter/facts/macosx/interfaces.rb +1 -0
  58. data/lib/facter/facts/macosx/memory/swap/available.rb +1 -1
  59. data/lib/facter/facts/macosx/memory/swap/available_bytes.rb +1 -1
  60. data/lib/facter/facts/macosx/memory/swap/total.rb +1 -1
  61. data/lib/facter/facts/macosx/memory/swap/total_bytes.rb +1 -1
  62. data/lib/facter/facts/macosx/memory/swap/used.rb +1 -1
  63. data/lib/facter/facts/macosx/memory/system/available.rb +1 -1
  64. data/lib/facter/facts/macosx/memory/system/available_bytes.rb +1 -1
  65. data/lib/facter/facts/macosx/memory/system/total.rb +1 -1
  66. data/lib/facter/facts/macosx/memory/system/total_bytes.rb +1 -1
  67. data/lib/facter/facts/macosx/memory/system/used.rb +1 -1
  68. data/lib/facter/facts/macosx/processors/speed.rb +1 -1
  69. data/lib/facter/facts/solaris/dhcp_servers.rb +1 -0
  70. data/lib/facter/facts/solaris/interfaces.rb +1 -0
  71. data/lib/facter/facts/solaris/is_virtual.rb +2 -2
  72. data/lib/facter/facts/solaris/ldom.rb +31 -4
  73. data/lib/facter/facts/solaris/memory/swap/available.rb +1 -1
  74. data/lib/facter/facts/solaris/memory/swap/available_bytes.rb +1 -1
  75. data/lib/facter/facts/solaris/memory/swap/total.rb +1 -1
  76. data/lib/facter/facts/solaris/memory/swap/total_bytes.rb +1 -1
  77. data/lib/facter/facts/solaris/memory/swap/used.rb +1 -1
  78. data/lib/facter/facts/solaris/memory/system/available.rb +1 -1
  79. data/lib/facter/facts/solaris/memory/system/available_bytes.rb +1 -1
  80. data/lib/facter/facts/solaris/memory/system/total.rb +1 -1
  81. data/lib/facter/facts/solaris/memory/system/total_bytes.rb +1 -1
  82. data/lib/facter/facts/solaris/memory/system/used.rb +1 -1
  83. data/lib/facter/facts/solaris/processors/speed.rb +1 -1
  84. data/lib/facter/facts/solaris/virtual.rb +1 -1
  85. data/lib/facter/facts/windows/dhcp_servers.rb +1 -0
  86. data/lib/facter/facts/windows/interfaces.rb +1 -0
  87. data/lib/facter/facts/windows/memory/system/available.rb +1 -1
  88. data/lib/facter/facts/windows/memory/system/available_bytes.rb +1 -1
  89. data/lib/facter/facts/windows/memory/system/total.rb +1 -1
  90. data/lib/facter/facts/windows/memory/system/total_bytes.rb +1 -1
  91. data/lib/facter/facts/windows/memory/system/used.rb +1 -1
  92. data/lib/facter/facts/windows/os/release.rb +1 -1
  93. data/lib/facter/framework/cli/cli.rb +1 -1
  94. data/lib/facter/framework/core/cache_manager.rb +1 -1
  95. data/lib/facter/framework/core/fact_loaders/external_fact_loader.rb +4 -2
  96. data/lib/facter/framework/core/fact_loaders/fact_loader.rb +16 -0
  97. data/lib/facter/framework/core/fact_manager.rb +14 -2
  98. data/lib/facter/framework/core/file_loader.rb +6 -2
  99. data/lib/facter/framework/core/options/option_store.rb +2 -2
  100. data/lib/facter/framework/logging/logger.rb +3 -3
  101. data/lib/facter/models/fact_collection.rb +11 -1
  102. data/lib/facter/models/loaded_fact.rb +2 -1
  103. data/lib/facter/resolvers/aio_agent_version.rb +1 -1
  104. data/lib/facter/resolvers/aix/architecture_resolver.rb +3 -3
  105. data/lib/facter/resolvers/aix/disks.rb +4 -4
  106. data/lib/facter/resolvers/aix/filesystem_resolver.rb +1 -1
  107. data/lib/facter/resolvers/aix/hardware_resolver.rb +2 -2
  108. data/lib/facter/resolvers/aix/memory.rb +2 -2
  109. data/lib/facter/resolvers/aix/mountpoints.rb +4 -4
  110. data/lib/facter/resolvers/aix/networking_resolver.rb +3 -2
  111. data/lib/facter/resolvers/aix/partitions.rb +5 -5
  112. data/lib/facter/resolvers/aix/processors.rb +3 -3
  113. data/lib/facter/resolvers/aix/serialnumber.rb +1 -1
  114. data/lib/facter/resolvers/base_resolver.rb +3 -0
  115. data/lib/facter/resolvers/cloud.rb +1 -1
  116. data/lib/facter/resolvers/containers.rb +3 -3
  117. data/lib/facter/resolvers/debian_version.rb +1 -1
  118. data/lib/facter/resolvers/disk_resolver.rb +2 -2
  119. data/lib/facter/resolvers/dmi_resolver.rb +1 -1
  120. data/lib/facter/resolvers/ec2.rb +3 -1
  121. data/lib/facter/resolvers/eos_release_resolver.rb +1 -1
  122. data/lib/facter/resolvers/filesystems_resolver.rb +1 -1
  123. data/lib/facter/resolvers/fips_enabled_resolver.rb +1 -1
  124. data/lib/facter/resolvers/freebsd/geom_resolver.rb +1 -1
  125. data/lib/facter/resolvers/freebsd/swap_memory_resolver.rb +3 -2
  126. data/lib/facter/resolvers/freebsd/system_memory_resolver.rb +2 -1
  127. data/lib/facter/resolvers/freebsd/virtual_resolver.rb +45 -0
  128. data/lib/facter/resolvers/gce.rb +1 -1
  129. data/lib/facter/resolvers/hostname_resolver.rb +67 -20
  130. data/lib/facter/resolvers/linux/docker_uptime.rb +1 -1
  131. data/lib/facter/resolvers/linux/load_averages.rb +1 -1
  132. data/lib/facter/resolvers/load_averages.rb +3 -2
  133. data/lib/facter/resolvers/macosx/mountpoints_resolver.rb +7 -7
  134. data/lib/facter/resolvers/macosx/system_profiler_resolver.rb +3 -3
  135. data/lib/facter/resolvers/memory_resolver.rb +1 -1
  136. data/lib/facter/resolvers/mountpoints_resolver.rb +8 -8
  137. data/lib/facter/resolvers/networking_linux_resolver.rb +183 -85
  138. data/lib/facter/resolvers/networking_resolver.rb +8 -5
  139. data/lib/facter/resolvers/open_vz.rb +1 -3
  140. data/lib/facter/resolvers/os_release_resolver.rb +1 -1
  141. data/lib/facter/resolvers/partitions.rb +5 -5
  142. data/lib/facter/resolvers/processors_resolver.rb +2 -2
  143. data/lib/facter/resolvers/redhat_release_resolver.rb +1 -1
  144. data/lib/facter/resolvers/selinux_resolver.rb +3 -3
  145. data/lib/facter/resolvers/solaris/disks.rb +1 -1
  146. data/lib/facter/resolvers/solaris/memory.rb +2 -2
  147. data/lib/facter/resolvers/solaris/mountpoints.rb +11 -10
  148. data/lib/facter/resolvers/solaris/networking.rb +49 -41
  149. data/lib/facter/resolvers/solaris/os_release.rb +1 -1
  150. data/lib/facter/resolvers/ssh_resolver.rb +3 -2
  151. data/lib/facter/resolvers/suse_release_resolver.rb +1 -1
  152. data/lib/facter/resolvers/uptime_resolver.rb +2 -2
  153. data/lib/facter/resolvers/windows/aio_agent_version.rb +1 -1
  154. data/lib/facter/resolvers/windows/dmi_bios_resolver.rb +1 -1
  155. data/lib/facter/resolvers/windows/dmi_computersystem_resolver.rb +1 -1
  156. data/lib/facter/resolvers/windows/memory_resolver.rb +4 -0
  157. data/lib/facter/resolvers/windows/networking_resolver.rb +3 -3
  158. data/lib/facter/resolvers/windows/processors_resolver.rb +1 -1
  159. data/lib/facter/resolvers/windows/ssh.rb +2 -2
  160. data/lib/facter/resolvers/windows/uptime_resolver.rb +1 -1
  161. data/lib/facter/resolvers/windows/virtualization_resolver.rb +1 -1
  162. data/lib/facter/resolvers/windows/win_os_description_resolver.rb +1 -1
  163. data/lib/facter/resolvers/xen.rb +1 -1
  164. data/lib/facter/util/aix/info_extractor.rb +24 -0
  165. data/lib/facter/util/aix/odm_query.rb +46 -0
  166. data/lib/facter/util/api_debugger.rb +33 -29
  167. data/lib/facter/util/facts/facts_utils.rb +14 -0
  168. data/lib/facter/util/facts/unit_converter.rb +61 -0
  169. data/lib/facter/util/facts/uptime_parser.rb +128 -0
  170. data/lib/facter/util/facts/virtual_detector.rb +90 -0
  171. data/lib/facter/util/facts/windows_release_finder.rb +55 -0
  172. data/lib/facter/{resolvers/macosx/utils → util/macosx}/system_profile_executor.rb +1 -1
  173. data/lib/facter/util/resolvers/aws_token.rb +37 -0
  174. data/lib/facter/{resolvers/utils → util/resolvers}/ffi/load_averages.rb +2 -2
  175. data/lib/facter/util/resolvers/filesystem_helper.rb +47 -0
  176. data/lib/facter/util/resolvers/fingerprint.rb +15 -0
  177. data/lib/facter/{resolvers/utils → util/resolvers}/http.rb +17 -10
  178. data/lib/facter/util/resolvers/networking.rb +90 -0
  179. data/lib/facter/util/resolvers/networking/dhcp.rb +21 -0
  180. data/lib/facter/util/resolvers/networking/networking.rb +109 -0
  181. data/lib/facter/util/resolvers/networking/primary_interface.rb +82 -0
  182. data/lib/facter/util/resolvers/ssh.rb +17 -0
  183. data/lib/facter/util/resolvers/ssh_helper.rb +31 -0
  184. data/lib/facter/{resolvers/utils → util/resolvers}/uptime_helper.rb +2 -2
  185. data/lib/facter/{framework/utils → util}/utils.rb +0 -0
  186. data/lib/facter/util/windows/win32ole.rb +30 -0
  187. data/lib/facter/version.rb +1 -1
  188. metadata +29 -41
  189. data/lib/facter/facts/aix/puppet_version.rb +0 -15
  190. data/lib/facter/facts/freebsd/puppet_version.rb +0 -15
  191. data/lib/facter/facts/linux/puppet_version.rb +0 -15
  192. data/lib/facter/facts/macosx/puppet_version.rb +0 -15
  193. data/lib/facter/facts/solaris/puppet_version.rb +0 -15
  194. data/lib/facter/facts/windows/puppet_version.rb +0 -15
  195. data/lib/facter/facts_utils/facts_utils.rb +0 -12
  196. data/lib/facter/facts_utils/unit_converter.rb +0 -59
  197. data/lib/facter/facts_utils/uptime_parser.rb +0 -124
  198. data/lib/facter/facts_utils/virtual_detector.rb +0 -78
  199. data/lib/facter/facts_utils/windows_release_finder.rb +0 -51
  200. data/lib/facter/resolvers/aix/utils/info_extractor.rb +0 -20
  201. data/lib/facter/resolvers/aix/utils/odm_query.rb +0 -42
  202. data/lib/facter/resolvers/puppet_version_resolver.rb +0 -26
  203. data/lib/facter/resolvers/utils/filesystem_helper.rb +0 -43
  204. data/lib/facter/resolvers/utils/fingerprint.rb +0 -11
  205. data/lib/facter/resolvers/utils/networking.rb +0 -88
  206. data/lib/facter/resolvers/utils/ssh.rb +0 -13
  207. data/lib/facter/resolvers/utils/ssh_helper.rb +0 -27
  208. data/lib/facter/resolvers/windows/utils/win32ole.rb +0 -24
@@ -22,7 +22,7 @@ module Facter
22
22
  end
23
23
 
24
24
  def query_for_metadata
25
- gce_data = extract_to_hash(Utils::Http.get_request(METADATA_URL, HEADERS))
25
+ gce_data = extract_to_hash(Facter::Util::Resolvers::Http.get_request(METADATA_URL, HEADERS))
26
26
  parse_instance(gce_data)
27
27
 
28
28
  gce_data.empty? ? nil : gce_data
@@ -3,41 +3,88 @@
3
3
  module Facter
4
4
  module Resolvers
5
5
  class Hostname < BaseResolver
6
+ # :fqdn
7
+ # :domain
8
+ # :hostname
9
+
6
10
  init_resolver
7
11
 
8
12
  class << self
9
13
  private
10
14
 
11
15
  def post_resolve(fact_name)
12
- @fact_list.fetch(fact_name) { retrieve_hostname(fact_name) }
16
+ @fact_list.fetch(fact_name) { retrieve_info(fact_name) }
13
17
  end
14
18
 
15
- def retrieve_hostname(fact_name)
16
- output = Facter::Core::Execution.execute('hostname', logger: log)
19
+ def retrieve_info(fact_name)
20
+ require 'socket'
21
+ output = Socket.gethostname
22
+ hostname, domain = retrieve_from_fqdn(output)
23
+
24
+ fqdn = retrieve_with_addrinfo(hostname) if hostname_and_no_domain?(hostname, domain)
25
+
26
+ _, domain = retrieve_from_fqdn(fqdn) if exists_and_valid_fqdn?(fqdn, hostname)
17
27
 
18
- # get domain
19
- domain = read_domain(output)
28
+ domain = read_domain unless exists_and_not_empty?(domain)
20
29
 
21
- # get hostname
22
- hostname = output =~ /(.*?)\./ ? Regexp.last_match(1) : output
23
- @fact_list[:hostname] ||= hostname&.strip
24
- @fact_list[:domain] ||= domain&.strip
25
- @fact_list[:fqdn] ||= "#{@fact_list[:hostname]}.#{@fact_list[:domain]}"
30
+ construct_fact_list(hostname, domain, fqdn)
26
31
  @fact_list[fact_name]
27
32
  end
28
33
 
29
- def read_domain(output)
30
- if output =~ /.*?\.(.+$)/
31
- domain = Regexp.last_match(1)
34
+ def retrieve_from_fqdn(output)
35
+ if output =~ /(.*?)\.(.+$)/
36
+ log.debug("Managed to read hostname: #{Regexp.last_match(1)} and domain: #{Regexp.last_match(2)}")
37
+ [Regexp.last_match(1), Regexp.last_match(2)]
32
38
  else
33
- file_content = Util::FileHelper.safe_read('/etc/resolv.conf')
34
- if file_content =~ /^search\s+(\S+)/
35
- domain = Regexp.last_match(1)
36
- elsif file_content =~ /^domain\s+(\S+)/
37
- domain = Regexp.last_match(1)
38
- end
39
+ log.debug("Only managed to read hostname: #{output}, no domain was found.")
40
+ [output, '']
41
+ end
42
+ end
43
+
44
+ def retrieve_with_addrinfo(host)
45
+ begin
46
+ name = Socket.getaddrinfo(host, 0, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME)[0]
47
+ rescue StandardError => e
48
+ @log.debug("Socket.getaddrinfo failed to retrieve fqdn for hostname #{host} with: #{e}")
49
+ return
39
50
  end
40
- domain
51
+ return if name.nil? || name.empty? || host == name[2] || name[2] == name[3]
52
+
53
+ name[2]
54
+ end
55
+
56
+ def exists_and_valid_fqdn?(fqdn, hostname)
57
+ exists_and_not_empty?(fqdn) && fqdn.start_with?("#{hostname}.")
58
+ end
59
+
60
+ def hostname_and_no_domain?(hostname, domain)
61
+ domain.empty? && !hostname.empty?
62
+ end
63
+
64
+ def read_domain
65
+ file_content = Facter::Util::FileHelper.safe_read('/etc/resolv.conf')
66
+ if file_content =~ /^domain\s+(\S+)/
67
+ Regexp.last_match(1)
68
+ elsif file_content =~ /^search\s+(\S+)/
69
+ Regexp.last_match(1)
70
+ end
71
+ end
72
+
73
+ def construct_fqdn(host, domain, fqdn)
74
+ return fqdn if exists_and_not_empty?(fqdn)
75
+ return if host.nil? || host.empty?
76
+
77
+ exists_and_not_empty?(domain) ? "#{host}.#{domain}" : host
78
+ end
79
+
80
+ def construct_fact_list(hostname, domain, fqdn)
81
+ @fact_list[:hostname] = hostname
82
+ @fact_list[:domain] = domain
83
+ @fact_list[:fqdn] = construct_fqdn(@fact_list[:hostname], @fact_list[:domain], fqdn)
84
+ end
85
+
86
+ def exists_and_not_empty?(variable)
87
+ variable && !variable.empty?
41
88
  end
42
89
  end
43
90
  end
@@ -16,7 +16,7 @@ module Facter
16
16
  def detect_uptime(fact_name)
17
17
  days, hours, minutes, seconds = extract_uptime_from_docker
18
18
  total_seconds = convert_to_seconds(days, hours, minutes, seconds)
19
- @fact_list = Utils::UptimeHelper.create_uptime_hash(total_seconds)
19
+ @fact_list = Facter::Util::Resolvers::UptimeHelper.create_uptime_hash(total_seconds)
20
20
 
21
21
  @fact_list[fact_name]
22
22
  end
@@ -14,7 +14,7 @@ module Facter
14
14
  end
15
15
 
16
16
  def read_load_averages_file(fact_name)
17
- output = Util::FileHelper.safe_read('/proc/loadavg')
17
+ output = Facter::Util::FileHelper.safe_read('/proc/loadavg')
18
18
  @fact_list[:load_averages] = {}.tap { |h| h['1m'], h['5m'], h['15m'], = output.split.map(&:to_f) }
19
19
 
20
20
  @fact_list[fact_name]
@@ -13,10 +13,11 @@ module Facter
13
13
  end
14
14
 
15
15
  def read_load_averages(fact_name)
16
- require_relative 'utils/ffi/load_averages'
16
+ require 'facter/util/resolvers/ffi/load_averages'
17
17
 
18
18
  log.debug('loading cpu load averages')
19
- @fact_list[:load_averages] = %w[1m 5m 15m].zip(Utils::Ffi::LoadAverages.read_load_averages).to_h
19
+ @fact_list[:load_averages] = %w[1m 5m 15m].zip(Facter::Util::Resolvers::Ffi::LoadAverages
20
+ .read_load_averages).to_h
20
21
 
21
22
  @fact_list[fact_name]
22
23
  end
@@ -4,7 +4,7 @@ module Facter
4
4
  module Resolvers
5
5
  module Macosx
6
6
  class Mountpoints < BaseResolver
7
- include Facter::FilesystemHelper
7
+ include Facter::Util::Resolvers::FilesystemHelper
8
8
  init_resolver
9
9
 
10
10
  class << self
@@ -17,7 +17,7 @@ module Facter
17
17
  def read_mounts
18
18
  mounts = {}
19
19
 
20
- FilesystemHelper.read_mountpoints.each do |fs|
20
+ Facter::Util::Resolvers::FilesystemHelper.read_mountpoints.each do |fs|
21
21
  device = fs.name
22
22
  filesystem = fs.mount_type
23
23
  path = fs.mount_point
@@ -35,7 +35,7 @@ module Facter
35
35
 
36
36
  def read_stats(path)
37
37
  begin
38
- stats = FilesystemHelper.read_mountpoint_stats(path)
38
+ stats = Facter::Util::Resolvers::FilesystemHelper.read_mountpoint_stats(path)
39
39
  size_bytes = stats.bytes_total
40
40
  available_bytes = stats.bytes_available
41
41
  used_bytes = size_bytes - available_bytes
@@ -47,10 +47,10 @@ module Facter
47
47
  size_bytes: size_bytes,
48
48
  used_bytes: used_bytes,
49
49
  available_bytes: available_bytes,
50
- capacity: FilesystemHelper.compute_capacity(used_bytes, size_bytes),
51
- size: Facter::FactsUtils::UnitConverter.bytes_to_human_readable(size_bytes),
52
- available: Facter::FactsUtils::UnitConverter.bytes_to_human_readable(available_bytes),
53
- used: Facter::FactsUtils::UnitConverter.bytes_to_human_readable(used_bytes)
50
+ capacity: Facter::Util::Resolvers::FilesystemHelper.compute_capacity(used_bytes, size_bytes),
51
+ size: Facter::Util::Facts::UnitConverter.bytes_to_human_readable(size_bytes),
52
+ available: Facter::Util::Facts::UnitConverter.bytes_to_human_readable(available_bytes),
53
+ used: Facter::Util::Facts::UnitConverter.bytes_to_human_readable(used_bytes)
54
54
  }
55
55
  end
56
56
  end
@@ -27,11 +27,11 @@ module Facter
27
27
  def retrieve_system_profiler(fact_name)
28
28
  case fact_name
29
29
  when *SP_HARDWARE_DATA_TYPE
30
- @fact_list.merge!(SystemProfileExecutor.execute('SPHardwareDataType'))
30
+ @fact_list.merge!(Facter::Util::Macosx::SystemProfileExecutor.execute('SPHardwareDataType'))
31
31
  when *SP_SOFTWARE_DATA_TYPE
32
- @fact_list.merge!(SystemProfileExecutor.execute('SPSoftwareDataType'))
32
+ @fact_list.merge!(Facter::Util::Macosx::SystemProfileExecutor.execute('SPSoftwareDataType'))
33
33
  when *SP_ETHERNET_DATA_TYPE
34
- @fact_list.merge!(SystemProfileExecutor.execute('SPEthernetDataType'))
34
+ @fact_list.merge!(Facter::Util::Macosx::SystemProfileExecutor.execute('SPEthernetDataType'))
35
35
  end
36
36
 
37
37
  @fact_list[fact_name]
@@ -16,7 +16,7 @@ module Facter
16
16
  end
17
17
 
18
18
  def read_meminfo_file(fact_name)
19
- meminfo_output = Util::FileHelper.safe_read('/proc/meminfo', nil)
19
+ meminfo_output = Facter::Util::FileHelper.safe_read('/proc/meminfo', nil)
20
20
  return unless meminfo_output
21
21
 
22
22
  read_system(meminfo_output)
@@ -3,7 +3,7 @@
3
3
  module Facter
4
4
  module Resolvers
5
5
  class Mountpoints < BaseResolver
6
- include Facter::FilesystemHelper
6
+ include Facter::Util::Resolvers::FilesystemHelper
7
7
 
8
8
  init_resolver
9
9
 
@@ -17,7 +17,7 @@ module Facter
17
17
  end
18
18
 
19
19
  def root_device
20
- cmdline = Util::FileHelper.safe_read('/proc/cmdline')
20
+ cmdline = Facter::Util::FileHelper.safe_read('/proc/cmdline')
21
21
  match = cmdline.match(/root=([^\s]+)/)
22
22
  root = match&.captures&.first
23
23
 
@@ -45,7 +45,7 @@ module Facter
45
45
 
46
46
  def read_mounts(fact_name)
47
47
  mounts = []
48
- FilesystemHelper.read_mountpoints.each do |file_system|
48
+ Facter::Util::Resolvers::FilesystemHelper.read_mountpoints.each do |file_system|
49
49
  mount = {}
50
50
  get_mount_data(file_system, mount)
51
51
 
@@ -67,16 +67,16 @@ module Facter
67
67
  end
68
68
 
69
69
  def get_mount_sizes(mount)
70
- stats = FilesystemHelper.read_mountpoint_stats(mount[:path])
70
+ stats = Facter::Util::Resolvers::FilesystemHelper.read_mountpoint_stats(mount[:path])
71
71
 
72
72
  get_bytes_data(mount, stats)
73
73
 
74
74
  total_bytes = mount[:used_bytes] + mount[:available_bytes]
75
- mount[:capacity] = FilesystemHelper.compute_capacity(mount[:used_bytes], total_bytes)
75
+ mount[:capacity] = Facter::Util::Resolvers::FilesystemHelper.compute_capacity(mount[:used_bytes], total_bytes)
76
76
 
77
- mount[:size] = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(mount[:size_bytes])
78
- mount[:available] = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(mount[:available_bytes])
79
- mount[:used] = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(mount[:used_bytes])
77
+ mount[:size] = Facter::Util::Facts::UnitConverter.bytes_to_human_readable(mount[:size_bytes])
78
+ mount[:available] = Facter::Util::Facts::UnitConverter.bytes_to_human_readable(mount[:available_bytes])
79
+ mount[:used] = Facter::Util::Facts::UnitConverter.bytes_to_human_readable(mount[:used_bytes])
80
80
  end
81
81
 
82
82
  def get_bytes_data(mount, stats)
@@ -6,6 +6,15 @@ module Facter
6
6
  init_resolver
7
7
 
8
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
9
18
 
10
19
  class << self
11
20
  private
@@ -17,55 +26,188 @@ module Facter
17
26
  end
18
27
 
19
28
  def retrieve_network_info(fact_name)
20
- retrieve_interface_info
21
- retrieve_interfaces_mac_and_mtu
22
- retrieve_default_interface
23
- ::Resolvers::Utils::Networking.expand_main_bindings(@fact_list)
29
+ mtu_and_indexes = interfaces_mtu_and_index
30
+ retrieve_interface_info(mtu_and_indexes)
31
+ add_info_from_routing_table
32
+ retrieve_primary_interface
33
+ Facter::Util::Resolvers::Networking.expand_main_bindings(@fact_list)
24
34
  @fact_list[fact_name]
25
35
  end
26
36
 
27
- def retrieve_interfaces_mac_and_mtu
28
- @fact_list[:interfaces].map do |name, info|
29
- macaddress = Util::FileHelper.safe_read("/sys/class/net/#{name}/address", nil)
30
- info[:mac] = macaddress.strip if macaddress && !macaddress.include?('00:00:00:00:00:00')
31
- mtu = Util::FileHelper.safe_read("/sys/class/net/#{name}/mtu", nil)
32
- info[:mtu] = mtu.strip.to_i if mtu
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
+ mtu = line.match(/mtu (\d+)/)&.captures&.first&.to_i
44
+ index_tokens = line.split(':')
45
+ index = index_tokens[0].strip
46
+ # vlans are displayed as <vlan_name>@<physical_interface>
47
+ name = index_tokens[1].split('@').first.strip
48
+ mtu_and_indexes[name] = [index, mtu]
33
49
  end
50
+ mtu_and_indexes
34
51
  end
35
52
 
36
- def retrieve_interface_info
37
- log.debug('retrieve_interface_info')
38
- output = Facter::Core::Execution.execute('ip -o address', logger: log)
39
- log.debug("ip -o address result is:\n#{output}")
40
-
53
+ def retrieve_interface_info(mtu_and_indexes)
54
+ require 'socket'
41
55
  interfaces = {}
56
+ Socket.getifaddrs.each do |interface|
57
+ interfaces[interface.name] = {} if interfaces[interface.name].nil?
58
+
59
+ if interfaces[interface.name][:mac].nil?
60
+ mac = extract_mac_address(interface)
61
+ interfaces[interface.name][:mac] = mac if mac
62
+ end
42
63
 
43
- output.each_line do |ip_line|
44
- ip_tokens = ip_line.split(' ')
64
+ if interfaces[interface.name][:mtu].nil?
65
+ mtu = mtu_and_indexes.dig(interface.name, 1)
66
+ interfaces[interface.name][:mtu] = mtu unless mtu.nil?
67
+ end
45
68
 
46
- log.debug("ip_tokens = #{ip_tokens}")
47
- log.debug("interfaces = #{interfaces}")
48
- fill_ip_v4_info!(ip_tokens, interfaces)
49
- fill_io_v6_info!(ip_tokens, interfaces)
50
- find_dhcp!(ip_tokens, interfaces)
69
+ if !interface.addr.nil? && !interface.netmask.nil?
70
+ begin
71
+ # ipv6 ips are retrieved as <ip>%<interface_name>
72
+ ip = interface.addr.ip_address.split('%').first if interface.addr.ip?
73
+ netmask = interface.netmask.ip_address
74
+ add_binding(interfaces, interface.name, ip, netmask, interface.addr.ipv4?)
75
+ rescue SocketError => e
76
+ end
77
+ end
78
+ find_dhcp!(interface.name, mtu_and_indexes, interfaces)
51
79
  end
52
80
 
53
81
  @fact_list[:interfaces] = interfaces
54
82
  end
55
83
 
56
- def find_dhcp!(tokens, network_info)
57
- interface_name = tokens[1]
58
- return if !network_info[interface_name] || network_info[interface_name][:dhcp]
84
+ def extract_mac_address(interface)
85
+ mac = get_bonded_interface_mac(interface.name)
86
+ begin
87
+ if mac.nil?
88
+ if Socket.const_defined? :PF_LINK
89
+ mac = interface.addr&.getnameinfo&.first #sometimes it returns localhost, ip but mac also
90
+ elsif Socket.const_defined? :PF_PACKET
91
+ return if interface.addr.nil? || interface.addr.inspect_sockaddr.nil?
92
+
93
+ mac = interface.addr&.inspect_sockaddr[/hwaddr=([\h:]+)/, 1]
94
+ end
95
+ end
96
+ rescue StandardError => e
97
+ log.debug("Could not read mac, got #{e}")
98
+ end
99
+ mac if !mac.nil? && mac != '00:00:00:00:00:00' && mac =~ /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/
100
+ end
101
+
102
+ def get_bonded_interface_mac(interface_name)
103
+ master = get_bond_master(interface_name)
104
+ return unless master
105
+
106
+ output = Facter::Util::FileHelper.safe_read("/proc/net/bonding/#{master}", nil)
107
+ return unless output
108
+
109
+ right_block = false
110
+ output.each_line do |line|
111
+ if line.strip == "Slave Interface: #{interface_name}"
112
+ right_block = true
113
+ elsif line.include? 'Slave Interface'
114
+ right_block = false
115
+ end
116
+ return Regexp.last_match(1) if right_block && line =~ /Permanent HW addr: (\S*)/
117
+ end
118
+ end
119
+
120
+ def get_bond_master(interface_name)
121
+ content = Facter::Core::Execution.execute("ip link show #{interface_name}", logger: log)
122
+ master = content.match(/master (\S*) /)
123
+ return master[1] if master
124
+
125
+ nil
126
+ end
127
+
128
+ def add_binding(interfaces, name, ip, netmask, ip_v4_type)
129
+ binding = Facter::Util::Resolvers::Networking.build_binding(ip, netmask)
130
+ return if binding.nil?
131
+
132
+ log.debug("Adding to interface #{name}, binding:\n#{binding}")
133
+ binding_key = ip_v4_type == true ? :bindings : :bindings6
134
+ interfaces[name][binding_key] = [] if interfaces[name][binding_key].nil?
135
+ interfaces[name][binding_key] << binding
136
+ end
137
+
138
+ def add_info_from_routing_table
139
+ routes4, routes6 = read_routing_table
140
+ compare_ips(routes4, :bindings)
141
+ compare_ips(routes6, :bindings6)
142
+ end
143
+
144
+
145
+ def read_routing_table
146
+ ipv4_output = Facter::Core::Execution.execute('ip route show', logger: log)
147
+ ipv6_output = Facter::Core::Execution.execute('ip -6 route show', logger: log)
148
+ routes4 = parse_routes(ipv4_output, 'ipv4')
149
+ routes6 = parse_routes(ipv6_output, 'ipv6')
150
+ [routes4, routes6]
151
+ end
152
+
153
+ def parse_routes(output, family)
154
+ routes = []
155
+ output.each_line do |line|
156
+ parts = line.split(' ').compact
157
+ next if parts.include?('linkdown')
158
+
159
+ route_type = parts[0]
160
+ parts.delete_at(0) if ROUTE_TYPES.include?(route_type)
161
+ next if family == 'ipv6' && !parts[0].include?(':')
162
+
163
+ route = construct_route(parts)
164
+ routes << route unless route[:ip].nil?
165
+ end
166
+ routes.uniq
167
+ end
168
+
169
+ def construct_route(parts)
170
+ route = {}
171
+ dev_index = parts.find_index { |elem| elem == 'dev' }
172
+ src_index = parts.find_index { |elem| elem == 'src' }
173
+ route[:interface] = parts[dev_index + 1] if dev_index
174
+ route[:ip] = parts[src_index + 1] if src_index
175
+ route
176
+ end
177
+
178
+ def compare_ips(routes, binding_key)
179
+ routes.each do |route|
180
+ # TODO we should simplify this
181
+ if @fact_list[:interfaces].key?(route[:interface])
182
+ if @fact_list[:interfaces][route[:interface]][binding_key].nil?
183
+ @fact_list[:interfaces][route[:interface]][binding_key] = [{ address: route[:ip] }]
184
+ elsif @fact_list[:interfaces][route[:interface]][binding_key].none? { |binding| binding[:address] == route[:ip] }
185
+ @fact_list[:interfaces][route[:interface]][binding_key] << { address: route[:ip] }
186
+ end
187
+ end
188
+ end
189
+ end
59
190
 
60
- index = tokens[0].delete(':')
61
- file_content = Util::FileHelper.safe_read("/run/systemd/netif/leases/#{index}", nil)
62
- dhcp = file_content.match(/SERVER_ADDRESS=(.*)/) if file_content
63
- if dhcp
64
- network_info[interface_name][:dhcp] = dhcp[1]
65
- else
66
- alternate_dhcp = retrieve_from_other_directories(interface_name)
67
- network_info[interface_name][:dhcp] = alternate_dhcp if alternate_dhcp
191
+ def find_dhcp!(interface_name, interface_indexes, interfaces)
192
+ return if !interfaces[interface_name] || interfaces[interface_name][:dhcp]
193
+
194
+ log.debug("Get DHCP for interface #{interface_name}")
195
+ unless interface_indexes[interface_name].nil?
196
+ index = interface_indexes[interface_name][0]
197
+ file_content = Facter::Util::FileHelper.safe_read("/run/systemd/netif/leases/#{index}", nil)
198
+ dhcp = file_content.match(/SERVER_ADDRESS=(.*)/) if file_content
199
+ if dhcp
200
+ interfaces[interface_name][:dhcp] = dhcp[1]
201
+ else
202
+ alternate_dhcp = retrieve_from_other_directories(interface_name)
203
+ interfaces[interface_name][:dhcp] = alternate_dhcp if alternate_dhcp
204
+ end
68
205
  end
206
+ return unless interfaces[interface_name][:dhcp].nil?
207
+
208
+ output = Facter::Core::Execution.execute("dhcpcd -U #{interface_name}", logger: log)
209
+ result = output.match(/dhcp_server_identifier='(.*)'/)&.captures&.first
210
+ interfaces[interface_name][:dhcp] = result if result
69
211
  end
70
212
 
71
213
  def retrieve_from_other_directories(interface_name)
@@ -76,7 +218,7 @@ module Facter
76
218
  next if lease_files.empty?
77
219
 
78
220
  lease_files.select do |file|
79
- content = Util::FileHelper.safe_read("#{dir}#{file}", nil)
221
+ content = Facter::Util::FileHelper.safe_read("#{dir}#{file}", nil)
80
222
  next unless content =~ /interface.*#{interface_name}/
81
223
 
82
224
  dhcp = content.match(/dhcp-server-identifier ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/)
@@ -93,7 +235,7 @@ module Facter
93
235
  lease_file = files.find { |file| file =~ /internal.*#{interface_name}\.lease/ }
94
236
  return unless lease_file
95
237
 
96
- dhcp = Util::FileHelper.safe_read("/var/lib/NetworkManager/#{lease_file}", nil)
238
+ dhcp = Facter::Util::FileHelper.safe_read("/var/lib/NetworkManager/#{lease_file}", nil)
97
239
 
98
240
  return unless dhcp
99
241
 
@@ -101,59 +243,15 @@ module Facter
101
243
  dhcp[1] if dhcp
102
244
  end
103
245
 
104
- def fill_ip_v4_info!(ip_tokens, network_info)
105
- log.debug('fill_ip_v4_info!')
106
- return unless ip_tokens[2].casecmp('inet').zero?
107
-
108
- interface_name, ip4_address, ip4_mask_length = retrieve_name_and_ip_info(ip_tokens)
109
-
110
- log.debug("interface_name = #{interface_name}\n" \
111
- "ip4_address = #{ip4_address}\n" \
112
- "ip4_mask_length = #{ip4_mask_length}")
113
-
114
- binding = ::Resolvers::Utils::Networking.build_binding(ip4_address, ip4_mask_length)
115
- return unless binding
116
-
117
- build_network_info_structure!(network_info, interface_name, :bindings)
118
-
119
- network_info[interface_name][:bindings] << binding
120
- end
121
-
122
- def retrieve_name_and_ip_info(tokens)
123
- interface_name = tokens[1]
124
- ip_info = tokens[4] =~ /peer/ ? tokens[5].split('/') : tokens[3].split('/')
125
- ip_address = ip_info[0]
126
- ip_mask_length = ip_info[1]
127
-
128
- [interface_name, ip_address, ip_mask_length]
129
- end
130
-
131
- def fill_io_v6_info!(ip_tokens, network_info)
132
- return unless ip_tokens[2].casecmp('inet6').zero?
133
-
134
- interface_name, ip6_address, ip6_mask_length = retrieve_name_and_ip_info(ip_tokens)
135
-
136
- binding = ::Resolvers::Utils::Networking.build_binding(ip6_address, ip6_mask_length)
137
-
138
- build_network_info_structure!(network_info, interface_name, :bindings6)
139
-
140
- network_info[interface_name][:scope6] ||= ip_tokens[5]
141
- network_info[interface_name][:bindings6] << binding
142
- end
143
-
144
- def retrieve_default_interface
145
- output = Facter::Core::Execution.execute('ip route get 1', logger: log)
146
-
147
- ip_route_tokens = output.each_line.first.strip.split(' ')
148
- default_interface = ip_route_tokens[4]
246
+ def retrieve_primary_interface
247
+ primary_helper = Facter::Util::Resolvers::Networking::PrimaryInterface
248
+ primary_interface = primary_helper.read_from_proc_route
249
+ primary_interface ||= primary_helper.read_from_ip_route
250
+ primary_interface ||= primary_helper.find_in_interfaces(@fact_list[:interfaces])
149
251
 
150
- @fact_list[:primary_interface] = default_interface
252
+ @fact_list[:primary_interface] = primary_interface
151
253
  end
152
254
 
153
- def build_network_info_structure!(network_info, interface_name, binding)
154
- network_info[interface_name] = {} unless network_info.dig(interface_name)
155
- network_info[interface_name][binding] = [] unless network_info.dig(interface_name, binding)
156
- end
157
255
  end
158
256
  end
159
257
  end