facter 4.0.50 → 4.2.0

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 (164) hide show
  1. checksums.yaml +4 -4
  2. data/lib/docs/generate_cli.rb +7 -0
  3. data/lib/facter.rb +90 -56
  4. data/lib/facter/config.rb +2 -0
  5. data/lib/facter/custom_facts/core/aggregate.rb +9 -0
  6. data/lib/facter/custom_facts/core/execution/base.rb +7 -3
  7. data/lib/facter/custom_facts/core/execution/popen3.rb +13 -1
  8. data/lib/facter/custom_facts/core/execution/posix.rb +2 -2
  9. data/lib/facter/custom_facts/core/execution/windows.rb +1 -1
  10. data/lib/facter/custom_facts/core/resolvable.rb +11 -0
  11. data/lib/facter/custom_facts/util/collection.rb +5 -0
  12. data/lib/facter/custom_facts/util/directory_loader.rb +1 -1
  13. data/lib/facter/custom_facts/util/normalization.rb +7 -2
  14. data/lib/facter/custom_facts/util/resolution.rb +2 -0
  15. data/lib/facter/custom_facts/util/windows_root.rb +2 -1
  16. data/lib/facter/facts/aix/processors/cores.rb +16 -0
  17. data/lib/facter/facts/aix/processors/threads.rb +16 -0
  18. data/lib/facter/facts/amzn/lsbdistcodename.rb +16 -0
  19. data/lib/facter/facts/amzn/lsbdistdescription.rb +16 -0
  20. data/lib/facter/facts/amzn/lsbdistid.rb +16 -0
  21. data/lib/facter/facts/amzn/os/distro/codename.rb +24 -0
  22. data/lib/facter/facts/amzn/os/distro/description.rb +21 -0
  23. data/lib/facter/facts/amzn/os/distro/id.rb +21 -0
  24. data/lib/facter/facts/amzn/os/distro/release.rb +32 -0
  25. data/lib/facter/facts/freebsd/is_virtual.rb +1 -5
  26. data/lib/facter/facts/freebsd/virtual.rb +1 -2
  27. data/lib/facter/facts/linux/az_metadata.rb +23 -0
  28. data/lib/facter/facts/linux/cloud/provider.rb +20 -0
  29. data/lib/facter/facts/linux/dhcp_servers.rb +2 -2
  30. data/lib/facter/facts/linux/ec2_metadata.rb +1 -5
  31. data/lib/facter/facts/linux/ec2_userdata.rb +1 -5
  32. data/lib/facter/facts/linux/hypervisors/xen.rb +1 -4
  33. data/lib/facter/facts/linux/interfaces.rb +1 -1
  34. data/lib/facter/facts/linux/ipaddress6_interfaces.rb +1 -1
  35. data/lib/facter/facts/linux/ipaddress_interfaces.rb +1 -1
  36. data/lib/facter/facts/linux/is_virtual.rb +1 -5
  37. data/lib/facter/facts/linux/macaddress_interfaces.rb +1 -1
  38. data/lib/facter/facts/linux/mtu_interfaces.rb +1 -1
  39. data/lib/facter/facts/linux/netmask6_interfaces.rb +1 -1
  40. data/lib/facter/facts/linux/netmask_interfaces.rb +1 -1
  41. data/lib/facter/facts/linux/network6_interfaces.rb +1 -1
  42. data/lib/facter/facts/linux/network_interfaces.rb +1 -1
  43. data/lib/facter/facts/linux/networking/dhcp.rb +1 -1
  44. data/lib/facter/facts/linux/networking/domain.rb +1 -1
  45. data/lib/facter/facts/linux/networking/fqdn.rb +1 -1
  46. data/lib/facter/facts/linux/networking/hostname.rb +1 -1
  47. data/lib/facter/facts/linux/networking/interfaces.rb +1 -1
  48. data/lib/facter/facts/linux/networking/ip.rb +1 -1
  49. data/lib/facter/facts/linux/networking/ip6.rb +1 -1
  50. data/lib/facter/facts/linux/networking/mac.rb +1 -1
  51. data/lib/facter/facts/linux/networking/mtu.rb +1 -1
  52. data/lib/facter/facts/linux/networking/netmask.rb +1 -1
  53. data/lib/facter/facts/linux/networking/netmask6.rb +1 -1
  54. data/lib/facter/facts/linux/networking/network.rb +1 -1
  55. data/lib/facter/facts/linux/networking/network6.rb +1 -1
  56. data/lib/facter/facts/linux/networking/primary.rb +1 -1
  57. data/lib/facter/facts/linux/networking/scope6.rb +1 -1
  58. data/lib/facter/facts/linux/processors/cores.rb +16 -0
  59. data/lib/facter/facts/linux/processors/threads.rb +16 -0
  60. data/lib/facter/facts/linux/scope6_interfaces.rb +1 -1
  61. data/lib/facter/facts/linux/virtual.rb +1 -2
  62. data/lib/facter/facts/macosx/os/macosx/version.rb +15 -4
  63. data/lib/facter/facts/macosx/processors/cores.rb +16 -0
  64. data/lib/facter/facts/macosx/processors/threads.rb +16 -0
  65. data/lib/facter/facts/rhel/lsbdistcodename.rb +16 -0
  66. data/lib/facter/facts/rhel/lsbdistdescription.rb +16 -0
  67. data/lib/facter/facts/rhel/lsbdistid.rb +16 -0
  68. data/lib/facter/facts/rhel/os/distro/codename.rb +2 -4
  69. data/lib/facter/facts/rhel/os/distro/description.rb +2 -4
  70. data/lib/facter/facts/rhel/os/distro/id.rb +2 -4
  71. data/lib/facter/facts/rhel/os/distro/release.rb +13 -12
  72. data/lib/facter/facts/sles/lsbdistcodename.rb +16 -0
  73. data/lib/facter/facts/sles/lsbdistdescription.rb +16 -0
  74. data/lib/facter/facts/sles/lsbdistid.rb +16 -0
  75. data/lib/facter/facts/sles/os/distro/codename.rb +3 -4
  76. data/lib/facter/facts/sles/os/distro/description.rb +2 -5
  77. data/lib/facter/facts/sles/os/distro/id.rb +6 -5
  78. data/lib/facter/facts/sles/os/distro/release.rb +17 -12
  79. data/lib/facter/facts/solaris/hypervisors/ldom.rb +1 -1
  80. data/lib/facter/facts/solaris/hypervisors/zone.rb +1 -1
  81. data/lib/facter/facts/solaris/mountpoints.rb +1 -1
  82. data/lib/facter/facts/solaris/processors/cores.rb +16 -0
  83. data/lib/facter/facts/solaris/processors/threads.rb +16 -0
  84. data/lib/facter/facts/ubuntu/lsbdistrelease.rb +2 -2
  85. data/lib/facter/facts/windows/az_metadata.rb +23 -0
  86. data/lib/facter/facts/windows/cloud/provider.rb +21 -0
  87. data/lib/facter/facts/windows/ec2_metadata.rb +1 -1
  88. data/lib/facter/facts/windows/ec2_userdata.rb +1 -1
  89. data/lib/facter/facts/windows/gce.rb +1 -1
  90. data/lib/facter/facts/windows/hypervisors/hyperv.rb +1 -1
  91. data/lib/facter/facts/windows/hypervisors/kvm.rb +2 -1
  92. data/lib/facter/facts/windows/hypervisors/virtualbox.rb +2 -2
  93. data/lib/facter/facts/windows/hypervisors/vmware.rb +1 -1
  94. data/lib/facter/facts/windows/hypervisors/xen.rb +3 -1
  95. data/lib/facter/facts/windows/is_virtual.rb +15 -0
  96. data/lib/facter/facts/windows/{virtualization/is_virtual.rb → processors/cores.rb} +4 -4
  97. data/lib/facter/facts/windows/{virtualization/virtual.rb → processors/threads.rb} +4 -4
  98. data/lib/facter/facts/windows/virtual.rb +15 -0
  99. data/lib/facter/framework/cli/cli.rb +6 -8
  100. data/lib/facter/framework/config/config_reader.rb +2 -0
  101. data/lib/facter/framework/config/fact_groups.rb +25 -2
  102. data/lib/facter/framework/core/cache_manager.rb +7 -3
  103. data/lib/facter/framework/core/fact/external/external_fact_manager.rb +0 -1
  104. data/lib/facter/framework/core/fact/internal/internal_fact_manager.rb +41 -39
  105. data/lib/facter/framework/core/fact_filter.rb +5 -15
  106. data/lib/facter/framework/core/fact_loaders/external_fact_loader.rb +9 -6
  107. data/lib/facter/framework/core/fact_loaders/fact_loader.rb +39 -37
  108. data/lib/facter/framework/core/fact_manager.rb +84 -14
  109. data/lib/facter/framework/core/file_loader.rb +1 -1
  110. data/lib/facter/framework/core/options.rb +1 -2
  111. data/lib/facter/framework/core/options/config_file_options.rb +7 -0
  112. data/lib/facter/framework/core/options/option_store.rb +12 -6
  113. data/lib/facter/framework/formatters/formatter_helper.rb +3 -5
  114. data/lib/facter/framework/logging/logger.rb +4 -4
  115. data/lib/facter/framework/parsers/query_parser.rb +5 -12
  116. data/lib/facter/models/fact_collection.rb +48 -5
  117. data/lib/facter/models/resolved_fact.rb +2 -3
  118. data/lib/facter/models/searched_fact.rb +2 -3
  119. data/lib/facter/resolvers/aix/ffi/ffi_helper.rb +1 -1
  120. data/lib/facter/resolvers/aix/processors.rb +4 -0
  121. data/lib/facter/resolvers/az.rb +39 -0
  122. data/lib/facter/resolvers/base_resolver.rb +2 -2
  123. data/lib/facter/resolvers/dmi_decode.rb +0 -1
  124. data/lib/facter/resolvers/linux/hostname.rb +126 -0
  125. data/lib/facter/resolvers/linux/networking.rb +124 -0
  126. data/lib/facter/resolvers/macosx/mountpoints.rb +14 -1
  127. data/lib/facter/resolvers/macosx/processor.rb +16 -1
  128. data/lib/facter/resolvers/mountpoints.rb +16 -8
  129. data/lib/facter/resolvers/networking.rb +3 -2
  130. data/lib/facter/resolvers/partitions.rb +1 -1
  131. data/lib/facter/resolvers/processors_lscpu.rb +44 -0
  132. data/lib/facter/resolvers/redhat_release.rb +28 -12
  133. data/lib/facter/resolvers/ruby.rb +1 -1
  134. data/lib/facter/resolvers/selinux.rb +5 -7
  135. data/lib/facter/resolvers/solaris/ffi/functions.rb +1 -1
  136. data/lib/facter/resolvers/solaris/ffi/structs.rb +12 -0
  137. data/lib/facter/resolvers/solaris/mountpoints.rb +22 -16
  138. data/lib/facter/resolvers/solaris/networking.rb +20 -5
  139. data/lib/facter/resolvers/solaris/processors.rb +7 -0
  140. data/lib/facter/resolvers/solaris/zone.rb +0 -1
  141. data/lib/facter/resolvers/windows/ffi/identity_ffi.rb +5 -0
  142. data/lib/facter/resolvers/windows/identity.rb +1 -6
  143. data/lib/facter/resolvers/windows/processors.rb +41 -4
  144. data/lib/facter/resolvers/windows/uptime.rb +3 -22
  145. data/lib/facter/resolvers/windows/virtualization.rb +46 -44
  146. data/lib/facter/resolvers/xen.rb +6 -1
  147. data/lib/facter/templates/man.erb +13 -5
  148. data/lib/facter/util/facts/posix/virtual_detector.rb +74 -0
  149. data/lib/facter/util/facts/unit_converter.rb +2 -2
  150. data/lib/facter/util/linux/dhcp.rb +86 -0
  151. data/lib/facter/util/linux/if_inet6.rb +73 -0
  152. data/lib/facter/util/linux/routing_table.rb +60 -0
  153. data/lib/facter/util/linux/socket_parser.rb +114 -0
  154. data/lib/facter/util/resolvers/ffi/hostname.rb +70 -0
  155. data/lib/facter/util/resolvers/http.rb +7 -1
  156. data/lib/facter/util/resolvers/networking/primary_interface.rb +11 -5
  157. data/lib/facter/util/utils.rb +18 -1
  158. data/lib/facter/version.rb +1 -1
  159. metadata +63 -13
  160. data/lib/facter/facts/linux/cloud.rb +0 -15
  161. data/lib/facter/framework/core/fact_augmenter.rb +0 -37
  162. data/lib/facter/resolvers/cloud.rb +0 -39
  163. data/lib/facter/resolvers/networking_linux.rb +0 -296
  164. data/lib/facter/util/facts/virtual_detector.rb +0 -90
