Skip to content

Commit

Permalink
Add environment field to Host(group) form
Browse files Browse the repository at this point in the history
Adds all js necessary to handle the environment field change.
Moves puppet parameters to the Puppet ENC tab.
  • Loading branch information
ezr-ondrej committed Oct 30, 2020
1 parent 1f14b27 commit 8e74cb1
Show file tree
Hide file tree
Showing 22 changed files with 994 additions and 109 deletions.
5 changes: 4 additions & 1 deletion .rubocop.yml
Expand Up @@ -4,13 +4,16 @@ inherit_gem:

inherit_from: .rubocop_todo.yml

inherit_mode:
merge:
- Exclude

Layout/ArgumentAlignment:
EnforcedStyle: with_fixed_indentation
IndentationWidth: 2

Rails/SkipsModelValidations:
Exclude:
- 'db/migrate/**/*'
- 'db/migrate_foreman/**/*'

Style/FormatStringToken:
Expand Down
@@ -0,0 +1,38 @@
module ForemanPuppetEnc
module Extensions
module HostgroupsControllerExtensions
extend ActiveSupport::Concern

PUPPET_AJAX_REQUESTS = %w[environment_selected puppetclass_parameters].freeze

included do
alias_method :ajax_request_for_puppet_hostgroup_extensions, :ajax_request
alias_method :taxonomy_scope_for_puppet_hostgroup_extensions, :taxonomy_scope

before_action :ajax_request_for_puppet_hostgroup_extensions, only: PUPPET_AJAX_REQUESTS
before_action :taxonomy_scope_for_puppet_hostgroup_extensions, only: PUPPET_AJAX_REQUESTS

helper ForemanPuppetEnc::HostsAndHostgroupsHelper
end

def environment_selected
env_id = params[:environment_id] || params[:hostgroup][:environment_id]
return not_found if env_id.to_i.positive? && !(@environment = Environment.find(env_id))

refresh_hostgroup
@hostgroup.environment = @environment if @environment

@hostgroup.puppetclasses = Puppetclass.where(id: params[:hostgroup][:puppetclass_ids])
@hostgroup.config_groups = ConfigGroup.where(id: params[:hostgroup][:config_group_ids])
render partial: 'hosts/form_puppet_enc_tab', locals: { obj: @hostgroup, resource_type: :hostgroup }
end

def puppetclass_parameters
Taxonomy.as_taxonomy @organization, @location do
render partial: 'foreman_puppet_enc/puppetclasses/classes_parameters',
locals: { obj: refresh_hostgroup }
end
end
end
end
end
Expand Up @@ -24,15 +24,15 @@ module HostsControllerExtensions

set_callback :set_class_variables, :after, :set_puppet_class_variables

helper ForemanPuppetEnc::HostsHelper
helper ForemanPuppetEnc::HostsAndHostgroupsHelper
end

def hostgroup_or_environment_selected
refresh_host
set_class_variables(@host)
Taxonomy.as_taxonomy @organization, @location do
if @environment || @hostgroup
render partial: 'puppetclasses/class_selection', locals: { obj: @host, resource_type: :host }
render partial: 'hosts/form_puppet_enc_tab', locals: { obj: @host, resource_type: :host }
else
logger.info 'environment_id or hostgroup_id is required to render puppetclasses'
end
Expand All @@ -41,7 +41,7 @@ def hostgroup_or_environment_selected

def puppetclass_parameters
Taxonomy.as_taxonomy @organization, @location do
render partial: 'puppetclasses/classes_parameters', locals: { obj: refresh_host }
render partial: 'foreman_puppet_enc/puppetclasses/classes_parameters', locals: { obj: refresh_host }
end
end

Expand Down
84 changes: 84 additions & 0 deletions app/helpers/foreman_puppet_enc/hosts_and_hostgroups_helper.rb
@@ -0,0 +1,84 @@
module ForemanPuppetEnc
module HostsAndHostgroupsHelper
UI.register_host_description do
multiple_actions_provider :puppet_host_multiple_actions
end

# TODO: remove me - prevents the puppetclass tab duplication
def puppetclasses_tab(puppetclasses_receiver)
end

def puppet_host_multiple_actions
if ForemanPuppetEnc.extracted_from_core?
[{ action: [_('Change Environment'), foreman_puppet_enc.select_multiple_environment_hosts_path], priority: 200 }]
else
[]
end
end

