Project

General

Profile

Download (4.55 KB) Statistics
| Branch: | Tag: | Revision:
06823dc7 Ohad Levy
class SmartProxy < ActiveRecord::Base
acfbc458 Marek Hulan
include Authorizable
8b737c9c Joseph Magen
extend FriendlyId
friendly_id :name
611f5bff Amos Benari
include Taxonomix
e768c976 Tomas Strachota
include Parameterizable::ByIdName
229d7436 Joseph Magen
audited :allow_mass_assignment => true
a92cdd40 Greg Sutcliffe
62d3a341 Joseph Mitchell Magen
attr_accessible :name, :url, :location_ids, :organization_ids
3034e8e2 Ori Rabin
validates_lengths_from_database
f20ddfe4 Joseph Magen
before_destroy EnsureNotUsedBy.new(:hosts, :hostgroups, :subnets, :domains, :puppet_ca_hosts, :puppet_ca_hostgroups, :realms)
06823dc7 Ohad Levy
#TODO check if there is a way to look into the tftp_id too
a989a617 Ohad Levy
# maybe with a predefined sql
2755ebe9 Paul Kelly
has_and_belongs_to_many :features
1ad4782a Ohad Levy
has_many :subnets, :foreign_key => 'dhcp_id'
has_many :domains, :foreign_key => 'dns_id'
has_many_hosts :foreign_key => 'puppet_proxy_id'
has_many :hostgroups, :foreign_key => 'puppet_proxy_id'
has_many :puppet_ca_hosts, :class_name => 'Host::Managed', :foreign_key => 'puppet_ca_proxy_id'
has_many :puppet_ca_hostgroups, :class_name => 'Hostgroup', :foreign_key => 'puppet_ca_proxy_id'
77f70152 Stephen Benjamin
has_many :realms, :foreign_key => 'realm_proxy_id'
36f93e4d Ohad Levy
URL_HOSTNAME_MATCH = %r{^(?:http|https):\/\/([^:\/]+)}
f2c78d4a Joseph Magen
validates :name, :uniqueness => true, :presence => true
1ad4782a Ohad Levy
validates :url, :presence => true, :format => { :with => URL_HOSTNAME_MATCH, :message => N_('is invalid - only http://, https:// are allowed') },
:uniqueness => { :message => N_('Only one declaration of a proxy is allowed') }
36f93e4d Ohad Levy
2755ebe9 Paul Kelly
# There should be no problem with associating features before the proxy is saved as the whole operation is in a transaction
before_save :sanitize_url, :associate_features
36f93e4d Ohad Levy
acfbc458 Marek Hulan
scoped_search :on => :name, :complete_value => :true
428b1cfb Joseph Magen
scoped_search :on => :url, :complete_value => :true
scoped_search :in => :features, :on => :name, :rename => :feature, :complete_value => :true
acfbc458 Marek Hulan
611f5bff Amos Benari
# with proc support, default_scope can no longer be chained
# include all default scoping here
default_scope lambda {
with_taxonomy_scope do
1ad4782a Ohad Levy
order('smart_proxies.name')
611f5bff Amos Benari
end
}
a92cdd40 Greg Sutcliffe
bb3572ff Daniel Lobato
scope :with_features, ->(*feature_names) { where(:features => { :name => feature_names }).joins(:features) if feature_names.any? }
06823dc7 Ohad Levy
36f93e4d Ohad Levy
def hostname
# This will always match as it is validated
url.match(URL_HOSTNAME_MATCH)[1]
end

dbb7c2f2 Paul Kelly
def to_s
f5d4e70a Jeremy Kitchen
if Setting[:legacy_puppet_hostname]
1ad4782a Ohad Levy
hostname =~ /^puppet\./ ? 'puppet' : hostname
f5d4e70a Jeremy Kitchen
else
hostname
end
dbb7c2f2 Paul Kelly
end

2fa95807 Joseph Mitchell Magen
def self.smart_proxy_ids_for(hosts)
ids = []
43c4bd72 Marek Hulan
ids << hosts.joins(:primary_interface => :subnet).pluck('DISTINCT subnets.dhcp_id')
ids << hosts.joins(:primary_interface => :subnet).pluck('DISTINCT subnets.tftp_id')
ids << hosts.joins(:primary_interface => :subnet).pluck('DISTINCT subnets.dns_id')
ids << hosts.joins(:primary_interface => :domain).pluck('DISTINCT domains.dns_id')
77f70152 Stephen Benjamin
ids << hosts.joins(:realm).pluck('DISTINCT realm_proxy_id')
2fa95807 Joseph Mitchell Magen
ids << hosts.pluck('DISTINCT puppet_proxy_id')
ids << hosts.pluck('DISTINCT puppet_ca_proxy_id')
671b45e9 Joseph Mitchell Magen
ids << hosts.joins(:hostgroup).pluck('DISTINCT hostgroups.puppet_proxy_id')
ids << hosts.joins(:hostgroup).pluck('DISTINCT hostgroups.puppet_ca_proxy_id')
# returned both 7, "7". need to convert to integer or there are duplicates
1ad4782a Ohad Levy
ids.flatten.compact.map { |i| i.to_i }.uniq
2fa95807 Joseph Mitchell Magen
end

c3d8dd61 Dominic Cleal
def refresh
8b80115c Amos Benari
associate_features
errors
end

1fa008a4 Joseph Magen
def taxonomy_foreign_conditions
8f657a84 Stephen Benjamin
conditions = {}
if has_feature?('Puppet') && has_feature?('Puppet CA')
1fa008a4 Joseph Magen
conditions = "puppet_proxy_id = #{id} OR puppet_ca_proxy_id = #{id}"
8f657a84 Stephen Benjamin
elsif has_feature?('Puppet')
1fa008a4 Joseph Magen
conditions[:puppet_proxy_id] = id
8f657a84 Stephen Benjamin
elsif has_feature?('Puppet CA')
1fa008a4 Joseph Magen
conditions[:puppet_ca_proxy_id] = id
end
conditions
end

8f657a84 Stephen Benjamin
def has_feature?(feature)
self.features.any? { |proxy_feature| proxy_feature.name == feature }
end

06823dc7 Ohad Levy
private

2755ebe9 Paul Kelly
def sanitize_url
1ad4782a Ohad Levy
self.url.chomp!('/') unless url.empty?
77bbe487 Ohad Levy
end

2755ebe9 Paul Kelly
def associate_features
1ad4782a Ohad Levy
return true if Rails.env == 'test'
2755ebe9 Paul Kelly
begin
reply = ProxyAPI::Features.new(:url => url).features
31e8c71b Ohad Levy
if reply.is_a?(Array) and reply.any?
ba402a75 Stephen Benjamin
self.features = Feature.where(:name => reply.map{|f| Feature.name_map[f]})
31e8c71b Ohad Levy
else
c3d8dd61 Dominic Cleal
self.features.clear
1ad4782a Ohad Levy
errors.add :base, _('No features found on this proxy, please make sure you enable at least one feature')
31e8c71b Ohad Levy
end
2755ebe9 Paul Kelly
rescue => e
1ad4782a Ohad Levy
errors.add(:base, _('Unable to communicate with the proxy: %s') % e)
errors.add(:base, _('Please check the proxy is configured and running on the host.'))
2755ebe9 Paul Kelly
end
31e8c71b Ohad Levy
features.any?
06823dc7 Ohad Levy
end
end