@@ -45,6 +45,8 @@ module Facter
45
45
  end
46
46
 
47
47
  def default_path
48
+ return '' if RUBY_PLATFORM == 'java'
49
+
48
50
  os = OsDetector.instance.identifier
49
51
 
50
52
  windows_path = File.join('C:', 'ProgramData', 'PuppetLabs', 'facter', 'etc', 'facter.conf')
@@ -7,7 +7,15 @@ module Facter
7
7
  attr_accessor :groups_ttls
8
8
  attr_reader :groups, :block_list, :facts_ttls
9
9
 
10
- STRING_TO_SECONDS = { 'seconds' => 1, 'minutes' => 60, 'hours' => 3600, 'days' => 3600 * 24 }.freeze
10
+ STRING_TO_SECONDS = { 'ns' => 1.fdiv(1_000_000_000), 'nanos' => 1.fdiv(1_000_000_000),
11
+ 'nanoseconds' => 1.fdiv(1_000_000_000),
12
+ 'us' => 1.fdiv(1_000_000), 'micros' => 1.fdiv(1_000_000), 'microseconds' => 1.fdiv(1_000_000),
13
+ '' => 1.fdiv(1000), 'ms' => 1.fdiv(1000), 'milis' => 1.fdiv(1000),
14
+ 'milliseconds' => 1.fdiv(1000),
15
+ 's' => 1, 'seconds' => 1,
16
+ 'm' => 60, 'minutes' => 60,
17
+ 'h' => 3600, 'hours' => 3600,
18
+ 'd' => 3600 * 24, 'days' => 3600 * 24 }.freeze
11
19
 
