Revision 8347a5ef
Added by Ori Rabin over 8 years ago
app/assets/javascripts/lookup_keys.js | ||
---|---|---|
var fields = reloadedItem.closest('.fields');
|
||
var mergeOverrides = fields.find("[id$='_merge_overrides']");
|
||
var avoidDuplicates = fields.find("[id$='_avoid_duplicates']");
|
||
var overrideMergeDiv = fields.find("[id$='lookup_key_override_merge']");
|
||
var mergeDefault = fields.find("[id$='_merge_default']");
|
||
var validators = fields.find("[id^='optional_input_validators']");
|
||
|
||
changeCheckboxEnabledStatus(mergeOverrides, keyType == 'array' || keyType == 'hash');
|
||
changeCheckboxEnabledStatus(avoidDuplicates, keyType == 'array' && $(mergeOverrides).attr('checked') == 'checked');
|
||
overrideMergeDiv.toggle(keyType == 'array' || keyType == 'hash');
|
||
var mergeOverrideChecked = $(mergeOverrides).attr('checked') == 'checked';
|
||
changeCheckboxEnabledStatus(avoidDuplicates, keyType == 'array' && mergeOverrideChecked);
|
||
changeCheckboxEnabledStatus(mergeDefault, mergeOverrideChecked);
|
||
validators.collapse('show');
|
||
validators.parent().find('legend').removeClass('collapsed');
|
||
}
|
||
... | ... | |
var fields = $(item).closest('.fields');
|
||
var keyType = fields.find("[id$='_key_type']").val();
|
||
var avoidDuplicates = fields.find("[id$='_avoid_duplicates']");
|
||
var mergeDefault = fields.find("[id$='_merge_default']");
|
||
changeCheckboxEnabledStatus(avoidDuplicates, keyType == 'array' && item.checked);
|
||
changeCheckboxEnabledStatus(mergeDefault, item.checked);
|
||
}
|
||
|
||
function toggleUsePuppetDefaultValue(item, value_field) {
|
app/controllers/api/v2/smart_class_parameters_controller.rb | ||
---|---|---|
param :parameter_type, LookupKey::KEY_TYPES, :desc => N_("Types of variable values")
|
||
param :required, :bool, :desc => N_("If true, will raise an error if there is no default value and no matcher provide a value")
|
||
param :merge_overrides, :bool, :desc => N_("Merge all matching values (only array/hash type)")
|
||
param :merge_default, :bool, :desc => N_("Include default value when merging all matching values")
|
||
param :avoid_duplicates, :bool, :desc => N_("Remove duplicate values (only array type)")
|
||
end
|
||
|
app/controllers/api/v2/smart_variables_controller.rb | ||
---|---|---|
param :validator_rule, String, :desc => N_("Used to enforce certain values for the parameter values")
|
||
param :variable_type, LookupKey::KEY_TYPES, :desc => N_("Types of variable values")
|
||
param :merge_overrides, :bool, :desc => N_("Merge all matching values (only array/hash type)")
|
||
param :merge_default, :bool, :desc => N_("Include default value when merging all matching values")
|
||
param :avoid_duplicates, :bool, :desc => N_("Remove duplicate values (only array type)")
|
||
end
|
||
end
|
app/models/lookup_key.rb | ||
---|---|---|
validates :key_type, :inclusion => {:in => KEY_TYPES, :message => N_("invalid")}, :allow_blank => true, :allow_nil => true
|
||
validate :validate_default_value
|
||
validates_associated :lookup_values
|
||
validate :ensure_type, :disable_merge_overrides, :disable_avoid_duplicates
|
||
validate :ensure_type, :disable_merge_overrides, :disable_avoid_duplicates, :disable_merge_default
|
||
|
||
before_save :sanitize_path
|
||
attr_name :key
|
||
... | ... | |
scoped_search :on => :lookup_values_count, :rename => :values_count
|
||
scoped_search :on => :override, :complete_value => {:true => true, :false => false}
|
||
scoped_search :on => :merge_overrides, :complete_value => {:true => true, :false => false}
|
||
scoped_search :on => :merge_default, :complete_value => {:true => true, :false => false}
|
||
scoped_search :on => :avoid_duplicates, :complete_value => {:true => true, :false => false}
|
||
scoped_search :in => :param_classes, :on => :name, :rename => :puppetclass, :complete_value => true
|
||
scoped_search :in => :lookup_values, :on => :value, :rename => :value, :complete_value => true
|
||
... | ... | |
self.errors.add(:avoid_duplicates, _("can only be set for arrays that have merge_overrides set to true"))
|
||
end
|
||
end
|
||
|
||
def disable_merge_default
|
||
if merge_default && !merge_overrides
|
||
self.errors.add(:merge_default, _("can only be set when merge overrides is set"))
|
||
end
|
||
end
|
||
end
|
app/services/classification/base.rb | ||
---|---|---|
end
|
||
value = nil
|
||
if key.merge_overrides
|
||
default = key.merge_default ? key.default_value : nil
|
||
case key.key_type
|
||
when "array"
|
||
value = update_array_matcher(key.avoid_duplicates, sorted_lookup_values, options)
|
||
value = update_array_matcher(default, key.avoid_duplicates, sorted_lookup_values, options)
|
||
when "hash"
|
||
value = update_hash_matcher(sorted_lookup_values, options)
|
||
value = update_hash_matcher(default, sorted_lookup_values, options)
|
||
else
|
||
raise "merging enabled for non mergeable key #{key.key}"
|
||
end
|
||
... | ... | |
computed_lookup_value
|
||
end
|
||
|
||
def update_array_matcher(should_avoid_duplicates, lookup_values, options)
|
||
def update_array_matcher(default, should_avoid_duplicates, lookup_values, options)
|
||
elements = []
|
||
values = []
|
||
element_names = []
|
||
|
||
unless default.nil?
|
||
values += default
|
||
elements << s_("LookupKey|Default value")
|
||
element_names << s_("LookupKey|Default value")
|
||
end
|
||
|
||
lookup_values.each do |lookup_value|
|
||
element, element_name = get_element_and_element_name(lookup_value)
|
||
next if (options[:skip_fqdn] && element=="fqdn")
|
||
... | ... | |
{:value => values, :element => elements, :element_name => element_names}
|
||
end
|
||
|
||
def update_hash_matcher(lookup_values, options)
|
||
def update_hash_matcher(default, lookup_values, options)
|
||
elements = []
|
||
values = {}
|
||
element_names = []
|
||
|
||
unless default.nil?
|
||
values = default
|
||
elements << s_("LookupKey|Default value")
|
||
element_names << s_("LookupKey|Default value")
|
||
end
|
||
|
||
# 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|
|
app/views/api/v2/smart_class_parameters/main.json.rabl | ||
---|---|---|
extends "api/v2/smart_class_parameters/base"
|
||
|
||
attributes :description, :override, :parameter_type, :default_value, :use_puppet_default, :required, :validator_type, :validator_rule,
|
||
:merge_overrides, :avoid_duplicates, :override_value_order, :override_values_count, :created_at, :updated_at
|
||
:merge_overrides, :merge_default, :avoid_duplicates, :override_value_order, :override_values_count, :created_at, :updated_at
|
app/views/api/v2/smart_variables/main.json.rabl | ||
---|---|---|
extends "api/v2/smart_variables/base"
|
||
|
||
attributes :description, :parameter_type, :default_value, :validator_type, :validator_rule,
|
||
:override_value_order, :override_values_count, :merge_overrides, :avoid_duplicates,
|
||
:override_value_order, :override_values_count, :merge_overrides, :merge_default, :avoid_duplicates,
|
||
:puppetclass_id, :puppetclass_name, :created_at, :updated_at
|
app/views/lookup_keys/_fields.html.erb | ||
---|---|---|
<%= checkbox_f(f, :override, :onchange => 'toggleOverrideValue(this)', :size => "col-md-8",
|
||
:help_inline => popover('', _('Whether the class parameter value is managed by Foreman.'))
|
||
) if is_param %>
|
||
|
||
<%= param_type_selector(f, :onchange => 'keyTypeChange(this)') %>
|
||
<%= textarea_f f, :default_value, :value => f.object.default_value_before_type_cast, :size => "col-md-8",
|
||
:disabled => (f.object.is_param && (!f.object.override || f.object.use_puppet_default)),
|
||
... | ... | |
<%= checkbox_f(f, :merge_overrides, :onchange => 'mergeOverridesChanged(this)', :table_field => true,
|
||
:disabled => !f.object.supports_merge?, :size => "col-md-1", :label_size => "col-md-3",
|
||
:help_inline => popover("", _("Continue to look for matches after first find (only array/hash type)? Note: merging overrides ignores all matchers that use Puppet default."))) %>
|
||
<%= checkbox_f(f, :merge_default, :disabled => !f.object.merge_overrides, :size => "col-md-1", :table_field => true,
|
||
:label_size => "col-md-3", :help_inline => popover('',_("Include default value when merging all matching values."))) %>
|
||
<%= checkbox_f(f, :avoid_duplicates, :disabled => (!f.object.supports_uniq? || !f.object.merge_overrides),
|
||
:size => "col-md-1", :label_size => "col-md-4", :table_field => true,
|
||
:size => "col-md-1", :label_size => "col-md-3", :table_field => true,
|
||
:help_inline => popover("", _("Avoid duplicate values when merging them (only array type)?"))) %>
|
||
</fieldset>
|
||
</br>
|
db/migrate/20150811170401_add_merge_default_to_lookup_key.rb | ||
---|---|---|
class AddMergeDefaultToLookupKey < ActiveRecord::Migration
|
||
def change
|
||
add_column :lookup_keys, :merge_default, :boolean, :null => false, :default => false
|
||
end
|
||
end
|
test/unit/classification_test.rb | ||
---|---|---|
:match => "location=#{taxonomies(:location1)}",
|
||
:value => {:example => {:a => 'test'}},
|
||
:use_puppet_default => false
|
||
end
|
||
as_admin do
|
||
LookupValue.create! :lookup_key_id => key.id,
|
||
:match => "organization=#{taxonomies(:organization1)}",
|
||
:value => {:example => {:b => 'test2'}},
|
||
:use_puppet_default => false
|
||
end
|
||
as_admin do
|
||
LookupValue.create! :lookup_key_id => key.id,
|
||
:match => "os=#{operatingsystems(:redhat)}",
|
||
:value => {:example => {:a => 'test3'}},
|
||
... | ... | |
global_param_classification.send(:values_hash))
|
||
end
|
||
|
||
test 'smart variable of hash without merge_default should not merge with default value' do
|
||
key = FactoryGirl.create(:lookup_key, :key_type => 'hash', :merge_overrides => true,
|
||
:default_value => {:default => 'example'}, :path => "organization\nos\nlocation",
|
||
:puppetclass => puppetclasses(:one))
|
||
|
||
as_admin do
|
||
LookupValue.create! :lookup_key_id => key.id,
|
||
:match => "organization=#{taxonomies(:organization1)}",
|
||
:value => {:a => 'test2'},
|
||
:use_puppet_default => false
|
||
end
|
||
key.reload
|
||
|
||
assert_equal({key.id => {key.key => {:value => {:a => 'test2' },
|
||
:element => ['organization'],
|
||
:element_name => ['Organization 1']}}},
|
||
global_param_classification.send(:values_hash))
|
||
end
|
||
|
||
test 'smart class parameter of hash with merge_overrides and merge_default should return merge all values' do
|
||
key = FactoryGirl.create(:lookup_key, :as_smart_class_param,
|
||
:override => true, :key_type => 'hash', :merge_overrides => true, :merge_default => true,
|
||
:default_value => { :default => 'default' }, :path => "organization\nlocation",
|
||
:puppetclass => puppetclasses(:one))
|
||
|
||
as_admin do
|
||
LookupValue.create! :lookup_key_id => key.id,
|
||
:match => "location=#{taxonomies(:location1)}",
|
||
:value => {:example => {:a => 'test'}},
|
||
:use_puppet_default => false
|
||
LookupValue.create! :lookup_key_id => key.id,
|
||
:match => "organization=#{taxonomies(:organization1)}",
|
||
:value => {:example => {:b => 'test2'}},
|
||
:use_puppet_default => false
|
||
end
|
||
key.reload
|
||
|
||
assert_equal({key.id => {key.key => {:value => {:default => 'default', :example => {:a => 'test', :b => 'test2'}},
|
||
:element => ['Default value', 'location', 'organization'],
|
||
:element_name => ['Default value', 'Location 1', 'Organization 1']}}},
|
||
classification.send(:values_hash))
|
||
end
|
||
|
||
test "#enc should not return class parameters when default value should use puppet default" do
|
||
lkey = FactoryGirl.create(:lookup_key, :as_smart_class_param, :with_override, :with_use_puppet_default,
|
||
:puppetclass => puppetclasses(:one))
|
test/unit/lookup_key_test.rb | ||
---|---|---|
assert_valid key
|
||
end
|
||
|
||
test "should be able to merge overrides with default_value for a hash" do
|
||
key = FactoryGirl.build(:lookup_key, :as_smart_class_param,
|
||
:override => true, :key_type => 'hash', :merge_overrides => true, :merge_default => true,
|
||
:default_value => {}, :puppetclass => puppetclasses(:one))
|
||
assert_valid key
|
||
end
|
||
|
||
test "should not be able to merge default when merge_override is false" do
|
||
key = FactoryGirl.build(:lookup_key, :as_smart_class_param,
|
||
:override => true, :key_type => 'hash', :merge_overrides => false, :merge_default => true,
|
||
:default_value => {}, :puppetclass => puppetclasses(:one))
|
||
refute_valid key
|
||
assert_equal "can only be set when merge overrides is set", key.errors[:merge_default].first
|
||
end
|
||
|
||
test "should not be able to avoid duplicates for a hash" do
|
||
key = FactoryGirl.build(:lookup_key, :as_smart_class_param,
|
||
:override => true, :key_type => 'hash', :merge_overrides => true, :avoid_duplicates => true,
|
Also available in: Unified diff
Fixes #10731 - Allow matches to merge with default values