Class: Hiera::Backend::Role_backend

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

Overview

This naming is required by puppet.

Instance Method Summary collapse

Constructor Details

#initialize(cache = nil) ⇒ Role_backend

Returns a new instance of Role_backend.



74
75
76
# File 'puppet/modules/wmflib/lib/hiera/backend/role_backend.rb', line 74

def initialize(cache = nil)
  @cache = cache || Filecache.new
end

Instance Method Details

#get_path(_key, role, source, scope) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'puppet/modules/wmflib/lib/hiera/backend/role_backend.rb', line 78

def get_path(_key, role, source, scope)
  config_section = :role

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

  # Variables for role::foo::bar will be searched in:
  # role/foo/bar.yaml
  # role/$::site/foo/bar.yaml
  # etc, depending on your hierarchy
  path = role.split('::').join('/')
  src = "role/#{source}/#{path}"

  # Use the datadir for the 'role' section of the config
  Backend.datafile(config_section, scope, src, "yaml")
end

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



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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
# File 'puppet/modules/wmflib/lib/hiera/backend/role_backend.rb', line 119

def lookup(key, scope, order_override, resolution_type)
  topscope_var = '_roles'
  resultset = nil
  return nil unless scope.include?topscope_var
  roles = scope[topscope_var]
  return nil if roles.nil?
  if Config.include?(:role_hierarchy)
    hierarchy = Config[:role_hierarchy]
  else
    hierarchy = nil
  end

  roles.keys.each do |role|
    Hiera.debug("Looking in hierarchy for role #{role}")
    answer = nil
    Backend.datasources(scope, order_override, hierarchy) do |source|
      yamlfile = get_path(key, role, source, scope)
      next if yamlfile.nil?
      Hiera.debug("Searching in file #{yamlfile} for #{key}")
      next unless File.exist?(yamlfile)

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

      next if data.nil? || data.empty?

      next unless data.include? key

      new_answer = Backend.parse_answer(data[key], scope)
      Hiera.debug("Found: #{key} =>  #{new_answer}")
      is_done, answer = merge_answer(new_answer, answer,
                                     resolution_type)
      break if is_done
    end
    # skip parsing if no answer was found.
    next if answer.nil?

    # Now we got one answer for this role, we can merge it with
    # what we got earlier.
    case resolution_type
    when :array
      resultset ||= []
      answer.each { |el| resultset.push(el) }
    when :hash
      resultset ||= {}
      resultset = Backend.merge_answer(answer, resultset)
    else
      # We raise an exception if we have received conflicting results
      if resultset && answer != resultset
        raise Exception, "Conflicting value for #{key} found in role #{role}"
      else
        resultset = answer
      end
    end
  end
  resultset
end

#merge_answer(new_answer, answer, resolution_type) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'puppet/modules/wmflib/lib/hiera/backend/role_backend.rb', line 101

def merge_answer(new_answer, answer, resolution_type)
  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
    return true, answer
  end

  [false, answer]
end