12
20
  def initialize
13
21
  @groups = Facter::Config::FACT_GROUPS.dup
@@ -103,7 +111,22 @@ module Facter
103
111
 
104
112
  def ttls_to_seconds(ttls)
105
113
  duration, unit = ttls.split(' ', 2)
106
- duration.to_i * STRING_TO_SECONDS[unit]
114
+ unit = '' if duration && !unit
115
+ unit = append_s(unit)
116
+ seconds = STRING_TO_SECONDS[unit]
117
+ if seconds
118
+ (duration.to_i * seconds).to_i
119
+ else
120
+ log = Log.new(self)
121
+ log.error("Could not parse time unit #{unit} (try #{STRING_TO_SECONDS.keys.reject(&:empty?).join(', ')})")
122
+ nil
123
+ end
124
+ end
125
+
126
+ def append_s(unit)
127
+ return unit + 's' if unit.length > 2 && unit[-1] != 's'
128
+
129
+ unit
107
130
  end
108
131
  end
109
132
  end
@@ -123,7 +123,7 @@ cache_format_version is incorrect!")
123
123
  return unless data[searched_fact.name]
124
124
 
125
125
  [Facter::ResolvedFact.new(searched_fact.name, data[searched_fact.name], searched_fact.type,
126
- searched_fact.user_query, searched_fact.filter_tokens)]
126
+ searched_fact.user_query)]
127
127
  end
