facter 4.0.26 → 4.0.28

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 (206) hide show
  1. checksums.yaml +4 -4
  2. data/.github/actions/presuite.rb +1 -12
  3. data/.github/workflows/acceptance_tests.yml +4 -4
  4. data/.github/workflows/checks.yaml +9 -3
  5. data/.github/workflows/coverage.yaml +1 -1
  6. data/.github/workflows/unit_tests.yaml +2 -2
  7. data/.rubocop.yml +5 -0
  8. data/.rubocop_todo.yml +6 -4
  9. data/CHANGELOG.md +22 -0
  10. data/Rakefile +2 -1
  11. data/VERSION +1 -1
  12. data/acceptance/.beaker.yml +15 -0
  13. data/acceptance/.gitignore +12 -0
  14. data/acceptance/Gemfile +24 -0
  15. data/acceptance/Rakefile +2 -0
  16. data/acceptance/bin/ci-bootstrap-from-artifacts.sh +55 -0
  17. data/acceptance/config/aio/options.rb +6 -0
  18. data/acceptance/config/git/options.rb +3 -0
  19. data/acceptance/config/nodes/aix-53-power.yaml +7 -0
  20. data/acceptance/config/nodes/aix-61-power.yaml +7 -0
  21. data/acceptance/config/nodes/aix-71-power.yaml +7 -0
  22. data/acceptance/config/nodes/huaweios-6-powerpc.yaml +7 -0
  23. data/acceptance/config/nodes/solaris-10-sparc.yaml +9 -0
  24. data/acceptance/config/nodes/solaris-11-sparc.yaml +9 -0
  25. data/acceptance/lib/facter/acceptance/base_fact_utils.rb +565 -0
  26. data/acceptance/lib/facter/acceptance/user_fact_utils.rb +132 -0
  27. data/acceptance/lib/helper.rb +3 -0
  28. data/acceptance/lib/puppet/acceptance/common_utils.rb +10 -0
  29. data/acceptance/lib/puppet/acceptance/git_utils.rb +19 -0
  30. data/acceptance/lib/puppet/acceptance/install_utils.rb +58 -0
  31. data/acceptance/setup/aio/pre-suite/001_run_with_facter_ng.rb +75 -0
  32. data/acceptance/tests/custom_facts/cached_custom_fact.rb +82 -0
  33. data/acceptance/tests/custom_facts/conflicts_with_builtin_fact.rb +106 -0
  34. data/acceptance/tests/custom_facts/custom_fact_with_10001_weight_overrides_external_fact.rb +30 -0
  35. data/acceptance/tests/custom_facts/expand_command.rb +30 -0
  36. data/acceptance/tests/custom_facts/having_multiple_facts_in_one_file.rb +40 -0
  37. data/acceptance/tests/custom_facts/not_expand_command.rb +30 -0
  38. data/acceptance/tests/custom_facts/using_win32ole_should_not_hang.rb +33 -0
  39. data/acceptance/tests/custom_facts/weighted_cached_custom_facts.rb +94 -0
  40. data/acceptance/tests/custom_facts/windows_not_expand_command.rb +30 -0
  41. data/acceptance/tests/external_facts/env_var_overrides_external_fact.rb +46 -0
  42. data/acceptance/tests/external_facts/external_dir_overrides_default_external_fact.rb +34 -0
  43. data/acceptance/tests/external_facts/external_fact_overrides_custom_fact.rb +29 -0
  44. data/acceptance/tests/external_facts/external_fact_overrides_custom_fact_with_10000_weight_or_less.rb +30 -0
  45. data/acceptance/tests/external_facts/external_fact_overrides_custom_fact_with_confine.rb +35 -0
  46. data/acceptance/tests/external_facts/external_fact_stderr_messages_output_to_stderr.rb +49 -0
  47. data/acceptance/tests/external_facts/external_facts_only_run_once.rb +43 -0
  48. data/acceptance/tests/external_facts/fact_directory_precedence.rb +109 -0
  49. data/acceptance/tests/external_facts/handle_same_filename_in_different_dirs.rb +59 -0
  50. data/acceptance/tests/external_facts/non_root_users_default_external_fact_directory.rb +142 -0
  51. data/acceptance/tests/external_facts/root_uses_default_external_fact_dir.rb +34 -0
  52. data/acceptance/tests/external_facts/structured_executable_facts.rb +139 -0
  53. data/acceptance/tests/facter_returns_success_on_non_existent_fact.rb +9 -0
  54. data/acceptance/tests/facts/dmi.rb +51 -0
  55. data/acceptance/tests/facts/facterversion.rb +11 -0
  56. data/acceptance/tests/facts/identity.rb +52 -0
  57. data/acceptance/tests/facts/mountpoints_fact.rb +12 -0
  58. data/acceptance/tests/facts/networking_facts.rb +93 -0
  59. data/acceptance/tests/facts/nim_type.rb +12 -0
  60. data/acceptance/tests/facts/non_root_users_without_errors.rb +32 -0
  61. data/acceptance/tests/facts/operatingsystem_detection_after_clear_on_ubuntu.rb +26 -0
  62. data/acceptance/tests/facts/os_processors_and_kernel.rb +20 -0
  63. data/acceptance/tests/facts/osx_numeric_hostname.rb +23 -0
  64. data/acceptance/tests/facts/partitions.rb +37 -0
  65. data/acceptance/tests/facts/productname.rb +15 -0
  66. data/acceptance/tests/facts/ruby.rb +59 -0
  67. data/acceptance/tests/facts/ssh_key.rb +59 -0
  68. data/acceptance/tests/facts/validate_file_system_size_bytes.rb +37 -0
  69. data/acceptance/tests/facts/verify_tmpfs_file_system.rb +54 -0
  70. data/acceptance/tests/facts/windows_os.rb +64 -0
  71. data/acceptance/tests/load_libfacter.rb +66 -0
  72. data/acceptance/tests/no_errors_on_stderr.rb +10 -0
  73. data/acceptance/tests/options/color.rb +16 -0
  74. data/acceptance/tests/options/config.rb +27 -0
  75. data/acceptance/tests/options/config_file/blocklist.rb +35 -0
  76. data/acceptance/tests/options/config_file/blocklist_from_puppet_facts.rb +40 -0
  77. data/acceptance/tests/options/config_file/custom_dir_overridden_by_cli_custom_dir.rb +56 -0
  78. data/acceptance/tests/options/config_file/custom_facts.rb +42 -0
  79. data/acceptance/tests/options/config_file/custom_facts_list.rb +56 -0
  80. data/acceptance/tests/options/config_file/debug.rb +34 -0
  81. data/acceptance/tests/options/config_file/debug_override_config_file.rb +34 -0
  82. data/acceptance/tests/options/config_file/default_file_location.rb +37 -0
  83. data/acceptance/tests/options/config_file/external_dir_conflicts_with_cli_no_external_facts.rb +37 -0
  84. data/acceptance/tests/options/config_file/external_dir_overridden_by_cli_external_dir.rb +40 -0
  85. data/acceptance/tests/options/config_file/external_facts.rb +37 -0
  86. data/acceptance/tests/options/config_file/external_facts_list.rb +43 -0
  87. data/acceptance/tests/options/config_file/load_from_ruby.rb +73 -0
  88. data/acceptance/tests/options/config_file/log_level.rb +35 -0
  89. data/acceptance/tests/options/config_file/no_custom_facts_and_custom_dir.rb +43 -0
  90. data/acceptance/tests/options/config_file/no_custom_facts_and_facterlib.rb +43 -0
  91. data/acceptance/tests/options/config_file/no_custom_facts_and_load_path.rb +49 -0
  92. data/acceptance/tests/options/config_file/no_external_facts.rb +38 -0
  93. data/acceptance/tests/options/config_file/no_external_facts_and_external_dir.rb +34 -0
  94. data/acceptance/tests/options/config_file/no_ruby_disables_custom_facts.rb +52 -0
  95. data/acceptance/tests/options/config_file/no_ruby_disables_ruby_facts.rb +34 -0
  96. data/acceptance/tests/options/config_file/trace.rb +48 -0
  97. data/acceptance/tests/options/config_file/ttls_cached_external_execution_resolver_with_json_output.rb +92 -0
  98. data/acceptance/tests/options/config_file/ttls_cached_external_execution_resolver_with_text_output.rb +74 -0
  99. data/acceptance/tests/options/config_file/ttls_cached_external_execution_resolver_with_yaml_output.rb +88 -0
  100. data/acceptance/tests/options/config_file/ttls_cached_external_json_resolver.rb +79 -0
  101. data/acceptance/tests/options/config_file/ttls_cached_external_text_resolver.rb +78 -0
  102. data/acceptance/tests/options/config_file/ttls_cached_external_yaml_resolver.rb +78 -0
  103. data/acceptance/tests/options/config_file/ttls_cached_facts_clear_by_empty_ttls_cache_list.rb +71 -0
  104. data/acceptance/tests/options/config_file/ttls_cached_facts_creates_json_cache_file.rb +48 -0
  105. data/acceptance/tests/options/config_file/ttls_cached_facts_expire_facts_do_not_read_the_old_cached_value.rb +58 -0
  106. data/acceptance/tests/options/config_file/ttls_cached_facts_expire_facts_refresh_the_cached_value.rb +61 -0
  107. data/acceptance/tests/options/config_file/ttls_cached_facts_read_from_the_cached_value.rb +57 -0
  108. data/acceptance/tests/options/config_file/ttls_cached_facts_that_are_corrupt_are_refreshed.rb +53 -0
  109. data/acceptance/tests/options/config_file/ttls_cached_facts_that_are_empty_return_an_empty_value.rb +53 -0
  110. data/acceptance/tests/options/config_file/ttls_puppet_facts_creates_json_for_cached_facts.rb +45 -0
  111. data/acceptance/tests/options/config_file/ttls_puppet_facts_honors_cached_facts.rb +54 -0
  112. data/acceptance/tests/options/config_file/verbose.rb +34 -0
  113. data/acceptance/tests/options/custom_facts.rb +34 -0
  114. data/acceptance/tests/options/custom_facts_facterlib.rb +33 -0
  115. data/acceptance/tests/options/custom_facts_list.rb +48 -0
  116. data/acceptance/tests/options/custom_facts_load_path.rb +42 -0
  117. data/acceptance/tests/options/debug.rb +12 -0
  118. data/acceptance/tests/options/external_facts.rb +28 -0
  119. data/acceptance/tests/options/external_facts_list.rb +35 -0
  120. data/acceptance/tests/options/help.rb +13 -0
  121. data/acceptance/tests/options/json.rb +43 -0
  122. data/acceptance/tests/options/list_block_groups.rb +15 -0
  123. data/acceptance/tests/options/list_block_groups_facter_4.rb +15 -0
  124. data/acceptance/tests/options/list_cache_groups.rb +65 -0
  125. data/acceptance/tests/options/log_level.rb +13 -0
  126. data/acceptance/tests/options/no_block.rb +34 -0
  127. data/acceptance/tests/options/no_cache_should_not_cache_facts.rb +43 -0
  128. data/acceptance/tests/options/no_cache_should_not_load_cached_facts.rb +58 -0
  129. data/acceptance/tests/options/no_cache_should_not_refresh_cached_facts.rb +63 -0
  130. data/acceptance/tests/options/no_color.rb +16 -0
  131. data/acceptance/tests/options/no_custom_facts.rb +34 -0
  132. data/acceptance/tests/options/no_custom_facts_and_custom_dir.rb +19 -0
  133. data/acceptance/tests/options/no_custom_facts_and_facterlib.rb +34 -0
  134. data/acceptance/tests/options/no_custom_facts_and_load_path.rb +43 -0
  135. data/acceptance/tests/options/no_external_facts.rb +28 -0
  136. data/acceptance/tests/options/no_external_facts_and_external_dir.rb +19 -0
  137. data/acceptance/tests/options/no_ruby.rb +44 -0
  138. data/acceptance/tests/options/puppet_facts.rb +37 -0
  139. data/acceptance/tests/options/show_legacy.rb +18 -0
  140. data/acceptance/tests/options/strict.rb +11 -0
  141. data/acceptance/tests/options/trace.rb +36 -0
  142. data/acceptance/tests/options/verbose.rb +12 -0
  143. data/acceptance/tests/options/version.rb +12 -0
  144. data/acceptance/tests/options/yaml.rb +43 -0
  145. data/acceptance/tests/ticket_1123_facter_with_invalid_locale.rb +23 -0
  146. data/acceptance/tests/ticket_1238_hostname_fqdn.rb +57 -0
  147. data/lib/custom_facts/core/execution/base.rb +18 -18
  148. data/lib/custom_facts/util/collection.rb +2 -7
  149. data/lib/custom_facts/util/config.rb +1 -1
  150. data/lib/custom_facts/util/directory_loader.rb +51 -24
  151. data/lib/custom_facts/util/fact.rb +10 -1
  152. data/lib/custom_facts/util/resolution.rb +1 -1
  153. data/lib/facts/aix/aio_agent_version.rb +14 -0
  154. data/lib/facts/bsd/processors/count.rb +17 -0
  155. data/lib/facts/bsd/processors/models.rb +23 -0
  156. data/lib/facts/bsd/processors/speed.rb +17 -0
  157. data/lib/facts/freebsd/disks.rb +15 -0
  158. data/lib/facts/freebsd/partitions.rb +15 -0
  159. data/lib/facts/freebsd/processors/count.rb +17 -0
  160. data/lib/facts/freebsd/processors/models.rb +23 -0
  161. data/lib/facts/freebsd/processors/speed.rb +17 -0
  162. data/lib/facts/linux/aio_agent_version.rb +14 -0
  163. data/lib/facts/linux/ec2_metadata.rb +47 -0
  164. data/lib/facts/linux/ec2_userdata.rb +47 -0
  165. data/lib/facts/linux/is_virtual.rb +2 -5
  166. data/lib/facts/linux/virtual.rb +1 -5
  167. data/lib/facts/macosx/aio_agent_version.rb +14 -0
  168. data/lib/facts/macosx/interfaces.rb +2 -2
  169. data/lib/facts/macosx/networking/dhcp.rb +17 -0
  170. data/lib/facts/macosx/networking/interfaces.rb +21 -0
  171. data/lib/facts/macosx/networking/ip.rb +4 -1
  172. data/lib/facts/macosx/networking/ip6.rb +21 -0
  173. data/lib/facts/macosx/networking/mac.rb +4 -1
  174. data/lib/facts/macosx/networking/mtu.rb +20 -0
  175. data/lib/facts/macosx/networking/netmask.rb +21 -0
  176. data/lib/facts/macosx/networking/netmask6.rb +21 -0
  177. data/lib/facts/macosx/networking/network.rb +21 -0
  178. data/lib/facts/macosx/networking/network6.rb +21 -0
  179. data/lib/facts/macosx/networking/primary.rb +17 -0
  180. data/lib/facts/macosx/networking/scope6.rb +20 -0
  181. data/lib/facts/solaris/aio_agent_version.rb +14 -0
  182. data/lib/facts/windows/aio_agent_version.rb +14 -0
  183. data/lib/facts/windows/ec2_metadata.rb +23 -0
  184. data/lib/facts/windows/ec2_userdata.rb +23 -0
  185. data/lib/facts_utils/hypervisors.rb +10 -0
  186. data/lib/framework/core/cache_manager.rb +42 -18
  187. data/lib/framework/core/fact/external/external_fact_manager.rb +3 -2
  188. data/lib/framework/core/fact_loaders/external_fact_loader.rb +3 -2
  189. data/lib/framework/formatters/legacy_fact_formatter.rb +6 -5
  190. data/lib/framework/parsers/query_parser.rb +14 -2
  191. data/lib/models/loaded_fact.rb +3 -1
  192. data/lib/models/resolved_fact.rb +1 -1
  193. data/lib/models/searched_fact.rb +1 -0
  194. data/lib/resolvers/{agent_resolver.rb → aio_agent_version.rb} +4 -3
  195. data/lib/resolvers/bsd/ffi/ffi_helper.rb +31 -0
  196. data/lib/resolvers/bsd/processors.rb +47 -0
  197. data/lib/resolvers/ec2.rb +77 -0
  198. data/lib/resolvers/freebsd/ffi/ffi_helper.rb +42 -0
  199. data/lib/resolvers/freebsd/geom_resolver.rb +109 -0
  200. data/lib/resolvers/freebsd/processors.rb +44 -0
  201. data/lib/resolvers/macosx/networking.rb +110 -0
  202. data/lib/resolvers/networking_linux_resolver.rb +8 -30
  203. data/lib/resolvers/utils/networking.rb +70 -0
  204. data/lib/resolvers/windows/aio_agent_version.rb +56 -0
  205. metadata +175 -5
  206. data/lib/resolvers/macosx/ipaddress_resolver.rb +0 -52
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facter
4
+ module Resolvers
5
+ module Bsd
6
+ class Processors < BaseResolver
7
+ @log = Facter::Log.new(self)
8
+ @semaphore = Mutex.new
9
+ @fact_list ||= {}
10
+ class << self
11
+ private
12
+
13
+ def post_resolve(fact_name)
14
+ @fact_list.fetch(fact_name) { collect_processors_info(fact_name) }
15
+ end
16
+
17
+ def collect_processors_info(fact_name)
18
+ require "#{ROOT_DIR}/lib/resolvers/bsd/ffi/ffi_helper"
19
+
20
+ @fact_list[:logical_count] = logical_count
21
+ @fact_list[:models] = Array.new(logical_count, model) if logical_count && model
22
+ @fact_list[:speed] = speed * 1000 * 1000 if speed
23
+
24
+ @fact_list[fact_name]
25
+ end
26
+
27
+ CTL_HW = 6
28
+ HW_MODEL = 2
29
+ HW_NCPU = 3
30
+ HW_CPUSPEED = 12
31
+
32
+ def model
33
+ @model ||= Facter::Bsd::FfiHelper.sysctl(:string, [CTL_HW, HW_MODEL])
34
+ end
35
+
36
+ def logical_count
37
+ @logical_count ||= Facter::Bsd::FfiHelper.sysctl(:uint32_t, [CTL_HW, HW_NCPU])
38
+ end
39
+
40
+ def speed
41
+ @speed ||= Facter::Bsd::FfiHelper.sysctl(:uint32_t, [CTL_HW, HW_CPUSPEED])
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+
5
+ module Facter
6
+ module Resolvers
7
+ class Ec2 < BaseResolver
8
+ @semaphore = Mutex.new
9
+ @fact_list ||= {}
10
+ EC2_METADATA_ROOT_URL = 'http://169.254.169.254/latest/meta-data/'
11
+ EC2_USERDATA_ROOT_URL = 'http://169.254.169.254/latest/user-data/'
12
+ EC2_CONNECTION_TIMEOUT = 0.6
13
+ EC2_SESSION_TIMEOUT = 5
14
+
15
+ class << self
16
+ private
17
+
18
+ def post_resolve(fact_name)
19
+ @fact_list.fetch(fact_name) { read_facts(fact_name) }
20
+ end
21
+
22
+ def read_facts(fact_name)
23
+ @fact_list[:metadata] = {}
24
+ query_for_metadata(EC2_METADATA_ROOT_URL, @fact_list[:metadata])
25
+ @fact_list[:userdata] = get_data_from(EC2_USERDATA_ROOT_URL).strip
26
+ @fact_list[fact_name]
27
+ end
28
+
29
+ def query_for_metadata(url, container)
30
+ metadata = get_data_from(url)
31
+ metadata.each_line do |line|
32
+ next if line.empty?
33
+
34
+ http_path_component = build_path_compoent(line)
35
+ next if http_path_component == 'security-credentials/'
36
+
37
+ if http_path_component.end_with?('/')
38
+ child = {}
39
+ child[http_path_component] = query_for_metadata("#{url}#{http_path_component}", child)
40
+ child.reject! { |key, _info| key == http_path_component }
41
+ name = http_path_component.chomp('/')
42
+ container[name] = child
43
+ else
44
+ container[http_path_component] = get_data_from("#{url}#{http_path_component}").strip
45
+ end
46
+ end
47
+ end
48
+
49
+ def build_path_compoent(line)
50
+ array_match = /^(\d+)=.*$/.match(line)
51
+ array_match ? "#{array_match[1]}/" : line.strip
52
+ end
53
+
54
+ def get_data_from(url)
55
+ parsed_url = URI.parse(url)
56
+ http = Net::HTTP.new(parsed_url.host)
57
+ http.read_timeout = determine_session_timeout
58
+ http.open_timeout = EC2_CONNECTION_TIMEOUT
59
+ resp = http.get(parsed_url.path)
60
+ response_code_valid?(resp.code) ? resp.body : ''
61
+ rescue StandardError => e
62
+ log.debug("Trying to connect to #{url} but got: #{e.message}")
63
+ ''
64
+ end
65
+
66
+ def response_code_valid?(http_code)
67
+ http_code.to_i.equal?(200)
68
+ end
69
+
70
+ def determine_session_timeout
71
+ session_env = ENV['EC2_SESSION_TIMEOUT']
72
+ session_env ? session_env.to_i : EC2_SESSION_TIMEOUT
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+
5
+ module Facter
6
+ module Freebsd
7
+ module FfiHelper
8
+ module Libc
9
+ extend FFI::Library
10
+
11
+ ffi_lib 'c'
12
+ attach_function :sysctlbyname, %i[string pointer pointer pointer size_t], :int
13
+ end
14
+
15
+ def self.sysctl_by_name(type, name)
16
+ oldp = FFI::Pointer::NULL
17
+ oldlenp = FFI::MemoryPointer.new(:size_t)
18
+
19
+ newp = FFI::Pointer::NULL
20
+ newlenp = 0
21
+
22
+ if type == :string
23
+ res = Libc.sysctlbyname(name, oldp, oldlenp, newp, newlenp)
24
+ return nil if res.negative?
25
+ else
26
+ oldlenp.write(:size_t, FFI.type_size(type))
27
+ end
28
+
29
+ oldp = FFI::MemoryPointer.new(:uint8_t, oldlenp.read(:size_t))
30
+ res = Libc.sysctlbyname(name, oldp, oldlenp, newp, newlenp)
31
+ return nil if res.negative?
32
+
33
+ case type
34
+ when :string
35
+ oldp.read_string
36
+ else
37
+ oldp.read(type)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facter
4
+ module Resolvers
5
+ module Freebsd
6
+ class Geom < BaseResolver
7
+ @semaphore = Mutex.new
8
+ @fact_list ||= {}
9
+
10
+ class << self
11
+ private
12
+
13
+ def post_resolve(fact_name)
14
+ @fact_list.fetch(fact_name) { read_facts(fact_name) }
15
+ end
16
+
17
+ def read_facts(fact_name)
18
+ require_relative 'ffi/ffi_helper'
19
+ require 'rexml/document'
20
+
21
+ read_disks
22
+ read_partitions
23
+
24
+ @fact_list[fact_name]
25
+ end
26
+
27
+ def read_disks
28
+ @fact_list[:disks] = {}
29
+
30
+ each_geom_class_provider('DISK') do |provider|
31
+ name = provider.get_text('./name').value
32
+
33
+ @fact_list[:disks][name] = %i[read_model read_serial_number read_size].map do |x|
34
+ send(x, provider)
35
+ end.inject(:merge)
36
+ end
37
+ end
38
+
39
+ def read_partitions
40
+ @fact_list[:partitions] = {}
41
+
42
+ each_geom_class_provider('PART') do |provider|
43
+ name = provider.get_text('./name').value
44
+
45
+ @fact_list[:partitions][name] = %i[read_partlabel read_partuuid read_size].map do |x|
46
+ send(x, provider)
47
+ end.inject(:merge)
48
+ end
49
+ end
50
+
51
+ def each_geom_class_provider(geom_class_name, &block)
52
+ REXML::XPath.each(geom_topology, "/mesh/class[name/text() = '#{geom_class_name}']/geom/provider", &block)
53
+ end
54
+
55
+ def read_size(provider)
56
+ res = {}
57
+ return res unless (mediasize = provider.get_text('mediasize'))
58
+
59
+ mediasize = Integer(mediasize.value)
60
+
61
+ res[:size_bytes] = mediasize
62
+ res[:size] = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(mediasize)
63
+ res
64
+ end
65
+
66
+ def read_model(provider)
67
+ res = {}
68
+ return res unless (model = provider.get_text('./config/descr'))
69
+
70
+ res[:model] = model.value
71
+ res
72
+ end
73
+
74
+ def read_partlabel(provider)
75
+ res = {}
76
+ return res unless (rawuuid = provider.get_text('./config/label'))
77
+
78
+ res[:partlabel] = rawuuid.value
79
+ res
80
+ end
81
+
82
+ def read_partuuid(provider)
83
+ res = {}
84
+ return res unless (rawuuid = provider.get_text('./config/rawuuid'))
85
+
86
+ res[:partuuid] = rawuuid.value
87
+ res
88
+ end
89
+
90
+ def read_serial_number(provider)
91
+ res = {}
92
+ return res unless (serial_number = provider.get_text('./config/ident'))
93
+
94
+ res[:serial_number] = serial_number.value
95
+ res
96
+ end
97
+
98
+ def geom_topology
99
+ @geom_topology ||= REXML::Document.new(geom_confxml)
100
+ end
101
+
102
+ def geom_confxml
103
+ Facter::Freebsd::FfiHelper.sysctl_by_name(:string, 'kern.geom.confxml')
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'resolvers/bsd/processors'
4
+
5
+ module Facter
6
+ module Resolvers
7
+ module Freebsd
8
+ class Processors < BaseResolver
9
+ @log = Facter::Log.new(self)
10
+ @semaphore = Mutex.new
11
+ @fact_list ||= {}
12
+ class << self
13
+ private
14
+
15
+ def post_resolve(fact_name)
16
+ @fact_list.fetch(fact_name) { collect_processors_info(fact_name) }
17
+ end
18
+
19
+ def collect_processors_info(fact_name)
20
+ require "#{ROOT_DIR}/lib/resolvers/freebsd/ffi/ffi_helper"
21
+
22
+ @fact_list[:logical_count] = logical_count
23
+ @fact_list[:models] = Array.new(logical_count, model) if logical_count && model
24
+ @fact_list[:speed] = speed * 1000 * 1000 if speed
25
+
26
+ @fact_list[fact_name]
27
+ end
28
+
29
+ def model
30
+ @model ||= Facter::Freebsd::FfiHelper.sysctl_by_name(:string, 'hw.model')
31
+ end
32
+
33
+ def logical_count
34
+ @logical_count ||= Facter::Freebsd::FfiHelper.sysctl_by_name(:uint32_t, 'hw.ncpu')
35
+ end
36
+
37
+ def speed
38
+ @speed ||= Facter::Freebsd::FfiHelper.sysctl_by_name(:uint32_t, 'hw.clockrate')
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facter
4
+ module Resolvers
5
+ module Macosx
6
+ class Networking < BaseResolver
7
+ @semaphore = Mutex.new
8
+ @fact_list ||= {}
9
+
10
+ class << self
11
+ private
12
+
13
+ def post_resolve(fact_name)
14
+ @fact_list.fetch(fact_name) { read_facts(fact_name) }
15
+ end
16
+
17
+ def read_facts(fact_name)
18
+ primary_interface
19
+ dhcp
20
+ interfaces_data
21
+ unless @fact_list[:interfaces].nil?
22
+ ::Resolvers::Utils::Networking.expand_main_bindings(@fact_list[:interfaces])
23
+ end
24
+ @fact_list[fact_name]
25
+ end
26
+
27
+ def primary_interface
28
+ result = Facter::Core::Execution.execute('route -n get default', logger: log)
29
+
30
+ @fact_list[:primary_interface] = result.match(/interface: (.+)/)&.captures&.first
31
+ end
32
+
33
+ def dhcp
34
+ return if @fact_list[:primary_interface].nil?
35
+
36
+ result = Facter::Core::Execution.execute("ipconfig getoption #{@fact_list[:primary_interface]} " \
37
+ 'server_identifier', logger: log)
38
+
39
+ @fact_list[:dhcp] = result.match(/^[\d.a-f:\s]+$/)&.to_s&.strip
40
+ end
41
+
42
+ def interfaces_data
43
+ command_response = Facter::Core::Execution.execute('ifconfig -a', logger: log)
44
+
45
+ clean_up_interfaces_response(command_response)
46
+ parse_interfaces_response(command_response)
47
+ end
48
+
49
+ def clean_up_interfaces_response(response)
50
+ # convert ip ranges into single ip. eg. 10.16.132.213 --> 10.16.132.213 is converted to 10.16.132.213
51
+ response.gsub!(/(\d+(\.\d+)*)\s+-->\s+\d+(\.\d+)*/, '\\1')
52
+ end
53
+
54
+ def parse_interfaces_response(response)
55
+ parsed_interfaces_data = {}
56
+ interfaces_data = Hash[*response.split(/^([A-Za-z0-9_]+): /)[1..-1]]
57
+
58
+ interfaces_data.each do |interface, properties|
59
+ values = {}
60
+
61
+ extract_mtu(properties, values)
62
+ extract_mac(properties, values)
63
+ extract_ip_data(properties, values)
64
+
65
+ parsed_interfaces_data[interface] = values
66
+ end
67
+ @fact_list[:interfaces] = parsed_interfaces_data unless parsed_interfaces_data.empty?
68
+ end
69
+
70
+ def extract_mtu(properties, values)
71
+ mtu = properties.match(/mtu\s+(\d+)/)&.captures&.first&.to_i
72
+ values[:mtu] = mtu unless mtu.nil?
73
+ end
74
+
75
+ def extract_mac(properties, values)
76
+ mac = properties.match(/(?:ether|lladdr)\s+(\w?\w:\w?\w:\w?\w:\w?\w:\w?\w:\w?\w)/)&.captures&.first
77
+ values[:mac] = mac unless mac.nil?
78
+ end
79
+
80
+ def extract_ip_data(properties, values)
81
+ ip = extract_values(properties, /inet (\S+)/)
82
+ mask = extract_values(properties, /netmask (\S+)/).map { |val| val.hex.to_s(2).count('1') }
83
+
84
+ ip6 = extract_values(properties, /inet6 (\S+)/).map { |val| val.gsub(/%.+/, '') }
85
+ mask6 = extract_values(properties, /prefixlen (\S+)/)
86
+
87
+ values[:bindings] = create_bindings(ip, mask) unless ip.empty?
88
+ values[:bindings6] = create_bindings(ip6, mask6) unless ip6.empty?
89
+ end
90
+
91
+ def extract_values(data, regex)
92
+ results = []
93
+ data.scan(regex).flatten.each do |val|
94
+ results << val
95
+ end
96
+ results
97
+ end
98
+
99
+ def create_bindings(ips, masks)
100
+ bindings = []
101
+ ips.zip(masks).each do |ip, mask|
102
+ bindings << ::Resolvers::Utils::Networking.build_binding(ip, mask)
103
+ end
104
+ bindings
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -46,6 +46,8 @@ module Facter
46
46
  find_dhcp!(ip_tokens, interfaces)
