Project

General

Profile

Download (8.91 KB) Statistics
| Branch: | Tag: | Revision:
c6eee281 Ohad Levy
class Puppetclass < ActiveRecord::Base
acfbc458 Marek Hulan
include Authorizable
e44f5c1c Daniel Lobato
include ScopedSearchExtensions
8b737c9c Joseph Magen
extend FriendlyId
friendly_id :name
e768c976 Tomas Strachota
include Parameterizable::ByIdName
e44f5c1c Daniel Lobato
3034e8e2 Ori Rabin
validates_lengths_from_database
ff8cc704 Joseph Mitchell Magen
before_destroy EnsureNotUsedBy.new(:hosts, :hostgroups)
f8d94608 Amos Benari
has_many :environment_classes, :dependent => :destroy
has_many :environments, :through => :environment_classes, :uniq => true
c6eee281 Ohad Levy
has_and_belongs_to_many :operatingsystems
83683ed0 Tomer Brisker
has_many :hostgroup_classes
has_many :hostgroups, :through => :hostgroup_classes, :dependent => :destroy
has_many :host_classes
has_many_hosts :through => :host_classes, :dependent => :destroy
111cde57 Joseph Magen
has_many :config_group_classes
83683ed0 Tomer Brisker
has_many :config_groups, :through => :config_group_classes, :dependent => :destroy
8a65dff7 Ohad Levy
7d993b41 Joseph Mitchell Magen
has_many :lookup_keys, :inverse_of => :puppetclass, :dependent => :destroy
bb3572ff Daniel Lobato
accepts_nested_attributes_for :lookup_keys, :reject_if => ->(a) { a[:key].blank? }, :allow_destroy => true
f8d94608 Amos Benari
# param classes
has_many :class_params, :through => :environment_classes, :uniq => true,
867084a0 Ohad Levy
:source => :lookup_key, :conditions => 'environment_classes.lookup_key_id is NOT NULL'
bb3572ff Daniel Lobato
accepts_nested_attributes_for :class_params, :reject_if => ->(a) { a[:key].blank? }, :allow_destroy => true
dff926cb Tomer Brisker
validates :name, :uniqueness => true, :presence => true, :no_whitespace => true
09f31315 Tomer Brisker
audited :allow_mass_assignment => true, :except => [:total_hosts, :lookup_keys_count, :global_class_params_count]
f8e711fe Ohad Levy
bbf64d99 Joseph Magen
alias_attribute :smart_variables, :lookup_keys
alias_attribute :smart_variable_ids, :lookup_key_ids
alias_attribute :smart_class_parameters, :class_params
alias_attribute :smart_class_parameter_ids, :class_param_ids

bb3572ff Daniel Lobato
default_scope -> { order('puppetclasses.name') }
af6e2624 Ohad Levy
ac7fe332 Ohad Levy
scoped_search :on => :name, :complete_value => :true
83683ed0 Tomer Brisker
scoped_search :on => :total_hosts
df471c78 Stephen Benjamin
scoped_search :on => :global_class_params_count, :rename => :params_count # Smart Parameters
scoped_search :on => :lookup_keys_count, :rename => :variables_count # Smart Variables
ac7fe332 Ohad Levy
scoped_search :in => :environments, :on => :name, :complete_value => :true, :rename => "environment"
scoped_search :in => :hostgroups, :on => :name, :complete_value => :true, :rename => "hostgroup"
d20aba2b Joseph Magen
scoped_search :in => :config_groups, :on => :name, :complete_value => :true, :rename => "config_group"
7d46a25e Ohad Levy
scoped_search :in => :hosts, :on => :name, :complete_value => :true, :rename => "host", :ext_method => :search_by_host, :only_explicit => true
0126385b Lukas Zapletal
scoped_search :in => :class_params, :on => :key, :complete_value => :true, :only_explicit => true
31207a31 Ohad Levy
bb3572ff Daniel Lobato
scope :not_in_any_environment, -> { includes(:environment_classes).where(:environment_classes => {:environment_id => nil}) }
31207a31 Ohad Levy
bd46fa41 Ohad Levy
# returns a hash containing modules and associated classes
5f029ed6 Daniel Lobato
def self.classes2hash(classes)
bd46fa41 Ohad Levy
hash = {}
for klass in classes
67799065 Ohad Levy
if (mod = klass.module_name)
bd46fa41 Ohad Levy
hash[mod] ||= []
hash[mod] << klass
else
next
end
92b7b44d Joseph Magen
end
96144a47 Daniel Lobato
hash
92b7b44d Joseph Magen
end

