Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes #16725 - add plugin extension point for smart proxies #3904

Merged
merged 1 commit into from
Oct 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/controllers/api/v2/domains_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ def show
param :domain, Hash, :required => true, :action_aware => true do
param :name, String, :required => true, :desc => N_("The full DNS domain name")
param :fullname, String, :required => false, :allow_nil => true, :desc => N_("Description of the domain")
param :dns_id, :number, :required => false, :allow_nil => true, :desc => N_("DNS proxy to use within this domain")
Domain.registered_smart_proxies.each do |name, options|
param :"#{name}_id", :number, :required => false, :allow_nil => true, :desc => options[:api_description]
end
param :domain_parameters_attributes, Array, :required => false, :desc => N_("Array of parameters (name, value)")
param_group :taxonomies, ::Api::V2::BaseController
end
Expand Down
5 changes: 3 additions & 2 deletions app/controllers/api/v2/hostgroups_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@ def show
param :pxe_loader, Operatingsystem.all_loaders, :desc => N_("DHCP filename option (Grub2/PXELinux by default)")
param :medium_id, :number, :desc => N_('Media ID')
param :ptable_id, :number, :desc => N_('Partition table ID')
param :puppet_ca_proxy_id, :number, :desc => N_('Puppet CA proxy ID')
param :subnet_id, :number, :desc => N_('Subnet ID')
param :domain_id, :number, :desc => N_('Domain ID')
param :realm_id, :number, :desc => N_('Realm ID')
param :puppet_proxy_id, :number, :desc => N_('Puppet proxy ID')
Hostgroup.registered_smart_proxies.each do |name, options|
param :"#{name}_id", :number, :desc => options[:api_description]
end
param :root_pass, String, :desc => N_('Root password on provisioned hosts')
param_group :taxonomies, ::Api::V2::BaseController
end
Expand Down
5 changes: 3 additions & 2 deletions app/controllers/api/v2/hosts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ def show
param :architecture_id, :number, :desc => N_("required if host is managed and value is not inherited from host group")
param :domain_id, :number, :desc => N_("required if host is managed and value is not inherited from host group")
param :realm_id, :number
param :puppet_proxy_id, :number
Host.registered_smart_proxies.each do |name, options|
param :"#{name}_id", :number, :desc => options[:api_description]
end
param :puppetclass_ids, Array
param :operatingsystem_id, String, :desc => N_("required if host is managed and value is not inherited from host group")
param :medium_id, String, :desc => N_("required if not imaged based provisioning and host is managed and value is not inherited from host group")
Expand All @@ -73,7 +75,6 @@ def show
param :hostgroup_id, :number
param :owner_id, :number
param :owner_type, Host::Base::OWNER_TYPES, :desc => N_("Host's owner type")
param :puppet_ca_proxy_id, :number
param :image_id, :number
param :host_parameters_attributes, Array, :desc => N_("Host's parameters (array or indexed hash)") do
param :name, String, :desc => N_("Name of the parameter"), :required => true
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/api/v2/realms_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ def show
def_param_group :realm do
param :realm, Hash, :required => true, :action_aware => true do
param :name, String, :required => true, :desc => N_("The realm name, e.g. EXAMPLE.COM")
param :realm_proxy_id, :number, :required => true, :allow_nil => true, :desc => N_("Proxy to use for this realm")
Realm.registered_smart_proxies.each do |name, options|
param :"#{name}_id", :number, :required => true, :allow_nil => true, :desc => options[:api_description]
end
param :realm_type, String, :required => true, :desc => N_("Realm type, e.g. FreeIPA or Active Directory")
param_group :taxonomies, ::Api::V2::BaseController
end
Expand Down
6 changes: 3 additions & 3 deletions app/controllers/api/v2/subnets_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ def show
param :to, String, :desc => N_("Ending IP Address for IP auto suggestion")
param :vlanid, String, :desc => N_("VLAN ID for this subnet")
param :domain_ids, Array, :desc => N_("Domains in which this subnet is part")
param :dhcp_id, :number, :desc => N_("DHCP Proxy to use within this subnet")
param :tftp_id, :number, :desc => N_("TFTP Proxy to use within this subnet")
param :dns_id, :number, :desc => N_("DNS Proxy to use within this subnet")
Subnet.registered_smart_proxies.each do |name, options|
param :"#{name}_id", :number, :desc => options[:api_description]
end
param :boot_mode, String, :desc => N_('Default boot mode for interfaces assigned to this subnet, valid values are "Static", "DHCP"')
param :subnet_parameters_attributes, Array, :required => false, :desc => N_("Array of parameters (name, value)")
param_group :taxonomies, ::Api::V2::BaseController
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ module Foreman::Controller::Parameters::Domain
extend ActiveSupport::Concern
include Foreman::Controller::Parameters::Parameter
include Foreman::Controller::Parameters::Taxonomix
include Foreman::Controller::Parameters::SmartProxiesCommon