128
128
  end
129
129
 
@@ -133,7 +133,7 @@ cache_format_version is incorrect!")
133
133
  next if fact_name == 'cache_format_version'
134
134
 
135
135
  fact = Facter::ResolvedFact.new(fact_name, fact_value, searched_fact.type,
136
- searched_fact.user_query, searched_fact.filter_tokens)
136
+ searched_fact.user_query)
137
137
  fact.file = searched_fact.file
138
138
  facts << fact
139
139
  end
@@ -209,7 +209,11 @@ cache_format_version is incorrect!")
209
209
  def delete_cache(group_name)
210
210
  cache_file_name = File.join(@cache_dir, group_name)
211
211
 
212
- File.delete(cache_file_name) if File.readable?(cache_file_name)
212
+ begin
213
+ File.delete(cache_file_name) if File.readable?(cache_file_name)
214
+ rescue Errno::EACCES => e
215
+ @log.warn("Could not delete cache: #{e.message}")
216
+ end
213
217
  end
214
218
  end
215
219
  end
@@ -19,7 +19,6 @@ module Facter
19
19
  custom_facts.each do |custom_fact|
20
20
  fact = LegacyFacter[custom_fact.name]
21
21
  resolved_fact = ResolvedFact.new(custom_fact.name, fact.value, :custom)