def host_puppet_environment_field(form, select_options = {}, html_options = {})
select_options = {
include_blank: true,
disable_button: _(::HostsAndHostgroupsHelper::INHERIT_TEXT),
disable_button_enabled: inherited_by_default?(:environment_id, form.object),
user_set: user_set?(:environment_id),
}.deep_merge(select_options)

html_options = {
data: {
host: {
id: form.object.id,
},
},
}.deep_merge(html_options)

puppet_environment_field(
form,
accessible_resource(form.object, :environment),
select_options,
html_options
)
end

def hostgroup_puppet_environment_field(form, select_options = {}, html_options = {})
select_options = {
include_blank: blank_or_inherit_f(form, :environment),
}.deep_merge(select_options)

puppet_environment_field(
form,
accessible_resource(form.object, :environment),
select_options,
html_options
)
end

def puppet_environment_field(form, environments_choice, select_options = {}, html_options = {})
html_options = {
onchange: 'tfm.puppetEnc.hostForm.updatePuppetclasses(this)',
help_inline: :indicator,
}.deep_merge(html_options)

select_f(
form,
:environment_id,
environments_choice,
:id,
:to_label,
select_options,
html_options
)
end

def puppetclasses_with_parameters_for(obj)
classes = obj.all_puppetclasses
ids = classes.reorder(nil).pluck(:id)
class_vars = ForemanPuppetEnc::PuppetclassLookupKey.reorder(nil)
.joins(:environment_classes)
.where(EnvironmentClass.arel_table[:puppetclass_id].in(ids))
.distinct
.pluck('environment_classes.puppetclass_id')
classes.where(id: class_vars)
end
end
end
15 changes: 0 additions & 15 deletions app/helpers/foreman_puppet_enc/hosts_helper.rb

This file was deleted.

17 changes: 13 additions & 4 deletions app/views/hosts/_form_puppet_enc_tab.html.erb
@@ -1,14 +1,23 @@
<% obj = local_assigns[pagelet.opts[:resource_type]] %>
<% resource_type ||= pagelet.opts[:resource_type] %>
<% obj ||= local_assigns[resource_type] %>
<% if resource_type == :host %>
<span id="puppet_klasses_reload_url" data-url="<%= foreman_puppet_enc.hostgroup_or_environment_selected_hosts_path %>"></span>
<% elsif resource_type == :hostgroup %>
<span id="puppet_klasses_reload_url" data-url="<%= foreman_puppet_enc.environment_selected_hostgroups_path %>"></span>
<% end %>
<% if @environment.present? || obj.environment.present? %>
<% if accessible_resource_records(:config_group).exists? %>
<%= render 'foreman_puppet_enc/config_groups/config_groups_selection', obj: obj, resource_type: pagelet.opts[:resource_type] %>
<%= render 'foreman_puppet_enc/config_groups/config_groups_selection', obj: obj, resource_type: resource_type %>
<% end %>
<%= render 'foreman_puppet_enc/puppetclasses/class_selection', obj: obj, resource_type: pagelet.opts[:resource_type] %>
<%= render 'foreman_puppet_enc/puppetclasses/class_selection', obj: obj, resource_type: resource_type %>
<% else %>
<%= alert(class: alert_class(:info),
header: _('Notice'),
text: _('Please select an environment first')) %>
<% end %>


<fieldset id="puppet_klasses_parameters" data-url="<%= foreman_puppet_enc.url_for(action: :puppetclass_parameters, only_path: true) %>">
<h2><%= _('Puppet Class Parameters') %></h2>
<%= render 'foreman_puppet_enc/puppetclasses/classes_parameters', obj: obj %>
</fieldset>
@@ -0,0 +1 @@
<%= public_send("#{pagelet.opts[:resource_type]}_puppet_environment_field", form) %>
9 changes: 9 additions & 0 deletions config/routes.rb
Expand Up @@ -26,10 +26,19 @@

resources :hosts, only: [], controller: '/hosts' do
collection do
post 'hostgroup_or_environment_selected'
post 'puppetclass_parameters'
match 'select_multiple_environment', via: %i[get post]
post 'update_multiple_environment'
end
end

resources :hostgroups, only: [], controller: '/hostgroups' do
collection do
post 'environment_selected'
post 'puppetclass_parameters'
end
end
end

Foreman::Application.routes.draw do
Expand Down
1 change: 1 addition & 0 deletions lib/foreman_puppet_enc/engine.rb
Expand Up @@ -26,6 +26,7 @@ class Engine < ::Rails::Engine
# To stay
LookupValue.include ForemanPuppetEnc::PuppetLookupValueExtensions
HostsController.include ForemanPuppetEnc::Extensions::HostsControllerExtensions
HostgroupsController.include ForemanPuppetEnc::Extensions::HostgroupsControllerExtensions
end

