Update stdlib and concat to 6.1.0 both
[mirror/dsa-puppet.git] / 3rdparty / modules / stdlib / lib / puppet / functions / fact.rb
1 # @summary
2 #   Digs into the facts hash using dot-notation
3 #
4 # Supports the use of dot-notation for referring to structured facts. If a fact requested
5 # does not exist, returns Undef.
6 #
7 # @example Example usage:
8 #     fact('osfamily')
9 #     fact('os.architecture')
10 #
11 # @example Array indexing:
12 #     fact('mountpoints."/dev".options.1')
13 #
14 # @example Fact containing a "." in the name:
15 #     fact('vmware."VRA.version"')
16 #
17 Puppet::Functions.create_function(:fact) do
18   # @param fact_name
19   #   The name of the fact to check
20   #
21   # @return
22   #   All information retrieved on the given fact_name
23   dispatch :fact do
24     param 'String', :fact_name
25   end
26
27   def to_dot_syntax(array_path)
28     array_path.map { |string|
29       string.include?('.') ? %("#{string}") : string
30     }.join('.')
31   end
32
33   def fact(fact_name)
34     facts = closure_scope['facts']
35
36     # Transform the dot-notation string into an array of paths to walk. Make
37     # sure to correctly extract double-quoted values containing dots as single
38     # elements in the path.
39     path = fact_name.scan(%r{([^."]+)|(?:")([^"]+)(?:")}).map { |x| x.compact.first }
40
41     walked_path = []
42     path.reduce(facts) do |d, k|
43       return nil if d.nil? || k.nil?
44
45       if d.is_a?(Array)
46         begin
47           result = d[Integer(k)]
48         rescue ArgumentError => e # rubocop:disable Lint/UselessAssignment : Causes errors if assigment is removed.
49           Puppet.warning("fact request for #{fact_name} returning nil: '#{to_dot_syntax(walked_path)}' is an array; cannot index to '#{k}'")
50           result = nil
51         end
52       elsif d.is_a?(Hash)
53         result = d[k]
54       else
55         Puppet.warning("fact request for #{fact_name} returning nil: '#{to_dot_syntax(walked_path)}' is not a collection; cannot walk to '#{k}'")
56         result = nil
57       end
58
59       walked_path << k
60       result
61     end
62   end
63 end