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,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facts
4
+ module Macosx
5
+ module Networking
6
+ class Network
7
+ FACT_NAME = 'networking.network'
8
+ ALIASES = 'network'
9
+
10
+ def call_the_resolver
11
+ interfaces = Facter::Resolvers::Macosx::Networking.resolve(:interfaces)
12
+ primary = Facter::Resolvers::Macosx::Networking.resolve(:primary_interface)
13
+
14
+ fact_value = interfaces.dig(primary, :network) unless interfaces.nil?
15
+
16
+ [Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facts
4
+ module Macosx
5
+ module Networking
6
+ class Network6
7
+ FACT_NAME = 'networking.network6'
8
+ ALIASES = 'network6'
9
+
10
+ def call_the_resolver
11
+ interfaces = Facter::Resolvers::Macosx::Networking.resolve(:interfaces)
12
+ primary = Facter::Resolvers::Macosx::Networking.resolve(:primary_interface)
13
+
14
+ fact_value = interfaces.dig(primary, :network6) unless interfaces.nil?
15
+
16
+ [Facter::ResolvedFact.new(FACT_NAME, fact_value), Facter::ResolvedFact.new(ALIASES, fact_value, :legacy)]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facts
4
+ module Macosx
5
+ module Networking
6
+ class Primary
7
+ FACT_NAME = 'networking.primary'
8
+
9
+ def call_the_resolver
10
+ fact_value = Facter::Resolvers::Macosx::Networking.resolve(:primary_interface)
11
+
12
+ Facter::ResolvedFact.new(FACT_NAME, fact_value)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facts
4
+ module Macosx
5
+ module Networking
6
+ class Scope6
7
+ FACT_NAME = 'networking.scope6'
8
+
9
+ def call_the_resolver
10
+ interfaces = Facter::Resolvers::Macosx::Networking.resolve(:interfaces)
11
+ primary = Facter::Resolvers::Macosx::Networking.resolve(:primary_interface)
12
+
13
+ fact_value = interfaces.dig(primary, :scope6) unless interfaces.nil?
14
+
15
+ Facter::ResolvedFact.new(FACT_NAME, fact_value)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facts
4
+ module Solaris
5
+ class AioAgentVersion
6
+ FACT_NAME = 'aio_agent_version'
7
+
8
+ def call_the_resolver
9
+ fact_value = Facter::Resolvers::AioAgentVersion.resolve(:aio_agent_version)
10
+ Facter::ResolvedFact.new(FACT_NAME, fact_value)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facts
4
+ module Windows
5
+ class AioAgentVersion
6
+ FACT_NAME = 'aio_agent_version'
7
+
8
+ def call_the_resolver
9
+ fact_value = Facter::Resolvers::Windows::AioAgentVersion.resolve(:aio_agent_version)
10
+ Facter::ResolvedFact.new(FACT_NAME, fact_value)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facts
4
+ module Windows
5
+ class Ec2Metadata
6
+ FACT_NAME = 'ec2_metadata'
7
+
8
+ def call_the_resolver
9
+ return Facter::ResolvedFact.new(FACT_NAME, nil) unless aws?
10
+
11
+ fact_value = Facter::Resolvers::Ec2.resolve(:metadata)
12
+
13
+ Facter::ResolvedFact.new(FACT_NAME, fact_value.empty? ? nil : fact_value)
14
+ end
15
+
16
+ def aws?
17
+ virtual = Facter::Resolvers::Virtualization.resolve(:virtual)
18
+
19
+ virtual == 'kvm' || virtual =~ /xen/
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facts
4
+ module Windows
5
+ class Ec2Userdata
6
+ FACT_NAME = 'ec2_userdata'
7
+
8
+ def call_the_resolver
9
+ return Facter::ResolvedFact.new(FACT_NAME, nil) unless aws?
10
+
11
+ fact_value = Facter::Resolvers::Ec2.resolve(:userdata)
12
+
13
+ Facter::ResolvedFact.new(FACT_NAME, fact_value.empty? ? nil : fact_value)
14
+ end
15
+
16
+ def aws?
17
+ virtual = Facter::Resolvers::Virtualization.resolve(:virtual)
18
+
19
+ virtual == 'kvm' || virtual =~ /xen/
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facter
4
+ module FactsUtils
5
+ HYPERVISORS_HASH = { 'VMware' => 'vmware', 'VirtualBox' => 'virtualbox', 'Parallels' => 'parallels',
6
+ 'KVM' => 'kvm', 'Virtual Machine' => 'hyperv', 'RHEV Hypervisor' => 'rhev',
7
+ 'oVirt Node' => 'ovirt', 'HVM domU' => 'xenhvm', 'Bochs' => 'bochs', 'OpenBSD' => 'vmm',
8
+ 'BHYVE' => 'bhyve' }.freeze
9
+ end
10
+ end
@@ -13,14 +13,17 @@ module Facter
13
13
  return searched_facts, [] if !File.directory?(@cache_dir) || !Options[:cache]
14
14
 
15
15
  facts = []
16
- searched_facts.each do |fact|
16
+ searched_facts.delete_if do |fact|
17
17
  res = resolve_fact(fact)
18
- facts << res if res
18
+ if res
19
+ facts << res
20
+ true
21
+ else
22
+ false
23
+ end
19
24
  end
20
- facts.each do |fact|
21
- searched_facts.delete_if { |f| f.name == fact.name }
22
- end
23
- [searched_facts, facts]
25
+
26
+ [searched_facts, facts.flatten]
24
27
  end
25
28
 
26
29
  def cache_facts(resolved_facts)
@@ -37,10 +40,21 @@ module Facter
37
40
  end
38
41
  end
39
42
 
43
+ def group_cached?(group_name)
44
+ cached = @fact_groups.get_group_ttls(group_name) ? true : false
45
+ delete_cache(group_name) unless cached
46
+ cached
47
+ end
48
+
40
49
  private
41
50
 
42
51
  def resolve_fact(searched_fact)
43
- group_name = @fact_groups.get_fact_group(searched_fact.name)
52
+ group_name = if searched_fact.file
53
+ searched_fact.name
54
+ else
55
+ @fact_groups.get_fact_group(searched_fact.name)
56
+ end
57
+
44
58
  return unless group_name
45
59
 
46
60
  return unless group_cached?(group_name)
@@ -51,16 +65,32 @@ module Facter
51
65
  return unless data
52
66
 
53
67
  @log.debug("loading cached values for #{group_name} facts")
54
- create_fact(searched_fact, data[searched_fact.name])
68
+
69
+ create_facts(searched_fact, data)
55
70
  end
56
71
 
57
- def create_fact(searched_fact, value)
58
- Facter::ResolvedFact.new(searched_fact.name, value, searched_fact.type,
59
- searched_fact.user_query, searched_fact.filter_tokens)
72
+ def create_facts(searched_fact, data)
73
+ if searched_fact.type == :file
74
+ facts = []
75
+ data.each do |fact_name, fact_value|
76
+ fact = Facter::ResolvedFact.new(fact_name, fact_value, searched_fact.type,
77
+ searched_fact.user_query, searched_fact.filter_tokens)
78
+ fact.file = searched_fact.file
79
+ facts << fact
80
+ end
81
+ facts
82
+ else
83
+ [Facter::ResolvedFact.new(searched_fact.name, data[searched_fact.name], searched_fact.type,
84
+ searched_fact.user_query, searched_fact.filter_tokens)]
85
+ end
60
86
  end
61
87
 
62
88
  def cache_fact(fact)
63
- group_name = @fact_groups.get_fact_group(fact.name)
89
+ group_name = if fact.file
90
+ File.basename(fact.file)
91
+ else
92
+ @fact_groups.get_fact_group(fact.name)
93
+ end
64
94
  return if !group_name || fact.value.nil?
65
95
 
66
96
  return unless group_cached?(group_name)
@@ -98,12 +128,6 @@ module Facter
98
128
  @groups[group_name] = data
99
129
  end
100
130
 
101
- def group_cached?(group_name)
102
- cached = @fact_groups.get_group_ttls(group_name) ? true : false
103
- delete_cache(group_name) unless cached
104
- cached
105
- end
106
-
107
131
  def check_ttls?(group_name)
108
132
  ttls = @fact_groups.get_group_ttls(group_name)
109
133
  return false unless ttls
@@ -17,10 +17,11 @@ module Facter
17
17
  resolved_custom_facts = []
18
18
 
19
19
  custom_facts.each do |custom_fact|
20
- fact_value = LegacyFacter.value(custom_fact.name)
21
- resolved_fact = ResolvedFact.new(custom_fact.name, fact_value, :custom)
20
+ fact = LegacyFacter[custom_fact.name]
21
+ resolved_fact = ResolvedFact.new(custom_fact.name, fact.value, :custom)
22
22
  resolved_fact.filter_tokens = []
23
23
  resolved_fact.user_query = custom_fact.user_query
24
+ resolved_fact.file = fact.options[:file]
24
25
 
25
26
  resolved_custom_facts << resolved_fact
26
27
  end
@@ -34,8 +34,9 @@ module Facter
34
34
 
35
35
  external_facts_to_load = LegacyFacter.collection.external_facts
36
36
 
37
- external_facts_to_load&.each do |external_fact_name|
38
- loaded_fact = LoadedFact.new(external_fact_name.to_s, nil, :external)
37
+ external_facts_to_load&.each do |k, v|
38
+ loaded_fact = LoadedFact.new(k.to_s, nil, :external)
39
+ loaded_fact.file = v.options[:file]
39
40
  external_facts << loaded_fact
40
41
  end
41
42
 
@@ -14,7 +14,8 @@ module Facter
14
14
 
15
15
  user_query = user_queries.first
16
16
  return format_for_no_query(resolved_facts) if user_query.empty?
17
- return format_for_single_user_query(user_queries.first, resolved_facts) unless user_query.empty?
17
+
18
+ format_for_single_user_query(user_queries.first, resolved_facts)
18
19
  end
19
20
 
20
21
  private
@@ -25,7 +26,7 @@ module Facter
25
26
  pretty_json = hash_to_facter_format(fact_collection)
26
27
 
27
28
  pretty_json = remove_enclosing_accolades(pretty_json)
28
- remove_comma_and_quation(pretty_json)
29
+ remove_comma_and_quotation(pretty_json)
29
30
  end
30
31
 
31
32
  def format_for_multiple_user_queries(user_queries, resolved_facts)
@@ -36,7 +37,7 @@ module Facter
36
37
  facts_to_display.each { |k, v| facts_to_display[k] = v.nil? ? '' : v }
37
38
  pretty_json = hash_to_facter_format(facts_to_display)
38
39
  pretty_json = remove_enclosing_accolades(pretty_json)
39
- pretty_json = remove_comma_and_quation(pretty_json)
40
+ pretty_json = remove_comma_and_quotation(pretty_json)
40
41
 
41
42
  @log.debug('Remove quotes from value if value is a string')
42
43
  pretty_json.gsub(/^(\S*) => \"(.*)\"/, '\1 => \2')
@@ -60,7 +61,7 @@ module Facter
60
61
  pretty_json = JSON.pretty_generate(facts_hash)
61
62
 
62
63
  @log.debug('Change key value delimiter from : to =>')
63
- pretty_json.gsub!(/":/, '" =>')
64
+ pretty_json.gsub!(/":\s/, '" => ')
64
65
 
65
66
  @log.debug('Remove quotes from parent nodes')
66
67
  pretty_json.gsub!(/\"(.*)\"\ =>/, '\1 =>')
@@ -83,7 +84,7 @@ module Facter
83
84
  pretty_fact_json.gsub(/^},/, '}')
84
85
  end
85
86
 
86
- def remove_comma_and_quation(output)
87
+ def remove_comma_and_quotation(output)
87
88
  # quotation marks that come after \ are not removed
88
89
  @log.debug('Remove unnecessary comma and quotation marks on root facts')
89
90
  output.split("\n")
@@ -26,7 +26,8 @@ module Facter
26
26
  matched_facts = []
27
27
  @log.debug "User query is: #{query_list}"
28
28
  @query_list = query_list
29
- query_list = loaded_fact.map(&:name) unless query_list.any?
29
+
30
+ return no_user_query(loaded_fact) unless query_list.any?
30
31
 
31
32
  query_list.each do |query|
32
33
  @log.debug "Query is #{query}"
@@ -37,6 +38,14 @@ module Facter
37
38
  matched_facts.flatten(1)
38
39
  end
39
40
 
41
+ def no_user_query(loaded_facts)
42
+ searched_facts = []
43
+ loaded_facts.each do |loaded_fact|
44
+ searched_facts << SearchedFact.new(loaded_fact.name, loaded_fact.klass, [], '', loaded_fact.type)
45
+ end
46
+ searched_facts
47
+ end
48
+
40
49
  def search_for_facts(query, loaded_fact_hash)
41
50
  resolvable_fact_list = []
42
51
  query = query.to_s
@@ -90,7 +99,10 @@ module Facter
90
99
  fact_name = loaded_fact.name.to_s
91
100
  klass_name = loaded_fact.klass
92
101
  type = loaded_fact.type
93
- SearchedFact.new(fact_name, klass_name, filter_tokens, user_query, type)
102
+ sf = SearchedFact.new(fact_name, klass_name, filter_tokens, user_query, type)
103
+ sf.file = loaded_fact.file
104
+
105
+ sf
94
106
  end
95
107
 
96
108
  def construct_filter_tokens(query_tokens, query_token_range)
@@ -3,11 +3,13 @@
3
3
  module Facter
4
4
  class LoadedFact
5
5
  attr_reader :name, :klass, :type
6
+ attr_accessor :file
6
7
 
7
- def initialize(name, klass, type = nil)
8
+ def initialize(name, klass, type = nil, file = nil)
8
9
  @name = name
9
10
  @klass = klass
10
11
  @type = type.nil? ? :core : type
12
+ @file = file
11
13
  end
12
14
  end
13
15
  end
@@ -3,7 +3,7 @@
3
3
  module Facter
4
4
  class ResolvedFact
5
5
  attr_reader :name, :type
6
- attr_accessor :user_query, :filter_tokens, :value
6
+ attr_accessor :user_query, :filter_tokens, :value, :file
7
7
 
8
8
  def initialize(name, value = '', type = :core, user_query = nil, filter_tokens = [])
9
9
  @name = name
@@ -3,6 +3,7 @@
3
3
  module Facter
4
4
  class SearchedFact
5
5
  attr_reader :name, :fact_class, :filter_tokens, :user_query, :type
6
+ attr_accessor :file
6
7
 
7
8
  def initialize(fact_name, fact_class, filter_tokens, user_query, type)
8
9
  @name = fact_name
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Facter
4
4
  module Resolvers
5
- class Agent < BaseResolver
5
+ class AioAgentVersion < BaseResolver
6
6
  @semaphore = Mutex.new
7
7
  @fact_list ||= {}
8
8
 
@@ -14,8 +14,9 @@ module Facter
14
14
  end
15
15
 
16
16
  def read_agent_version
17
- version_file = ::File.join(ROOT_DIR, 'lib/puppet/VERSION')
18
- @fact_list[:aio_agent_version] = ::File.read(version_file)
17
+ aio_agent_version = Util::FileHelper.safe_read('/opt/puppetlabs/puppet/VERSION', nil)&.chomp
18
+ aio_agent_version = aio_agent_version&.match(/^\d+\.\d+\.\d+(\.\d+){0,2}/)&.to_s
19
+ @fact_list[:aio_agent_version] = aio_agent_version
19
20
  end
20
21
  end
21
22
  end
@@ -10,6 +10,7 @@ module Facter
10
10
 
11
11
  ffi_lib 'c'
12
12
  attach_function :getloadavg, %i[pointer int], :int
13
+ attach_function :sysctl, %i[pointer uint pointer pointer pointer size_t], :int
13
14
  end
14
15
 
15
16
  def self.read_load_averages
@@ -20,6 +21,36 @@ module Facter
20
21
 
21
22
  raw_loadavg.read_array_of_double(res)
22
23
  end
24
+
25
+ def self.sysctl(type, oids)
26
+ name = FFI::MemoryPointer.new(:uint, oids.size)
27
+ name.write_array_of_uint(oids)
28
+ namelen = oids.size
29
+
30
+ oldp = FFI::Pointer::NULL
31
+ oldlenp = FFI::MemoryPointer.new(:size_t)
32
+
33
+ newp = FFI::Pointer::NULL
34
+ newlen = 0
35
+
36
+ if type == :string
37
+ res = Libc.sysctl(name, namelen, oldp, oldlenp, newp, newlen)
38
+ return nil if res.negative?
39
+ else
40
+ oldlenp.write(:size_t, FFI.type_size(type))
41
+ end
42
+
43
+ oldp = FFI::MemoryPointer.new(:uint8_t, oldlenp.read(:size_t))
44
+ res = Libc.sysctl(name, namelen, oldp, oldlenp, newp, newlen)
45
+ return nil if res.negative?
46
+
47
+ case type
48
+ when :string
49
+ oldp.read_string
50
+ else
51
+ oldp.read(type)
52
+ end
53
+ end
23
54
  end
24
55
  end
25
56
  end