rake_tasks do
Expand Down
17 changes: 16 additions & 1 deletion lib/foreman_puppet_enc/register.rb
Expand Up @@ -143,17 +143,32 @@
end
end

unless ForemanPuppetEnc.extracted_from_core?
Rails.application.config.after_initialize do
list = Pagelets::Manager.instance.instance_variable_get(:@pagelets)['hosts/_form'][:main_tabs]
core_pagelet = list.detect { |pagelet| pagelet.opts[:id] == :puppet_klasses }
list.delete(core_pagelet)
end
end

# extend host(group) form with puppet ENC Tab
%i[host hostgroup].each do |resource_type|
host_onlyif = ->(host, context) { context.send(:accessible_resource, host, :smart_proxy, :name, association: :puppet_proxy).present? }
extend_page("#{resource_type}s/_form") do |context|
context.add_pagelet :main_tabs,
id: :puppet_klasses,
id: :puppet_enc_tab,
name: N_('Puppet ENC'),
partial: 'hosts/form_puppet_enc_tab',
resource_type: resource_type,
priority: 100,
onlyif: (host_onlyif if resource_type == :host)

if ForemanPuppetEnc.extracted_from_core?
context.add_pagelet :main_tab_fields,
partial: 'hosts/foreman_puppet_enc/form_main_tab_fields',
resource_type: resource_type,
priority: 100
end
end
end
end
73 changes: 73 additions & 0 deletions test/controllers/foreman_puppet_enc/hostgroups_controller_test.rb
@@ -0,0 +1,73 @@
require 'test_puppet_enc_helper'

module ForemanPuppetEnc
class HostgroupsControllerTest < ActionController::TestCase
tests ::HostgroupsController

setup do
@routes = ForemanPuppetEnc::Engine.routes
end

describe '#environment_selected' do
setup do
@environment = FactoryBot.create(:environment)
@puppetclass = FactoryBot.create(:puppetclass)
@hostgroup = FactoryBot.create(:hostgroup, environment: @environment)
@params = {
id: @hostgroup.id,
hostgroup: {
name: @hostgroup.name,
environment_id: '',
puppetclass_ids: [@puppetclass.id],
},
}
end

test 'should return the selected puppet classes on environment change' do
assert_equal 0, @hostgroup.puppetclasses.length

post :environment_selected, params: @params, session: set_session_user, xhr: true
assert_equal(1, assigns(:hostgroup).puppetclasses.length)
assert_include assigns(:hostgroup).puppetclasses, @puppetclass
end

context 'environment_id param is set' do
test 'it will take the hostgroup params environment_id' do
other_environment = FactoryBot.create(:environment)
@params[:hostgroup][:environment_id] = other_environment.id

post :environment_selected, params: @params, session: set_session_user, xhr: true
assert_equal assigns(:environment), other_environment
end
end

test 'should not escape lookup values on environment change' do
skip 'Needs fully extracted puppet' unless ForemanPuppetEnc.extracted_from_core?
hostgroup = FactoryBot.create(:hostgroup, environment: @environment, puppetclass_ids: [@puppetclass.id])
lookup_key = FactoryBot.create(:puppetclass_lookup_key, :array, default_value: %w[a b],
override: true,
puppetclass: @puppetclass,
overrides: { "hostgroup=#{hostgroup.name}" => %w[c d] })
lookup_value = lookup_key.lookup_values.first
FactoryBot.create(:environment_class, puppetclass: @puppetclass, environment: @environment, puppetclass_lookup_key: lookup_key)

# sending exactly what the host form would send which is lookup_value.value_before_type_cast
lk = { 'lookup_values_attributes' => { lookup_key.id.to_s => { 'value' => lookup_value.value_before_type_cast,
'id' => lookup_value.id,
'lookup_key_id' => lookup_key.id,
'_destroy' => false } } }

params = {
hostgroup_id: hostgroup.id,
hostgroup: hostgroup.attributes.merge(lk),
}

# environment change calls puppetclass_parameters which caused the extra escaping
post :puppetclass_parameters, params: params, session: set_session_user, xhr: true

# if this was escaped during refresh_host the value in response.body after unescapeHTML would include "[\\\"c\\\",\\\"d\\\"]"
assert_includes CGI.unescapeHTML(response.body), '["c","d"]'
end
end
end
end

0 comments on commit 8e74cb1

Please sign in to comment.