Revision e76ac9ca
Added by Ohad Levy over 11 years ago
- ID e76ac9ca4690f34791d726ccac41373e43616df6
app/models/classification.rb | ||
---|---|---|
class Classification
|
||
delegate :hostgroup, :environment_id,
|
||
:to => :host
|
||
|
||
def initialize args = { }
|
||
@host = args[:host]
|
||
end
|
||
|
||
def enc
|
||
klasses = { }
|
||
key_hash = hashed_class_parameters
|
||
values = values_hash
|
||
classes.each do |klass|
|
||
klasses[klass.name] ||= { }
|
||
if key_hash[klass.id]
|
||
key_hash[klass.id].each do |param|
|
||
klasses[klass.name][param.to_s] = values[param.to_s] ? values[param.to_s][:value] : param.default_value
|
||
end
|
||
else
|
||
klasses[klass.name] = nil
|
||
end
|
||
end
|
||
klasses
|
||
end
|
||
|
||
private
|
||
|
||
attr_reader :host
|
||
|
||
def puppetclass_ids
|
||
return @puppetclass_ids if @puppetclass_ids
|
||
@puppetclass_ids = host.host_classes.pluck(:puppetclass_id)
|
||
@puppetclass_ids += HostgroupClass.where(:hostgroup_id => hostgroup.path_ids).pluck(:puppetclass_id) if hostgroup
|
||
|
||
@puppetclass_ids
|
||
end
|
||
|
||
def classes
|
||
Puppetclass.where(:id => puppetclass_ids)
|
||
end
|
||
|
||
def class_parameters
|
||
@keys ||= LookupKey.includes(:environment_classes).parameters_for_class(puppetclass_ids, environment_id)
|
||
end
|
||
|
||
def possible_value_orders
|
||
class_parameters.select do |key|
|
||
# take only keys with actual values
|
||
key.lookup_values_count > 0 # we use counter cache, so its safe to make that query
|
||
end.map(&:path_elements).flatten.uniq
|
||
end
|
||
|
||
def values_hash
|
||
values = {}
|
||
path2matches.each do |match|
|
||
LookupValue.where(:match => match).where(:lookup_key_id => class_parameters.map(&:id)).each do |value|
|
||
key = @keys.detect{|k| k.id == value.lookup_key_id }
|
||
name = key.to_s
|
||
element = match.split(LookupKey::EQ_DELM).first
|
||
if values[name].nil?
|
||
values[name] = {:value => value.value, :element => element}
|
||
else
|
||
if key.path.index(element) < key.path.index(values[name][:element])
|
||
values[name] = {:value => value.value, :element => element}
|
||
end
|
||
end
|
||
end
|
||
end
|
||
values
|
||
end
|
||
|
||
def hashed_class_parameters
|
||
h = {}
|
||
class_parameters.each do |key|
|
||
klass_id = key.environment_classes.first.puppetclass_id
|
||
h[klass_id] ||= []
|
||
h[klass_id] << key
|
||
end
|
||
h
|
||
end
|
||
|
||
# Generate possible lookup values type matches to a given host
|
||
def path2matches
|
||
matches = []
|
||
possible_value_orders.each do |rule|
|
||
match = []
|
||
rule.each do |element|
|
||
match << "#{element}#{LookupKey::EQ_DELM}#{attr_to_value(element)}"
|
||
end
|
||
matches << match.join(LookupKey::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 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 path_elements path = nil
|
||
path.split.map do |paths|
|
||
paths.split(LookupKey::KEY_DELM).map do |element|
|
||
element
|
||
end
|
||
end
|
||
end
|
||
|
||
end
|
app/models/host.rb | ||
---|---|---|
end
|
||
|
||
def lookup_keys_class_params
|
||
p={}
|
||
classes = all_puppetclasses
|
||
keys = EnvironmentClass.parameters_for_class(classes.map(&:id), environment_id).includes(:lookup_key).group_by(&:puppetclass_id)
|
||
classes.each do |klass|
|
||
p[klass.name] = nil
|
||
keys[klass.id].map(&:lookup_key).each do |lookup_key|
|
||
p[klass.name] ||= {}
|
||
value = lookup_key.value_for(self)
|
||
p[klass.name].merge!({lookup_key.key => value})
|
||
end if keys[klass.id]
|
||
end
|
||
p
|
||
Classification.new(:host => self).enc
|
||
end
|
||
|
||
# align common mac and ip address input
|
app/models/lookup_key.rb | ||
---|---|---|
default_scope :order => 'lookup_keys.key'
|
||
scope :override, where(:override => true)
|
||
|
||
scope :parameters_for_class, lambda {|puppetclass_ids, environment_id|
|
||
override.joins(:environment_classes).where(:environment_classes => {:puppetclass_id => puppetclass_ids, :environment_id => environment_id})
|
||
}
|
||
|
||
def to_param
|
||
"#{id}-#{key}"
|
||
end
|
Also available in: Unified diff
fixes #2003 - Improve Parameterized classes values retrieval time
This patch adds a new classification class which
tries to fetch all values at once
The initial implementation cared about a name / value at a time
however getting all at once (e.g. during a puppet ENC call) is much more
common.
This patch creates in memory tree of all possible values and process
them in memory instead of asking the database for each possible match.