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