2 # Digs into the facts hash using dot-notation
4 # Supports the use of dot-notation for referring to structured facts. If a fact requested
5 # does not exist, returns Undef.
7 # @example Example usage:
9 # fact('os.architecture')
11 # @example Array indexing:
12 # fact('mountpoints."/dev".options.1')
14 # @example Fact containing a "." in the name:
15 # fact('vmware."VRA.version"')
17 Puppet::Functions.create_function(:fact) do
19 # The name of the fact to check
22 # All information retrieved on the given fact_name
24 param 'String', :fact_name
27 def to_dot_syntax(array_path)
28 array_path.map { |string|
29 string.include?('.') ? %("#{string}") : string
34 facts = closure_scope['facts']
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 }
42 path.reduce(facts) do |d, k|
43 return nil if d.nil? || k.nil?
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}'")
55 Puppet.warning("fact request for #{fact_name} returning nil: '#{to_dot_syntax(walked_path)}' is not a collection; cannot walk to '#{k}'")