47
47
  end
48
48
 
49
+ ::Resolvers::Utils::Networking.expand_main_bindings(interfaces)
50
+
49
51
  @fact_list[:interfaces] = interfaces
50
52
  end
51
53
 
@@ -92,17 +94,10 @@ module Facter
92
94
 
93
95
  interface_name, ip4_address, ip4_mask_length = retrieve_name_and_ip_info(ip_tokens)
94
96
 
95
- binding = build_binding(ip4_address, ip4_mask_length)
96
- build_network_info_structure!(network_info, interface_name, 'bindings')
97
-
98
- populate_other_ipv4_facts(network_info, interface_name, binding)
99
- end
97
+ binding = ::Resolvers::Utils::Networking.build_binding(ip4_address, ip4_mask_length)
98
+ build_network_info_structure!(network_info, interface_name, :bindings)
100
99
 
101
- def populate_other_ipv4_facts(network_info, interface_name, binding)
102
- network_info[interface_name]['bindings'] << binding
103
- network_info[interface_name][:ip] ||= binding[:address]
104
- network_info[interface_name][:network] ||= binding[:network]
105
- network_info[interface_name][:netmask] ||= binding[:netmask]
100
+ network_info[interface_name][:bindings] << binding
106
101
  end
107
102
 
108
103
  def retrieve_name_and_ip_info(tokens)
