Class: Hiera::Backend::Nuyaml_backend

Inherits:
Object
  • Object
show all
Defined in:
puppet/modules/wmflib/lib/hiera/backend/nuyaml_backend.rb

Overview

This naming is required by puppet.

Instance Method Summary collapse

Constructor Details

#initialize(cache = nil) ⇒ Nuyaml_backend

Returns a new instance of Nuyaml_backend.



71
72
73
74
75
76
# File 'puppet/modules/wmflib/lib/hiera/backend/nuyaml_backend.rb', line 71

def initialize(cache = nil)
  require 'yaml'
  @cache = cache || Filecache.new
  config = Config[:nuyaml]
  @expand_path = config[:expand_path] || []
end

Instance Method Details

#get_path(key, scope, source) ⇒ Object



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
119
120
121
# File 'puppet/modules/wmflib/lib/hiera/backend/nuyaml_backend.rb', line 78

def get_path(key, scope, source)
  config_section = :nuyaml
  # Special case: regex
  if %r{^regex/}.match(source)
    Hiera.debug("Regex match going on - using regex.yaml")
    return Backend.datafile(config_section, scope, 'regex', "yaml")
  end

  # Special case: 'private' repository.
  # We use a different datadir in this case.
  # Example: private/common will search in the common source
  # within the private datadir
  if %r{private/(.*)} =~ source
    config_section = :private
    source = Regexp.last_match(1)
  end

  # Special case: 'secret' repository. This is practically labs only
  # We use a different datadir in this case.
  # Example: private/common will search in the common source
  # within the private datadir
  if %r{secret/(.*)} =~ source
    config_section = :secret
    source = Regexp.last_match(1)
  end

  Hiera.debug("The source is: #{source}")
  # If the source is in the expand_path list, perform path
  # expansion. This is thought to allow large codebases to live
  # with fairly small yaml files as opposed to a very large one.
  # Example:
  # $apache::mpm::worker will be in common/apache/mpm.yaml
  paths = @expand_path.map{ |x| Backend.parse_string(x, scope) }
  if paths.include? source
    namespaces = key.gsub(/^::/, '').split('::')
    namespaces.pop

    unless namespaces.empty?
      source += "/".concat(namespaces.join('/'))
    end
  end

  Backend.datafile(config_section, scope, source, "yaml")
end

#lookup(key, scope, order_override, resolution_type) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'puppet/modules/wmflib/lib/hiera/backend/nuyaml_backend.rb', line 143

def lookup(key, scope, order_override, resolution_type)
  answer = nil

  Hiera.debug("Looking up #{key}")

  Backend.datasources(scope, order_override) do |source|
    Hiera.debug("Loading info from #{source} for #{key}")

    yamlfile = get_path(key, scope, source)

    Hiera.debug("Searching for #{key} in #{yamlfile}")

    next if yamlfile.nil?

    Hiera.debug("Loading file #{yamlfile}")

    next unless File.exist?(yamlfile)

    data = @cache.read(yamlfile, Hash) do |content|
      YAML.load(content)
    end

    next if data.nil?

    if %r{regex/(.*)$} =~ source
      matchto = Regexp.last_match(1)
      new_answer = regex_lookup(key, matchto, data, scope)
    else
      new_answer = plain_lookup(key, data, scope)
    end

    next if new_answer.nil?
    # Extra logging that we found the key. This can be outputted
    # multiple times if the resolution type is array or hash but that
    # should be expected as the logging will then tell the user ALL the
    # places where the key is found.
    Hiera.debug("Found #{key} in #{source}")

    # for array resolution we just append to the array whatever
    # we find, we then goes onto the next file and keep adding to
    # the array
    #
    # for priority searches we break after the first found data
    # item

    case resolution_type
    when :array
      raise Exception, "Hiera type mismatch: expected Array and got #{new_answer.class}" unless new_answer.kind_of?(Array) || new_answer.kind_of?(String)
      answer ||= []
      answer << new_answer
    when :hash
      raise Exception, "Hiera type mismatch: expected Hash and got #{new_answer.class}" unless new_answer.kind_of? Hash
      answer ||= {}
      answer = Backend.merge_answer(new_answer, answer)
    else
      answer = new_answer
      break
    end
  end

  answer
end

#plain_lookup(key, data, scope) ⇒ Object



123
124
125
126
# File 'puppet/modules/wmflib/lib/hiera/backend/nuyaml_backend.rb', line 123

def plain_lookup(key, data, scope)
    return nil unless data.include?(key)
    Backend.parse_answer(data[key], scope)
end

#regex_lookup(key, matchon, data, scope) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'puppet/modules/wmflib/lib/hiera/backend/nuyaml_backend.rb', line 128

def regex_lookup(key, matchon, data, scope)
  data.each do |label, datahash|
    r = datahash["__regex"]
    Hiera.debug("Scanning label #{label} for matches to '#{r}' in '#{matchon}' ")
    next unless r.match(matchon)
    Hiera.debug("Label #{label} matches; searching within it")
    next unless datahash.include?(key)
    return Backend.parse_answer(datahash[key], scope)
  end
  return nil
rescue => detail
  Hiera.debug(detail)
  return nil
end