22
- resolved_fact.filter_tokens = []
23
22
  resolved_fact.user_query = custom_fact.user_query
24
23
  resolved_fact.file = fact.options[:file]
25
24
 
@@ -2,20 +2,25 @@
2
2
 
3
3
  module Facter
4
4
  class InternalFactManager
5
- @@log = Facter::Log.new(self)
6
-
5
+ # resolves each SearchFact and filter out facts that do not match the given user query
6
+ # @param searched_facts [Array<Facter::SearchedFact>] array of searched facts
7
+ #
8
+ # @return [Array<Facter::ResolvedFact>]
9
+ #
10
+ # @api private
7
11
  def resolve_facts(searched_facts)
8
12
  internal_searched_facts = filter_internal_facts(searched_facts)
9
-
10
13
  resolved_facts = if Options[:sequential]
11
- @@log.debug('Resolving facts sequentially')
14
+ log.debug('Resolving facts sequentially')
12
15
  resolve_sequentially(internal_searched_facts)
13
16
  else
14
- @@log.debug('Resolving fact in parallel')
15
- threads = start_threads(internal_searched_facts)
16
- join_threads(threads, internal_searched_facts)
17
+ log.debug('Resolving fact in parallel')
18
+ resolve_in_parallel(internal_searched_facts)
17
19
  end
18
20
 
21
+ resolved_facts.flatten!
22
+ resolved_facts.compact!
23
+
19
24
  nil_resolved_facts = resolve_nil_facts(searched_facts)
20
25
 
21
26
  resolved_facts.concat(nil_resolved_facts)
@@ -27,6 +32,17 @@ module Facter
27
32
  searched_facts.select { |searched_fact| %i[core legacy].include? searched_fact.type }
28
33
  end
29
34
 
35
+ def valid_fact?(searched_fact, resolved_fact)
36
+ return if resolved_fact.value.nil?
37
+
38
+ searched_fact_name = searched_fact.name
39
+ if searched_fact_name.include?('.*')
40
+ resolved_fact.name.match(searched_fact_name)
41
+ else
42
+ resolved_fact.name == searched_fact_name
43
+ end
44
+ end
45
+
30
46
  def resolve_nil_facts(searched_facts)
31
47
  resolved_facts = []
32
48
  searched_facts.select { |fact| fact.type == :nil }.each do |fact|
@@ -37,49 +53,35 @@ module Facter
37
53
  end
38
54
 
39
55
  def resolve_sequentially(searched_facts)
40
- resolved_facts = []
41
-
42
- searched_facts
43
- .uniq { |searched_fact| searched_fact.fact_class.name }
44
- .each do |searched_fact|
45
- begin
46
- fact = CoreFact.new(searched_fact)
47
- fact_value = fact.create
48
- resolved_facts << fact_value unless fact_value.nil?
49
- rescue StandardError => e
50
- @@log.log_exception(e)
51
- end
52
- end
56
+ searched_facts.map! { |searched_fact| resolve_fact(searched_fact) }
57
+ end
53
58
 
54
- resolved_facts.flatten!
55
- FactAugmenter.augment_resolved_facts(searched_facts, resolved_facts)
59
+ def resolve_in_parallel(searched_facts)
60
+ searched_facts.map! do |searched_fact|
61
+ Thread.new { resolve_fact(searched_fact) }
62
+ end.map!(&:value)
56
63
  end
57
64
 
58
- def start_threads(searched_facts)
59
- # only resolve a fact once, even if multiple search facts depend on that fact
60
- searched_facts
61
- .uniq { |searched_fact| searched_fact.fact_class.name }
62
- .map do |searched_fact|
63
- Thread.new do
64
- resolve_fact(searched_fact)
65
+ def resolve_fact(searched_fact)
66
+ fact_value = core_fact(searched_fact)
67
+ Array(fact_value).map! do |resolved_fact|
68
+ if valid_fact?(searched_fact, resolved_fact)
69
+ resolved_fact.user_query = searched_fact.user_query
70
+ resolved_fact
65
71
  end
66
72
  end
67
73
  end
68
74
 