# For API v2 - eliminate node :puppetclass for each object. returns a hash containing modules and associated classes
5f029ed6 Daniel Lobato
def self.classes2hash_v2(classes)
92b7b44d Joseph Magen
hash = {}
classes.each do |klass|
if (mod = klass.module_name)
hash[mod] ||= []
hash[mod] << {:id => klass.id, :name => klass.name, :created_at => klass.created_at, :updated_at => klass.updated_at}
end
bd46fa41 Ohad Levy
end
96144a47 Daniel Lobato
hash
bd46fa41 Ohad Levy
end

# returns module name (excluding of the class name)
4ebe38c7 Ohad Levy
# if class separator does not exists (the "::" chars), then returns the whole class name
bd46fa41 Ohad Levy
def module_name
67799065 Ohad Levy
(i = name.index("::")) ? name[0..i-1] : name
bd46fa41 Ohad Levy
end

# returns class name (excluding of the module name)
def klass
67799065 Ohad Levy
name.gsub(module_name+"::","")
163711af Ohad Levy
end

83683ed0 Tomer Brisker
# return host ids from config groups by type
def host_ids_from_config_groups(host_type)
ids = config_groups.joins(:host_config_groups)
.where("host_config_groups.host_type='#{host_type}'")
.pluck('host_config_groups.host_id') unless config_group_classes.empty?
ids || []
end

def all_hostgroups(with_descendants = true)
ids = hostgroup_ids
ids += host_ids_from_config_groups('Hostgroup')
hgs = Hostgroup.unscoped.where(:id => ids.uniq)
eb8c02e1 Tomer Brisker
hgs = hgs.flat_map(&:subtree).uniq if with_descendants
hgs
83683ed0 Tomer Brisker
end

def all_hosts
ids = host_ids
ids += all_hostgroups.flat_map(&:host_ids)
ids += host_ids_from_config_groups('Host::Base')
Host::Managed.unscoped.where(:id => ids.uniq)
end

def update_total_hosts
update_attribute(:total_hosts, all_hosts.count)
end

a67b0923 Paul Kelly
# Populates the rdoc tree with information about all the classes in your modules.
# Firstly, we prepare the modules tree
# Secondly we run puppetdoc over the modulespath and manifestdir for all environments
# The results are written into document_root/puppet/rdoc/<env>/<class>"
5f029ed6 Daniel Lobato
def self.rdoc(root)
a67b0923 Paul Kelly
debug, verbose = false, false
relocated = root != "/" # This is true if the prepare phase copied the modules tree

# Retrieve an optional http server's DocumentRoot from the settings.yaml file, and prepare it for writing
76607ed5 Ohad Levy
doc_root = Pathname.new(Setting[:document_root])
a67b0923 Paul Kelly
doc_root.mkpath
unless doc_root.directory? and doc_root.writable?
puts "Unable to write html to #{doc_root}"
return false
end
aa6430ed Paul Kelly
validator = '<div id="validator-badges">'
a67b0923 Paul Kelly
# For each environment we write a puppetdoc tree
for env, path in Environment.puppetEnvs
# We may need to rewrite the modulepaths because they have been changed by the prepare step
modulepaths = relocated ? path.split(":").map{|p| root + p}.join(":") : path

# Identify and prepare the output directory
b04622a4 Lee Lowder
out = doc_root + env
a67b0923 Paul Kelly
out.rmtree if out.directory?

aa6430ed Paul Kelly
replacement = "<div id=\\\"validator-badges\\\"><small><a href=\\\"/puppet/rdoc/#{env}/\\\">[Browser]</a></small>"

