fact.rb 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  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. def to_dot_syntax(array_path)
  21. array_path.map { |string|
  22. string.include?('.') ? %("#{string}") : string
  23. }.join('.')
  24. end
  25. def fact(fact_name)
  26. facts = closure_scope['facts']
  27. # Transform the dot-notation string into an array of paths to walk. Make
  28. # sure to correctly extract double-quoted values containing dots as single
  29. # elements in the path.
  30. path = fact_name.scan(%r{([^."]+)|(?:")([^"]+)(?:")}).map { |x| x.compact.first }
  31. walked_path = []
  32. path.reduce(facts) do |d, k|
  33. return nil if d.nil? || k.nil?
  34. if d.is_a?(Array)
  35. begin
  36. result = d[Integer(k)]
  37. rescue ArgumentError => e # rubocop:disable Lint/UselessAssignment : Causes errors if assigment is removed.
  38. Puppet.warning("fact request for #{fact_name} returning nil: '#{to_dot_syntax(walked_path)}' is an array; cannot index to '#{k}'")
  39. result = nil
  40. end
  41. elsif d.is_a?(Hash)
  42. result = d[k]
  43. else
  44. Puppet.warning("fact request for #{fact_name} returning nil: '#{to_dot_syntax(walked_path)}' is not a collection; cannot walk to '#{k}'")
  45. result = nil
  46. end
  47. walked_path << k
  48. result
  49. end
  50. end
  51. end