69
- def join_threads(threads, searched_facts)
70
- resolved_facts = threads.map(&:value)
71
- resolved_facts.compact!
72
- resolved_facts.flatten!
73
-
74
- FactAugmenter.augment_resolved_facts(searched_facts, resolved_facts)
75
- end
76
-
77
- def resolve_fact(searched_fact)
75
+ def core_fact(searched_fact)
78
76
  fact = CoreFact.new(searched_fact)
79
77
  fact.create
80
78
  rescue StandardError => e
81
- @@log.log_exception(e)
79
+ log.log_exception(e)
82
80
  nil
83
81
  end
82
+
83
+ def log
84
+ @log ||= Facter::Log.new(self)
85
+ end
84
86
  end
85
87
  end
@@ -1,21 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Facter
4
- # Filter inside value of a fact.
5
- # e.g. os.release.major is the user query, os.release is the fact
6
- # and major is the filter criteria inside tha fact
7
4
  class FactFilter
8
- def filter_facts!(searched_facts)
9
- filter_legacy_facts!(searched_facts)
10
- filter_blocked_legacy_facts!(searched_facts)
11
-
12
- searched_facts.each do |fact|
13
- fact.value = if fact.filter_tokens.any? && fact.value.respond_to?(:dig)
14
- fact.value.dig(*fact.filter_tokens)
15
- else
16
- fact.value
17
- end
18
- end
5
+ def filter_facts!(resolved_facts, user_query)
6
+ filter_legacy_facts!(resolved_facts) if user_query.empty?
7
+ filter_blocked_legacy_facts!(resolved_facts)
8
+ resolved_facts
19
9
  end
20
10
 
21
11
  private
@@ -32,7 +22,7 @@ module Facter
32
22
  end
33
23
 
34
24
  def filter_legacy_facts!(resolved_facts)
35
- return unless !Options[:show_legacy] && Options[:user_query].empty?
25
+ return if Options[:show_legacy]
36
26
 
37
27
  resolved_facts.reject!(&:legacy?)
38
28
  end
@@ -10,20 +10,23 @@ module Facter
10
10
  @external_facts = load_external_facts
11
11
  end
12
12
 
13
+ def load_fact(fact_name)
14
+ build_custom_facts(LegacyFacter.collection.custom_fact(fact_name)) || []
15
+ end
16
+
13
17
  private
14
18
 
15
19
  def load_custom_facts
16
- custom_facts = []
17
-
18
20
  custom_facts_to_load = LegacyFacter.collection.custom_facts
21
+ build_custom_facts(custom_facts_to_load) || []
22
+ end
19
23
 
20
- custom_facts_to_load&.each do |k, v|
24
+ def build_custom_facts(custom_facts_to_load)
25
+ custom_facts_to_load&.map do |k, v|
21
26
  loaded_fact = LoadedFact.new(k.to_s, nil, :custom)
22
27
  loaded_fact.is_env = v.options[:is_env] if v.options[:is_env]
23
- custom_facts << loaded_fact
28
+ loaded_fact
24
29
  end
25
-
26
- custom_facts
27
30
  end
28
31
 
29
32
  def load_external_facts
@@ -11,45 +11,27 @@ module Facter
11
11
 
12
12
  @internal_facts = []
13
13
  @external_facts = []
14
+ @custom_facts = []
14
15
  @facts = []
15
- end
16
16
 
17
- def load(options)
18
17
  @internal_loader ||= InternalFactLoader.new
19
18
  @external_fact_loader ||= ExternalFactLoader.new
19
+ end
20
20
 
21
- @facts = []
22
- @external_facts = []
23
-
24
- @internal_facts = load_internal_facts(options)
21
+ def load(user_query, options)
22
+ @internal_facts = load_internal_facts(user_query, options)
23
+ @custom_facts = load_custom_facts(options)
25
24
  @external_facts = load_external_facts(options)
26
25
 
27
26
  filter_env_facts
28
27
 
29
- @facts = @internal_facts + @external_facts
30
- end
31
-
32
- private
33
-
34
- def filter_env_facts
35
- env_fact_names = @external_facts.select { |fact| fact.is_env == true }.map(&:name)
36
- return unless env_fact_names.any?
37
-
38
- @internal_facts.delete_if do |fact|
39
- if env_fact_names.include?(fact.name)
40
- @log.debug("Reading #{fact.name} fact from environment variable")
41
- true
42
- else
43
- false
44
- end
45
- end
28
+ @facts = @internal_facts + @external_facts + @custom_facts
46
29
  end