class_methods do
def domain_params_filter
Foreman::ParameterFilter.new(::Domain).tap do |filter|
filter.permit :dns_id, :dns_name,
:fullname,
filter.permit :fullname,
:name,
:domain_parameters_attributes => [parameter_params_filter(DomainParameter)]
add_taxonomix_params_filter(filter)
add_smart_proxies_common_params_filter(filter)
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ def add_host_base_params_filter(filter)
:operatingsystem, :operatingsystem_id, :operatingsystem_name,
:organization, :organization_id, :organization_name,
:ptable, :ptable_id, :ptable_name,
:puppet_ca_proxy, :puppet_ca_proxy_id, :puppet_ca_proxy_name,
:puppet_proxy, :puppet_proxy_id, :puppet_proxy_name,
:progress_report, :progress_report_id, :progress_report_name,
:realm, :realm_id, :realm_name,
:subnet, :subnet_id, :subnet_name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Foreman::Controller::Parameters::HostCommon
extend ActiveSupport::Concern
include Foreman::Controller::Parameters::LookupValue
include Foreman::Controller::Parameters::Parameter
include Foreman::Controller::Parameters::SmartProxiesCommon

class_methods do
def add_host_common_params_filter(filter)
Expand All @@ -12,6 +13,7 @@ def add_host_common_params_filter(filter)
:lookup_value_matcher,
:use_image,
:lookup_values_attributes => [lookup_value_params_filter]
add_smart_proxies_common_params_filter(filter)
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ def hostgroup_params_filter
:operatingsystem_id, :operatingsystem_name,
:os, :os_id, :os_name,
:ptable_id, :ptable_name,
:puppet_ca_proxy_id, :puppet_ca_proxy_name,
:puppet_proxy_id, :puppet_proxy_name,
:config_group_names => [], :config_group_ids => [],
:puppetclass_ids => [], :puppetclass_names => [],
:group_parameters_attributes => [parameter_params_filter(::GroupParameter)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module Foreman::Controller::Parameters::Realm
extend ActiveSupport::Concern
include Foreman::Controller::Parameters::Taxonomix
include Foreman::Controller::Parameters::SmartProxiesCommon

class_methods do
def realm_params_filter
Expand All @@ -9,6 +10,7 @@ def realm_params_filter
:realm_type,
:realm_proxy, :realm_proxy_id, :realm_proxy_name
add_taxonomix_params_filter(filter)
add_smart_proxies_common_params_filter(filter)
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Foreman::Controller::Parameters::SmartProxiesCommon
extend ActiveSupport::Concern

class_methods do
def add_smart_proxies_common_params_filter(filter)
filter.resource_class.registered_smart_proxies.keys.each do |proxy|
filter.permit proxy, :"#{proxy}_id", :"#{proxy}_name"
end
filter
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ module Foreman::Controller::Parameters::Subnet
extend ActiveSupport::Concern
include Foreman::Controller::Parameters::Parameter
include Foreman::Controller::Parameters::Taxonomix
include Foreman::Controller::Parameters::SmartProxiesCommon

class_methods do
def subnet_params_filter
Foreman::ParameterFilter.new(::Subnet).tap do |filter|
filter.permit :boot_mode,
:cidr,
:dhcp, :dhcp_id,
:dns, :dns_id,
:dns_primary,
:dns_secondary,
:from,
Expand All @@ -19,13 +18,13 @@ def subnet_params_filter
:name,
:network,
:network_type,
:tftp, :tftp_id,
:to,
:type,
:vlanid,
:domain_ids => [], :domain_names => [],
:subnet_parameters_attributes => [parameter_params_filter(::SubnetParameter)]
add_taxonomix_params_filter(filter)
add_smart_proxies_common_params_filter(filter)
end
end
end
Expand Down
39 changes: 39 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -440,4 +440,43 @@ def webpack_dev_server
return unless Rails.configuration.webpack.dev_server.enabled
javascript_include_tag "#{@dev_server}/webpack-dev-server.js"
end

def accessible_resource_records(resource, order = :name)
klass = resource.to_s.classify.constantize
klass = klass.with_taxonomy_scope_override(@location, @organization) if klass.include? Taxonomix
klass.authorized.reorder(order)
end

def accessible_resource(obj, resource, order = :name)
list = accessible_resource_records(resource, order).to_a
# we need to allow the current value even if it was filtered
current = obj.public_send(resource) if obj.respond_to?(resource)
list |= [current] if current.present?
list
end

def accessible_related_resource(obj, relation, opts = {})
return [] if obj.blank?
order = opts.fetch(:order, :name)
where = opts.fetch(:where, nil)
related = obj.public_send(relation)
related = related.with_taxonomy_scope_override(@location, @organization) if obj.class.reflect_on_association(relation).klass.include?(Taxonomix)
related.authorized.where(where).reorder(order)
end

def explicit_value?(field)
return true if params[:action] == 'clone'
return false unless params[:host]
!!params[:host][field]
end

def user_set?(field)
# if the host has no hostgroup
return true unless @host && @host.hostgroup
# when editing a host, the values are specified explicitly
return true if params[:action] == 'edit'
return true if params[:action] == 'clone'
# check if the user set the field explicitly despite setting a hostgroup.
params[:host] && params[:host][:hostgroup_id] && params[:host][field]
end
end
74 changes: 0 additions & 74 deletions app/helpers/hosts_and_hostgroups_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,6 @@ def model_name(host)
name
end

def accessible_resource_records(resource, order = :name)
klass = resource.to_s.classify.constantize
klass = klass.with_taxonomy_scope_override(@location, @organization) if klass.include? Taxonomix
klass.authorized.reorder(order)
end

def accessible_resource(obj, resource, order = :name)
list = accessible_resource_records(resource, order).to_a
# we need to allow the current value even if it was filtered
current = obj.public_send(resource) if obj.respond_to?(resource)
list |= [current] if current.present?
list
end

def accessible_related_resource(obj, relation, opts = {})
return [] if obj.blank?
order = opts.fetch(:order, :name)
where = opts.fetch(:where, nil)
related = obj.public_send(relation)
related = related.with_taxonomy_scope_override(@location, @organization) if obj.class.reflect_on_association(relation).klass.include?(Taxonomix)
related.authorized.where(where).reorder(order)
end

def parent_classes(obj)
return obj.hostgroup.classes if obj.is_a?(Host::Base) && obj.hostgroup
return obj.is_root? ? [] : obj.parent.classes if obj.is_a?(Hostgroup)
Expand Down Expand Up @@ -66,43 +43,8 @@ def os_ptable
accessible_related_resource(@operatingsystem, :ptables)
end

def puppet_master_fields(f, can_override = false, override = false)
"#{puppet_ca(f, can_override, override)} #{puppet_master(f, can_override, override)}".html_safe
end

INHERIT_TEXT = N_("inherit")

def puppet_ca(f, can_override, override)
# Don't show this if we have no CA proxies, otherwise always include blank
# so the user can choose not to sign the puppet cert on this host
proxies = accessible_puppet_ca_proxies(f.object)
return unless proxies.present?
select_f f, :puppet_ca_proxy_id, proxies, :id, :name,
{ :include_blank => blank_or_inherit_f(f, :puppet_ca_proxy),
:disable_button => can_override ? _(INHERIT_TEXT) : nil,
:disable_button_enabled => override && !explicit_value?(:puppet_ca_proxy_id),
:user_set => user_set?(:puppet_ca_proxy_id)
},
{ :label => _("Puppet CA"),
:help_inline => _("Use this puppet server as a CA server") }
end

def puppet_master(f, can_override, override)
# Don't show this if we have no Puppet proxies, otherwise always include blank
# so the user can choose not to use puppet on this host
proxies = accessible_puppet_proxies(f.object)
return unless proxies.present?
select_f f, :puppet_proxy_id, proxies, :id, :name,
{ :include_blank => blank_or_inherit_f(f, :puppet_proxy),
:disable_button => can_override ? _(INHERIT_TEXT) : nil,
:disable_button_enabled => override && !explicit_value?(:puppet_proxy_id),
:user_set => user_set?(:puppet_proxy_id)

},
{ :label => _("Puppet Master"),
:help_inline => _("Use this puppet server as an initial Puppet Server or to execute puppet runs") }
end

def realm_field(f, can_override = false, override = false)
# Don't show this if we have no Realms, otherwise always include blank
# so the user can choose not to use a Realm on this host
Expand Down Expand Up @@ -185,22 +127,6 @@ def interesting_puppetclasses(obj)
classes.where(:id => klasses)
end

def explicit_value?(field)
return true if params[:action] == 'clone'
return false unless params[:host]
!!params[:host][field]
end

def user_set?(field)
# if the host has no hostgroup
return true unless @host && @host.hostgroup
# when editing a host, the values are specified explicitly
return true if params[:action] == 'edit'
return true if params[:action] == 'clone'
# check if the user set the field explicitly despite setting a hostgroup.
params[:host] && params[:host][:hostgroup_id] && params[:host][field]
end

def puppetclasses_tab(puppetclasses_receiver)
return unless accessible_puppet_proxies(puppetclasses_receiver).present?
content_tag(:div, :class => 'tab-pane', :id => 'puppet_klasses') do
Expand Down
42 changes: 42 additions & 0 deletions app/helpers/shared_smart_proxies_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module SharedSmartProxiesHelper
def smart_proxy_fields(f, options = {})
object = options.fetch(:object, f.object)

safe_join(object.registered_smart_proxies.map do |proxy_name, proxy_options|
smart_proxy_select_f(f, proxy_name, options.merge(proxy_options))
end)
end

INHERIT_TEXT = N_("inherit")

def smart_proxy_select_f(f, resource, options)
required = options.fetch(:required, false)
hidden = options[:if].present? && !options[:if].call(f.object)
can_override = options.fetch(:can_override, false)
override = options.fetch(:override, false)
blank = options.fetch(:blank, blank_or_inherit_f(f, resource))

proxies = accessible_smart_proxies(f.object, resource, options[:feature])
return if !required && !proxies.present?

select_options = {
:disable_button => can_override ? _(INHERIT_TEXT) : nil,
:disable_button_enabled => override && !explicit_value?(:"#{resource}_id"),
:user_set => user_set?(:"#{resource}_id")
}
select_options[:include_blank] = blank unless required

select_f f, :"#{resource}_id", proxies, :id, :name,
select_options,
:label => _(options[:label]),
:help_inline => _(options[:description]),
:wrapper_class => "form-group #{'hide' if hidden}"
end

def accessible_smart_proxies(obj, resource, feature)
list = accessible_resource_records(:smart_proxy).with_features(feature).to_a
current = obj.public_send(resource) if obj.respond_to?(resource)
list |= [current] if current.present?
list
end
end
Loading