@@ -119,19 +114,12 @@ module Facter
119
114
 
120
115
  interface_name, ip6_address, ip6_mask_length = retrieve_name_and_ip_info(ip_tokens)
121
116
 
122
- binding = build_binding(ip6_address, ip6_mask_length)
117
+ binding = ::Resolvers::Utils::Networking.build_binding(ip6_address, ip6_mask_length)
123
118
 
124
- build_network_info_structure!(network_info, interface_name, 'bindings6')
119
+ build_network_info_structure!(network_info, interface_name, :bindings6)
125
120
 
126
121
  network_info[interface_name][:scope6] ||= ip_tokens[5]
127
- populate_other_ipv6_facts(network_info, interface_name, binding)
128
- end
129
-
130
- def populate_other_ipv6_facts(network_info, interface_name, binding)
131
- network_info[interface_name]['bindings6'] << binding
132
- network_info[interface_name][:ip6] ||= binding[:address]
133
- network_info[interface_name][:network6] ||= binding[:network]
134
- network_info[interface_name][:netmask6] ||= binding[:netmask]
122
+ network_info[interface_name][:bindings6] << binding
135
123
  end
136
124
 
137
125
  def retrieve_default_interface
@@ -143,16 +131,6 @@ module Facter
143
131
  @fact_list[:primary_interface] = default_interface
144
132
  end
145
133
 
146
- def build_binding(addr, mask_length)
147
- require 'ipaddr'
148
-
149
- ip = IPAddr.new(addr)
150
- mask_helper = ip.ipv6? ? 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' : '255.255.255.255'
151
- mask = IPAddr.new(mask_helper).mask(mask_length)
152
-
153
- { address: addr, netmask: mask.to_s, network: ip.mask(mask_length).to_s }
154
- end
155
-
156
134
  def build_network_info_structure!(network_info, interface_name, binding)
157
135
  network_info[interface_name] = {} unless network_info.dig(interface_name)
158
136
  network_info[interface_name][binding] = [] unless network_info.dig(interface_name, binding)