47
30
 
48
- def load_internal_facts(options)
31
+ def load_internal_facts(user_query, options)
49
32
  @log.debug('Loading internal facts')
50
33
  internal_facts = []
51
-
52
- if options[:user_query] || options[:show_legacy]
34
+ if user_query || options[:show_legacy]
53
35
  # if we have a user query, then we must search in core facts and legacy facts
54
36
  @log.debug('Loading all internal facts')
55
37
  internal_facts = @internal_loader.facts
@@ -61,23 +43,43 @@ module Facter
61
43
  block_facts(internal_facts, options)
62
44
  end
63
45
 
46
+ def load_custom_fact(options, fact_name)
47
+ return [] unless options[:custom_facts]
48
+
49
+ custom_facts = @external_fact_loader.load_fact(fact_name)
50
+ block_facts(custom_facts, options)
51
+ end
52
+
53
+ def load_custom_facts(options)
54
+ return [] unless options[:custom_facts]
55
+
56
+ @log.debug('Loading custom facts')
57
+ custom_facts = @external_fact_loader.custom_facts
58
+ block_facts(custom_facts, options)
59
+ end
60
+
64
61
  def load_external_facts(options)
62
+ return [] unless options[:external_facts]
63
+
65
64
  @log.debug('Loading external facts')
66
- external_facts = []
65
+ external_facts = @external_fact_loader.external_facts
66
+ block_facts(external_facts, options)
67
+ end
67
68
 
68
- if options[:custom_facts]
69
- @log.debug('Loading custom facts')
70
- external_facts += @external_fact_loader.custom_facts
71
- end
69
+ private
72
70
 
73
- external_facts = block_facts(external_facts, options)
71
+ def filter_env_facts
72
+ env_fact_names = @external_facts.select { |fact| fact.is_env == true }.map(&:name)
73
+ return unless env_fact_names.any?
74
74
 
75
- if options[:external_facts]
76
- @log.debug('Loading external facts')
77
- external_facts += @external_fact_loader.external_facts
75
+ @internal_facts.delete_if do |fact|
76
+ if env_fact_names.include?(fact.name)
77
+ @log.debug("Reading #{fact.name} fact from environment variable")
78
+ true
79
+ else
80
+ false
81
+ end
78
82
  end
79
-
80
- external_facts
81
83
  end
82
84
 
83
85
  def block_facts(facts, options)
@@ -8,18 +8,16 @@ module Facter
8
8
  @internal_fact_mgr = InternalFactManager.new
9
9
  @external_fact_mgr = ExternalFactManager.new
10
10
  @fact_loader = FactLoader.instance
11
+ @options = Options.get
11
12
  @log = Log.new(self)
12
13
  end
13
14
 
14
- def searched_facts(user_query = [])
15
- loaded_facts = @fact_loader.load(Options.get)
16
- QueryParser.parse(user_query, loaded_facts)
17
- end
18
-
19
15
  def resolve_facts(user_query = [])
20
- searched_facts = parse_user_query(user_query)
21
-
16
+ @options[:user_query] = user_query
22
17
  cache_manager = Facter::CacheManager.new
18
+
19
+ searched_facts = QueryParser.parse(user_query, @fact_loader.load(user_query, @options))
20
+
23
21
  searched_facts, cached_facts = cache_manager.resolve_facts(searched_facts)
24
22
  internal_facts = @internal_fact_mgr.resolve_facts(searched_facts)
25
23
  external_facts = @external_fact_mgr.resolve_facts(searched_facts)
@@ -29,27 +27,99 @@ module Facter
29
27
  resolved_facts = resolved_facts.concat(cached_facts)
30
28
  cache_manager.cache_facts(resolved_facts)
31
29
 
32
- FactFilter.new.filter_facts!(resolved_facts)
30
+ FactFilter.new.filter_facts!(resolved_facts, user_query)
33
31
 
34
32
  log_resolved_facts(resolved_facts)
35
33
  resolved_facts
36
34
  end
37
35
 