a67b0923 Paul Kelly
# Create the documentation
aa6430ed Paul Kelly
815923d0 Paul Kelly
puts "*********Proccessing environment #{env} *************"
aa6430ed Paul Kelly
cmd = "puppetdoc --output #{out} --modulepath #{modulepaths} -m rdoc"
e4fde4e3 Ivan Nečas
puts cmd if Foreman.in_rake?
aa6430ed Paul Kelly
sh cmd do |ok, res|
815923d0 Paul Kelly
if ok
# Add a link to the class browser
96144a47 Daniel Lobato
files = `find #{out} -exec grep -l 'validator-badges' {} \\; 2>/dev/null`.gsub(/\n/, " ")
815923d0 Paul Kelly
if files.empty?
warn "No files to update with the browser link in #{out}. This is probably due to a previous error."
else
cmd = "ruby -p -i -e '$_.gsub!(/#{validator}/,\"#{replacement}\")' #{files}"
puts cmd if debug
afe02d30 Daniel Lobato
sh cmd
815923d0 Paul Kelly
end
# Relocate the paths for files and references if the manifests were relocated and sanitized
96144a47 Daniel Lobato
if relocated and (files = `find #{out} -exec grep -l '#{root}' {} \\;`.gsub(/\n/, " ")) != ""
815923d0 Paul Kelly
puts "Rewriting..." if verbose
cmd = "ruby -p -i -e 'rex=%r{#{root}};$_.gsub!(rex,\"\")' #{files}"
puts cmd if debug
sh cmd
# Now relocate the files/* files to match the rewritten url
mv Dir.glob("#{out}/files/#{root}/*"), "#{out}/files", :verbose => verbose
end
a67b0923 Paul Kelly
else
815923d0 Paul Kelly
logger.warn "Failed to process puppetdocs for #{out} while executing #{cmd}"
puts "Failed to process puppetdocs for #{out} while executing #{cmd}"
a67b0923 Paul Kelly
end
end
815923d0 Paul Kelly
puts
a67b0923 Paul Kelly
end
end

# Optionally creates a copy of the current puppet modules and sanitizes it.
# If your 'live' manifests and modules can be parsed by puppetdoc
4ebe38c7 Ohad Levy
# then you do not need to do this step. (Unfortunately some sites have circular
a67b0923 Paul Kelly
# symlinks which have to be removed.)
017e1049 Ohad Levy
# If the executable Rails,root/script/rdoc_prepare_script exists then it is run
a67b0923 Paul Kelly
# and passed a list of all directory paths in all environments.
# It should return the directory into which it has copied the cleaned modules"
5f029ed6 Daniel Lobato
def self.prepare_rdoc(root)
a67b0923 Paul Kelly
debug, verbose = false, false

017e1049 Ohad Levy
prepare_script = Pathname.new(Rails.root) + "script/rdoc_prepare_script.rb"
a67b0923 Paul Kelly
if prepare_script.executable?
dirs = Environment.puppetEnvs.values.join(":").split(":").uniq.sort.join(" ")
puts "Running #{prepare_script} #{dirs}" if debug
96144a47 Daniel Lobato
location = `#{prepare_script} #{dirs}`
4f7a4d0b David Davis
if $CHILD_STATUS == 0
a67b0923 Paul Kelly
root = location.chomp
puts "Relocated modules to #{root}" if verbose
end
else
puts "No executable #{prepare_script} found so using the uncopied module sources" if verbose
end
root
end
3aa6ea3f Ohad Levy
31207a31 Ohad Levy
def self.search_by_host(key, operator, value)
387b764b Amos Benari
conditions = sanitize_sql_for_conditions(["hosts.name #{operator} ?", value_to_sql(operator, value)])
0e1c5371 Tomer Brisker
direct = Puppetclass.joins(:hosts).where(conditions).uniq.pluck('puppetclasses.id')
aca6fd3a Joseph Mitchell Magen
hostgroup = Hostgroup.joins(:hosts).where(conditions).first
0e1c5371 Tomer Brisker
indirect = hostgroup.blank? ? [] : HostgroupClass.where(:hostgroup_id => hostgroup.path_ids).uniq.pluck('puppetclass_id')
aca6fd3a Joseph Mitchell Magen
return { :conditions => "1=0" } if direct.blank? && indirect.blank?

puppet_classes = (direct + indirect).uniq
{ :conditions => "puppetclasses.id IN(#{puppet_classes.join(',')})" }
31207a31 Ohad Levy
end
6e50fa1d Ohad Levy
end