Project

General

Profile

« Previous | Next » 

Revision a3d8204a

Added by Ori Rabin about 9 years ago

Fixes #8333 - correct matcher values with multi-key matchers

View differences:

app/services/classification/base.rb
class_parameters.each do |key|
lookup_values_for_key = all_lookup_values.where(:lookup_key_id => key.id, :use_puppet_default => false).includes(:lookup_key)
sorted_lookup_values = lookup_values_for_key.sort_by do |lv|
# splitting the matcher hostgroup=example to 'hostgroup' and 'example'
matcher_element, matcher_value = lv.match.split(LookupKey::EQ_DELM)
matcher_key = ''
matcher_value = ''
lv.match.split(LookupKey::KEY_DELM).each do |match_key|
element = match_key.split(LookupKey::EQ_DELM).first
matcher_key += element + ','
if element == 'hostgroup'
matcher_value = match_key.split(LookupKey::EQ_DELM).last
end
end
# prefer matchers in order of the path, then more specific matches (i.e. hostgroup children)
[key.path.index(matcher_element), -1 * matcher_value.length]
[key.path.index(matcher_key.chomp(',')), -1 * matcher_value.length]
end
value = nil
if key.merge_overrides
......
Rails.logger.warn "Unable to type cast #{value} to #{key.key_type}"
end
def get_element_and_element_name(lookup_value)
element = ''
element_name = ''
lookup_value.match.split(LookupKey::KEY_DELM).each do |match_key|
lv_element, lv_element_name = match_key.split(LookupKey::EQ_DELM)
element += lv_element + ','
element_name += lv_element_name + ','
end
[element.chomp(','), element_name.chomp(',')]
end
def update_generic_matcher(lookup_values, options)
computed_lookup_value = nil
lookup_values.each do |lookup_value|
element, element_name = lookup_value.match.split(LookupKey::EQ_DELM)
element, element_name = get_element_and_element_name(lookup_value)
next if (options[:skip_fqdn] && element=="fqdn")
value_method = %w(yaml json).include?(lookup_value.lookup_key.key_type) ? :value_before_type_cast : :value
computed_lookup_value = {:value => lookup_value.send(value_method), :element => element,
......
element_names = []
lookup_values.each do |lookup_value|
element, element_name = lookup_value.match.split(LookupKey::EQ_DELM)
element, element_name = get_element_and_element_name(lookup_value)
next if (options[:skip_fqdn] && element=="fqdn")
elements << element
element_names << element_name
......
# to make sure seep merge overrides by priority, putting in the values with the lower priority first
# and then merging with higher priority
lookup_values.reverse.each do |lookup_value|
element, element_name = lookup_value.match.split(LookupKey::EQ_DELM)
element, element_name = get_element_and_element_name(lookup_value)
next if (options[:skip_fqdn] && element=="fqdn")
elements << element
element_names << element_name
test/unit/classification_test.rb
assert_equal 'child', enc["apache"][key.key]
end
test 'enc should return correct values for multi-key matchers' do
key = FactoryGirl.create(:lookup_key, :as_smart_class_param,
:override => true, :key_type => 'string', :default_value => '',
:path => "organization\norganization,location\nlocation",
:puppetclass => puppetclasses(:one))
as_admin do
LookupValue.create! :lookup_key_id => key.id,
:match => "location=#{taxonomies(:location1)}",
:value => 'test_incorrect',
:use_puppet_default => false
end
value2 = as_admin do
LookupValue.create! :lookup_key_id => key.id,
:match => "organization=#{taxonomies(:organization1)},location=#{taxonomies(:location1)}",
:value => 'test_correct',
:use_puppet_default => false
end
enc = classification.enc
key.reload
assert_equal value2.value, enc["base"][key.key]
end
test 'enc should return correct values for multi-key matchers' do
key = FactoryGirl.create(:lookup_key, :as_smart_class_param, :use_puppet_default => true,
:override => true, :key_type => 'string', :merge_overrides => false,
:path => "hostgroup,organization\nlocation",
:puppetclass => puppetclasses(:two))
parent_hostgroup = FactoryGirl.create(:hostgroup,
:puppetclasses => [puppetclasses(:two)],
:environment => environments(:production))
child_hostgroup = FactoryGirl.create(:hostgroup, :parent => parent_hostgroup)
host = @classification.send(:host)
host.hostgroup = child_hostgroup
host.save
as_admin do
LookupValue.create! :lookup_key_id => key.id,
:match => "hostgroup=#{parent_hostgroup},organization=#{taxonomies(:organization1)}",
:value => "parent",
:use_puppet_default => false
end
as_admin do
LookupValue.create! :lookup_key_id => key.id,
:match => "hostgroup=#{child_hostgroup},organization=#{taxonomies(:organization1)}",
:value => "child",
:use_puppet_default => false
end
as_admin do
LookupValue.create! :lookup_key_id => key.id,
:match =>"location=#{taxonomies(:location1)}",
:value => "loc",
:use_puppet_default => false
end
enc = classification.enc
key.reload
assert_equal 'child', enc["apache"][key.key]
end
test 'smart class parameter should accept string with erb for arrays and evaluate it properly' do
key = FactoryGirl.create(:lookup_key, :as_smart_class_param,
:override => true, :key_type => 'array', :merge_overrides => false,
......
assert_equal({key.id => {key.key => {:value => '<%= [3,4] %>',
:element => 'organization',
:element_name => 'Organization 1'}}},
classification.send(:values_hash))
classification.send(:values_hash))
assert_equal [3,4], classification.enc['base'][key.key]
end

Also available in: Unified diff