38
- def resolve_core(user_query = [])
39
- loaded_facts_hash = @fact_loader.internal_facts
36
+ # resolve a fact by name, in a similar way that facter 3 does.
37
+ # search is done in multiple steps, and the next step is executed
38
+ # only if the previous one was not able to resolve the fact
39
+ # - load the `fact_name.rb` from the configured custom directories
40
+ # - load all the core facts, external facts and env facts
41
+ # - load all custom facts
42
+ def resolve_fact(user_query)
43
+ @options[:user_query] = user_query
44
+ @log.debug("resolving fact with user_query: #{user_query}")
45
+
46
+ @cache_manager = Facter::CacheManager.new
47
+
48
+ custom_facts = custom_fact_by_filename(user_query) || []
49
+ core_and_external_facts = core_or_external_fact(user_query) || []
50
+ resolved_facts = core_and_external_facts + custom_facts
51
+
52
+ resolved_facts = all_custom_facts(user_query) if resolved_facts.empty?
53
+
54
+ @cache_manager.cache_facts(resolved_facts)
55
+
56
+ log_resolved_facts(resolved_facts)
57
+ resolved_facts
58
+ end
59
+
60
+ def resolve_core(user_query = [], options = {})
61
+ @cache_manager = CacheManager.new
62
+ core_fact(user_query, options)
63
+ end
64
+
65
+ private
66
+
67
+ def core_fact(user_query, options)
68
+ loaded_facts_hash = @fact_loader.load_internal_facts(user_query, options)
40
69
 
41
70
  searched_facts = QueryParser.parse(user_query, loaded_facts_hash)
71
+ searched_facts, cached_facts = @cache_manager.resolve_facts(searched_facts)
72
+
42
73
  resolved_facts = @internal_fact_mgr.resolve_facts(searched_facts)
43
- FactFilter.new.filter_facts!(resolved_facts)
74
+ resolved_facts = resolved_facts.concat(cached_facts)
75
+
76
+ FactFilter.new.filter_facts!(resolved_facts, user_query)
44
77
 
45
78
  resolved_facts
46
79
  end
47
80
 
48
- private
81
+ def custom_fact_by_filename(user_query)
82
+ @log.debug("Searching fact: #{user_query} in file: #{user_query}.rb")
83
+
84
+ custom_fact = @fact_loader.load_custom_fact(@options, user_query)
85
+ return unless custom_fact.any?
86
+
87
+ searched_facts = parse_user_query(custom_fact, user_query)
88
+ searched_facts, cached_facts = @cache_manager.resolve_facts(searched_facts)
89
+
90
+ resolved_facts = @external_fact_mgr.resolve_facts(searched_facts)
91
+ resolved_facts = resolved_facts.concat(cached_facts)
92
+ resolved_facts if resolved_facts.any?
93
+ end
49
94
 
50
- def parse_user_query(user_query)
51
- loaded_facts = @fact_loader.load(Options.get)
95
+ def core_or_external_fact(user_query)
96
+ @log.debug("Searching fact: #{user_query} in core facts and external facts")
97
+
98
+ core_facts = core_fact([user_query], @options)
99
+ external_facts = @fact_loader.load_external_facts(@options)
100
+ searched_facts = parse_user_query(external_facts, user_query)
101
+ searched_facts, cached_facts = @cache_manager.resolve_facts(searched_facts)
102
+
103
+ resolved_facts = @external_fact_mgr.resolve_facts(searched_facts)
104
+ resolved_facts = override_core_facts(core_facts, resolved_facts)
105
+ resolved_facts = resolved_facts.concat(cached_facts)
106
+
107
+ resolved_facts unless resolved_facts.map(&:value).compact.empty?
108
+ end
109
+
110
+ def all_custom_facts(user_query)
111
+ @log.debug("Searching fact: #{user_query} in all custom facts")
112
+
113
+ custom_facts = @fact_loader.load_custom_facts(@options)
114
+ searched_facts = parse_user_query(custom_facts, user_query)
115
+ searched_facts, cached_facts = @cache_manager.resolve_facts(searched_facts)
116
+
117
+ resolved_facts = @external_fact_mgr.resolve_facts(searched_facts)
118
+ resolved_facts.concat(cached_facts)
119
+ end
52
120
 
121
+ def parse_user_query(loaded_facts, user_query)
122
+ user_query = Array(user_query)
53
123
  QueryParser.parse(user_query, loaded_facts)
54
124
  end
55
125