Revision 6b4b489f
Added by Ori Rabin over 8 years ago
app/controllers/api/v1/lookup_keys_controller.rb | ||
---|---|---|
param :per_page, String, :desc => "number of entries per request"
|
||
|
||
def index
|
||
@lookup_keys = LookupKey.
|
||
authorized(:view_external_variables).
|
||
search_for(*search_options).paginate(paginate_options)
|
||
@lookup_keys = PuppetclassLookupKey.authorized(:view_external_variables).
|
||
search_for(*search_options).paginate(paginate_options).to_a +
|
||
VariableLookupKey.authorized(:view_external_variables).
|
||
search_for(*search_options).paginate(paginate_options).to_a
|
||
end
|
||
|
||
api :GET, "/lookup_keys/:id/", "Show a lookup key."
|
app/controllers/concerns/api/v2/lookup_keys_common_controller.rb | ||
---|---|---|
|
||
def find_smart_variable
|
||
id = params.keys.include?('smart_variable_id') ? params['smart_variable_id'] : params['id']
|
||
@smart_variable = LookupKey.authorized(:view_external_variables).smart_variables.find_by_id(id.to_i) if id.to_i > 0
|
||
@smart_variable = VariableLookupKey.authorized(:view_external_variables).smart_variables.find_by_id(id.to_i) if id.to_i > 0
|
||
@smart_variable ||= (puppet_cond = { :puppetclass_id => @puppetclass.id } if @puppetclass
|
||
LookupKey.authorized(:view_external_variables).smart_variables.where(puppet_cond).find_by_key(id)
|
||
VariableLookupKey.authorized(:view_external_variables).smart_variables.where(puppet_cond).find_by_key(id)
|
||
)
|
||
@smart_variable
|
||
end
|
||
... | ... | |
end
|
||
|
||
def smart_variables_resource_scope
|
||
return LookupKey.authorized(:view_external_variables).smart_variables unless (@puppetclass || @host || @hostgroup)
|
||
return VariableLookupKey.authorized(:view_external_variables).smart_variables unless (@puppetclass || @host || @hostgroup)
|
||
puppetclass_ids = @puppetclass.id if @puppetclass
|
||
puppetclass_ids ||= @hostgroup.all_puppetclasses.map(&:id) if @hostgroup
|
||
puppetclass_ids ||= @host.all_puppetclasses.map(&:id) if @host
|
||
LookupKey.authorized(:view_external_variables).global_parameters_for_class(puppetclass_ids)
|
||
VariableLookupKey.authorized(:view_external_variables).global_parameters_for_class(puppetclass_ids)
|
||
end
|
||
|
||
def find_smart_class_parameter
|
||
id = params.keys.include?('smart_class_parameter_id') ? params['smart_class_parameter_id'] : params['id']
|
||
@smart_class_parameter = LookupKey.authorized(:view_external_variables).smart_class_parameters.find_by_id(id.to_i) if id.to_i > 0
|
||
@smart_class_parameter = PuppetclassLookupKey.authorized(:view_external_variables).smart_class_parameters.find_by_id(id.to_i) if id.to_i > 0
|
||
@smart_class_parameter ||= (puppet_cond = { 'environment_classes.puppetclass_id'=> @puppetclass.id } if @puppetclass
|
||
env_cond = { 'environment_classes.environment_id' => @environment.id } if @environment
|
||
LookupKey.authorized(:view_external_variables).smart_class_parameters.where(puppet_cond).where(env_cond).where(:key => id).first
|
||
PuppetclassLookupKey.authorized(:view_external_variables).smart_class_parameters.where(puppet_cond).where(env_cond).where(:key => id).first
|
||
)
|
||
@smart_class_parameter
|
||
end
|
||
... | ... | |
end
|
||
|
||
def smart_class_parameters_resource_scope
|
||
base = LookupKey.authorized(:view_external_variables)
|
||
base = PuppetclassLookupKey.authorized(:view_external_variables)
|
||
return base.smart_class_parameters unless (@puppetclass || @environment || @host || @hostgroup)
|
||
if @puppetclass && @environment
|
||
base.smart_class_parameters_for_class(@puppetclass.id, @environment.id)
|
app/controllers/lookup_keys_controller.rb | ||
---|---|---|
|
||
def index
|
||
@lookup_keys = resource_base.search_for(params[:search], :order => params[:order])
|
||
.includes(:param_classes)
|
||
.includes(:puppetclass)
|
||
.paginate(:page => params[:page])
|
||
@puppetclass_authorizer = Authorizer.new(User.current, :collection => @lookup_keys.map(&:puppetclass_id).compact.uniq)
|
||
@puppetclass_authorizer = Authorizer.new(User.current, :collection => @lookup_keys.pluck(:puppetclass_id).compact.uniq)
|
||
end
|
||
|
||
def edit
|
||
end
|
||
|
||
def update
|
||
if @lookup_key.update_attributes(params[:lookup_key])
|
||
if resource.update_attributes(params[resource_name])
|
||
process_success
|
||
else
|
||
process_error
|
||
... | ... | |
end
|
||
|
||
def destroy
|
||
if @lookup_key.destroy
|
||
if resource.destroy
|
||
process_success
|
||
else
|
||
process_error
|
app/controllers/puppetclass_lookup_keys_controller.rb | ||
---|---|---|
class PuppetclassLookupKeysController < LookupKeysController
|
||
before_filter :setup_search_options, :only => :index
|
||
|
||
def index
|
||
@lookup_keys = resource_base.search_for(params[:search], :order => params[:order])
|
||
.paginate(:page => params[:page])
|
||
.includes(:param_classes)
|
||
@puppetclass_authorizer = Authorizer.new(User.current, :collection => @lookup_keys.pluck(:puppetclass_id).compact.uniq)
|
||
end
|
||
|
||
def resource
|
||
@puppetclass_lookup_key
|
||
end
|
||
end
|
app/controllers/variable_lookup_keys_controller.rb | ||
---|---|---|
class VariableLookupKeysController < LookupKeysController
|
||
def resource
|
||
@variable_lookup_key
|
||
end
|
||
end
|
app/helpers/hosts_and_hostgroups_helper.rb | ||
---|---|---|
def interesting_klasses(obj)
|
||
classes = obj.all_puppetclasses
|
||
classes_ids = classes.reorder('').pluck('puppetclasses.id')
|
||
smart_vars = LookupKey.reorder('').where(:puppetclass_id => classes_ids).uniq.pluck(:puppetclass_id)
|
||
class_vars = LookupKey.reorder('').joins(:environment_classes).where(:environment_classes => { :puppetclass_id => classes_ids }).uniq.pluck('environment_classes.puppetclass_id')
|
||
smart_vars = VariableLookupKey.reorder('').where(:puppetclass_id => classes_ids).uniq.pluck(:puppetclass_id)
|
||
class_vars = PuppetclassLookupKey.reorder('').joins(:environment_classes).where(:environment_classes => { :puppetclass_id => classes_ids }).uniq.pluck('environment_classes.puppetclass_id')
|
||
klasses = (smart_vars + class_vars).uniq
|
||
|
||
classes.where(:id => klasses)
|
app/helpers/lookup_keys_helper.rb | ||
---|---|---|
# Show the parent puppetclass as a context, but permit no change.
|
||
if params["puppetclass_id"]
|
||
select_f f, :puppetclass_id, [Puppetclass.find(params["puppetclass_id"])], :id, :to_label, {}, {:label => _("Puppet class"), :disabled => true}
|
||
elsif f.object.is_param && f.object.param_class
|
||
elsif f.object.puppet? && f.object.param_class
|
||
field(f, :puppetclass_id, :label => _('Puppet Class')) do
|
||
content_tag(:input, nil, :value => f.object.param_class, :type => 'text', :disabled => true)
|
||
end
|
||
... | ... | |
|
||
def param_type_selector(f, options = {})
|
||
selectable_f f, :key_type, options_for_select(LookupKey::KEY_TYPES.map { |e| [_(e),e] }, f.object.key_type),{},
|
||
options.merge({ :disabled => (f.object.is_param && !f.object.override), :size => "col-md-8", :class=> "without_select2",
|
||
options.merge({ :disabled => (f.object.puppet? && !f.object.override), :size => "col-md-8", :class=> "without_select2",
|
||
:help_inline => popover("",_("<dl>" +
|
||
"<dt>String</dt> <dd>Everything is taken as a string.</dd>" +
|
||
"<dt>Boolean</dt> <dd>Common representation of boolean values are accepted.</dd>" +
|
||
... | ... | |
|
||
def validator_type_selector(f)
|
||
selectable_f f, :validator_type, options_for_select(LookupKey::VALIDATOR_TYPES.map { |e| [_(e),e] }, f.object.validator_type),{:include_blank => _("None")},
|
||
{ :disabled => (f.object.is_param && !f.object.override), :size => "col-md-8", :class=> "without_select2",
|
||
{ :disabled => (f.object.puppet? && !f.object.override), :size => "col-md-8", :class=> "without_select2",
|
||
:onchange => 'validatorTypeSelected(this)',
|
||
:help_inline => popover("",_("<dl>" +
|
||
"<dt>List</dt> <dd>A list of the allowed values, specified in the Validator rule field.</dd>" +
|
app/models/concerns/counter_cache_fix.rb | ||
---|---|---|
if key =~ /_id/
|
||
association = self.association(key.sub(/_id$/, '').to_sym)
|
||
if association.options[ :counter_cache ]
|
||
counter_name = self.class.name.underscore.split("/")[0].pluralize.to_sym
|
||
association.klass.reset_counters(old_value, counter_name) if old_value
|
||
association.klass.reset_counters(new_value, counter_name) if new_value
|
||
|
||
# in case of counter cache on STI, specify the :inverse_of option, otherwise, we might throw an error.
|
||
# i.e. VariableLookupKey belongs to puppetclass, but the association name on the puppetclass is lookup_keys, not puppetclass_lookup_keys
|
||
# thus, we define the correct name for the association to be derived.
|
||
if association.options[:inverse_of].is_a?(Symbol)
|
||
counter_name = association.options[:inverse_of]
|
||
else
|
||
counter_name = self.class.name.underscore.split("/")[0].pluralize.to_sym
|
||
end
|
||
|
||
association_name = counter_name.to_s.sub(/_count$/, "").to_sym
|
||
association.klass.reset_counters(old_value, association_name) if old_value
|
||
association.klass.reset_counters(new_value, association_name) if new_value
|
||
end
|
||
end
|
||
end
|
app/models/environment_class.rb | ||
---|---|---|
class EnvironmentClass < ActiveRecord::Base
|
||
belongs_to :environment
|
||
belongs_to :puppetclass
|
||
belongs_to :lookup_key
|
||
validates :lookup_key_id, :uniqueness => {:scope => [:environment_id, :puppetclass_id]}
|
||
belongs_to :puppetclass_lookup_key
|
||
validates :puppetclass_lookup_key_id, :uniqueness => {:scope => [:environment_id, :puppetclass_id]}
|
||
validates :puppetclass_id, :environment_id, :presence => true
|
||
|
||
scope :parameters_for_class, lambda {|puppetclasses_ids, environment_id|
|
||
all_parameters_for_class(puppetclasses_ids, environment_id).where(:lookup_keys => {:override => true})
|
||
all_parameters_for_class(puppetclasses_ids, environment_id).where(:puppetclass_lookup_keys => {:override => true})
|
||
}
|
||
|
||
scope :all_parameters_for_class, lambda {|puppetclasses_ids, environment_id|
|
||
where(:puppetclass_id => puppetclasses_ids, :environment_id => environment_id).
|
||
where('lookup_key_id is NOT NULL').
|
||
includes(:lookup_key)
|
||
where('puppetclass_lookup_key_id is NOT NULL').
|
||
includes(:puppetclass_lookup_key)
|
||
}
|
||
|
||
scope :used_by_other_environment_classes, lambda{|lookup_key_id, this_environment_class_id|
|
||
where(:lookup_key_id => lookup_key_id).
|
||
scope :used_by_other_environment_classes, lambda{|puppetclass_lookup_key_id, this_environment_class_id|
|
||
where(:puppetclass_lookup_key_id => puppetclass_lookup_key_id).
|
||
where("id != #{this_environment_class_id}")
|
||
}
|
||
|
||
# These counters key track of unique puppet class keys (parameters) across environments
|
||
after_create do |record|
|
||
Puppetclass.increment_counter(:global_class_params_count, self.puppetclass.id) unless self.lookup_key.blank? ||
|
||
EnvironmentClass.used_by_other_environment_classes(self.lookup_key, self.id).count > 0
|
||
Puppetclass.increment_counter(:global_class_params_count, self.puppetclass.id) unless self.puppetclass_lookup_key.blank? ||
|
||
EnvironmentClass.used_by_other_environment_classes(self.puppetclass_lookup_key, self.id).count > 0
|
||
end
|
||
|
||
after_destroy do |record|
|
||
Puppetclass.decrement_counter(:global_class_params_count, self.puppetclass.id) unless self.lookup_key.blank? ||
|
||
EnvironmentClass.used_by_other_environment_classes(self.lookup_key, self.id).count > 0
|
||
Puppetclass.decrement_counter(:global_class_params_count, self.puppetclass.id) unless self.puppetclass_lookup_key.blank? ||
|
||
EnvironmentClass.used_by_other_environment_classes(self.puppetclass_lookup_key, self.id).count > 0
|
||
end
|
||
|
||
def lookup_key_id=(val)
|
||
Foreman::Deprecation.deprecation_warning("1.12", "lookup_key_id= is deprecated, please use puppetclass_lookup_key_id= instead.")
|
||
self.puppetclass_lookup_key_id=val
|
||
end
|
||
|
||
def lookup_key=(val)
|
||
Foreman::Deprecation.deprecation_warning("1.12", "lookup_key= is deprecated, please use puppetclass_lookup_key= instead.")
|
||
self.puppetclass_lookup_key=val
|
||
end
|
||
|
||
#TODO move these into scopes?
|
||
def self.is_in_any_environment(puppetclass, lookup_key)
|
||
EnvironmentClass.where(:puppetclass_id => puppetclass, :lookup_key_id => lookup_key ).count > 0
|
||
def self.is_in_any_environment(puppetclass, puppetclass_lookup_key)
|
||
EnvironmentClass.where(:puppetclass_id => puppetclass, :puppetclass_lookup_key_id => puppetclass_lookup_key ).count > 0
|
||
end
|
||
|
||
def self.key_in_environment(env, puppetclass, lookup_key)
|
||
EnvironmentClass.where(:environment_id => env, :puppetclass_id => puppetclass, :lookup_key_id => lookup_key ).first
|
||
def self.key_in_environment(env, puppetclass, puppetclass_lookup_key)
|
||
EnvironmentClass.where(:environment_id => env, :puppetclass_id => puppetclass, :puppetclass_lookup_key_id => puppetclass_lookup_key ).first
|
||
end
|
||
end
|
app/models/lookup_key.rb | ||
---|---|---|
class LookupKey < ActiveRecord::Base
|
||
include Authorizable
|
||
include CounterCacheFix
|
||
|
||
KEY_TYPES = [N_("string"), N_("boolean"), N_("integer"), N_("real"), N_("array"), N_("hash"), N_("yaml"), N_("json")]
|
||
VALIDATOR_TYPES = [N_("regexp"), N_("list") ]
|
||
|
||
KEY_DELM = ","
|
||
EQ_DELM = "="
|
||
VALUE_REGEX =/\A[^#{KEY_DELM}]+#{EQ_DELM}[^#{KEY_DELM}]+(#{KEY_DELM}[^#{KEY_DELM}]+#{EQ_DELM}[^#{KEY_DELM}]+)*\Z/
|
||
|
||
audited :associated_with => :audit_class, :allow_mass_assignment => true, :except => :lookup_values_count
|
||
validates_lengths_from_database
|
||
|
||
serialize :default_value
|
||
|
||
belongs_to :puppetclass, :inverse_of => :lookup_keys, :counter_cache => true
|
||
has_many :environment_classes, :dependent => :destroy
|
||
has_many :environments, :through => :environment_classes, :uniq => true
|
||
has_many :param_classes, :through => :environment_classes, :source => :puppetclass
|
||
def param_class
|
||
param_classes.first
|
||
end
|
||
|
||
def audit_class
|
||
param_class || puppetclass
|
||
end
|
||
|
||
has_many :lookup_values, :dependent => :destroy, :inverse_of => :lookup_key
|
||
accepts_nested_attributes_for :lookup_values,
|
||
:reject_if => :reject_invalid_lookup_values,
|
||
:allow_destroy => true
|
||
|
||
before_validation :cast_default_value, :unless => Proc.new{|p| p.use_puppet_default }
|
||
validates :key, :uniqueness => {:scope => :is_param }, :unless => Proc.new{|p| p.is_param?}
|
||
|
||
validates :key, :presence => true
|
||
validates :puppetclass, :presence => true, :unless => Proc.new {|k| k.is_param?}
|
||
validates :validator_type, :inclusion => { :in => VALIDATOR_TYPES, :message => N_("invalid")}, :allow_blank => true, :allow_nil => true
|
||
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, :disable_merge_default
|
||
|
||
before_save :sanitize_path
|
||
attr_name :key
|
||
|
||
scoped_search :on => :key, :complete_value => true, :default_order => true
|
||
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
|
||
|
||
default_scope -> { order('lookup_keys.key') }
|
||
|
||
scope :override, -> { where(:override => true) }
|
||
|
||
scope :smart_class_parameters_for_class, lambda { |puppetclass_ids, environment_id|
|
||
joins(:environment_classes).where(:environment_classes => {:puppetclass_id => puppetclass_ids, :environment_id => environment_id})
|
||
}
|
||
|
||
scope :parameters_for_class, lambda { |puppetclass_ids, environment_id|
|
||
override.smart_class_parameters_for_class(puppetclass_ids,environment_id)
|
||
}
|
||
|
||
scope :global_parameters_for_class, lambda { |puppetclass_ids|
|
||
where(:puppetclass_id => puppetclass_ids)
|
||
}
|
||
|
||
scope :smart_variables, -> { where('lookup_keys.puppetclass_id > 0').readonly(false) }
|
||
scope :smart_class_parameters, -> { where(:is_param => true).joins(:environment_classes).readonly(false) }
|
||
|
||
# new methods for API instead of revealing db names
|
||
alias_attribute :parameter, :key
|
||
alias_attribute :variable, :key
|
||
alias_attribute :parameter_type, :key_type
|
||
alias_attribute :variable_type, :key_type
|
||
alias_attribute :override_value_order, :path
|
||
alias_attribute :override_values_count, :lookup_values_count
|
||
alias_attribute :override_values, :lookup_values
|
||
alias_attribute :override_value_ids, :lookup_value_ids
|
||
|
||
# to prevent errors caused by find_resource from override_values controller
|
||
def self.find_by_name(str)
|
||
nil
|
||
end
|
||
|
||
def to_label
|
||
"#{audit_class}::#{key}"
|
||
end
|
||
|
||
def is_smart_variable?
|
||
puppetclass_id.to_i > 0
|
||
end
|
||
|
||
def is_smart_class_parameter?
|
||
is_param? && environment_classes.any?
|
||
end
|
||
|
||
def supports_merge?
|
||
['array', 'hash'].include?(key_type)
|
||
end
|
||
|
||
def supports_uniq?
|
||
key_type == 'array'
|
||
end
|
||
|
||
def to_param
|
||
Parameterizable.parameterize("#{id}-#{key}")
|
||
end
|
||
|
||
def to_s
|
||
key
|
||
end
|
||
|
||
def path
|
||
path = read_attribute(:path)
|
||
path.blank? ? array2path(Setting["Default_variables_Lookup_Path"]) : path
|
||
end
|
||
|
||
def path=(v)
|
||
return unless v
|
||
using_default = v.tr("\r","") == array2path(Setting["Default_variables_Lookup_Path"])
|
||
write_attribute(:path, using_default ? nil : v)
|
||
end
|
||
|
||
def reject_invalid_lookup_values(attributes)
|
||
attributes[:match].empty? ||
|
||
(attributes[:value].blank? &&
|
||
(attributes[:use_puppet_default].nil? || attributes[:use_puppet_default] == "0"))
|
||
end
|
||
|
||
def default_value_before_type_cast
|
||
value_before_type_cast default_value
|
||
end
|
||
|
||
def value_before_type_cast(val)
|
||
case key_type.to_sym
|
||
when :json, :array
|
||
begin
|
||
val = JSON.dump(val)
|
||
rescue JSON::GeneratorError => error
|
||
## http://projects.theforeman.org/issues/9553
|
||
## @TODO: remove when upgrading to json >= 1.8
|
||
logger.debug "Fallback to quirks mode from error: '#{error}'"
|
||
val = JSON.dump_in_quirks_mode(val)
|
||
end
|
||
when :yaml, :hash
|
||
val = YAML.dump val
|
||
val.sub!(/\A---\s*$\n/, '')
|
||
end unless key_type.blank?
|
||
val
|
||
end
|
||
|
||
def path_elements
|
||
path.split.map do |paths|
|
||
paths.split(KEY_DELM).map do |element|
|
||
element
|
||
end
|
||
end
|
||
end
|
||
|
||
def contains_erb?(value)
|
||
value =~ /<%.*%>/
|
||
end
|
||
|
||
def overridden?(host)
|
||
return false unless host.is_a?(Host::Base) || host.is_a?(Hostgroup)
|
||
lookup_values.find_by_match(host.send(:lookup_value_match)).present?
|
||
end
|
||
|
||
private
|
||
|
||
# Generate possible lookup values type matches to a given host
|
||
def path2matches(host)
|
||
raise ::Foreman::Exception.new(N_("Invalid Host")) unless host.class.model_name == "Host"
|
||
matches = []
|
||
path_elements.each do |rule|
|
||
match = []
|
||
rule.each do |element|
|
||
match << "#{element}#{EQ_DELM}#{attr_to_value(host,element)}"
|
||
end
|
||
matches << match.join(KEY_DELM)
|
||
end
|
||
matches
|
||
end
|
||
|
||
# translates an element such as domain to its real value per host
|
||
# tries to find the host attribute first, parameters and then fallback to a puppet fact.
|
||
def attr_to_value(host, element)
|
||
# direct host attribute
|
||
return host.send(element) if host.respond_to?(element)
|
||
# host parameter
|
||
return host.host_params[element] if host.host_params.include?(element)
|
||
# fact attribute
|
||
if (fn = host.fact_names.first(:conditions => { :name => element }))
|
||
return FactValue.where(:host_id => host.id, :fact_name_id => fn.id).first.value
|
||
end
|
||
end
|
||
|
||
def sanitize_path
|
||
self.path = path.tr("\s","").downcase unless path.blank?
|
||
end
|
||
|
||
def array2path(array)
|
||
raise ::Foreman::Exception.new(N_("invalid path")) unless array.is_a?(Array)
|
||
array.map do |sub_array|
|
||
sub_array.is_a?(Array) ? sub_array.join(KEY_DELM) : sub_array
|
||
end.join("\n")
|
||
end
|
||
|
||
def cast_default_value
|
||
return true if default_value.nil? || contains_erb?(default_value)
|
||
begin
|
||
Foreman::Parameters::Caster.new(self, :attribute_name => :default_value, :to => key_type).cast!
|
||
true
|
||
rescue
|
||
errors.add(:default_value, _("is invalid"))
|
||
false
|
||
end
|
||
end
|
||
|
||
def load_yaml_or_json(value)
|
||
return value unless value.is_a? String
|
||
begin
|
||
JSON.load value
|
||
rescue
|
||
YAML.load value
|
||
end
|
||
end
|
||
|
||
def ensure_type
|
||
if puppetclass_id.present? and is_param?
|
||
self.errors.add(:base, _('Global variable or class Parameter, not both'))
|
||
end
|
||
end
|
||
|
||
def validate_default_value
|
||
Foreman::Parameters::Validator.new(self,
|
||
:type => validator_type,
|
||
:validate_with => validator_rule,
|
||
:getter => :default_value).validate!
|
||
end
|
||
|
||
def disable_merge_overrides
|
||
if merge_overrides && !supports_merge?
|
||
self.errors.add(:merge_overrides, _("can only be set for array or hash"))
|
||
end
|
||
end
|
||
|
||
def disable_avoid_duplicates
|
||
if avoid_duplicates && (!merge_overrides || !supports_uniq?)
|
||
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/models/lookup_keys/lookup_key.rb | ||
---|---|---|
class LookupKey < ActiveRecord::Base
|
||
include Authorizable
|
||
include CounterCacheFix
|
||
|
||
KEY_TYPES = [N_("string"), N_("boolean"), N_("integer"), N_("real"), N_("array"), N_("hash"), N_("yaml"), N_("json")]
|
||
VALIDATOR_TYPES = [N_("regexp"), N_("list") ]
|
||
|
||
KEY_DELM = ","
|
||
EQ_DELM = "="
|
||
VALUE_REGEX =/\A[^#{KEY_DELM}]+#{EQ_DELM}[^#{KEY_DELM}]+(#{KEY_DELM}[^#{KEY_DELM}]+#{EQ_DELM}[^#{KEY_DELM}]+)*\Z/
|
||
|
||
audited :associated_with => :audit_class, :allow_mass_assignment => true, :except => :lookup_values_count
|
||
validates_lengths_from_database
|
||
|
||
serialize :default_value
|
||
|
||
has_many :lookup_values, :dependent => :destroy, :inverse_of => :lookup_key
|
||
accepts_nested_attributes_for :lookup_values,
|
||
:reject_if => :reject_invalid_lookup_values,
|
||
:allow_destroy => true
|
||
|
||
before_validation :cast_default_value
|
||
|
||
validates :key, :presence => true
|
||
validates :validator_type, :inclusion => { :in => VALIDATOR_TYPES, :message => N_("invalid")}, :allow_blank => true, :allow_nil => true
|
||
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 :disable_merge_overrides, :disable_avoid_duplicates, :disable_merge_default
|
||
|
||
before_save :sanitize_path
|
||
attr_name :key
|
||
|
||
def self.inherited(child)
|
||
child.instance_eval do
|
||
scoped_search :on => :key, :complete_value => true, :default_order => true
|
||
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 => :lookup_values, :on => :value, :rename => :value, :complete_value => true
|
||
end
|
||
end
|
||
|
||
default_scope -> { order('lookup_keys.key') }
|
||
|
||
scope :override, -> { where(:override => true) }
|
||
|
||
# new methods for API instead of revealing db names
|
||
alias_attribute :parameter, :key
|
||
alias_attribute :variable, :key
|
||
alias_attribute :parameter_type, :key_type
|
||
alias_attribute :variable_type, :key_type
|
||
alias_attribute :override_value_order, :path
|
||
alias_attribute :override_values_count, :lookup_values_count
|
||
alias_attribute :override_values, :lookup_values
|
||
alias_attribute :override_value_ids, :lookup_value_ids
|
||
|
||
# to prevent errors caused by find_resource from override_values controller
|
||
def self.find_by_name(str)
|
||
nil
|
||
end
|
||
|
||
def audit_class
|
||
self
|
||
end
|
||
|
||
def to_label
|
||
"#{audit_class}::#{key}"
|
||
end
|
||
|
||
def supports_merge?
|
||
['array', 'hash'].include?(key_type)
|
||
end
|
||
|
||
def supports_uniq?
|
||
key_type == 'array'
|
||
end
|
||
|
||
def to_param
|
||
Parameterizable.parameterize("#{id}-#{key}")
|
||
end
|
||
|
||
def to_s
|
||
key
|
||
end
|
||
|
||
def path
|
||
path = read_attribute(:path)
|
||
path.blank? ? array2path(Setting["Default_variables_Lookup_Path"]) : path
|
||
end
|
||
|
||
def path=(v)
|
||
return unless v
|
||
using_default = v.tr("\r","") == array2path(Setting["Default_variables_Lookup_Path"])
|
||
write_attribute(:path, using_default ? nil : v)
|
||
end
|
||
|
||
def reject_invalid_lookup_values(attributes)
|
||
attributes[:match].empty? ||
|
||
(attributes[:value].blank? &&
|
||
(attributes[:use_puppet_default].nil? || attributes[:use_puppet_default] == "0"))
|
||
end
|
||
|
||
def default_value_before_type_cast
|
||
value_before_type_cast default_value
|
||
end
|
||
|
||
def value_before_type_cast(val)
|
||
case key_type.to_sym
|
||
when :json, :array
|
||
begin
|
||
val = JSON.dump(val)
|
||
rescue JSON::GeneratorError => error
|
||
## http://projects.theforeman.org/issues/9553
|
||
## @TODO: remove when upgrading to json >= 1.8
|
||
logger.debug "Fallback to quirks mode from error: '#{error}'"
|
||
val = JSON.dump_in_quirks_mode(val)
|
||
end
|
||
when :yaml, :hash
|
||
val = YAML.dump val
|
||
val.sub!(/\A---\s*$\n/, '')
|
||
end unless key_type.blank?
|
||
val
|
||
end
|
||
|
||
def path_elements
|
||
path.split.map do |paths|
|
||
paths.split(KEY_DELM).map do |element|
|
||
element
|
||
end
|
||
end
|
||
end
|
||
|
||
def contains_erb?(value)
|
||
value =~ /<%.*%>/
|
||
end
|
||
|
||
def overridden?(host)
|
||
return false unless host.is_a?(Host::Base) || host.is_a?(Hostgroup)
|
||
lookup_values.find_by_match(host.send(:lookup_value_match)).present?
|
||
end
|
||
|
||
def puppet?
|
||
false
|
||
end
|
||
|
||
private
|
||
|
||
# Generate possible lookup values type matches to a given host
|
||
def path2matches(host)
|
||
raise ::Foreman::Exception.new(N_("Invalid Host")) unless host.class.model_name == "Host"
|
||
matches = []
|
||
path_elements.each do |rule|
|
||
match = []
|
||
rule.each do |element|
|
||
match << "#{element}#{EQ_DELM}#{attr_to_value(host,element)}"
|
||
end
|
||
matches << match.join(KEY_DELM)
|
||
end
|
||
matches
|
||
end
|
||
|
||
# translates an element such as domain to its real value per host
|
||
# tries to find the host attribute first, parameters and then fallback to a puppet fact.
|
||
def attr_to_value(host, element)
|
||
# direct host attribute
|
||
return host.send(element) if host.respond_to?(element)
|
||
# host parameter
|
||
return host.host_params[element] if host.host_params.include?(element)
|
||
# fact attribute
|
||
if (fn = host.fact_names.first(:conditions => { :name => element }))
|
||
return FactValue.where(:host_id => host.id, :fact_name_id => fn.id).first.value
|
||
end
|
||
end
|
||
|
||
def sanitize_path
|
||
self.path = path.tr("\s","").downcase unless path.blank?
|
||
end
|
||
|
||
def array2path(array)
|
||
raise ::Foreman::Exception.new(N_("invalid path")) unless array.is_a?(Array)
|
||
array.map do |sub_array|
|
||
sub_array.is_a?(Array) ? sub_array.join(KEY_DELM) : sub_array
|
||
end.join("\n")
|
||
end
|
||
|
||
def cast_default_value
|
||
return true if default_value.nil? || contains_erb?(default_value)
|
||
begin
|
||
Foreman::Parameters::Caster.new(self, :attribute_name => :default_value, :to => key_type).cast!
|
||
true
|
||
rescue
|
||
errors.add(:default_value, _("is invalid"))
|
||
false
|
||
end
|
||
end
|
||
|
||
def load_yaml_or_json(value)
|
||
return value unless value.is_a? String
|
||
begin
|
||
JSON.load value
|
||
rescue
|
||
YAML.load value
|
||
end
|
||
end
|
||
|
||
def validate_default_value
|
||
Foreman::Parameters::Validator.new(self,
|
||
:type => validator_type,
|
||
:validate_with => validator_rule,
|
||
:getter => :default_value).validate!
|
||
end
|
||
|
||
def disable_merge_overrides
|
||
if merge_overrides && !supports_merge?
|
||
self.errors.add(:merge_overrides, _("can only be set for array or hash"))
|
||
end
|
||
end
|
||
|
||
def disable_avoid_duplicates
|
||
if avoid_duplicates && (!merge_overrides || !supports_uniq?)
|
||
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/models/lookup_keys/puppetclass_lookup_key.rb | ||
---|---|---|
class PuppetclassLookupKey < LookupKey
|
||
has_many :environment_classes, :dependent => :destroy
|
||
has_many :environments, :through => :environment_classes, :uniq => true
|
||
has_many :param_classes, :through => :environment_classes, :source => :puppetclass
|
||
|
||
scoped_search :in => :param_classes, :on => :name, :rename => :puppetclass, :complete_value => true
|
||
|
||
scope :smart_class_parameters_for_class, lambda { |puppetclass_ids, environment_id|
|
||
joins(:environment_classes).where(:environment_classes => {:puppetclass_id => puppetclass_ids, :environment_id => environment_id})
|
||
}
|
||
|
||
scope :parameters_for_class, lambda { |puppetclass_ids, environment_id|
|
||
override.smart_class_parameters_for_class(puppetclass_ids,environment_id)
|
||
}
|
||
|
||
scope :smart_class_parameters, -> { joins(:environment_classes).readonly(false) }
|
||
|
||
def param_class
|
||
param_classes.first
|
||
end
|
||
|
||
def audit_class
|
||
param_class
|
||
end
|
||
|
||
def cast_default_value
|
||
super unless use_puppet_default
|
||
true
|
||
end
|
||
|
||
def validate_default_value
|
||
super unless use_puppet_default
|
||
true
|
||
end
|
||
|
||
def puppet?
|
||
true
|
||
end
|
||
end
|
app/models/lookup_keys/variable_lookup_key.rb | ||
---|---|---|
class VariableLookupKey < LookupKey
|
||
belongs_to :puppetclass, :inverse_of => :lookup_keys, :counter_cache => :variable_lookup_keys_count
|
||
|
||
validates :puppetclass, :presence => true
|
||
validates :key, :uniqueness => true
|
||
|
||
scoped_search :in => :puppetclass, :on => :name, :complete_value => true, :rename => :puppetclass
|
||
|
||
def audit_class
|
||
puppetclass
|
||
end
|
||
|
||
def param_class
|
||
puppetclass
|
||
end
|
||
|
||
scope :global_parameters_for_class, lambda { |puppetclass_ids|
|
||
where(:puppetclass_id => puppetclass_ids)
|
||
}
|
||
|
||
scope :smart_variables, -> { where('lookup_keys.puppetclass_id > 0').readonly(false) }
|
||
end
|
app/models/puppetclass.rb | ||
---|---|---|
has_many_hosts :through => :host_classes, :dependent => :destroy
|
||
has_many :config_group_classes
|
||
has_many :config_groups, :through => :config_group_classes, :dependent => :destroy
|
||
|
||
has_many :lookup_keys, :inverse_of => :puppetclass, :dependent => :destroy
|
||
has_many :lookup_keys, :inverse_of => :puppetclass, :dependent => :destroy, :class_name => 'VariableLookupKey'
|
||
accepts_nested_attributes_for :lookup_keys, :reject_if => ->(a) { a[:key].blank? }, :allow_destroy => true
|
||
# param classes
|
||
has_many :class_params, :through => :environment_classes, :uniq => true,
|
||
:source => :lookup_key, :conditions => 'environment_classes.lookup_key_id is NOT NULL'
|
||
:source => :puppetclass_lookup_key, :conditions => 'environment_classes.puppetclass_lookup_key_id is NOT NULL'
|
||
accepts_nested_attributes_for :class_params, :reject_if => ->(a) { a[:key].blank? }, :allow_destroy => true
|
||
|
||
validates :name, :uniqueness => true, :presence => true, :no_whitespace => true
|
||
audited :allow_mass_assignment => true, :except => [:total_hosts, :lookup_keys_count, :global_class_params_count]
|
||
audited :allow_mass_assignment => true, :except => [:total_hosts, :variable_lookup_keys_count, :global_class_params_count]
|
||
|
||
alias_attribute :smart_variables, :lookup_keys
|
||
alias_attribute :smart_variable_ids, :lookup_key_ids
|
||
... | ... | |
scoped_search :on => :name, :complete_value => :true
|
||
scoped_search :on => :total_hosts
|
||
scoped_search :on => :global_class_params_count, :rename => :params_count # Smart Parameters
|
||
scoped_search :on => :lookup_keys_count, :rename => :variables_count # Smart Variables
|
||
scoped_search :on => :variable_lookup_keys_count, :rename => :variables_count # Smart Variables
|
||
scoped_search :in => :environments, :on => :name, :complete_value => :true, :rename => "environment"
|
||
scoped_search :in => :hostgroups, :on => :name, :complete_value => :true, :rename => "hostgroup"
|
||
scoped_search :in => :config_groups, :on => :name, :complete_value => :true, :rename => "config_group"
|
app/services/classification/class_param.rb | ||
---|---|---|
protected
|
||
|
||
def class_parameters
|
||
@keys ||= LookupKey.includes(:environment_classes).parameters_for_class(puppetclass_ids, environment_id)
|
||
@keys ||= PuppetclassLookupKey.includes(:environment_classes).parameters_for_class(puppetclass_ids, environment_id)
|
||
end
|
||
|
||
private
|
app/services/classification/global_param.rb | ||
---|---|---|
protected
|
||
|
||
def class_parameters
|
||
@keys ||= LookupKey.global_parameters_for_class(puppetclass_ids)
|
||
@keys ||= VariableLookupKey.global_parameters_for_class(puppetclass_ids)
|
||
end
|
||
end
|
||
end
|
app/services/foreman/access_permissions.rb | ||
---|---|---|
|
||
permission_set.security_block :external_variables do |map|
|
||
map.permission :view_external_variables, {:lookup_keys => [:index, :show, :auto_complete_search],
|
||
:puppetclass_lookup_keys => [:index, :show, :auto_complete_search],
|
||
:variable_lookup_keys => [:index, :show, :auto_complete_search],
|
||
:lookup_values => [:index],
|
||
:"api/v1/lookup_keys" => [:index, :show],
|
||
:"api/v2/smart_variables" => [:index, :show],
|
||
:"api/v2/smart_class_parameters" => [:index, :show],
|
||
:"api/v2/override_values" => [:index, :show]}
|
||
map.permission :create_external_variables, {:lookup_keys => [:new, :create],
|
||
:puppetclass_lookup_keys => [:new, :create],
|
||
:variable_lookup_keys => [:new, :create],
|
||
:lookup_values => [:create],
|
||
:"api/v1/lookup_keys" => [:create],
|
||
:"api/v2/smart_variables" => [:create],
|
||
:"api/v2/smart_class_parameters" => [:create],
|
||
:"api/v2/override_values" => [:create]}
|
||
map.permission :edit_external_variables, {:lookup_keys => [:edit, :update],
|
||
:puppetclass_lookup_keys => [:edit, :update],
|
||
:variable_lookup_keys => [:edit, :update],
|
||
:lookup_values => [:create, :update, :destroy],
|
||
:"api/v1/lookup_keys" => [:update],
|
||
:"api/v2/smart_variables" => [:update],
|
||
:"api/v2/smart_class_parameters" => [:update],
|
||
:"api/v2/override_values" => [:create, :update, :destroy]}
|
||
map.permission :destroy_external_variables, {:lookup_keys => [:destroy],
|
||
:puppetclass_lookup_keys => [:destroy],
|
||
:variable_lookup_keys => [:destroy],
|
||
:lookup_values => [:destroy],
|
||
:"api/v1/lookup_keys" => [:destroy],
|
||
:"api/v2/smart_variables" => [:destroy],
|
app/services/menu/loader.rb | ||
---|---|---|
menu.item :environments, :caption => N_('Environments')
|
||
menu.item :puppetclasses, :caption => N_('Classes')
|
||
menu.item :config_groups, :caption => N_('Config groups')
|
||
menu.item :lookup_keys, :caption => N_('Smart variables')
|
||
menu.item :variable_lookup_keys, :caption => N_('Smart variables')
|
||
menu.item :puppetclass_lookup_keys, :caption => N_('Smart class parameters')
|
||
end
|
||
|
||
menu.sub_menu :infrastructure_menu, :caption => N_('Infrastructure') do
|
app/services/puppet_class_importer.rb | ||
---|---|---|
return [] unless db_environments.include?(environment) && actual_environments.include?(environment)
|
||
HashWithIndifferentAccess[
|
||
db_classes(environment).map do |db_class|
|
||
params = EnvironmentClass.all_parameters_for_class(db_class.id, find_or_create_env(environment).id).map(&:lookup_key)
|
||
params = EnvironmentClass.all_parameters_for_class(db_class.id, find_or_create_env(environment).id).map(&:puppetclass_lookup_key)
|
||
compare_classes(environment, db_class.name, params)
|
||
end.compact
|
||
]
|
||
... | ... | |
|
||
def find_or_create_puppet_class_param(klass, param_name, value)
|
||
klass.class_params.where(:key => param_name).first ||
|
||
LookupKey.create!(:key => param_name, :is_param => true,
|
||
:required => value.nil?, :override => value.nil?, :default_value => value,
|
||
:key_type => Foreman::ImporterPuppetclass.suggest_key_type(value))
|
||
PuppetclassLookupKey.create!(:key => param_name, :required => value.nil?,
|
||
:override => value.nil?, :default_value => value,
|
||
:key_type => Foreman::ImporterPuppetclass.suggest_key_type(value))
|
||
end
|
||
end
|
app/views/api/v1/lookup_keys/index.json.rabl | ||
---|---|---|
collection @lookup_keys
|
||
collection @lookup_keys, :object_root => "lookup_key"
|
||
|
||
extends "api/v1/lookup_keys/show"
|
app/views/api/v1/lookup_keys/show.json.rabl | ||
---|---|---|
object @lookup_key
|
||
object @lookup_key => :lookup_key
|
||
|
||
attributes :key, :is_param, :required, :override, :description, :default_value, :id
|
||
attributes :key, :required, :override, :description, :default_value, :id
|
||
|
||
node(:is_param) { |key| key.puppet? }
|
app/views/common_parameters/_puppetclass_parameter.html.erb | ||
---|---|---|
<tr class="form-group <%= 'error' if f.object.errors.any? %>">
|
||
<td class="col-md-3">
|
||
<%= f.hidden_field :lookup_key_id, :'data-property' => 'lookup_key_id' %>
|
||
<% puppetclass = f.object.lookup_key ? f.object.lookup_key.puppetclass || f.object.lookup_key.param_class : nil %>
|
||
<% puppetclass = f.object.lookup_key ? f.object.lookup_key.param_class : nil %>
|
||
<%= text_field_tag '', (puppetclass.name rescue ''), :class => 'form-control', :'data-property' => 'class', :disabled => true, :title => _('Puppetclass') %>
|
||
</td>
|
||
<td class="col-md-2">
|
app/views/lookup_keys/_edit.html.erb | ||
---|---|---|
<%= form_for(lookup_key) do |f| %>
|
||
<%= render 'lookup_keys/fields', :f => f %>
|
||
<%= submit_or_cancel f %>
|
||
<% end %>
|
app/views/lookup_keys/_fields.html.erb | ||
---|---|---|
<div id='<%= (f.object.key || 'new_lookup_keys').to_s.gsub(' ', '_') + '_' + f.object.id.to_s %>' class='tab-pane fields'>
|
||
<% is_param = f.object.is_param %>
|
||
<% is_param = f.object.puppet? %>
|
||
|
||
<%= remove_child_link(_("Remove %s?") % (f.object.new_record? ? _("Variable") : f.object), f, { :class => 'btn btn-danger hide' }) unless controller_name == "lookup_keys" %>
|
||
<%= remove_child_link(_("Remove %s?") % (f.object.new_record? ? _("Variable") : f.object), f, { :class => 'btn btn-danger hide' }) unless controller_name == "variable_lookup_keys" || "puppetclass_lookup_keys" %>
|
||
<fieldset>
|
||
<legend><%= _("Parameter details") %></legend>
|
||
<%= text_f f, :key, :disabled => f.object.is_param, :size => "col-md-8" %>
|
||
<%= text_f f, :key, :disabled => is_param, :size => "col-md-8" %>
|
||
<%= f.hidden_field :key if is_param %>
|
||
<%= textarea_f f, :description, :rows => :auto, :size => "col-md-8", :class => "no-stretch" %>
|
||
<%= text_f(f, :environment_classes, :value => f.object.environment_classes.map(&:environment).to_sentence, :label => _('Puppet Environments'), :size => "col-md-8", :disabled => true) if is_param %>
|
||
... | ... | |
</fieldset>
|
||
<fieldset>
|
||
<legend><%= _("Default behavior") %></legend>
|
||
<h6><%= _("Override the default value of the Puppet class parameter.") if f.object.is_param%></h6>
|
||
<h6><%= _("Override the default value of the Puppet class parameter.") if is_param%></h6>
|
||
<%= 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)),
|
||
:disabled => (is_param && (!f.object.override || f.object.use_puppet_default)),
|
||
:fullscreen => :true,
|
||
:rows => :auto,
|
||
:help_inline => popover('', _("Value to use when there is no match.")),
|
||
... | ... | |
<%= checkbox_f(f, :use_puppet_default, :label => _('Use Puppet default'), :size => "col-md-8",
|
||
:help_inline => use_puppet_default_help,
|
||
:onchange => 'toggleUsePuppetDefaultValue(this, "default_value")',
|
||
:disabled => (f.object.is_param && !f.object.override)) if is_param %>
|
||
:disabled => (is_param && !f.object.override)) if is_param %>
|
||
</br>
|
||
</fieldset>
|
||
<fieldset>
|
||
... | ... | |
</div>
|
||
</fieldset>
|
||
</br>
|
||
<div class="matcher-parent" <%= "id=#{(f.object.key || 'new_lookup_keys').to_s.gsub(' ', '_')}_lookup_key_override_value" %> style=<%= "display:none;" if (f.object.is_param && !f.object.override) %>>
|
||
<div class="matcher-parent" <%= "id=#{(f.object.key || 'new_lookup_keys').to_s.gsub(' ', '_')}_lookup_key_override_value" %> style=<%= "display:none;" if (is_param && !f.object.override) %>>
|
||
<fieldset>
|
||
<legend><%= _("Prioritize attribute order") %></legend>
|
||
<h6><%= popover("", _("The order in which matchers keys are processed, first match wins.<br> You may use multiple attributes as a matcher key, for example, an order of <code>host group, environment</code> would expect a matcher such as <code>hostgroup = \"web servers\", environment = production</code>"),
|
app/views/lookup_keys/edit.html.erb | ||
---|---|---|
<%= javascript "lookup_keys" %>
|
||
<% title(_("Edit Smart Variable")) %>
|
||
|
||
<%= form_for(@lookup_key) do |f| %>
|
||
<%= render 'fields', :f => f %>
|
||
<%= submit_or_cancel f %>
|
||
<% end %>
|
app/views/lookup_keys/index.html.erb | ||
---|---|---|
<%= javascript "lookup_keys" %>
|
||
<% title _("Smart variables") %>
|
||
<% title_actions documentation_button('4.2.4SmartVariables') %>
|
||
<table class="table table-bordered table-striped table-two-pane">
|
||
<thead>
|
||
<tr>
|
||
<th><%= sort :key, :as => _("Variable") %></th>
|
||
<th><%= sort :puppetclass, :as => _("Puppetclass") %></th>
|
||
<th><%= sort :values_count, :as => _('Number of values'), :default => "DESC" %></th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<% @lookup_keys.each do |lookup_key| %>
|
||
<tr>
|
||
<td class="display-two-pane"><%= link_to_if_authorized trunc_with_tooltip(lookup_key.key), hash_for_edit_lookup_key_path(:id => lookup_key).merge(:auth_object => lookup_key, :permission => 'edit_external_variables', :authorizer => authorizer) %></td>
|
||
<% puppet_class = lookup_key.param_class %>
|
||
<td class="display-two-pane"><%= link_to_if_authorized trunc_with_tooltip(puppet_class), hash_for_edit_puppetclass_path(:id => puppet_class).merge(:auth_object => puppet_class, :authorizer => @puppetclass_authorizer) if puppet_class %></td>
|
||
<td><%=h lookup_key.lookup_values_count %></td>
|
||
<td><%= display_delete_if_authorized hash_for_lookup_key_path(:id => lookup_key).merge(:auth_object => lookup_key, :permission => 'destroy_external_variables', :authorizer => authorizer),
|
||
:data => { :confirm => _("Delete %s?") % lookup_key.key } %></td>
|
||
</tr>
|
||
<% end %>
|
||
</tbody>
|
||
</table>
|
||
<%= will_paginate_with_info @lookup_keys %>
|
app/views/puppetclass_lookup_keys/edit.html.erb | ||
---|---|---|
<%= javascript "lookup_keys" %>
|
||
<% title(_("Edit Smart class parameters")) %>
|
||
<%= render 'lookup_keys/edit', :lookup_key => @puppetclass_lookup_key %>
|
app/views/puppetclass_lookup_keys/index.html.erb | ||
---|---|---|
<%= javascript "lookup_keys" %>
|
||
<% title _("Smart class parameters") %>
|
||
<% title_actions documentation_button('4.2.5ParameterizedClasses') %>
|
||
<table class="table table-bordered table-striped table-two-pane">
|
||
<thead>
|
||
<tr>
|
||
<th><%= sort :key, :as => _("Parameter") %></th>
|
||
<th><%= sort :puppetclass, :as => _("Puppetclass") %></th>
|
||
<th><%= sort :values_count, :as => _('Number of values'), :default => "DESC" %></th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<% @lookup_keys.each do |lookup_key| %>
|
||
<tr>
|
||
<td class="display-two-pane"><%= link_to_if_authorized trunc_with_tooltip(lookup_key.key), hash_for_edit_puppetclass_lookup_key_path(:id => lookup_key).merge(:auth_object => lookup_key, :permission => 'edit_external_variables', :authorizer => authorizer) %></td>
|
||
<% puppet_class = lookup_key.param_class %>
|
||
<td><%= link_to_if_authorized trunc_with_tooltip(puppet_class), hash_for_edit_puppetclass_path(:id => puppet_class).merge(:auth_object => puppet_class, :authorizer => @puppetclass_authorizer) if puppet_class %></td>
|
||
<td><%=h lookup_key.lookup_values_count %></td>
|
||
<td><%= display_delete_if_authorized hash_for_lookup_key_path(:id => lookup_key).merge(:auth_object => lookup_key, :permission => 'destroy_external_variables', :authorizer => authorizer),
|
||
:data => { :confirm => _("Delete %s?") % lookup_key.key } %></td>
|
||
</tr>
|
||
<% end %>
|
||
</tbody>
|
||
</table>
|
||
<%= will_paginate_with_info @lookup_keys %>
|
app/views/puppetclasses/index.html.erb | ||
---|---|---|
<td><%= puppetclass.all_hostgroups(false).map {|hg| link_to_if_authorized trunc_with_tooltip(hg), hash_for_edit_hostgroup_path(:id=>hg).merge(:auth_object => hg, :authorizer => @hostgroups_authorizer)}.to_sentence.html_safe %></td>
|
||
<td> <%= link_to puppetclass.total_hosts, hosts_path(:search => "class = #{puppetclass.name}")%></td>
|
||
<td><%= puppetclass.global_class_params_count %> </td>
|
||
<td><%= puppetclass.lookup_keys_count %> </td>
|
||
<td><%
|
||
<td><%= puppetclass.variable_lookup_keys_count %> </td>
|
||
<td>
|
||
<%
|
||
links = [display_delete_if_authorized(hash_for_puppetclass_path(:id => puppetclass).merge(:auth_object => puppetclass, :authorizer => authorizer), :data => { :confirm => _("Delete %s?") % puppetclass.name }, :action => :delete)]
|
||
links.push(display_link_if_authorized(_('Override all parameters'), hash_for_override_puppetclass_path(:enable => true, :id => puppetclass), :method => :post, :data => { :confirm => _("This will set all parameters of the class %s as overridden. Continue?") % puppetclass.name })) if puppetclass.class_params.present? && !overridden?(puppetclass)
|
||
links.push(display_link_if_authorized(_('Set parameters to defaults'), hash_for_override_puppetclass_path(:enable => false, :id => puppetclass), :method => :post, :data => { :confirm => _("This will reset parameters of the class %s to their default values. Continue?") % puppetclass.name })) if puppetclass.class_params.present? && overridden?(puppetclass)
|
app/views/variable_lookup_keys/edit.html.erb | ||
---|---|---|
<%= javascript "lookup_keys" %>
|
||
<% title(_("Edit Smart Variable")) %>
|
||
<%= render 'lookup_keys/edit', :lookup_key => @variable_lookup_key%>
|
app/views/variable_lookup_keys/index.html.erb | ||
---|---|---|
<%= javascript "lookup_keys" %>
|
||
<% title _("Smart variables") %>
|
||
<% title_actions documentation_button('4.2.4SmartVariables') %>
|
||
<table class="table table-bordered table-striped table-two-pane">
|
||
<thead>
|
||
<tr>
|
||
<th><%= sort :key, :as => _("Variable") %></th>
|
||
<th><%= sort :puppetclass, :as => _("Puppetclass") %></th>
|
||
<th><%= sort :values_count, :as => _('Number of values'), :default => "DESC" %></th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<% @lookup_keys.each do |lookup_key| %>
|
||
<tr>
|
||
<td class="display-two-pane"><%= link_to_if_authorized trunc_with_tooltip(lookup_key.key), hash_for_edit_variable_lookup_key_path(:id => lookup_key).merge(:auth_object => lookup_key, :permission => 'edit_external_variables', :authorizer => authorizer) %></td>
|
||
<td><%= link_to_if_authorized trunc_with_tooltip(lookup_key.puppetclass), hash_for_edit_puppetclass_path(:id => lookup_key.puppetclass).merge(:auth_object => lookup_key.puppetclass, :authorizer => @puppetclass_authorizer) %></td>
|
||
<td><%=h lookup_key.lookup_values_count %></td>
|
||
<td><%= display_delete_if_authorized hash_for_lookup_key_path(:id => lookup_key).merge(:auth_object => lookup_key, :permission => 'destroy_external_variables', :authorizer => authorizer),
|
||
:data => { :confirm => _("Delete %s?") % lookup_key.key } %></td>
|
||
</tr>
|
||
<% end %>
|
||
</tbody>
|
||
</table>
|
||
<%= will_paginate_with_info @lookup_keys %>
|
config/application.rb | ||
---|---|---|
|
||
config.autoload_paths += %W(#{config.root}/app/models/auth_sources)
|
||
config.autoload_paths += %W(#{config.root}/app/models/compute_resources)
|
||
config.autoload_paths += %W(#{config.root}/app/models/lookup_keys)
|
||
config.autoload_paths += %W(#{config.root}/app/models/operatingsystems)
|
||
config.autoload_paths += %W(#{config.root}/app/models/parameters)
|
||
config.autoload_paths += %W(#{config.root}/app/models/trends)
|
config/routes.rb | ||
---|---|---|
end
|
||
|
||
resources :bookmarks, :except => [:show]
|
||
resources :lookup_keys, :except => [:show, :new, :create] do
|
||
resources :lookup_values, :only => [:index, :create, :update, :destroy]
|
||
collection do
|
||
get 'auto_complete_search'
|
||
[:lookup_keys, :variable_lookup_keys, :puppetclass_lookup_keys].each do |key|
|
||
resources key, :except => [:show, :new, :create] do
|
||
resources :lookup_values, :only => [:index, :create, :update, :destroy]
|
||
collection do
|
||
get 'auto_complete_search'
|
||
end
|
||
end
|
||
end
|
||
|
db/migrate/20150606065713_add_sti_to_lookup_keys.rb | ||
---|---|---|
class AddStiToLookupKeys < ActiveRecord::Migration
|
||
def up
|
||
add_column :lookup_keys, :type, :string
|
||
LookupKey.where(:is_param => true).update_all(:type => 'PuppetclassLookupKey')
|
||
LookupKey.where(:is_param => false).update_all(:type => 'VariableLookupKey')
|
||
add_index :lookup_keys, :type
|
||
|
||
remove_foreign_key :environment_classes, :lookup_keys if foreign_key_exists?(:environment_classes, :lookup_keys)
|
||
rename_column :environment_classes, :lookup_key_id, :puppetclass_lookup_key_id
|
||
add_foreign_key :environment_classes, :lookup_keys, :column => :puppetclass_lookup_key_id, :name => "environment_classes_lookup_key_id_fk"
|
||
end
|
||
|
||
def down
|
||
LookupKey.where(:type => "PuppetclassLookupKey").update_all(:is_param => true)
|
||
remove_column :lookup_keys, :type
|
||
|
||
remove_foreign_key :environment_classes, :lookup_keys if foreign_key_exists?(:environment_classes, :lookup_keys)
|
||
rename_column :environment_classes, :puppetclass_lookup_key_id, :lookup_key_id
|
||
add_foreign_key :environment_classes, :lookup_keys
|
||
end
|
||
end
|
db/migrate/20150614171717_rename_puppetclass_counters_for_lk_sti.rb | ||
---|---|---|
class RenamePuppetclassCountersForLkSti < ActiveRecord::Migration
|
||
def up
|
||
# This is the counter for the total number of params for a given puppet class
|
||
# across all environments. It was poorly named.
|
||
rename_column :puppetclasses, :lookup_keys_count, :variable_lookup_keys_count
|
||
end
|
||
|
||
def down
|
||
rename_column :puppetclasses, :variable_lookup_keys_count, :lookup_keys_count
|
||
end
|
||
end
|
db/migrate/20150714132601_remove_is_param.rb | ||
---|---|---|
class RemoveIsParam < ActiveRecord::Migration
|
||
def up
|
||
remove_column :lookup_keys, :is_param
|
||
end
|
||
|
||
def down
|
||
add_column :lookup_keys, :is_param, :boolean
|
||
end
|
||
end
|
locale/en/foreman.po | ||
---|---|---|
msgstr ""
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "LookupKey|Avoid duplicates"
|
||
msgid "Variable lookup key"
|
||
msgstr ""
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "LookupKey|Default value"
|
||
msgid "VariableLookupKey|Avoid duplicates"
|
||
msgstr ""
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "VariableLookupKey|Default value"
|
||
msgstr "Default value"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "LookupKey|Description"
|
||
msgid "VariableLookupKey|Description"
|
||
msgstr "Description"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "LookupKey|Is param"
|
||
msgid "VariableLookupKey|Is param"
|
||
msgstr "Is parameter"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "LookupKey|Key"
|
||
msgid "VariableLookupKey|Key"
|
||
msgstr "Parameter"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "LookupKey|Key type"
|
||
msgid "VariableLookupKey|Key type"
|
||
msgstr "Parameter type"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "LookupKey|Lookup values count"
|
||
msgid "VariableLookupKey|Variable lookup values count"
|
||
msgstr "Number of values"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "LookupKey|Merge overrides"
|
||
msgid "VariableLookupKey|Merge overrides"
|
||
msgstr ""
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "VariableLookupKey|Override"
|
||
msgstr "Override"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "VariableLookupKey|Path"
|
||
msgstr "Path"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "VariableLookupKey|Required"
|
||
msgstr "Required"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "VariableLookupKey|Validator rule"
|
||
msgstr "Validator rule"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "VariableLookupKey|Validator type"
|
||
msgstr "Validator type"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "Puppetclass lookup key"
|
||
msgstr ""
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "PuppetclassLookupKey|Avoid duplicates"
|
||
msgstr ""
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "PuppetclassLookupKey|Default value"
|
||
msgstr "Default value"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "PuppetclassLookupKey|Description"
|
||
msgstr "Description"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "PuppetclassLookupKey|Is param"
|
||
msgstr "Is parameter"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "PuppetclassLookupKey|Key"
|
||
msgstr "Parameter"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "PuppetclassLookupKey|Key type"
|
||
msgstr "Parameter type"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "PuppetclassLookupKey|Merge overrides"
|
||
msgstr ""
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "LookupKey|Override"
|
||
msgid "PuppetclassLookupKey|Override"
|
||
msgstr "Override"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "LookupKey|Path"
|
||
msgid "PuppetclassLookupKey|Path"
|
||
msgstr "Path"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "LookupKey|Required"
|
||
msgid "PuppetclassLookupKey|Required"
|
||
msgstr "Required"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "LookupKey|Validator rule"
|
||
msgid "PuppetclassLookupKey|Validator rule"
|
||
msgstr "Validator rule"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
msgid "LookupKey|Validator type"
|
||
msgid "PuppetclassLookupKey|Validator type"
|
||
msgstr "Validator type"
|
||
|
||
#. TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
locale/model_attributes.rb | ||
---|---|---|
# TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
_('Lookup key')
|
||
# TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
_('LookupKey|Avoid duplicates')
|
||
_('Variable lookup key')
|
||
# TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
_('LookupKey|Default value')
|
||
_('VariableLookupKey|Avoid duplicates')
|
||
# TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
_('LookupKey|Description')
|
||
_('VariableLookupKey|Default value')
|
||
# TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
_('LookupKey|Is param')
|
||
_('VariableLookupKey|Description')
|
||
# TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
_('LookupKey|Key')
|
||
_('VariableLookupKey|Is param')
|
||
# TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
_('LookupKey|Key type')
|
||
_('VariableLookupKey|Key')
|
||
# TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
_('LookupKey|Lookup values count')
|
||
_('VariableLookupKey|Key type')
|
||
# TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
_('LookupKey|Merge overrides')
|
||
_('VariableLookupKey|Variable lookup values count')
|
||
# TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
_('LookupKey|Override')
|
||
_('VariableLookupKey|Merge overrides')
|
||
# TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
_('LookupKey|Path')
|
||
_('VariableLookupKey|Override')
|
||
# TRANSLATORS: "Table name" or "Table name|Column name" for error messages
|
||
_('LookupKey|Required')
|
Also available in: Unified diff
fixes #10832 - separating lookup keys into puppet and variable