File: hiera.rb

package info (click to toggle)
hiera 3.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid, stretch
  • size: 628 kB
  • ctags: 162
  • sloc: ruby: 3,056; makefile: 31; sh: 17
file content (118 lines) | stat: -rw-r--r-- 6,141 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
require 'yaml'

class Hiera
  require "hiera/error"
  require "hiera/version"
  require "hiera/config"
  require "hiera/util"
  require "hiera/backend"
  require "hiera/console_logger"
  require "hiera/puppet_logger"
  require "hiera/noop_logger"
  require "hiera/fallback_logger"
  require "hiera/filecache"

  class << self
    attr_reader :logger

    # Loggers are pluggable, just provide a class called
    # Hiera::Foo_logger and respond to :warn and :debug
    #
    # See hiera-puppet for an example that uses the Puppet
    # loging system instead of our own
    def logger=(logger)
      require "hiera/#{logger}_logger"

      @logger = Hiera::FallbackLogger.new(
        Hiera.const_get("#{logger.capitalize}_logger"),
        Hiera::Console_logger)
    rescue Exception => e
      @logger = Hiera::Console_logger
      warn("Failed to load #{logger} logger: #{e.class}: #{e}")
    end

    def warn(msg); @logger.warn(msg); end
    def debug(msg); @logger.debug(msg); end
  end

  attr_reader :options, :config

  # If the config option is a string its assumed to be a filename,
  # else a hash of what would have been in the YAML config file
  def initialize(options={})
    config = options[:config]
    if config.nil?
      # Look in codedir first, then confdir
      config = File.join(Util.code_dir, 'hiera.yaml')
      config = File.join(Util.config_dir, 'hiera.yaml') unless File.exist?(config)
    end
    @config = Config.load(config)

    Config.load_backends
  end

  # Calls the backends to do the actual lookup.
  #
  # The _scope_ can be anything that responds to `[]`, if you have input
  # data like a Puppet Scope that does not you can wrap that data in a
  # class that has a `[]` method that fetches the data from your source.
  # See hiera-puppet for an example of this.
  #
  # The order-override will insert as first in the hierarchy a data source
  # of your choice.
  #
  # Possible values for the _resolution_type_ parameter:
  #
  # - _:priority_ - This is the default. First found value is returned and no merge is performed
  # - _:array_ - An array merge lookup assembles a value from every matching level of the hierarchy. It retrieves all
  #     of the (string or array) values for a given key, then flattens them into a single array of unique values.
  #     If _priority_ lookup can be thought of as a “default with overrides” pattern, _array_ merge lookup can be though
  #     of as “default with additions.”
  # - _:hash_ - A hash merge lookup assembles a value from every matching level of the hierarchy. It retrieves all of
  #     the (hash) values for a given key, then merges the hashes into a single hash. Hash merge lookups will fail with
  #     an error if any of the values found in the data sources are strings or arrays. It only works when every value
  #     found is a hash. The actual merge behavior is determined by looking up the keys `:merge_behavior` and
  #     `:deep_merge_options` in the Hiera config. `:merge_behavior` can be set to `:deep`, :deeper` or `:native`
  #     (explained in detail below).
  # - _{ deep merge options }_ - Configured values for `:merge_behavior` and `:deep_merge_options`will be completely
  #     ignored. Instead the _resolution_type_ will be a `:hash` merge where the `:merge_behavior` will be the value
  #     keyed by `:behavior` in the given hash and the `:deep_merge_options` will be the remaining top level entries of
  #     that same hash.
  #
  # Valid behaviors for the _:hash_ resolution type:
  #
  # - _native_ - Performs a simple hash-merge by overwriting keys of lower lookup priority.
  # - _deeper_ - In a deeper hash merge, Hiera recursively merges keys and values in each source hash. For each key,
  #     if the value is:
  #        - only present in one source hash, it goes into the final hash.
  #        - a string/number/boolean and exists in two or more source hashes, the highest priority value goes into
  #          the final hash.
  #        - an array and exists in two or more source hashes, the values from each source are merged into a single
  #          array and de-duplicated (but not automatically flattened, as in an array merge lookup).
  #        - a hash and exists in two or more source hashes, the values from each source are recursively merged, as
  #          though they were source hashes.
  #        - mismatched between two or more source hashes, we haven’t validated the behavior. It should act as
  #          described in the deep_merge gem documentation.
  # - _deep_ - In a deep hash merge, Hiera behaves the same as for _deeper_, except that when a string/number/boolean
  #     exists in two or more source hashes, the lowest priority value goes into the final hash. This is considered
  #     largely useless and should be avoided. Use _deeper_ instead.
  #
  # The _merge_ can be given as a hash with the mandatory key `:strategy` to denote the actual strategy. This
  # is useful for the `:deeper` and `:deep` strategy since they can use additional options to control the behavior.
  # The options can be passed as top level keys in the `merge` parameter when it is a given as a hash. Recognized
  # options are:
  #
  #  - 'knockout_prefix' Set to string value to signify prefix which deletes elements from existing element. Defaults is _undef_
  #  - 'sort_merged_arrays' Set to _true_ to sort all arrays that are merged together. Default is _false_
  #  - 'merge_hash_arrays' Set to _true_ to merge hashes within arrays. Default is _false_
  #
  # @param key [String] The key to lookup
  # @param default [Object,nil] The value to return when there is no match for _key_
  # @param scope [#[],nil] The scope to use for the lookup
  # @param order_override [#[]] An override that will considered the first source of lookup
  # @param resolution_type [String,Hash<Symbol,String>] Symbolic resolution type or deep merge configuration
  # @return [Object] The found value or the given _default_ value
  def lookup(key, default, scope, order_override=nil, resolution_type=:priority)
    Backend.lookup(key, default, scope, order_override, resolution_type)
  end
end