Project

General

Profile

« Previous | Next » 

Revision 007bf254

Added by Shimon Shtein over 7 years ago

Fixes #15403 - moved puppet to a concern in hosts UI controller

View differences:

app/controllers/concerns/foreman/controller/action_permission_dsl.rb
module Foreman::Controller::ActionPermissionDsl
extend ActiveSupport::Concern
included do |klass|
klass.class_attribute :action_permissions
end
module ClassMethods
def define_action_permission(actions, permission)
self.action_permissions ||= {}
# for single action case
[actions].flatten.each do |action|
self.action_permissions[action] = permission
end
end
end
def action_permission
action_permissions[params[:action]] || super
end
end
app/controllers/concerns/foreman/controller/puppet/hosts_controller_extensions.rb
module Foreman::Controller::Puppet::HostsControllerExtensions
extend ActiveSupport::Concern
PUPPETMASTER_ACTIONS=[ :externalNodes, :lookup ]
PUPPET_AJAX_REQUESTS=%w{hostgroup_or_environment_selected puppetclass_parameters}
MULTIPLE_EDIT_ACTIONS = %w(select_multiple_environment update_multiple_environment
select_multiple_puppet_proxy update_multiple_puppet_proxy
select_multiple_puppet_ca_proxy update_multiple_puppet_ca_proxy)
PUPPET_MULTIPLE_ACTIONS = %w(multiple_puppetrun update_multiple_puppetrun) + MULTIPLE_EDIT_ACTIONS
included do
add_smart_proxy_filters PUPPETMASTER_ACTIONS, :features => ['Puppet']
alias_method :find_resource_for_puppet_host_extensions, :find_resource
alias_method :ajax_request_for_puppet_host_extensions, :ajax_request
before_action :ajax_request_for_puppet_host_extensions, :only => PUPPET_AJAX_REQUESTS
before_action :find_resource_for_puppet_host_extensions, :only => [:puppetrun]
before_action :taxonomy_scope_for_puppet_host_extensions, :only => PUPPET_AJAX_REQUESTS
before_action :find_multiple_for_puppet_host_extensions, :only => PUPPET_MULTIPLE_ACTIONS
before_action :validate_multiple_puppet_proxy, :only => :update_multiple_puppet_proxy
before_action :validate_multiple_puppet_ca_proxy, :only => :update_multiple_puppet_ca_proxy
define_action_permission ['puppetrun', 'multiple_puppetrun', 'update_multiple_puppetrun'], :puppetrun
define_action_permission MULTIPLE_EDIT_ACTIONS, :edit
set_callback :set_class_variables, :after, :set_puppet_class_variables
end
def hostgroup_or_environment_selected
Taxonomy.as_taxonomy @organization, @location do
if params['host']['environment_id'].present? || params['host']['hostgroup_id'].present?
render :partial => 'puppetclasses/class_selection', :locals => {:obj => (refresh_host)}
else
logger.info "environment_id or hostgroup_id is required to render puppetclasses"
end
end
end
def puppetclass_parameters
Taxonomy.as_taxonomy @organization, @location do
render :partial => "puppetclasses/classes_parameters", :locals => { :obj => refresh_host}
end
end
def multiple_puppetrun
deny_access unless Setting[:puppetrun]
end
def update_multiple_puppetrun
return deny_access unless Setting[:puppetrun]
if @hosts.map(&:puppetrun!).uniq == [true]
notice _("Successfully executed, check reports and/or log files for more details")
else
error _("Some or all hosts execution failed, Please check log files for more information")
end
redirect_back_or_to hosts_path
end
def select_multiple_environment
end
def update_multiple_environment
# simple validations
if (params[:environment].nil?) || (id=params["environment"]["id"]).nil?
error _('No environment selected!')
redirect_to(select_multiple_environment_hosts_path)
return
end
ev = Environment.find_by_id(id)
#update the hosts
@hosts.each do |host|
host.environment = (id == 'inherit' && host.hostgroup.present?) ? host.hostgroup.environment : ev
host.save(:validate => false)
end
notice _('Updated hosts: changed environment')
redirect_back_or_to hosts_path
end
def environment_from_param
# simple validations
if (params[:environment].nil?) || (id=params["environment"]["id"]).nil?
error _('No environment selected!')
redirect_to(select_multiple_environment_hosts_path)
return
end
id
end
def get_environment_id(env_params)
env_params['id'] if env_params
end
def get_environment_for(host, id)
if id == 'inherit' && host.hostgroup.present?
host.hostgroup.environment
else
Environment.find_by_id(id)
end
end
def validate_multiple_puppet_proxy
validate_multiple_proxy(select_multiple_puppet_proxy_hosts_path)
end
def validate_multiple_puppet_ca_proxy
validate_multiple_proxy(select_multiple_puppet_ca_proxy_hosts_path)
end
def validate_multiple_proxy(redirect_path)
if params[:proxy].nil? || (proxy_id = params[:proxy][:proxy_id]).nil?
error _('No proxy selected!')
redirect_to(redirect_path)
return false
end
if !proxy_id.blank? && !SmartProxy.find_by_id(proxy_id)
error _('Invalid proxy selected!')
redirect_to(redirect_path)
return false
end
end
def update_multiple_proxy(proxy_type, host_update_method)
proxy_id = params[:proxy][:proxy_id]
if proxy_id
proxy = SmartProxy.find_by_id(proxy_id)
else
proxy = nil
end
failed_hosts = {}
@hosts.each do |host|
begin
host.send(host_update_method, proxy)
host.save!
rescue => error
failed_hosts[host.name] = error
message = _('Failed to set %{proxy_type} proxy for %{host}.') % {:host => host, :proxy_type => proxy_type}
Foreman::Logging.exception(message, error)
end
end
if failed_hosts.empty?
if proxy
notice _('The %{proxy_type} proxy of the selected hosts was set to %{proxy_name}.') % {:proxy_name => proxy.name, :proxy_type => proxy_type}
else
notice _('The %{proxy_type} proxy of the selected hosts was cleared.') % {:proxy_type => proxy_type}
end
else
error n_("The %{proxy_type} proxy could not be set for host: %{host_names}.",
"The %{proxy_type} puppet ca proxy could not be set for hosts: %{host_names}.",
failed_hosts.count) % {:proxy_type => proxy_type, :host_names => failed_hosts.map {|h, err| "#{h} (#{err})"}.to_sentence}
end
redirect_back_or_to hosts_path
end
def handle_proxy_messages(errors, proxy, proxy_type)
if errors.empty?
if proxy
notice _('The %{proxy_type} proxy of the selected hosts was set to %{proxy_name}.') % {:proxy_name => proxy.name, :proxy_type => proxy_type}
else
notice _('The %{proxy_type} proxy of the selected hosts was cleared.') % {:proxy_type => proxy_type}
end
else
error n_("The %{proxy_type} proxy could not be set for host: %{host_names}.",
"The %{proxy_type} puppet ca proxy could not be set for hosts: %{host_names}.",
errors.count) % {:proxy_type => proxy_type, :host_names => errors.map {|h, err| "#{h} (#{err})"}.to_sentence}
end
end
def select_multiple_puppet_proxy
end
def update_multiple_puppet_proxy
update_multiple_proxy(_('Puppet'), :puppet_proxy=)
end
def select_multiple_puppet_ca_proxy
end
def update_multiple_puppet_ca_proxy
update_multiple_proxy(_('Puppet CA'), :puppet_ca_proxy=)
end
def set_puppet_class_variables
@environment = @host.environment
end
def taxonomy_scope_for_puppet_host_extensions
taxonomy_scope
end
def find_multiple_for_puppet_host_extensions
find_multiple
end
end
app/controllers/hosts_controller.rb
class HostsController < ApplicationController
define_callbacks :set_class_variables
include Foreman::Controller::ActionPermissionDsl
include ScopesPerAction
include Foreman::Controller::HostDetails
include Foreman::Controller::AutoCompleteSearch
include Foreman::Controller::TaxonomyMultiple
include Foreman::Controller::SmartProxyAuth
include Foreman::Controller::Parameters::Host
include Foreman::Controller::Puppet::HostsControllerExtensions
PUPPETMASTER_ACTIONS=[ :externalNodes, :lookup ]
SEARCHABLE_ACTIONS= %w[index active errors out_of_sync pending disabled ]
AJAX_REQUESTS=%w{compute_resource_selected hostgroup_or_environment_selected current_parameters puppetclass_parameters process_hostgroup process_taxonomy review_before_build scheduler_hint_selected}
AJAX_REQUESTS=%w{compute_resource_selected current_parameters process_hostgroup process_taxonomy review_before_build scheduler_hint_selected}
BOOT_DEVICES={ :disk => N_('Disk'), :cdrom => N_('CDROM'), :pxe => N_('PXE'), :bios => N_('BIOS') }
MULTIPLE_ACTIONS = %w(multiple_parameters update_multiple_parameters select_multiple_hostgroup
update_multiple_hostgroup select_multiple_environment update_multiple_environment
update_multiple_hostgroup
multiple_destroy submit_multiple_destroy multiple_build
submit_multiple_build multiple_disable submit_multiple_disable
multiple_enable submit_multiple_enable multiple_puppetrun
update_multiple_puppetrun multiple_disassociate update_multiple_disassociate
multiple_enable submit_multiple_enable
multiple_disassociate update_multiple_disassociate
rebuild_config submit_rebuild_config select_multiple_owner update_multiple_owner
select_multiple_power_state update_multiple_power_state
select_multiple_puppet_proxy update_multiple_puppet_proxy
select_multiple_puppet_ca_proxy update_multiple_puppet_ca_proxy)
select_multiple_power_state update_multiple_power_state)
HOST_POWER = {
:on => { :state => 'on', :title => N_('On') },
......
:na => { :state => 'na', :title => N_('N/A') }
}.freeze
add_smart_proxy_filters PUPPETMASTER_ACTIONS, :features => ['Puppet']
before_action :ajax_request, :only => AJAX_REQUESTS + [:get_power_state]
before_action :find_resource, :only => [:show, :clone, :edit, :update, :destroy, :puppetrun, :review_before_build,
:setBuild, :cancelBuild, :power, :get_power_state, :overview, :bmc, :vm,
......
before_action :set_host_type, :only => [:update]
before_action :find_multiple, :only => MULTIPLE_ACTIONS
before_action :validate_power_action, :only => :update_multiple_power_state
before_action :validate_multiple_puppet_proxy, :only => :update_multiple_puppet_proxy
before_action :validate_multiple_puppet_ca_proxy, :only => :update_multiple_puppet_ca_proxy
helper :hosts, :reports, :interfaces
def index(title = nil)
......
redirect_back_or_to hosts_path
end
def select_multiple_environment
end
def update_multiple_environment
# simple validations
if (params[:environment].nil?) || (id=params["environment"]["id"]).nil?
error _('No environment selected!')
redirect_to(select_multiple_environment_hosts_path)
return
end
ev = Environment.find_by_id(id)
#update the hosts
@hosts.each do |host|
host.environment = (id == 'inherit' && host.hostgroup.present?) ? host.hostgroup.environment : ev
host.save(:validate => false)
end
notice _('Updated hosts: changed environment')
redirect_back_or_to hosts_path
end
def select_multiple_owner
end
......
redirect_back_or_to hosts_path
end
def select_multiple_puppet_proxy
end
def update_multiple_puppet_proxy
update_multiple_proxy(_('Puppet'), :puppet_proxy=)
end
def select_multiple_puppet_ca_proxy
end
def update_multiple_puppet_ca_proxy
update_multiple_proxy(_('Puppet CA'), :puppet_ca_proxy=)
end
def multiple_destroy
end
......
toggle_hostmode
end
def multiple_puppetrun
deny_access unless Setting[:puppetrun]
end
def update_multiple_puppetrun
return deny_access unless Setting[:puppetrun]
if @hosts.map(&:puppetrun!).uniq == [true]
notice _("Successfully executed, check reports and/or log files for more details")
else
error _("Some or all hosts execution failed, Please check log files for more information")
end
redirect_back_or_to hosts_path
end
def multiple_disassociate
@non_physical_hosts = @hosts.with_compute_resource
@physical_hosts = @hosts.to_a - @non_physical_hosts.to_a
......
end
@host.set_hostgroup_defaults true
@host.set_compute_attributes unless params[:host][:compute_profile_id]
@architecture = @host.architecture
@operatingsystem = @host.operatingsystem
@environment = @host.environment
@domain = @host.domain
@subnet = @host.subnet
@compute_profile = @host.compute_profile
@realm = @host.realm
set_class_variables(@host)
render :partial => "form"
end
......
@resource_base ||= Host.authorized(current_permission, Host)
end
def action_permission
case params[:action]
when 'clone', 'externalNodes', 'overview', 'bmc', 'vm', 'runtime', 'resources', 'templates', 'nics',
'pxe_config', 'storeconfig_klasses', 'active', 'errors', 'out_of_sync', 'pending', 'disabled',
'get_power_state'
:view
when 'puppetrun', 'multiple_puppetrun', 'update_multiple_puppetrun'
:puppetrun
when 'setBuild', 'cancelBuild', 'multiple_build', 'submit_multiple_build', 'review_before_build',
'rebuild_config', 'submit_rebuild_config'
:build
when 'power'
:power
when 'ipmi_boot'
:ipmi_boot
when 'console'
:console
when 'toggle_manage', 'multiple_parameters', 'update_multiple_parameters',
'select_multiple_hostgroup', 'update_multiple_hostgroup', 'select_multiple_environment',
'update_multiple_environment', 'multiple_disable', 'submit_multiple_disable',
'multiple_enable', 'submit_multiple_enable',
'update_multiple_organization', 'select_multiple_organization',
'update_multiple_location', 'select_multiple_location',
'disassociate', 'update_multiple_disassociate', 'multiple_disassociate',
'select_multiple_owner', 'update_multiple_owner',
'select_multiple_power_state', 'update_multiple_power_state',
'select_multiple_puppet_proxy', 'update_multiple_puppet_proxy',
'select_multiple_puppet_ca_proxy', 'update_multiple_puppet_ca_proxy',
'random_name'
:edit
when 'multiple_destroy', 'submit_multiple_destroy'
:destroy
else
super
end
end
define_action_permission [
'clone', 'externalNodes', 'overview', 'bmc', 'vm', 'runtime', 'resources', 'templates', 'nics',
'pxe_config', 'storeconfig_klasses', 'active', 'errors', 'out_of_sync', 'pending', 'disabled', 'get_power_state'], :view
define_action_permission [
'setBuild', 'cancelBuild', 'multiple_build', 'submit_multiple_build', 'review_before_build',
'rebuild_config', 'submit_rebuild_config'], :build
define_action_permission 'power', :power
define_action_permission 'ipmi_boot', :ipmi_boot
define_action_permission 'console', :console
define_action_permission [
'toggle_manage', 'multiple_parameters', 'update_multiple_parameters',
'select_multiple_hostgroup', 'update_multiple_hostgroup',
'multiple_disable', 'submit_multiple_disable',
'multiple_enable', 'submit_multiple_enable',
'update_multiple_organization', 'select_multiple_organization',
'update_multiple_location', 'select_multiple_location',
'disassociate', 'update_multiple_disassociate', 'multiple_disassociate',
'select_multiple_owner', 'update_multiple_owner',
'select_multiple_power_state', 'update_multiple_power_state', 'random_name'], :edit
define_action_permission ['multiple_destroy', 'submit_multiple_destroy'], :destroy
def refresh_host
@host = Host::Base.authorized(:view_hosts, Host).find_by_id(params['host_id'])
......
return unless @host
taxonomy_scope
@environment = @host.environment
@architecture = @host.architecture
@domain = @host.domain
@operatingsystem = @host.operatingsystem
@medium = @host.medium
if @host.compute_resource_id && params[:host] && params[:host][:compute_attributes]
@host.compute_attributes = params[:host][:compute_attributes]
end
set_class_variables(@host)
end
def find_multiple
......
raise Foreman::Exception.new(N_("No templates found")) if @templates.empty?
end
def set_class_variables(host)
run_callbacks :set_class_variables do
@architecture = host.architecture
@operatingsystem = host.operatingsystem
@domain = host.domain
@subnet = host.subnet
@compute_profile = host.compute_profile
@realm = host.realm
end
end
def host_power_ping(result)
timeout = 3
Timeout.timeout(timeout) do
test/unit/concerns/action_permission_dsl_test.rb
require 'test_helper'
module ActionPermissionDslTestModule
class DummyControllerBase
def action_permission
:base_controller_permission
end
end
class DummyController < DummyControllerBase
include ::Foreman::Controller::ActionPermissionDsl
attr_accessor :params
end
class ActionPermissionDslTest < ActiveSupport::TestCase
setup do
@storage = {}
DummyController.stubs(:action_permissions).returns(@storage)
end
test 'it enbales singular initialization' do
DummyController.define_action_permission :action1, :permission1
instance = DummyController.new
instance.params = {:action => :action1}
actual = instance.action_permission
assert_equal :permission1, actual
end
test 'it enables multiple initialization' do
DummyController.define_action_permission [:action1, :action2], :permission1
instance = DummyController.new
instance.params = {:action => :action1}
actual = instance.action_permission
assert_equal :permission1, actual
instance.params = {:action => :action2}
actual = instance.action_permission
assert_equal :permission1, actual
end
test 'it enables sequential initializations' do
DummyController.define_action_permission :action1, :permission1
DummyController.define_action_permission :action2, :permission1
instance = DummyController.new
instance.params = {:action => :action1}
actual = instance.action_permission
assert_equal :permission1, actual
instance.params = {:action => :action2}
actual = instance.action_permission
assert_equal :permission1, actual
end
test 'it runs the base method if the action was not specified explicitly' do
DummyController.define_action_permission :action1, :permission1
instance = DummyController.new
instance.params = {:action => :other_action}
actual = instance.action_permission
assert_equal :base_controller_permission, actual
end
end
end

Also available in: Unified diff