foreman/app/models/hostgroup.rb @ 9d43fc71
4deab2f3 | Lukas Zapletal | class Hostgroup < ApplicationRecord
|
|
a03e5341 | Marek Hulan | audited
|
|
acfbc458 | Marek Hulan | include Authorizable
|
|
8b737c9c | Joseph Magen | extend FriendlyId
|
|
friendly_id :title
|
|||
611f5bff | Amos Benari | include Taxonomix
|
|
e5d3f34e | Ohad Levy | include HostCommon
|
|
0a17d4da | Tom Caspy | ||
7ff50dd8 | Joseph Magen | include NestedAncestryCommon
|
|
08763fc2 | Dominic Cleal | include NestedAncestryCommon::Search
|
|
3326499a | Daniel Lobato | ||
0a17d4da | Tom Caspy | validates :name, :presence => true, :uniqueness => {:scope => :ancestry, :case_sensitive => false}
|
|
9d56081f | Timo Goebel | validate :validate_subnet_types
|
|
6b65706a | Baptiste Agasse | validates_with SubnetsConsistencyValidator
|
|
9d56081f | Timo Goebel | ||
111cde57 | Joseph Magen | include ScopedSearchExtensions
|
|
b71d6837 | Shimon Shtein | include SelectiveClone
|
|
e2d3654e | Joseph Mitchell Magen | ||
5fbe760e | Ori Rabin | validates_lengths_from_database :except => [:name]
|
|
ff8cc704 | Joseph Mitchell Magen | before_destroy EnsureNotUsedBy.new(:hosts)
|
|
83683ed0 | Tomer Brisker | has_many :hostgroup_classes
|
|
has_many :puppetclasses, :through => :hostgroup_classes, :dependent => :destroy
|
|||
9c30b63e | Joseph Magen | validates :root_pass, :allow_blank => true, :length => {:minimum => 8, :message => _('should be 8 characters or more')}
|
|
998e1438 | Ori Rabin | has_many :group_parameters, :dependent => :destroy, :foreign_key => :reference_id, :inverse_of => :hostgroup
|
|
32ced385 | Ori Rabin | accepts_nested_attributes_for :group_parameters, :allow_destroy => true
|
|
998e1438 | Ori Rabin | include ParameterValidators
|
|
4cbf879e | Lukas Zapletal | include PxeLoaderValidator
|
|
include PxeLoaderSuggestion
|
|||
d7b8c7ad | Shlomi Zadok | alias_attribute :hostgroup_parameters, :group_parameters
|
|
fef6cff7 | Tomer Brisker | has_many_hosts
|
|
7d993b41 | Joseph Mitchell Magen | has_many :template_combinations, :dependent => :destroy
|
|
510d53cd | Marek Hulan | has_many :provisioning_templates, :through => :template_combinations
|
|
43c4bd72 | Marek Hulan | ||
c773c0ef | Tomer Brisker | belongs_to :domain
|
|
43c4bd72 | Marek Hulan | belongs_to :subnet
|
|
9d56081f | Timo Goebel | belongs_to :subnet6, :class_name => "Subnet"
|
|
43c4bd72 | Marek Hulan | ||
50541c05 | Ohad Levy | before_save :remove_duplicated_nested_class
|
|
36f93e4d | Ohad Levy | ||
1cb5ba7e | Stephen Benjamin | alias_attribute :arch, :architecture
|
|
e5d3f34e | Ohad Levy | alias_attribute :os, :operatingsystem
|
|
fe4629de | rbirnie | has_many :trends, :as => :trendable, :class_name => "ForemanTrend"
|
|
086ec942 | Ohad Levy | ||
d5d2d63f | Ondřej Pražák | nested_attribute_for :compute_profile_id, :environment_id, :domain_id, :puppet_proxy_id, :puppet_ca_proxy_id, :compute_resource_id,
|
|
4cbf879e | Lukas Zapletal | :operatingsystem_id, :architecture_id, :medium_id, :ptable_id, :subnet_id, :subnet6_id, :realm_id, :pxe_loader
|
|
34897490 | Joseph Magen | ||
611f5bff | Amos Benari | # with proc support, default_scope can no longer be chained
|
|
# include all default scoping here
|
|||
4b9d1fa7 | Stephen Benjamin | default_scope lambda {
|
|
with_taxonomy_scope do
|
|||
832c0925 | Joseph Magen | order("hostgroups.title")
|
|
4b9d1fa7 | Stephen Benjamin | end
|
|
}
|
|||
611f5bff | Amos Benari | ||
b80fa6f1 | Ohad Levy | scoped_search :on => :name, :complete_value => :true
|
|
9d43fc71 | Michael Moll | scoped_search :relation => :group_parameters, :on => :value, :on_key => :name, :complete_value => true, :only_explicit => true, :rename => :params
|
|
0c387178 | Marek Hulan | scoped_search :relation => :hosts, :on => :name, :complete_value => :true, :rename => "host", :only_explicit => true
|
|
2eb0e4de | Justin Sherrill | scoped_search :relation => :puppetclasses, :on => :name, :complete_value => true, :rename => :class, :only_explicit => true, :operators => ['= ', '~ ']
|
|
0c387178 | Marek Hulan | scoped_search :relation => :environment, :on => :name, :complete_value => :true, :rename => :environment, :only_explicit => true
|
|
3ab02530 | kgaikwad | scoped_search :on => :id, :complete_enabled => false, :only_explicit => true, :validator => ScopedSearch::Validators::INTEGER
|
|
d8894ebb | Ohad Levy | # for legacy purposes, keep search on :label
|
|
scoped_search :on => :title, :complete_value => true, :rename => :label
|
|||
ed67b8c9 | Dominic Cleal | scoped_search :relation => :config_groups, :on => :name, :complete_value => true, :rename => :config_group, :only_explicit => true, :operators => ['= ', '~ '], :ext_method => :search_by_config_group
|
|
111cde57 | Joseph Magen | ||
def self.search_by_config_group(key, operator, value)
|
|||
f4459c11 | David Davis | conditions = sanitize_sql_for_conditions(["config_groups.name #{operator} ?", value_to_sql(operator, value)])
|
|
111cde57 | Joseph Magen | hostgroup_ids = Hostgroup.unscoped.with_taxonomy_scope.joins(:config_groups).where(conditions).map(&:subtree_ids).flatten.uniq
|
|
opts = 'hostgroups.id < 0'
|
|||
85021506 | Michael Moll | opts = "hostgroups.id IN(#{hostgroup_ids.join(',')})" if hostgroup_ids.present?
|
|
96144a47 | Daniel Lobato | {:conditions => opts}
|
|
111cde57 | Joseph Magen | end
|
|
b80fa6f1 | Ohad Levy | if SETTINGS[:unattended]
|
|
0c387178 | Marek Hulan | scoped_search :relation => :architecture, :on => :name, :complete_value => true, :rename => :architecture, :only_explicit => true
|
|
scoped_search :relation => :operatingsystem, :on => :name, :complete_value => true, :rename => :os, :only_explicit => true
|
|||
scoped_search :relation => :operatingsystem, :on => :description, :complete_value => true, :rename => :os_description, :only_explicit => true
|
|||
scoped_search :relation => :operatingsystem, :on => :title, :complete_value => true, :rename => :os_title, :only_explicit => true
|
|||
scoped_search :relation => :operatingsystem, :on => :major, :complete_value => true, :rename => :os_major, :only_explicit => true
|
|||
scoped_search :relation => :operatingsystem, :on => :minor, :complete_value => true, :rename => :os_minor, :only_explicit => true
|
|||
3ab02530 | kgaikwad | scoped_search :relation => :operatingsystem, :on => :id, :complete_enabled => false, :rename => :os_id, :only_explicit => true, :validator => ScopedSearch::Validators::INTEGER
|
|
0c387178 | Marek Hulan | scoped_search :relation => :medium, :on => :name, :complete_value => true, :rename => "medium", :only_explicit => true
|
|
scoped_search :relation => :provisioning_templates, :on => :name, :complete_value => true, :rename => "template", :only_explicit => true
|
|||
b80fa6f1 | Ohad Levy | end
|
|
54358a76 | Greg Sutcliffe | # returns reports for hosts in the User's filter set
|
|
scope :my_groups, lambda {
|
|||
user = User.current
|
|||
f2c78d4a | Joseph Magen | unless user.admin?
|
|
89776bd5 | Ohad Levy | conditions = sanitize_sql_for_conditions([" (hostgroups.id in (?))", user.hostgroup_ids])
|
|
54358a76 | Greg Sutcliffe | conditions.sub!(/\s*\(\)\s*/, "")
|
|
conditions.sub!(/^(?:\(\))?\s?(?:and|or)\s*/, "")
|
|||
conditions.sub!(/\(\s*(?:or|and)\s*\(/, "((")
|
|||
end
|
|||
f2c78d4a | Joseph Magen | where(conditions)
|
|
54358a76 | Greg Sutcliffe | }
|
|
e5d3f34e | Ohad Levy | class Jail < Safemode::Jail
|
|
218bd6e0 | Justin Sherrill | allow :name, :diskLayout, :puppetmaster, :operatingsystem, :architecture,
|
|
4efcf484 | Ondrej Prazak | :environment, :ptable, :url_for_boot, :params, :puppetproxy,
|
|
:puppet_ca_server, :indent, :os, :arch, :domain, :subnet,
|
|||
959d3847 | Daniel Lobato Garcia | :subnet6, :realm, :root_pass, :description, :pxe_loader
|
|
e5d3f34e | Ohad Levy | end
|
|
68388bc2 | Michael Moll | # TODO: add a method that returns the valid os for a hostgroup
|
|
086ec942 | Ohad Levy | ||
9fd7478e | Paul Kelly | def hostgroup
|
|
self
|
|||
end
|
|||
e5d3f34e | Ohad Levy | ||
833e2aef | Amir Fefer | def self.title_name
|
|
"title".freeze
|
|||
end
|
|||
e5d3f34e | Ohad Levy | def diskLayout
|
|
de9e7ada | Marek Hulan | ptable.layout.tr("\r", '')
|
|
e5d3f34e | Ohad Levy | end
|
|
111cde57 | Joseph Magen | def all_config_groups
|
|
(config_groups + parent_config_groups).uniq
|
|||
end
|
|||
def parent_config_groups
|
|||
return [] unless parent
|
|||
groups = []
|
|||
ancestors.each do |hostgroup|
|
|||
groups += hostgroup.config_groups
|
|||
end
|
|||
96144a47 | Daniel Lobato | groups.uniq
|
|
2aabb456 | Ohad Levy | end
|
|
111cde57 | Joseph Magen | # the environment used by #clases nees to be self.environment and not self.parent.environment
|
|
def parent_classes
|
|||
return [] unless parent
|
|||
parent.classes(self.environment)
|
|||
4d4b84f6 | Ohad Levy | end
|
|
5f029ed6 | Daniel Lobato | def inherited_lookup_value(key)
|
|
84579c3a | David Davis | ancestors.reverse_each do |hg|
|
|
8ac0ffd9 | Michael Moll | if (v = LookupValue.find_by(:lookup_key_id => key.id, :id => hg.lookup_values))
|
|
0f9df583 | Amos Benari | return v.value, hg.to_label
|
|
end
|
|||
end if key.path_elements.flatten.include?("hostgroup") && Setting["host_group_matchers_inheritance"]
|
|||
96144a47 | Daniel Lobato | [key.default_value, _("Default value")]
|
|
0f9df583 | Amos Benari | end
|
|
e282ff7b | Ori Rabin | def parent_params(include_source = false)
|
|
4d4b84f6 | Ohad Levy | hash = {}
|
|
ids = ancestor_ids
|
|||
2aabb456 | Ohad Levy | # need to pull out the hostgroups to ensure they are sorted first,
|
|
# otherwise we might be overwriting the hash in the wrong order.
|
|||
e282ff7b | Ori Rabin | groups = Hostgroup.sort_by_ancestry(Hostgroup.includes(:group_parameters).find(ids))
|
|
2aabb456 | Ohad Levy | groups.each do |hg|
|
|
c7f55be1 | Ori Rabin | hg.group_parameters.authorized(:view_params).each {|p| hash[p.name] = include_source ? {:value => p.value, :source => p.associated_type, :safe_value => p.safe_value, :source_name => hg.title} : p.value }
|
|
96144a47 | Daniel Lobato | end
|
|
e282ff7b | Ori Rabin | hash
|
|
end
|
|||
04c6b019 | Tiffany | ||
e282ff7b | Ori Rabin | # returns self and parent parameters as a hash
|
|
def parameters(include_source = false)
|
|||
hash = parent_params(include_source)
|
|||
18c4b17f | Ori Rabin | group_parameters.each {|p| hash[p.name] = include_source ? {:value => p.value, :source => p.associated_type, :safe_value => p.safe_value, :source_name => title} : p.value }
|
|
4d4b84f6 | Ohad Levy | hash
|
|
end
|
|||
e14b6968 | Daniel Lobato | def global_parameters
|
|
4cdc0455 | Daniel Lobato | Hostgroup.sort_by_ancestry(Hostgroup.includes(:group_parameters).find(ancestor_ids + id)).map(&:group_parameters).uniq
|
|
e14b6968 | Daniel Lobato | end
|
|
e5d3f34e | Ohad Levy | def params
|
|
parameters = {}
|
|||
# read common parameters
|
|||
e5c21815 | Tomer Brisker | CommonParameter.where(nil).find_each {|p| parameters.update Hash[p.name => p.value] }
|
|
e5d3f34e | Ohad Levy | # read OS parameters
|
|
b03dcd1b | Michael Moll | operatingsystem&.os_parameters&.each {|p| parameters.update Hash[p.name => p.value] }
|
|
e5d3f34e | Ohad Levy | # read group parameters only if a host belongs to a group
|
|
1fa008a4 | Joseph Magen | parameters.update self.parameters if hostgroup
|
|
e5d3f34e | Ohad Levy | parameters
|
|
end
|
|||
f00eaf07 | Ohad Levy | # no need to store anything in the db if the password is our default
|
|
def root_pass
|
|||
74275f51 | Michael Moll | return self[:root_pass] if self[:root_pass].present?
|
|
db176297 | Dominic Cleal | npw = nested_root_pw
|
|
return npw if npw.present?
|
|||
Setting[:root_pass]
|
|||
f00eaf07 | Ohad Levy | end
|
|
b8b00a96 | Swapnil Abnave | def explicit_pxe_loader
|
|
74275f51 | Michael Moll | self[:pxe_loader].presence
|
|
b8b00a96 | Swapnil Abnave | end
|
|
def pxe_loader
|
|||
explicit_pxe_loader || nested(:pxe_loader).presence
|
|||
end
|
|||
b71d6837 | Shimon Shtein | include_in_clone :lookup_values, :hostgroup_classes, :locations, :organizations, :group_parameters
|
|
exclude_from_clone :name, :title, :lookup_value_matcher
|
|||
5eb88cf5 | Ori Rabin | # Clone the hostgroup
|
|
def clone(name = "")
|
|||
b71d6837 | Shimon Shtein | new = self.selective_clone
|
|
5eb88cf5 | Ori Rabin | new.name = name
|
|
9dd00534 | Tom Caspy | new.title = name
|
|
00335956 | Dominic Cleal | new.lookup_values.each do |lv|
|
|
lv.match = new.lookup_value_match
|
|||
lv.host_or_hostgroup = new
|
|||
end
|
|||
5f7e1ee4 | Tom Caspy | ||
new.config_groups = self.config_groups
|
|||
5eb88cf5 | Ori Rabin | new
|
|
end
|
|||
6d728e55 | amirfefer | def hosts_count
|
|
Host::Managed.authorized(:view_hosts, Host).where(:hostgroup => id).size
|
|||
end
|
|||
2fc4d6da | Shlomi Zadok | def children_hosts_count
|
|
fef6cff7 | Tomer Brisker | Host::Managed.authorized.where(:hostgroup => subtree_ids).size
|
|
2fc4d6da | Shlomi Zadok | end
|
|
abd38baa | Trey Dockendorf | # rebuilds orchestration configuration for hostgroup's hosts
|
|
# takes all the methods from Orchestration modules that are registered for configuration rebuild
|
|||
# arguments:
|
|||
# => only : Array of rebuild methods to execute (Example: ['TFTP'])
|
|||
# => children_hosts : Boolean that if true will operate on children hostgroup's hosts
|
|||
# returns : Hash with 'true' if rebuild was a success for a given key (Example: {'host.example.com': {"TFTP" => true, "DNS" => false}})
|
|||
def recreate_hosts_config(only = nil, children_hosts = false)
|
|||
result = {}
|
|||
e5c21815 | Tomer Brisker | Host::Managed.authorized.where(:hostgroup => (children_hosts ? subtree_ids : self.id)).find_each do |host|
|
|
abd38baa | Trey Dockendorf | result[host.name] = host.recreate_config(only)
|
|
end
|
|||
result
|
|||
end
|
|||
00335956 | Dominic Cleal | protected
|
|
d5707b63 | Ohad Levy | ||
7acc469b | Amos Benari | def lookup_value_match
|
|
"hostgroup=#{to_label}"
|
|||
end
|
|||
00335956 | Dominic Cleal | private
|
|
f00eaf07 | Ohad Levy | def nested_root_pw
|
|
84579c3a | David Davis | Hostgroup.sort_by_ancestry(ancestors).reverse_each do |a|
|
|
85021506 | Michael Moll | return a.root_pass if a.root_pass.present?
|
|
2aabb456 | Ohad Levy | end if ancestry.present?
|
|
f00eaf07 | Ohad Levy | nil
|
|
end
|
|||
50541c05 | Ohad Levy | def remove_duplicated_nested_class
|
|
self.puppetclasses -= ancestors.map(&:puppetclasses).flatten
|
|||
end
|
|||
1fa008a4 | Joseph Magen | # overwrite method in taxonomix, since hostgroup has ancestry
|
|
def used_taxonomy_ids(type)
|
|||
return [] if new_record? && parent_id.blank?
|
|||
ff1e9ffc | Dominic Cleal | Host::Base.where(:hostgroup_id => self.path_ids).distinct.pluck(type).compact
|
|
1fa008a4 | Joseph Magen | end
|
|
75dc676f | Tom Caspy | ||
def password_base64_encrypted?
|
|||
!root_pass_changed?
|
|||
end
|
|||
9d56081f | Timo Goebel | ||
def validate_subnet_types
|
|||
errors.add(:subnet, _("must be of type Subnet::Ipv4.")) if self.subnet.present? && self.subnet.type != 'Subnet::Ipv4'
|
|||
errors.add(:subnet6, _("must be of type Subnet::Ipv6.")) if self.subnet6.present? && self.subnet6.type != 'Subnet::Ipv6'
|
|||
end
|
|||
086ec942 | Ohad Levy | end
|