diff --git a/app/assets/images/svg/vendor-ansible_tower_configuration.svg b/app/assets/images/svg/vendor-ansible_tower_automation.svg similarity index 98% rename from app/assets/images/svg/vendor-ansible_tower_configuration.svg rename to app/assets/images/svg/vendor-ansible_tower_automation.svg index 931b7f796b8..abf75db448e 100644 --- a/app/assets/images/svg/vendor-ansible_tower_configuration.svg +++ b/app/assets/images/svg/vendor-ansible_tower_automation.svg @@ -1,10 +1,10 @@ - - - - - - + + + + + + diff --git a/app/assets/javascripts/controllers/automation_manager/automation_manager_form_controller.js b/app/assets/javascripts/controllers/automation_manager/automation_manager_form_controller.js new file mode 100644 index 00000000000..ed49f664f38 --- /dev/null +++ b/app/assets/javascripts/controllers/automation_manager/automation_manager_form_controller.js @@ -0,0 +1,116 @@ +ManageIQ.angular.app.controller('automationManagerFormController', ['$http', '$scope', 'automationManagerFormId', 'miqService', function($http, $scope, automationManagerFormId, miqService) { + $scope.automationManagerModel = { + name: '', + url: '', + zone: '', + verify_ssl: '', + log_userid: '', + log_password: '', + log_verify: '', + }; + $scope.formId = automationManagerFormId; + $scope.afterGet = false; + $scope.validateClicked = miqService.validateWithAjax; + $scope.modelCopy = angular.copy( $scope.automationManagerModel ); + $scope.model = 'automationManagerModel'; + + ManageIQ.angular.scope = $scope; + + if (automationManagerFormId === 'new') { + $scope.newRecord = true; + + $scope.automationManagerModel.name = ''; + $scope.automationManagerModel.url = ''; + $scope.automationManagerModel.verify_ssl = false; + $scope.automationManagerModel.log_userid = ''; + $scope.automationManagerModel.log_password = ''; + $scope.automationManagerModel.log_verify = ''; + + $http.get('/automation_manager/automation_manager_form_fields/' + automationManagerFormId) + .then(getAutomationManagerNewFormDataComplete) + .catch(miqService.handleFailure); + } else { + $scope.newRecord = false; + miqService.sparkleOn(); + + $http.get('/automation_manager/automation_manager_form_fields/' + automationManagerFormId) + .then(getAutomationManagerFormDataComplete) + .catch(miqService.handleFailure); + + miqService.sparkleOff(); + } + + function getAutomationManagerNewFormDataComplete(response) { + var data = response.data; + $scope.afterGet = true; + $scope.automationManagerModel.zone = data.zone; + $scope.modelCopy = angular.copy($scope.automationManagerModel); + } + + function getAutomationManagerFormDataComplete(response) { + var data = response.data; + $scope.afterGet = true; + + $scope.automationManagerModel.name = data.name; + $scope.automationManagerModel.zone = data.zone; + $scope.automationManagerModel.url = data.url; + $scope.automationManagerModel.verify_ssl = data.verify_ssl == "1"; + + $scope.automationManagerModel.log_userid = data.log_userid; + + if($scope.automationManagerModel.log_userid != '') { + $scope.automationManagerModel.log_password = $scope.automationManagerModel.log_verify = miqService.storedPasswordPlaceholder; + } + $scope.modelCopy = angular.copy( $scope.automationManagerModel ); + } + + $scope.canValidateBasicInfo = function() { + if ($scope.isBasicInfoValid()) { + return true; + } + else { + return false; + } + }; + + $scope.isBasicInfoValid = function() { + if($scope.angularForm.url.$valid && + $scope.angularForm.log_userid.$valid && + $scope.angularForm.log_password.$valid && + $scope.angularForm.log_verify.$valid) + return true; + else + return false; + }; + + var automationManagerEditButtonClicked = function(buttonName, serializeFields) { + miqService.sparkleOn(); + var url = '/automation_manager/edit/' + automationManagerFormId + '?button=' + buttonName; + if (serializeFields === undefined) { + miqService.miqAjaxButton(url); + } else { + miqService.miqAjaxButton(url, serializeFields); + } + }; + + $scope.cancelClicked = function() { + automationManagerEditButtonClicked('cancel'); + $scope.angularForm.$setPristine(true); + }; + + $scope.resetClicked = function() { + $scope.$broadcast('resetClicked'); + $scope.automationManagerModel = angular.copy( $scope.modelCopy ); + $scope.angularForm.$setPristine(true); + miqService.miqFlash('warn', __('All changes have been reset')); + }; + + $scope.saveClicked = function() { + automationManagerEditButtonClicked('save', true); + $scope.angularForm.$setPristine(true); + }; + + $scope.addClicked = function() { + $scope.saveClicked(); + }; +}]); diff --git a/app/controllers/application_controller/ci_processing.rb b/app/controllers/application_controller/ci_processing.rb index 6c1b9c433cb..c185a8fb605 100644 --- a/app/controllers/application_controller/ci_processing.rb +++ b/app/controllers/application_controller/ci_processing.rb @@ -1944,7 +1944,7 @@ def process_objects(objs, task, display_name = nil) :models => ui_lookup(:models => klass.to_s)}) end - def foreman_button_operation(method, display_name) + def manager_button_operation(method, display_name) items = [] if params[:id] if params[:id].nil? || !ExtManagementSystem.where(:id => params[:id]).exists? @@ -1959,25 +1959,30 @@ def foreman_button_operation(method, display_name) if items.empty? add_flash(_("No providers were selected for %{task}") % {:task => display_name}, :error) else - process_cfgmgr(items, method) unless items.empty? && !flash_errors? + process_managers(items, method) unless items.empty? && !flash_errors? end end - def process_cfgmgr(providers, task) - providers, _services_out_region = filter_ids_in_region(providers, "ManageIQ::Providers::ConfigurationManager") - return if providers.empty? + def process_managers(managers, task) + controller_class = request.parameters[:controller] + provider_class = case controller_class + when 'provider_foreman' then ManageIQ::Providers::ConfigurationManager + when 'automation_manager' then ManageIQ::Providers::AutomationManager + end - options = {:ids => providers, :task => task, :userid => session[:userid]} - kls = ManageIQ::Providers::ConfigurationManager.find_by_id(providers.first).class + manager_ids, _services_out_region = filter_ids_in_region(managers, provider_class.to_s) + return if manager_ids.empty? + + options = {:ids => manager_ids, :task => task, :userid => session[:userid]} + kls = provider_class.find_by(:id => manager_ids.first).class kls.process_tasks(options) rescue => err add_flash(_("Error during '%{task}': %{message}") % {:task => task, :message => err.message}, :error) else - add_flash(n_("%{task} initiated for %{count} provider (%{controller})", - "%{task} initiated for %{count} providers (%{controller})", providers.length) % - {:task => task_name(task), - :controller => ProviderForemanController.model_to_name(kls.to_s), - :count => providers.length}) + add_flash(n_("%{task} initiated for %{count} provider", + "%{task} initiated for %{count} providers)", manager_ids.length) % + {:task => task_name(task), + :count => manager_ids.length}) end # Delete all selected or single displayed VM(s) diff --git a/app/controllers/application_controller/filter.rb b/app/controllers/application_controller/filter.rb index 090d824e4de..c7929d5c5f7 100644 --- a/app/controllers/application_controller/filter.rb +++ b/app/controllers/application_controller/filter.rb @@ -421,8 +421,8 @@ def adv_search_button if ["delete", "saveit"].include?(params[:button]) if @edit[:in_explorer] || x_active_tree == :storage_tree - if "cs_filter_tree" == x_active_tree.to_s - build_configuration_manager_tree(:cs_filter, x_active_tree) + if "configuration_manager_cs_filter_tree" == x_active_tree.to_s + build_configuration_manager_tree(:configuration_manager_cs_filter, x_active_tree) else tree_type = x_active_tree.to_s.sub(/_tree/, '').to_sym builder = TreeBuilder.class_for_type(tree_type) @@ -451,7 +451,7 @@ def adv_search_button if ["delete", "saveit"].include?(params[:button]) if @edit[:in_explorer] || x_active_tree == :storage_tree tree_name = x_active_tree.to_s - if "cs_filter_tree" == tree_name + if "configuration_manager_cs_filter_tree_tree" == tree_name page.replace_html("#{tree_name}_div", :partial => "provider_foreman/#{tree_name}") else page.replace_html("#{tree_name}_div", :partial => "shared/tree", :locals => { @@ -511,7 +511,7 @@ def adv_search_clear if x_active_tree.to_s =~ /_filter_tree$/ && !["Vm", "MiqTemplate"].include?(TreeBuilder.get_model_for_prefix(@nodetype)) search_id = 0 - if x_active_tree == :cs_filter_tree + if x_active_tree == :configuration_manager_cs_filter_tree || x_active_tree == :automation_manager_cs_filter_tree adv_search_build("ConfiguredSystem") else adv_search_build(vm_model_from_active_tree(x_active_tree)) diff --git a/app/controllers/automation_manager_controller.rb b/app/controllers/automation_manager_controller.rb new file mode 100644 index 00000000000..97a73aa278a --- /dev/null +++ b/app/controllers/automation_manager_controller.rb @@ -0,0 +1,580 @@ +class AutomationManagerController < ApplicationController + before_action :check_privileges + before_action :get_session_data + + after_action :cleanup_action + after_action :set_session_data + + include Mixins::GenericSessionMixin + include Mixins::ManagerControllerMixin + + def self.model + ManageIQ::Providers::AnsibleTower + end + + def self.table_name + @table_name ||= "automation_manager" + end + + CM_X_BUTTON_ALLOWED_ACTIONS = { + 'configscript_service_dialog' => :configscript_service_dialog, + }.freeze + + def self.model_to_name(provmodel) + if provmodel.include?("ManageIQ::Providers::AnsibleTower") + Dictionary.gettext('ansible_tower', :type => :ui_title, :translate => false) + end + end + + def self.model_to_type_name(provmodel) + if provmodel.include?("ManageIQ::Providers::AnsibleTower") + 'ansible_tower' + end + end + + def model_to_name(provmodel) + AutomationManagerController.model_to_name(provmodel) + end + + def model_to_type_name(provmodel) + AutomationManagerController.model_to_type_name(provmodel) + end + + def managed_group_kls + ManageIQ::Providers::AutomationManager::InventoryGroup + end + + def manager_prefix + 'automation_manager' + end + + def new + assert_privileges("automation_manager_add_provider") + @provider_manager = ManageIQ::Providers::AnsibleTower::AutomationManager.new + @server_zones = Zone.in_my_region.order('lower(description)').pluck(:description, :name) + render_form + end + + def edit + @server_zones = Zone.in_my_region.order('lower(description)').pluck(:description, :name) + case params[:button] + when "cancel" + cancel_provider + when "save" + add_provider + save_provider + else + assert_privileges("automation_manager_edit_provider") + manager_id = from_cid(params[:miq_grid_checks] || params[:id] || find_checked_items[0]) + @provider_manager = find_record(ManageIQ::Providers::AnsibleTower::AutomationManager, manager_id) + @providerdisplay_type = model_to_name(@provider_manager.type) + render_form + end + end + + def delete + assert_privileges("automation_manager_delete_provider") + checked_items = find_checked_items + checked_items.push(params[:id]) if checked_items.empty? && params[:id] + providers = ManageIQ::Providers::AutomationManager.where(:id => checked_items).includes(:provider).collect(&:provider) + if providers.empty? + add_flash(_("No %{model} were selected for %{task}") % {:model => ui_lookup(:tables => "providers"), :task => "deletion"}, :error) + else + providers.each do |provider| + AuditEvent.success( + :event => "provider_record_delete_initiated", + :message => "[#{provider.name}] Record delete initiated", + :target_id => provider.id, + :target_class => provider.type, + :userid => session[:userid] + ) + provider.destroy_queue + end + + add_flash(n_("Delete initiated for %{count} Provider", + "Delete initiated for %{count} Providers", + providers.length) % {:count => providers.length}) + end + replace_right_cell + end + + def refresh + assert_privileges("automation_manager_refresh_provider") + @explorer = true + manager_button_operation('refresh_ems', _('Refresh')) + replace_right_cell + end + + def tagging + case x_active_accord + when :automation_manager_providers + assert_privileges("automation_manager_provider_configured_system_tag") + tagging_edit('ConfiguredSystem', false) + when :automation_manager_cs_filter + assert_privileges("automation_manager_configured_system_tag") + tagging_edit('ConfiguredSystem', false) + when :configuration_scripts + assert_privileges("automation_manager_configuration_script_tag") + tagging_edit('ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript', false) + end + render_tagging_form + end + + def automation_manager_form_fields + assert_privileges("automation_manager_edit_provider") + # set value of read only zone text box, when there is only single zone + if params[:id] == "new" + return render :json => {:zone => Zone.in_my_region.size >= 1 ? Zone.in_my_region.first.name : nil} + end + + manager = find_record(ManageIQ::Providers::AnsibleTower::AutomationManager, params[:id]) + provider = manager.provider + + render :json => {:name => provider.name, + :zone => provider.zone.name, + :url => provider.url, + :verify_ssl => provider.verify_ssl, + :log_userid => provider.authentications.first.userid} + end + + def load_or_clear_adv_search + adv_search_build("ConfiguredSystem") + session[:edit] = @edit + @explorer = true + + if x_active_tree != :automation_manager_cs_filter_tree || x_node == "root" + listnav_search_selected(0) + else + @nodetype, id = parse_nodetype_and_id(valid_active_node(x_node)) + + if x_active_tree == :automation_manager_cs_filter_tree && @nodetype == "xx-csa" + search_id = @nodetype == "root" ? 0 : from_cid(id) + listnav_search_selected(search_id) unless params.key?(:search_text) # Clear or set the adv search filter + if @edit[:adv_search_applied] && + MiqExpression.quick_search?(@edit[:adv_search_applied][:exp]) && + %w(reload tree_select).include?(params[:action]) + self.x_node = params[:id] + quick_search_show + end + end + end + end + + def x_show + tree_record + + if request.format.js? && !@record + return + end + + generic_x_show + end + + def tree_record + @record = + case x_active_tree + when :automation_manager_providers_tree then automation_manager_providers_tree_rec + when :automation_manager_cs_filter_tree then automation_manager_cs_filter_tree_rec + when :configuration_scripts_tree then configuration_scripts_tree_rec + end + end + + def automation_manager_providers_tree_rec + nodes = x_node.split('-') + case nodes.first + when "root" then find_record(ManageIQ::Providers::AnsibleTower::AutomationManager, params[:id]) + when "at" then find_record(ManageIQ::Providers::AutomationManager::InventoryGroup, params[:id]) + when "f" then find_record(ManageIQ::Providers::AnsibleTower::AutomationManager::ConfiguredSystem, params[:id]) + when "xx" then + case nodes.second + when "at" then find_record(ManageIQ::Providers::AnsibleTower::AutomationManager, params[:id]) + when "csa" then find_record(ConfiguredSystem, params[:id]) + end + end + end + + def automation_manager_cs_filter_tree_rec + nodes = x_node.split('-') + case nodes.first + when "root", "xx" then find_record(ConfiguredSystem, params[:id]) + when "ms" then find_record(ConfiguredSystem, from_cid(params[:id])) + end + end + + def configuration_scripts_tree_rec + nodes = x_node.split('-') + case nodes.first + when "root", "at" + find_record(ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript, params[:id]) + end + end + + def show_record(_id = nil) + @display = params[:display] || "main" unless pagination_or_gtl_request? + @lastaction = "show" + + if @record.nil? + add_flash(_("Error: Record no longer exists in the database"), :error) + if request.xml_http_request? && params[:id] # Is this an Ajax request clicking on a node that no longer exists? + @delete_node = params[:id] # Set node to be removed from the tree + end + return + end + + if @record.kind_of?(ConfiguredSystem) + rec_cls = "#{model_to_type_name(@record.ext_management_system.class.to_s)}_configured_system" + end + return unless @display == 'main' + @button_group = case x_active_accord + when :automation_manager_cs_filter + rec_cls.to_s + when :automation_manager_providers + "automation_manager_#{rec_cls}" + when :configuration_scripts + @record.kind_of?(ConfigurationScript) ? "configuration_script" : "configuration_scripts" + end + end + + def configscript_service_dialog_submit + case params[:button] + when "cancel" + configscript_service_dialog_submit_cancel + when "save" + configscript_service_dialog_submit_save + end + end + + private ########### + + def provider_class + ManageIQ::Providers::AnsibleTower::Provider + end + + def find_or_build_provider + @provider = provider_class.new if params[:id] == "new" + @provider ||= find_record(ManageIQ::Providers::AutomationManager, params[:id]).provider + end + + def features + [ + {:role => "automation_manager_providers", + :role_any => true, + :name => :automation_manager_providers, + :title => _("Providers")}, + {:role => "automation_manager_configured_system", + :role_any => true, + :name => :automation_manager_cs_filter, + :title => _("Configured Systems")}, + {:role => "automation_manager_configuration_scripts_accord", + :role_any => true, + :name => :configuration_scripts, + :title => _("Job Templates")} + ].map do |hsh| + ApplicationController::Feature.new_with_hash(hsh) + end + end + + def build_automation_manager_tree(type, name) + tree = case name + when :automation_manager_providers_tree + TreeBuilderAutomationManagerProviders.new(name, type, @sb) + when :automation_manager_cs_filter_tree + TreeBuilderAutomationManagerConfiguredSystems.new(name, type, @sb) + else + TreeBuilderAutomationManagerConfigurationScripts.new(name, type, @sb) + end + instance_variable_set :"@#{name}", tree.tree_nodes + tree + end + + def get_node_info(treenodeid) + @sb[:action] = nil + @nodetype, id = parse_nodetype_and_id(valid_active_node(treenodeid)) + + model = TreeBuilder.get_model_for_prefix(@nodetype) + if model == "Hash" + model = TreeBuilder.get_model_for_prefix(id) + id = nil + end + + case model + when "ManageIQ::Providers::AnsibleTower::AutomationManager" + provider_list(id, model) + when "EmsFolder" + inventory_group_node(id, model) + when "ManageIQ::Providers::AnsibleTower::AutomationManager::ConfiguredSystem", "ConfiguredSystem" + configured_system_list(id, model) + when "ConfigurationScript" + configuration_scripts_list(id, model) + when "MiqSearch" + miq_search_node + else + default_node + end + @right_cell_text += @edit[:adv_search_applied][:text] if x_tree && x_tree[:type] == :automation_manager_cs_filter && @edit && @edit[:adv_search_applied] + + if @edit && @edit.fetch_path(:adv_search_applied, :qs_exp) # If qs is active, save it in history + x_history_add_item(:id => x_node, + :qs_exp => @edit[:adv_search_applied][:qs_exp], + :text => @right_cell_text) + else + x_history_add_item(:id => treenodeid, :text => @right_cell_text) # Add to history pulldown array + end + end + + def provider_node(id, model) + @record = provider = find_record(ExtManagementSystem, id) + if provider.nil? + self.x_node = "root" + get_node_info("root") + elsif x_active_tree == :configuration_scripts_tree + cs_provider_node(provider) + else + @no_checkboxes = true + options = {:model => "ManageIQ::Providers::AutomationManager::InventoryGroup", + :match_via_descendants => ConfiguredSystem, + :where_clause => ["ems_id IN (?)", provider.id]} + process_show_list(options) + record_model = ui_lookup(:model => model_to_name(model || TreeBuilder.get_model_for_prefix(@nodetype))) + @right_cell_text = _("%{model} \"%{name}\"") % {:name => provider.name, + :model => "#{ui_lookup(:tables => "inventory_group")} under #{record_model} Provider"} + end + end + + def cs_provider_node(provider) + options = {:model => "ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript", + :match_via_descendants => ConfigurationScript, + :where_clause => ["manager_id IN (?)", provider.id]} + process_show_list(options) + @right_cell_text = _("%{model} \"%{name}\"") % {:name => provider.name, + :model => "#{ui_lookup(:tables => "job_templates")} under "} + end + + def inventory_group_node(id, model) + @record = @inventory_group_record = find_record(ManageIQ::Providers::AutomationManager::InventoryGroup, id) if model + + if @inventory_group_record.nil? + self.x_node = "root" + get_node_info("root") + else + options = {:model => "ConfiguredSystem", :match_via_descendants => ConfiguredSystem} + options[:where_clause] = ["inventory_root_group_id IN (?)", from_cid(@inventory_group_record.id)] + process_show_list(options) + record_model = ui_lookup(:model => model || TreeBuilder.get_model_for_prefix(@nodetype)) + if @sb[:active_tab] == 'configured_systems' + inventory_group_right_cell_text(model) + else + @pages = nil + @right_cell_text = _("%{model} \"%{name}\"") % {:name => @inventory_group_record.name, :model => record_model} + end + end + end + + def configuration_scripts_list(id, model) + return configuration_script_node(id) if id + @listicon = "configuration_script" + if x_active_tree == :configuration_scripts_tree + options = {:model => model.to_s} + @right_cell_text = _("All Ansible Tower Job Templates") + process_show_list(options) + end + end + + def configuration_script_node(id) + @record = @configuration_script_record = find_record(ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript, id) + display_node(id, nil) + end + + def default_node + return unless x_node == "root" + if x_active_tree == :automation_manager_providers_tree + options = {:model => "ManageIQ::Providers::AnsibleTower::AutomationManager"} + process_show_list(options) + @right_cell_text = _("All Ansible Tower Providers") + elsif x_active_tree == :automation_manager_cs_filter_tree + options = {:model => "ManageIQ::Providers::AnsibleTower::AutomationManager::ConfiguredSystem"} + process_show_list(options) + @right_cell_text = _("All Ansible Tower Configured Systems") + elsif x_active_tree == :configuration_scripts_tree + options = {:model => "ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript"} + process_show_list(options) + @right_cell_text = _("All Ansible Tower Job Templates") + end + end + + def rebuild_trees(replace_trees) + trees = {} + if replace_trees + if replace_trees.include?(:automation_manager_providers) + trees[:automation_manager_providers] = build_automation_manager_tree(:automation_manager_providers, + :automation_manager_providers_tree) + end + if replace_trees.include?(:automation_manager_cs_filter) + trees[:automation_manager_cs_filter] = build_automation_manager_tree(:automation_manager_cs_filter, + :automation_manager_cs_filter_tree) + end + if replace_trees.include?(:configuration_scripts) + trees[:configuration_scripts] = build_automation_manager_tree(:configuration_scripts, + :configuration_scripts_tree) + end + end + trees + end + + def leaf_record + get_node_info(x_node) + @delete_node = params[:id] if @replace_trees + type, _id = parse_nodetype_and_id(x_node) + type && %w(ConfiguredSystem ConfigurationScript).include?(TreeBuilder.get_model_for_prefix(type)) + end + + def managed_group_record?(node = x_node) + type, _id = parse_nodetype_and_id(node) + type && %w(EmsFolder).include?(TreeBuilder.get_model_for_prefix(type)) + end + + def automation_manager_manager_record?(node = x_node) + return @record.kind_of?(ManageIQ::Providers::AnsibleTower::AutomationManager) if @record + + type, _id = node.split("-") + type && ["ManageIQ::Providers::AnsibleTower::AutomationManager"].include?(TreeBuilder.get_model_for_prefix(type)) + end + + def provider_record?(node = x_node) + automation_manager_manager_record?(node) + end + + def search_text_type(node) + return "provider" if provider_record?(node) + return "inventory_group" if managed_group_record?(node) + node + end + + def update_partials(record_showing, presenter, r) + if record_showing && valid_configured_system_record?(@configured_system_record) + get_tagdata(@record) + presenter.hide(:form_buttons_div) + path_dir = controller_name + presenter.update(:main_div, r[:partial => "#{path_dir}/main", + :locals => {:controller => controller_name}]) + elsif @in_a_form + partial_locals = {:controller => controller_name} + @right_cell_text = + if @sb[:action] == "automation_manager_add_provider" + _("Add a new Automation Manager Provider") + elsif @sb[:action] == "automation_manager_edit_provider" + _("Edit Provider") + end + partial = 'form' + presenter.update(:main_div, r[:partial => partial, :locals => partial_locals]) + elsif valid_managed_group_record?(@inventory_group_record) + presenter.hide(:form_buttons_div) + presenter.update(:main_div, r[:partial => "inventory_group", + :locals => {:controller => controller_name}]) + elsif valid_configuration_script_record?(@configuration_script_record) + presenter.hide(:form_buttons_div) + presenter.update(:main_div, r[:partial => "configuration_script", + :locals => {:controller => controller_name}]) + else + presenter.update(:main_div, r[:partial => 'layouts/x_gtl']) + end + end + + def group_summary_tab_selected? + @inventory_group_record && @sb[:active_tab] == 'summary' + end + + def locals_for_service_dialog + {:action_url => 'service_dialog', + :no_reset => true, + :record_id => @sb[:rec_id] || @edit[:object_ids] && @edit[:object_ids][0]} + end + + def update_service_dialog_partials(presenter, r) + presenter.update(:main_div, r[:partial => 'configscript_service_dialog', + :locals => locals_for_service_dialog]) + locals = {:record_id => @edit[:rec_id], + :action_url => "configscript_service_dialog_submit", + :no_reset => true, + :serialize => true} + presenter.update(:form_buttons_div, r[:partial => 'layouts/x_edit_buttons', :locals => locals]) + end + + def active_tab_configured_systems? + (%w(x_show x_search_by_name).include?(action_name) && managed_group_record?) + end + + def empty_managed_group_record?(inventory_group_record) + inventory_group_record.try(:id).nil? + end + + def valid_managed_group_record?(inventory_group_record) + inventory_group_record.try(:id) + end + + def inventory_group_right_cell_text(model) + return if @sb[:active_tab] != 'configured_systems' + if valid_managed_group_record?(@inventory_group_record) + record_model = ui_lookup(:model => model || TreeBuilder.get_model_for_prefix(@nodetype)) + @right_cell_text = _("%{model} under Inventory Group \"%{name}\"") % + {:model => ui_lookup(:tables => "configured_system"), + :record_model => record_model, + :name => @inventory_group_record.name} + end + end + + def valid_configuration_script_record?(configuration_script_record) + configuration_script_record.try(:id) + end + + def process_show_list(options = {}) + options[:dbname] = case x_active_accord + when :automation_manager_providers + options[:model] && options[:model] == 'ConfiguredSystem' ? :automation_manager_configured_systems : :automation_manager_providers + when :automation_manager_cs_filter + :automation_manager_configured_systems + when :configuration_scripts + :configuration_scripts + end + super + end + + def configscript_service_dialog + assert_privileges("automation_manager_configuration_script_service_dialog") + cs = ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript.find_by(:id => params[:id]) + @edit = {:new => {:dialog_name => ""}, + :key => "cs_edit__#{cs.id}", + :rec_id => cs.id} + @in_a_form = true + @right_cell_text = _("Adding a new Service Dialog from \"%{name}\"") % {:name => cs.name} + render_service_dialog_form + end + + def configscript_service_dialog_submit_cancel + add_flash(_("Creation of a new Service Dialog was cancelled by the user")) + @in_a_form = false + @edit = @record = nil + replace_right_cell + end + + def configscript_service_dialog_submit_save + assert_privileges("automation_manager_configuration_script_service_dialog") + load_edit("cs_edit__#{params[:id]}", "replace_cell__explorer") + begin + cs = ConfigurationScript.find_by(:id => params[:id]) + AnsibleTowerJobTemplateDialogService.new.create_dialog(cs, @edit[:new][:dialog_name]) + rescue => bang + add_flash(_("Error when creating Service Dialog: %{error_message}") % + {:error_message => bang.message}, :error) + javascript_flash + else + add_flash(_("Service Dialog \"%{name}\" was successfully created") % + {:name => @edit[:new][:dialog_name]}, :success) + @in_a_form = false + @edit = @record = nil + replace_right_cell + end + end + + menu_section :aut +end diff --git a/app/controllers/mixins/manager_controller_mixin.rb b/app/controllers/mixins/manager_controller_mixin.rb new file mode 100644 index 00000000000..661e201e517 --- /dev/null +++ b/app/controllers/mixins/manager_controller_mixin.rb @@ -0,0 +1,459 @@ +module Mixins + module ManagerControllerMixin + def index + redirect_to :action => 'explorer' + end + + def show_list + redirect_to :action => 'explorer', :flash_msg => @flash_array.try(:fetch_path, 0, :message) + end + + def add_provider + find_or_build_provider + sync_form_to_instance + + update_authentication_provider(:save) + end + + def update_authentication_provider(mode = :validate) + @provider.update_authentication(build_credentials, :save => mode == :save) + end + + def build_credentials + return {} unless params[:log_userid] + { + :default => { + :userid => params[:log_userid], + :password => params[:log_password] || @provider.authentication_password + } + } + end + + def save_provider + if @provider.save + construct_edit_for_audit + AuditEvent.success(build_created_audit(@provider, @edit)) + @in_a_form = false + @sb[:action] = nil + model = "#{model_to_name(@provider.type)} #{ui_lookup(:model => 'ExtManagementSystem')}" + if params[:id] == "new" + add_flash(_("%{model} \"%{name}\" was added") % {:model => model, :name => @provider.name}) + process_managers([@provider.instance_eval(manager_prefix).id], "refresh_ems") + else + add_flash(_("%{model} \"%{name}\" was updated") % {:model => model, :name => @provider.name}) + end + replace_right_cell + else + @provider.errors.each do |field, msg| + @sb[:action] = nil + add_flash("#{field.to_s.capitalize} #{msg}", :error) + end + render_flash + end + end + + def cancel_provider + @in_a_form = false + @sb[:action] = nil + if params[:id] == "new" + add_flash(_("Add of %{provider} was cancelled by the user") % + {:provider => ui_lookup(:model => 'ExtManagementSystem')}) + else + add_flash(_("Edit of %{provider} was cancelled by the user") % + {:provider => ui_lookup(:model => 'ExtManagementSystem')}) + end + replace_right_cell + end + + def authentication_validate + find_or_build_provider + sync_form_to_instance + update_authentication_provider + + begin + @provider.verify_credentials(params[:type]) + rescue => error + render_flash(_("Credential validation was not successful: %{details}") % {:details => error}, :error) + else + render_flash(_("Credential validation was successful")) + end + end + + def explorer + @explorer = true + @lastaction = "explorer" + + # if AJAX request, replace right cell, and return + if request.xml_http_request? + replace_right_cell + return + end + + if params[:accordion] + self.x_active_tree = "#{params[:accordion]}_tree" + self.x_active_accord = params[:accordion] + end + if params[:button] + @miq_after_onload = "miqAjax('/#{controller_name}/x_button?pressed=#{params[:button]}');" + end + + build_accordions_and_trees + + params.instance_variable_get(:@parameters).merge!(session[:exp_parms]) if session[:exp_parms] # Grab any explorer parm overrides + session.delete(:exp_parms) + @in_a_form = false + + if params[:id] # If a tree node id came in, show in one of the trees + nodetype, id = params[:id].split("-") + # treebuilder initializes x_node to root first time in locals_for_render, + # need to set this here to force & activate node when link is clicked outside of explorer. + @reselect_node = self.x_node = "#{nodetype}-#{to_cid(id)}" + get_node_info(x_node) + end + render :layout => "application" + end + + def tree_autoload + @view ||= session[:view] + super + end + + def change_tab + @sb[:active_tab] = params[:tab_id] + replace_right_cell + end + + def cs_edit_get_form_vars + @edit[:new][:name] = params[:name] if params[:name] + @edit[:new][:description] = params[:description] if params[:description] + @edit[:new][:draft] = params[:draft] == "true" if params[:draft] + @edit[:new][:dialog_name] = params[:dialog_name] if params[:dialog_name] + end + + def cs_form_field_changed + id = params[:id] + return unless load_edit("cs_edit__#{id}", "replace_cell__explorer") + cs_edit_get_form_vars + render :update do |page| + page << javascript_prologue + page << javascript_hide("buttons_off") + page << javascript_show("buttons_on") + end + end + + def show(id = nil) + @flash_array = [] if params[:display] + @sb[:action] = nil + + @display = params[:display] || "main" + @lastaction = "show" + @record = if managed_group_record? + find_record(managed_group_kls, id || params[:id]) + else + find_record(ConfiguredSystem, id || params[:id]) + end + return if record_no_longer_exists?(@record) + + @explorer = true if request.xml_http_request? # Ajax request means in explorer + + @gtl_url = "/show" + end + + def tree_select + @lastaction = "explorer" + @flash_array = nil + self.x_active_tree = params[:tree] if params[:tree] + self.x_node = params[:id] + load_or_clear_adv_search + apply_node_search_text if x_active_tree == "#{manager_prefix}_providers_tree".to_sym + + if action_name == "reload" + replace_right_cell(:replace_trees => [x_active_accord]) + else + @sb[:active_tab] = if active_tab_configured_systems? + 'configured_systems' + else + 'summary' + end + replace_right_cell + end + end + + def accordion_select + @lastaction = "explorer" + + @sb["#{controller_name.underscore}_search_text".to_sym] ||= {} + @sb["#{controller_name.underscore}_search_text".to_sym]["#{x_active_accord}_search_text"] = @search_text + + self.x_active_accord = params[:id].sub(/_accord$/, '') + self.x_active_tree = "#{x_active_accord}_tree" + + @search_text = @sb["#{controller_name.underscore}_search_text".to_sym]["#{x_active_accord}_search_text"] + + load_or_clear_adv_search + replace_right_cell(:replace_trees => [x_active_accord]) + end + + private ########### + + def replace_right_cell(options = {}) + replace_trees = options[:replace_trees] + return if @in_a_form + @explorer = true + @in_a_form = false + @sb[:action] = nil + trees = rebuild_trees(replace_trees) + + record_showing = leaf_record + presenter, r = rendering_objects + update_partials(record_showing, presenter, r) + replace_search_box(presenter, r) + handle_bottom_cell(presenter, r) + replace_trees_by_presenter(presenter, trees) + rebuild_toolbars(record_showing, presenter) + presenter[:right_cell_text] = @right_cell_text + presenter[:osf_node] = x_node # Open, select, and focus on this node + + render :json => presenter.for_render + end + + def display_node(id, _mode) + if @record.nil? + self.x_node = "root" + get_node_info("root") + else + show_record(from_cid(id)) + model_string = ui_lookup(:model => @record.class.to_s) + @right_cell_text = _("%{model} \"%{name}\"") % {:name => @record.name, :model => model_string} + end + end + + def sync_form_to_instance + @provider.name = params[:name] + @provider.url = params[:url] + @provider.verify_ssl = params[:verify_ssl].eql?("on") + @provider.zone = Zone.find_by(:name => params[:zone].to_s) + end + + def provider_list(id, model) + return provider_node(id, model) if id + options = {:model => model.to_s} + @right_cell_text = _("All %{title} Providers") % {:title => model_to_name(model)} + process_show_list(options) + end + + def configured_system_list(id, model) + return configured_system_node(id, model) if id + if x_active_tree == :configuration_manager_cs_filter_tree || x_active_tree == :automation_manager_cs_filter_tree + options = {:model => model.to_s} + @right_cell_text = _("All %{title} Configured Systems") % {:title => model_to_name(model)} + process_show_list(options) + end + end + + def configured_system_node(id, model) + @record = @configured_system_record = find_record(ConfiguredSystem, id) + display_node(id, model) + end + + def display_adv_searchbox + !(@configured_system_record || @in_a_form || group_summary_tab_selected?) + end + + def miq_search_node + options = {:model => "ConfiguredSystem"} + process_show_list(options) + @right_cell_text = _("All Configured Systems") + end + + def rendering_objects + presenter = ExplorerPresenter.new( + :active_tree => x_active_tree, + :delete_node => @delete_node, + ) + r = proc { |opts| render_to_string(opts) } + return presenter, r + end + + def render_form + presenter, r = rendering_objects + @in_a_form = true + presenter.update(:main_div, r[:partial => 'form', :locals => {:controller => controller_name}]) + update_title(presenter) + rebuild_toolbars(false, presenter) + handle_bottom_cell(presenter, r) + + render :json => presenter.for_render + end + + def render_tagging_form + return if %w(cancel save).include?(params[:button]) + @in_a_form = true + @right_cell_text = _("Edit Tags") + clear_flash_msg + presenter, r = rendering_objects + update_tagging_partials(presenter, r) + update_title(presenter) + rebuild_toolbars(false, presenter) + handle_bottom_cell(presenter, r) + + render :json => presenter.for_render + end + + def render_service_dialog_form + return if %w(cancel save).include?(params[:button]) + @in_a_form = true + clear_flash_msg + presenter, r = rendering_objects + update_service_dialog_partials(presenter, r) + rebuild_toolbars(false, presenter) + handle_bottom_cell(presenter, r) + presenter[:right_cell_text] = @right_cell_text + + render :json => presenter.for_render + end + + def update_tree_and_render_list(replace_trees) + @explorer = true + get_node_info(x_node) + presenter, r = rendering_objects + replace_explorer_trees(replace_trees, presenter, r) + + presenter.update(:main_div, r[:partial => 'layouts/x_gtl']) + rebuild_toolbars(false, presenter) + handle_bottom_cell(presenter, r) + + render :json => presenter.for_render + end + + def update_title(presenter) + @right_cell_text = + case action_name + when "new" then _("Add a new Provider") + when "edit" then _("Edit Provider") + end + presenter[:right_cell_text] = @right_cell_text + end + + def apply_node_search_text + setup_search_text_for_node + previous_nodetype = search_text_type(@sb["#{controller_name.underscore}_search_text".to_sym][:previous_node]) + current_nodetype = search_text_type(@sb["#{controller_name.underscore}_search_text".to_sym][:current_node]) + + @sb["#{controller_name.underscore}_search_text".to_sym]["#{previous_nodetype}_search_text"] = @search_text + @search_text = @sb["#{controller_name.underscore}_search_text".to_sym]["#{current_nodetype}_search_text"] + @sb["#{controller_name.underscore}_search_text".to_sym]["#{x_active_accord}_search_text"] = @search_text + end + + def setup_search_text_for_node + @sb["#{controller_name.underscore}_search_text".to_sym] ||= {} + @sb["#{controller_name.underscore}_search_text".to_sym][:current_node] ||= x_node + @sb["#{controller_name.underscore}_search_text".to_sym][:previous_node] = @sb["#{controller_name.underscore}_search_text".to_sym][:current_node] + @sb["#{controller_name.underscore}_search_text".to_sym][:current_node] = x_node + end + + def replace_search_box(presenter, r) + # Replace the searchbox + presenter.replace(:adv_searchbox_div, + r[:partial => 'layouts/x_adv_searchbox']) + + presenter[:clear_gtl_list_grid] = @gtl_type && @gtl_type != 'list' + end + + def handle_bottom_cell(presenter, r) + # Handle bottom cell + if @pages || @in_a_form + if @pages && !@in_a_form + @ajax_paging_buttons = true + if @sb[:action] && @record # Came in from an action link + presenter.update(:paging_div, r[:partial => 'layouts/x_pagingcontrols', + :locals => {:action_url => @sb[:action], + :action_method => @sb[:action], + :action_id => @record.id}]) + else + presenter.update(:paging_div, r[:partial => 'layouts/x_pagingcontrols']) + end + presenter.hide(:form_buttons_div).show(:pc_div_1) + elsif @in_a_form + presenter.hide(:pc_div_1).show(:form_buttons_div) + end + presenter.show(:paging_div) + else + presenter.hide(:paging_div) + end + end + + def rebuild_toolbars(record_showing, presenter) + if group_summary_tab_selected? + center_tb = "blank_view_tb" + record_showing = true + end + + if !@in_a_form && !@sb[:action] + center_tb ||= center_toolbar_filename + c_tb = build_toolbar(center_tb) + v_tb = build_toolbar(record_showing ? "x_summary_view_tb" : "x_gtl_view_tb") + end + + h_tb = build_toolbar("x_history_tb") unless @in_a_form + + presenter.reload_toolbars(:history => h_tb, :center => c_tb, :view => v_tb) + + presenter.set_visibility(h_tb.present? || c_tb.present? || v_tb.present?, :toolbar) + + presenter[:record_id] = @record.try(:id) + + # Hide/show searchbox depending on if a list is showing + presenter.set_visibility(display_adv_searchbox, :adv_searchbox_div) + presenter[:clear_search_toggle] = clear_search_status + + presenter.hide(:blocker_div) unless @edit && @edit[:adv_search_open] + presenter.hide(:quicksearchbox) + presenter[:hide_modal] = true + + presenter.lock_tree(x_active_tree, @in_a_form) + end + + def construct_edit_for_audit + @edit ||= {} + @edit[:current] = {:name => @provider.name, + :provtype => model_to_name(@provider.type), + :url => @provider.url, + :verify_ssl => @provider.verify_ssl} + @edit[:new] = {:name => params[:name], + :provtype => params[:provtype], + :url => params[:url], + :verify_ssl => params[:verify_ssl]} + end + + def breadcrumb_name(_model) + "#{ui_lookup(:ui_title => 'foreman')} #{ui_lookup(:model => 'ExtManagementSystem')}" + end + + def tagging_explorer_controller? + @explorer + end + + def valid_configured_system_record?(configured_system_record) + configured_system_record.try(:id) + end + + def find_record(model, id) + raise _("Invalid input") unless is_integer?(from_cid(id)) + begin + record = model.where(:id => from_cid(id)).first + rescue ActiveRecord::RecordNotFound, StandardError => ex + if @explorer + self.x_node = "root" + add_flash(ex.message, :error, true) + session[:flash_msgs] = @flash_array.dup + end + end + record + end + + def title + _("Providers") + end + end +end diff --git a/app/controllers/mixins/sandbox.rb b/app/controllers/mixins/sandbox.rb index b5368dc5475..6a1979c3fce 100644 --- a/app/controllers/mixins/sandbox.rb +++ b/app/controllers/mixins/sandbox.rb @@ -39,6 +39,8 @@ def x_active_tree alert_profile_tree alert_tree automate_tree + automation_manager_providers_tree + automation_manager_cs_filter_tree bottlenecks_tree cb_assignments_tree cb_rates_tree @@ -48,7 +50,8 @@ def x_active_tree condition_tree containers_tree containers_filter_tree - cs_filter_tree + configuration_manager_cs_filter_tree + configuration_manager_providers_tree customization_templates_tree datacenter_tree datastore_tree @@ -110,6 +113,9 @@ def x_active_tree action alert alert_profile + automation_manager_providers + automation_manager_cs_filter + automation_manager_configuration_scripts cb_assignments cb_rates cb_reports @@ -117,7 +123,8 @@ def x_active_tree condition containers containers_filter - cs_filter + configuration_manager_cs_filter + configuration_manager_providers customization_templates datastores db diff --git a/app/controllers/provider_foreman_controller.rb b/app/controllers/provider_foreman_controller.rb index 9f5af326183..d7713c15a36 100644 --- a/app/controllers/provider_foreman_controller.rb +++ b/app/controllers/provider_foreman_controller.rb @@ -6,6 +6,7 @@ class ProviderForemanController < ApplicationController after_action :set_session_data include Mixins::GenericSessionMixin + include Mixins::ManagerControllerMixin def self.model ManageIQ::Providers::ConfigurationManager @@ -15,26 +16,22 @@ def self.table_name @table_name ||= "provider_foreman" end - CM_X_BUTTON_ALLOWED_ACTIONS = { - 'configscript_service_dialog' => :configscript_service_dialog, - }.freeze - def self.model_to_name(provmodel) - if provmodel.include?("ManageIQ::Providers::AnsibleTower") - Dictionary.gettext('ansible_tower', :type => :ui_title, :translate => false) - elsif provmodel.include?("ManageIQ::Providers::Foreman") + if provmodel.include?("ManageIQ::Providers::Foreman") Dictionary.gettext('foreman', :type => :ui_title, :translate => false) end end def self.model_to_type_name(provmodel) - if provmodel.include?("ManageIQ::Providers::AnsibleTower") - 'ansible_tower' - elsif provmodel.include?("ManageIQ::Providers::Foreman") + if provmodel.include?("ManageIQ::Providers::Foreman") 'foreman' end end + def manager_prefix + 'configuration_manager' + end + def model_to_name(provmodel) ProviderForemanController.model_to_name(provmodel) end @@ -43,36 +40,28 @@ def model_to_type_name(provmodel) ProviderForemanController.model_to_type_name(provmodel) end - def index - redirect_to :action => 'explorer' - end - - def show_list - redirect_to :action => 'explorer', :flash_msg => @flash_array.try(:fetch_path, 0, :message) - end - def new assert_privileges("provider_foreman_add_provider") - @provider_cfgmgmt = ManageIQ::Providers::ConfigurationManager.new - @provider_types = ["Ansible Tower", ui_lookup(:ui_title => 'foreman')] + @provider_manager = ManageIQ::Providers::ConfigurationManager.new + @provider_types = [ui_lookup(:ui_title => 'foreman')] @server_zones = Zone.in_my_region.order('lower(description)').pluck(:description, :name) render_form end def edit - @provider_types = ["Ansible Tower", ui_lookup(:ui_title => 'foreman')] + @provider_types = [ui_lookup(:ui_title => 'foreman')] @server_zones = Zone.in_my_region.order('lower(description)').pluck(:description, :name) case params[:button] when "cancel" - cancel_provider_foreman + cancel_provider when "save" - add_provider_foreman - save_provider_foreman + add_provider + save_provider else assert_privileges("provider_foreman_edit_provider") manager_id = from_cid(params[:miq_grid_checks] || params[:id] || find_checked_items[0]) - @provider_cfgmgmt = find_record(ManageIQ::Providers::ConfigurationManager, manager_id) - @providerdisplay_type = model_to_name(@provider_cfgmgmt.type) + @provider_manager = find_record(ManageIQ::Providers::ConfigurationManager, manager_id) + @providerdisplay_type = model_to_name(@provider_manager.type) render_form end end @@ -87,7 +76,7 @@ def delete else providers.each do |provider| AuditEvent.success( - :event => "configuration_manager_record_delete_initiated", # TODO: Should be provider_record_delete_initiated + :event => "provider_record_delete_initiated", :message => "[#{provider.name}] Record delete initiated", :target_id => provider.id, :target_class => provider.type, @@ -106,13 +95,13 @@ def delete def refresh assert_privileges("provider_foreman_refresh_provider") @explorer = true - foreman_button_operation('refresh_ems', _('Refresh')) + manager_button_operation('refresh_ems', _('Refresh')) replace_right_cell end def provision assert_privileges("provider_foreman_configured_system_provision") if x_active_accord == :configuration_manager_providers - assert_privileges("configured_system_provision") if x_active_accord == :cs_filter + assert_privileges("configured_system_provision") if x_active_accord == :configuration_manager_cs_filter provisioning_ids = find_checked_items provisioning_ids.push(params[:id]) if provisioning_ids.empty? @@ -141,84 +130,24 @@ def tagging when :configuration_manager_providers assert_privileges("provider_foreman_configured_system_tag") tagging_edit('ConfiguredSystem', false) - when :cs_filter + when :configuration_manager_cs_filter assert_privileges("configured_system_tag") tagging_edit('ConfiguredSystem', false) - when :configuration_scripts - assert_privileges("configuration_script_tag") - tagging_edit('ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript', false) end render_tagging_form end - def add_provider_foreman - find_or_build_provider - sync_form_to_instance - - update_authentication_provider(:save) - end - - def update_authentication_provider(mode = :validate) - @provider_cfgmgmt.update_authentication(build_credentials, :save => mode == :save) - end - - def build_credentials - return {} unless params[:log_userid] - { - :default => { - :userid => params[:log_userid], - :password => params[:log_password] || @provider_cfgmgmt.authentication_password - } - } - end - - def save_provider_foreman - if @provider_cfgmgmt.save - construct_edit - AuditEvent.success(build_created_audit(@provider_cfgmgmt, @edit)) - @in_a_form = false - @sb[:action] = nil - model = "#{model_to_name(@provider_cfgmgmt.type)} #{ui_lookup(:model => 'ExtManagementSystem')}" - if params[:id] == "new" - add_flash(_("%{model} \"%{name}\" was added") % {:model => model, :name => @provider_cfgmgmt.name}) - process_cfgmgr([@provider_cfgmgmt.configuration_manager.id], "refresh_ems") - else - add_flash(_("%{model} \"%{name}\" was updated") % {:model => model, :name => @provider_cfgmgmt.name}) - end - replace_right_cell(:replace_trees => [:configuration_manager_providers]) - else - @provider_cfgmgmt.errors.each do |field, msg| - @sb[:action] = nil - add_flash("#{field.to_s.capitalize} #{msg}", :error) - end - render_flash - end - end - - def cancel_provider_foreman - @in_a_form = false - @sb[:action] = nil - if params[:id] == "new" - add_flash(_("Add of Configuration Manager %{provider} was cancelled by the user") % - {:provider => ui_lookup(:model => 'ExtManagementSystem')}) - else - add_flash(_("Edit of Configuration Manager %{provider} was cancelled by the user") % - {:provider => ui_lookup(:model => 'ExtManagementSystem')}) - end - replace_right_cell - end - def provider_foreman_form_fields assert_privileges("provider_foreman_edit_provider") # set value of read only zone text box, when there is only single zone - return render :json => { - :zone => Zone.in_my_region.size >= 1 ? Zone.in_my_region.first.name : nil - } if params[:id] == "new" + if params[:id] == "new" + return render :json => {:zone => Zone.in_my_region.size >= 1 ? Zone.in_my_region.first.name : nil} + end - config_mgr = find_record(ManageIQ::Providers::ConfigurationManager, params[:id]) - provider = config_mgr.provider + manager = find_record(ManageIQ::Providers::ConfigurationManager, params[:id]) + provider = manager.provider - render :json => {:provtype => model_to_name(config_mgr.type), + render :json => {:provtype => model_to_name(manager.type), :name => provider.name, :zone => provider.zone.name, :url => provider.url, @@ -226,74 +155,8 @@ def provider_foreman_form_fields :log_userid => provider.authentications.first.userid} end - def authentication_validate - find_or_build_provider - sync_form_to_instance - update_authentication_provider - - begin - @provider_cfgmgmt.verify_credentials(params[:type]) - rescue => error - render_flash(_("Credential validation was not successful: %{details}") % {:details => error}, :error) - else - render_flash(_("Credential validation was successful")) - end - end - - def show(id = nil) - @flash_array = [] if params[:display] - @sb[:action] = nil - - @display = params[:display] || "main" - @lastaction = "show" - @showtype = "config" - @record = if configuration_profile_record? - find_record(ConfigurationProfile, id || params[:id]) - elsif inventory_group_record? - find_record(ManageIQ::Providers::AutomationManager::InventoryGroup, id || params[:id]) - else - find_record(ConfiguredSystem, id || params[:id]) - end - return if record_no_longer_exists?(@record) - - @explorer = true if request.xml_http_request? # Ajax request means in explorer - - @gtl_url = "/show" - end - - def tree_select - @lastaction = "explorer" - @flash_array = nil - self.x_active_tree = params[:tree] if params[:tree] - self.x_node = params[:id] - load_or_clear_adv_search - apply_node_search_text if x_active_tree == :configuration_manager_providers_tree - - unless action_name == "reload" - @sb[:active_tab] = if active_tab_configured_systems? - 'configured_systems' - else - 'summary' - end - replace_right_cell - else - replace_right_cell(:replace_trees => [:configuration_manager_providers]) - end - end - - def accordion_select - @lastaction = "explorer" - - @sb[:foreman_search_text] ||= {} - @sb[:foreman_search_text]["#{x_active_accord}_search_text"] = @search_text - - self.x_active_accord = params[:id].sub(/_accord$/, '') - self.x_active_tree = "#{x_active_accord}_tree" - - @search_text = @sb[:foreman_search_text]["#{x_active_accord}_search_text"] - - load_or_clear_adv_search - replace_right_cell(:replace_trees => [x_active_accord]) + def managed_group_kls + ConfigurationProfile end def load_or_clear_adv_search @@ -301,12 +164,12 @@ def load_or_clear_adv_search session[:edit] = @edit @explorer = true - if x_active_tree != :cs_filter_tree || x_node == "root" + if x_active_tree != :configuration_manager_cs_filter_tree || x_node == "root" listnav_search_selected(0) else @nodetype, id = parse_nodetype_and_id(valid_active_node(x_node)) - if x_active_tree == :cs_filter_tree && (@nodetype == "xx-csf" || @nodetype == "xx-csa") + if x_active_tree == :cs_filter_tree && @nodetype == "xx-csf" search_id = @nodetype == "root" ? 0 : from_cid(id) listnav_search_selected(search_id) unless params.key?(:search_text) # Clear or set the adv search filter if @edit[:adv_search_applied] && @@ -334,8 +197,7 @@ def tree_record @record = case x_active_tree when :configuration_manager_providers_tree then configuration_manager_providers_tree_rec - when :cs_filter_tree then cs_filter_tree_rec - when :configuration_scripts_tree then configuration_scripts_tree_rec + when :configuration_manager_cs_filter_tree then configuration_manager_cs_filter_tree_rec end end @@ -363,19 +225,16 @@ def configuration_manager_providers_tree_rec case nodes.first when "root" then find_record(ManageIQ::Providers::ConfigurationManager, params[:id]) when "fr" then find_record(ManageIQ::Providers::Foreman::ConfigurationManager::ConfigurationProfile, params[:id]) - when "at" then find_record(ManageIQ::Providers::AutomationManager::InventoryGroup, params[:id]) - when "f" then find_record(ManageIQ::Providers::AnsibleTower::AutomationManager::ConfiguredSystem, params[:id]) when "cp" then find_record(ManageIQ::Providers::Foreman::ConfigurationManager::ConfiguredSystem, params[:id]) when "xx" then case nodes.second - when "at" then find_record(ManageIQ::Providers::AnsibleTower::AutomationManager, params[:id]) when "fr" then find_record(ManageIQ::Providers::Foreman::ConfigurationManager, params[:id]) - when "csa", "csf" then find_record(ConfiguredSystem, params[:id]) + when "csf" then find_record(ConfiguredSystem, params[:id]) end end end - def cs_filter_tree_rec + def configuration_manager_cs_filter_tree_rec nodes = x_node.split('-') case nodes.first when "root", "xx" then find_record(ConfiguredSystem, params[:id]) @@ -383,18 +242,9 @@ def cs_filter_tree_rec end end - def configuration_scripts_tree_rec - nodes = x_node.split('-') - case nodes.first - when "root", "at" - find_record(ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript, params[:id]) - end - end - def show_record(_id = nil) @display = params[:display] || "main" unless pagination_or_gtl_request? @lastaction = "show" - @showtype = "config" if @record.nil? add_flash(_("Error: Record no longer exists in the database"), :error) @@ -410,106 +260,22 @@ def show_record(_id = nil) return unless @display == 'main' @showtype = "main" @button_group = case x_active_accord - when :cs_filter + when :configuration_manager_cs_filter rec_cls.to_s when :configuration_manager_providers "provider_foreman_#{rec_cls}" - when :configuration_scripts - @record.kind_of?(ConfigurationScript) ? "configuration_script" : "configuration_scripts" end end - def explorer - @explorer = true - @lastaction = "explorer" - - # if AJAX request, replace right cell, and return - if request.xml_http_request? - replace_right_cell - return - end - - if params[:accordion] - self.x_active_tree = "#{params[:accordion]}_tree" - self.x_active_accord = params[:accordion] - end - if params[:button] - @miq_after_onload = "miqAjax('/#{controller_name}/x_button?pressed=#{params[:button]}');" - end - - build_accordions_and_trees - - params.instance_variable_get(:@parameters).merge!(session[:exp_parms]) if session[:exp_parms] # Grab any explorer parm overrides - session.delete(:exp_parms) - @in_a_form = false - - if params[:id] # If a tree node id came in, show in one of the trees - nodetype, id = params[:id].split("-") - # treebuilder initializes x_node to root first time in locals_for_render, - # need to set this here to force & activate node when link is clicked outside of explorer. - @reselect_node = self.x_node = "#{nodetype}-#{to_cid(id)}" - get_node_info(x_node) - end - render :layout => "application" - end - - def tree_autoload - @view ||= session[:view] - super - end - - def change_tab - @sb[:active_tab] = params[:tab_id] - replace_right_cell - end - - def cs_form_field_changed - id = params[:id] - return unless load_edit("cs_edit__#{id}", "replace_cell__explorer") - cs_edit_get_form_vars - render :update do |page| - page << javascript_prologue - page << javascript_hide("buttons_off") - page << javascript_show("buttons_on") - end - end - - def configscript_service_dialog_submit - case params[:button] - when "cancel" - configscript_service_dialog_submit_cancel - when "save" - configscript_service_dialog_submit_save - end - end - private ########### - def display_node(id, model) - if @record.nil? - self.x_node = "root" - get_node_info("root") - else - show_record(from_cid(id)) - model_string = ui_lookup(:model => @record.class.to_s) - @right_cell_text = _("%{model} \"%{name}\"") % {:name => @record.name, :model => model_string} - end - end - def find_or_build_provider - @provider_cfgmgmt = provider_class_from_provtype.new if params[:id] == "new" - @provider_cfgmgmt ||= find_record(ManageIQ::Providers::ConfigurationManager, params[:id]).provider # TODO: Why is params[:id] an ExtManagementSystem ID instead of Provider ID? + @provider = provider_class_from_provtype.new if params[:id] == "new" + @provider ||= find_record(ManageIQ::Providers::ConfigurationManager, params[:id]).provider # TODO: Why is params[:id] an ExtManagementSystem ID instead of Provider ID? end def provider_class_from_provtype - params[:provtype] == 'Ansible Tower' ? ManageIQ::Providers::AnsibleTower::Provider : ManageIQ::Providers::Foreman::Provider - end - - def sync_form_to_instance - @provider_cfgmgmt.name = params[:name] - @provider_cfgmgmt.url = params[:url] - @provider_cfgmgmt.verify_ssl = params[:verify_ssl].eql?("on") - @provider_cfgmgmt.zone = Zone.find_by_name(params[:zone].to_s) + params[:provtype] = ManageIQ::Providers::Foreman::Provider end def features @@ -519,12 +285,8 @@ def features :title => _("Providers")}, {:role => "configured_systems_filter_accord", :role_any => true, - :name => :cs_filter, + :name => :configuration_manager_cs_filter, :title => _("Configured Systems")}, - {:role => "configuration_scripts_accord", - :role_any => true, - :name => :configuration_scripts, - :title => _("Ansible Tower Job Templates")} ].map do |hsh| ApplicationController::Feature.new_with_hash(hsh) end @@ -534,10 +296,8 @@ def build_configuration_manager_tree(type, name) tree = case name when :configuration_manager_providers_tree TreeBuilderConfigurationManager.new(name, type, @sb) - when :cs_filter_tree + when :configuration_manager_cs_filter_tree TreeBuilderConfigurationManagerConfiguredSystems.new(name, type, @sb) - else - TreeBuilderConfigurationManagerConfigurationScripts.new(name, type, @sb) end instance_variable_set :"@#{name}", tree.tree_nodes tree @@ -554,16 +314,12 @@ def get_node_info(treenodeid) end case model - when "ManageIQ::Providers::Foreman::ConfigurationManager", "ManageIQ::Providers::AnsibleTower::AutomationManager" + when "ManageIQ::Providers::Foreman::ConfigurationManager" provider_list(id, model) when "ConfigurationProfile" configuration_profile_node(id, model) - when "EmsFolder" - inventory_group_node(id, model) - when "ManageIQ::Providers::Foreman::ConfigurationManager::ConfiguredSystem", "ManageIQ::Providers::AnsibleTower::AutomationManager::ConfiguredSystem", "ConfiguredSystem" + when "ManageIQ::Providers::Foreman::ConfigurationManager::ConfiguredSystem", "ConfiguredSystem" configured_system_list(id, model) - when "ConfigurationScript" - configuration_scripts_list(id, model) when "MiqSearch" miq_search_node else @@ -573,7 +329,7 @@ def get_node_info(treenodeid) default_node end end - @right_cell_text += @edit[:adv_search_applied][:text] if x_tree && x_tree[:type] == :cs_filter && @edit && @edit[:adv_search_applied] + @right_cell_text += @edit[:adv_search_applied][:text] if x_tree && x_tree[:type] == :configuration_manager_cs_filter && @edit && @edit[:adv_search_applied] if @edit && @edit.fetch_path(:adv_search_applied, :qs_exp) # If qs is active, save it in history x_history_add_item(:id => x_node, @@ -589,8 +345,6 @@ def provider_node(id, model) if provider.nil? self.x_node = "root" get_node_info("root") - elsif x_active_tree == :configuration_scripts_tree - cs_provider_node(provider) else @no_checkboxes = true case @record.type @@ -602,36 +356,10 @@ def provider_node(id, model) @right_cell_text = _("%{model} \"%{name}\"") % {:name => provider.name, :model => "#{ui_lookup(:tables => "configuration_profile")} under #{record_model} Provider"} - when "ManageIQ::Providers::AnsibleTower::AutomationManager" - options = {:model => "ManageIQ::Providers::AutomationManager::InventoryGroup", :match_via_descendants => ConfiguredSystem, :where_clause => ["ems_id IN (?)", provider.id]} - process_show_list(options) - record_model = ui_lookup(:model => model_to_name(model || TreeBuilder.get_model_for_prefix(@nodetype))) - @right_cell_text = _("%{model} \"%{name}\"") % - {:name => provider.name, :model => "#{ui_lookup(:tables => "inventory_group")} under #{record_model} Provider"} end end end - def cs_provider_node(provider) - options = { - :model => "ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript", - :match_via_descendants => ConfigurationScript, - :where_clause => ["manager_id IN (?)", provider.id] - } - process_show_list(options) - @right_cell_text = _("%{model} \"%{name}\"") % - {:name => provider.name, :model => "#{ui_lookup(:tables => "job_templates")} under "} - end - - def provider_list(id, model) - return provider_node(id, model) if id - if x_active_tree == :configuration_manager_providers_tree - options = {:model => model.to_s} - @right_cell_text = _("All %{title} Providers") % {:title => model_to_name(model)} - process_show_list(options) - end - end - def configuration_profile_node(id, model) @record = @configuration_profile_record = model ? find_record(ConfigurationProfile, id) : ConfigurationProfile.new if @configuration_profile_record.nil? @@ -657,182 +385,34 @@ def configuration_profile_node(id, model) end end - def inventory_group_node(id, model) - @record = @inventory_group_record = find_record(ManageIQ::Providers::AutomationManager::InventoryGroup, id) if model - - if @inventory_group_record.nil? - self.x_node = "root" - get_node_info("root") - else - options = {:model => "ConfiguredSystem", :match_via_descendants => ConfiguredSystem} - options[:where_clause] = ["inventory_root_group_id IN (?)", from_cid(@inventory_group_record.id)] - process_show_list(options) - record_model = ui_lookup(:model => model || TreeBuilder.get_model_for_prefix(@nodetype)) - if @sb[:active_tab] == 'configured_systems' - inventory_group_right_cell_text(model) - else - @showtype = 'main' - @pages = nil - @right_cell_text = _("%{model} \"%{name}\"") % {:name => @inventory_group_record.name, :model => record_model} - end - end - end - - def configured_system_list(id, model) - return configured_system_node(id, model) if id - if x_active_tree == :cs_filter_tree - options = {:model => model.to_s} - @right_cell_text = _("All %{title} Configured Systems") % {:title => model_to_name(model)} - process_show_list(options) - end - end - - def configured_system_node(id, model) - @record = @configured_system_record = find_record(ConfiguredSystem, id) - display_node(id, model) - end - - def miq_search_node - options = {:model => "ConfiguredSystem"} - process_show_list(options) - @right_cell_text = _("All %{title} Configured Systems") % {:title => ui_lookup(:ui_title => "foreman")} - end - - def configuration_scripts_list(id, model) - return configuration_script_node(id, model) if id - @listicon = "configuration_script" - if x_active_tree == :configuration_scripts_tree - options = {:model => model.to_s} - @right_cell_text = _("All Ansible Tower Job Templates") - process_show_list(options) - end - end - - def configuration_script_node(id, model) - @record = @configuration_script_record = find_record(ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript, id) - display_node(id, model) - end - def default_node return unless x_node == "root" if x_active_tree == :configuration_manager_providers_tree options = {:model => "ManageIQ::Providers::ConfigurationManager"} process_show_list(options) @right_cell_text = _("All Configuration Management Providers") - elsif x_active_tree == :cs_filter_tree + elsif x_active_tree == :configuration_manager_cs_filter_tree options = {:model => "ConfiguredSystem"} process_show_list(options) @right_cell_text = _("All Configured Systems") - elsif x_active_tree == :configuration_scripts_tree - options = {:model => "ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript"} - process_show_list(options) - @right_cell_text = _("All Ansible Tower Job Templates") end end - def rendering_objects - presenter = ExplorerPresenter.new( - :active_tree => x_active_tree, - :delete_node => @delete_node, - ) - r = proc { |opts| render_to_string(opts) } - return presenter, r - end - - def render_form - presenter, r = rendering_objects - @in_a_form = true - presenter.update(:main_div, r[:partial => 'form', :locals => {:controller => 'provider_foreman'}]) - update_title(presenter) - rebuild_toolbars(false, presenter) - handle_bottom_cell(presenter, r) - - render :json => presenter.for_render - end - - def render_tagging_form - return if %w(cancel save).include?(params[:button]) - @in_a_form = true - @right_cell_text = _("Edit Tags") - clear_flash_msg - presenter, r = rendering_objects - update_tagging_partials(presenter, r) - update_title(presenter) - rebuild_toolbars(false, presenter) - handle_bottom_cell(presenter, r) - - render :json => presenter.for_render - end - - def render_service_dialog_form - return if %w(cancel save).include?(params[:button]) - @in_a_form = true - clear_flash_msg - presenter, r = rendering_objects - update_service_dialog_partials(presenter, r) - rebuild_toolbars(false, presenter) - handle_bottom_cell(presenter, r) - presenter[:right_cell_text] = @right_cell_text - - render :json => presenter.for_render - end - - def update_tree_and_render_list(replace_trees) - @explorer = true - get_node_info(x_node) - presenter, r = rendering_objects - replace_explorer_trees(replace_trees, presenter, r) - - presenter.update(:main_div, r[:partial => 'layouts/x_gtl']) - rebuild_toolbars(false, presenter) - handle_bottom_cell(presenter, r) - - render :json => presenter.for_render - end - - def update_title(presenter) - @right_cell_text = - case action_name - when "new" then _("Add a new Configuration Management Provider") - when "edit" then _("Edit Configuration Manager Provider") - end - presenter[:right_cell_text] = @right_cell_text - end - - def replace_right_cell(options = {}) - replace_trees = options[:replace_trees] - return if @in_a_form - @explorer = true - @in_a_form = false - @sb[:action] = nil - + def rebuild_trees(replace_trees) trees = {} if replace_trees trees[:configuration_manager_providers] = build_configuration_manager_tree(:configuration_manager_providers, :configuration_manager_providers_tree) if replace_trees.include?(:configuration_manager_providers) - trees[:cs_filter] = build_configuration_manager_tree(:cs_filter, - :cs_filter_tree) if replace_trees.include?(:cs_filter) - trees[:configuration_scripts] = build_configuration_manager_tree(:configuration_scripts, - :configuration_scripts_tree) if replace_trees.include?(:configuration_scripts) + trees[:configuration_manager_cs_filter] = build_configuration_manager_tree(:configuration_manager_cs_filter, :configuration_manager_cs_filter_tree) if replace_trees.include?(:configuration_manager_cs_filter) end - record_showing = leaf_record - presenter, r = rendering_objects - update_partials(record_showing, presenter, r) - replace_search_box(presenter, r) - handle_bottom_cell(presenter, r) - replace_trees_by_presenter(presenter, trees) - rebuild_toolbars(record_showing, presenter) - presenter[:right_cell_text] = @right_cell_text - presenter[:osf_node] = x_node # Open, select, and focus on this node - - render :json => presenter.for_render + trees end def leaf_record get_node_info(x_node) @delete_node = params[:id] if @replace_trees type, _id = parse_nodetype_and_id(x_node) - type && %w(ConfiguredSystem ConfigurationScript).include?(TreeBuilder.get_model_for_prefix(type)) + type && %w(ConfiguredSystem).include?(TreeBuilder.get_model_for_prefix(type)) end def configuration_profile_record?(node = x_node) @@ -840,208 +420,54 @@ def configuration_profile_record?(node = x_node) type && %w(ConfigurationProfile).include?(TreeBuilder.get_model_for_prefix(type)) end - def inventory_group_record?(node = x_node) - type, _id = parse_nodetype_and_id(node) - type && %w(EmsFolder).include?(TreeBuilder.get_model_for_prefix(type)) - end - def foreman_provider_record?(node = x_node) node = node.split("-").last if node.split("-").first == 'xx' type, _id = node.split("-") type && ["ManageIQ::Providers::Foreman::ConfigurationManager"].include?(TreeBuilder.get_model_for_prefix(type)) end - def ansible_tower_cfgmgr_record?(node = x_node) - return @record.kind_of?(ManageIQ::Providers::AnsibleTower::AutomationManager) if @record - - type, _id = node.split("-") - type && ["ManageIQ::Providers::AnsibleTower::AutomationManager"].include?(TreeBuilder.get_model_for_prefix(type)) - end - def provider_record?(node = x_node) - foreman_provider_record?(node) || ansible_tower_cfgmgr_record?(node) + foreman_provider_record?(node) end def search_text_type(node) return "provider" if provider_record?(node) return "configuration_profile" if configuration_profile_record?(node) - return "inventory_group" if inventory_group_record?(node) node end - def apply_node_search_text - setup_search_text_for_node - previous_nodetype = search_text_type(@sb[:foreman_search_text][:previous_node]) - current_nodetype = search_text_type(@sb[:foreman_search_text][:current_node]) - - @sb[:foreman_search_text]["#{previous_nodetype}_search_text"] = @search_text - @search_text = @sb[:foreman_search_text]["#{current_nodetype}_search_text"] - @sb[:foreman_search_text]["#{x_active_accord}_search_text"] = @search_text - end - - def setup_search_text_for_node - @sb[:foreman_search_text] ||= {} - @sb[:foreman_search_text][:current_node] ||= x_node - @sb[:foreman_search_text][:previous_node] = @sb[:foreman_search_text][:current_node] - @sb[:foreman_search_text][:current_node] = x_node - end - def update_partials(record_showing, presenter, r) if record_showing && valid_configured_system_record?(@configured_system_record) get_tagdata(@record) presenter.hide(:form_buttons_div) - path_dir = "provider_foreman" + path_dir = controller_name presenter.update(:main_div, r[:partial => "#{path_dir}/main", - :locals => {:controller => 'provider_foreman'}]) + :locals => {:controller => controller_name}]) elsif @in_a_form - partial_locals = {:controller => 'provider_foreman'} + partial_locals = {:controller => controller_name} @right_cell_text = - if @sb[:action] == "provider_foreman_add_provider" - _("Add a new Configuration Manager Provider") - elsif @sb[:action] == "provider_foreman_edit_provider" - # set the title based on the configuration manager provider type - _("Edit Configuration Manager Provider") + if @sb[:action] == "#{controller_name}_add_provider" + _("Add a new Configuration Management Provider") + elsif @sb[:action] == "#{controller_name}_edit_provider" + _("Edit Provider") end partial = 'form' presenter.update(:main_div, r[:partial => partial, :locals => partial_locals]) elsif valid_configuration_profile_record?(@configuration_profile_record) presenter.hide(:form_buttons_div) presenter.update(:main_div, r[:partial => "configuration_profile", - :locals => {:controller => 'provider_foreman'}]) - elsif valid_inventory_group_record?(@inventory_group_record) - presenter.hide(:form_buttons_div) - presenter.update(:main_div, r[:partial => "inventory_group", - :locals => {:controller => 'provider_foreman'}]) - elsif valid_configuration_script_record?(@configuration_script_record) - presenter.hide(:form_buttons_div) - presenter.update(:main_div, r[:partial => "configuration_script", - :locals => {:controller => 'provider_foreman'}]) + :locals => {:controller => controller_name}]) else presenter.update(:main_div, r[:partial => 'layouts/x_gtl']) end end - def replace_search_box(presenter, r) - # Replace the searchbox - presenter.replace(:adv_searchbox_div, - r[:partial => 'layouts/x_adv_searchbox']) - - presenter[:clear_gtl_list_grid] = @gtl_type && @gtl_type != 'list' - end - - def handle_bottom_cell(presenter, r) - # Handle bottom cell - if @pages || @in_a_form - if @pages && !@in_a_form - @ajax_paging_buttons = true - if @sb[:action] && @record # Came in from an action link - presenter.update(:paging_div, r[:partial => 'layouts/x_pagingcontrols', - :locals => {:action_url => @sb[:action], - :action_method => @sb[:action], - :action_id => @record.id}]) - else - presenter.update(:paging_div, r[:partial => 'layouts/x_pagingcontrols']) - end - presenter.hide(:form_buttons_div).show(:pc_div_1) - elsif @in_a_form - presenter.hide(:pc_div_1).show(:form_buttons_div) - end - presenter.show(:paging_div) - else - presenter.hide(:paging_div) - end - end - - def rebuild_toolbars(record_showing, presenter) - if configuration_profile_summary_tab_selected? || inventory_group_summary_tab_selected? - center_tb = "blank_view_tb" - record_showing = true - end - - if !@in_a_form && !@sb[:action] - center_tb ||= center_toolbar_filename - c_tb = build_toolbar(center_tb) - - v_tb = if record_showing - build_toolbar("x_summary_view_tb") - else - build_toolbar("x_gtl_view_tb") - end - end - - h_tb = build_toolbar("x_history_tb") unless @in_a_form - - presenter.reload_toolbars(:history => h_tb, :center => c_tb, :view => v_tb) - - presenter.set_visibility(h_tb.present? || c_tb.present? || v_tb.present?, :toolbar) - - presenter[:record_id] = @record.try(:id) - - # Hide/show searchbox depending on if a list is showing - presenter.set_visibility(display_adv_searchbox, :adv_searchbox_div) - presenter[:clear_search_toggle] = clear_search_status - - presenter.hide(:blocker_div) unless @edit && @edit[:adv_search_open] - presenter.hide(:quicksearchbox) - presenter[:hide_modal] = true - - presenter.lock_tree(x_active_tree, @in_a_form) - end - - def display_adv_searchbox - !(@configured_system_record || - @in_a_form || - configuration_profile_summary_tab_selected? || @configuration_script_record) - end - - def configuration_profile_summary_tab_selected? + def group_summary_tab_selected? @configuration_profile_record && @sb[:active_tab] == 'summary' end - def inventory_group_summary_tab_selected? - @inventory_group_record && @sb[:active_tab] == 'summary' - end - - def construct_edit - @edit ||= {} - @edit[:current] = {:name => @provider_cfgmgmt.name, - :provtype => model_to_name(@provider_cfgmgmt.type), - :url => @provider_cfgmgmt.url, - :verify_ssl => @provider_cfgmgmt.verify_ssl} - @edit[:new] = {:name => params[:name], - :provtype => params[:provtype], - :url => params[:url], - :verify_ssl => params[:verify_ssl]} - end - - def locals_for_service_dialog - {:action_url => 'service_dialog', - :no_reset => true, - :record_id => @sb[:rec_id] || @edit[:object_ids] && @edit[:object_ids][0] - } - end - - def update_service_dialog_partials(presenter, r) - presenter.update(:main_div, r[:partial => 'configscript_service_dialog', - :locals => locals_for_service_dialog]) - locals = {:record_id => @edit[:rec_id], - :action_url => "configscript_service_dialog_submit", - :no_reset => true, - :serialize => true} - presenter.update(:form_buttons_div, r[:partial => 'layouts/x_edit_buttons', - :locals => locals]) - end - - def breadcrumb_name(_model) - "#{ui_lookup(:ui_title => 'foreman')} #{ui_lookup(:model => 'ExtManagementSystem')}" - end - - def tagging_explorer_controller? - @explorer - end - def active_tab_configured_systems? - (%w(x_show x_search_by_name).include?(action_name) && (configuration_profile_record? || inventory_group_record?)) || + (%w(x_show x_search_by_name).include?(action_name) && configuration_profile_record?) || unassigned_configuration_profile?(x_node) end @@ -1112,106 +538,15 @@ def add_unassigned_configuration_profile_record_to_view(unassigned_profile_row, @grid_hash = view_to_hash(@view) end - def empty_inventory_group_record?(inventory_group_record) - inventory_group_record.try(:id).nil? - end - - def valid_inventory_group_record?(inventory_group_record) - inventory_group_record.try(:id) - end - - def inventory_group_right_cell_text(model) - return if @sb[:active_tab] != 'configured_systems' - if valid_inventory_group_record?(@inventory_group_record) - record_model = ui_lookup(:model => model || TreeBuilder.get_model_for_prefix(@nodetype)) - @right_cell_text = _("%{model} under Inventory Group \"%{name}\"") % - {:model => ui_lookup(:tables => "configured_system"), - :record_model => record_model, - :name => @inventory_group_record.name} - end - end - - def valid_configuration_script_record?(configuration_script_record) - configuration_script_record.try(:id) - end - - def valid_configured_system_record?(configured_system_record) - configured_system_record.try(:id) - end - def process_show_list(options = {}) options[:dbname] = case x_active_accord when :configuration_manager_providers options[:model] && options[:model] == 'ConfiguredSystem' ? :cm_configured_systems : :cm_providers - when :cs_filter + when :configuration_manager_cs_filter :cm_configured_systems - when :configuration_scripts - :configuration_scripts end super end - def find_record(model, id) - raise _("Invalid input") unless is_integer?(from_cid(id)) - begin - record = model.where(:id => from_cid(id)).first - rescue ActiveRecord::RecordNotFound, StandardError => ex - if @explorer - self.x_node = "root" - add_flash(ex.message, :error, true) - session[:flash_msgs] = @flash_array.dup - end - end - record - end - - def title - _("Providers") - end - - def configscript_service_dialog - assert_privileges("configscript_service_dialog") - cs = ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript.find_by_id(params[:id]) - @edit = {:new => {:dialog_name => ""}, - :key => "cs_edit__#{cs.id}", - :rec_id => cs.id} - @in_a_form = true - @right_cell_text = _("Adding a new Service Dialog from \"%{name}\"") % {:name => cs.name} - render_service_dialog_form - end - - def configscript_service_dialog_submit_cancel - add_flash(_("Creation of a new Service Dialog was cancelled by the user")) - @in_a_form = false - @edit = @record = nil - replace_right_cell - end - - def configscript_service_dialog_submit_save - assert_privileges("configscript_service_dialog") - load_edit("cs_edit__#{params[:id]}", "replace_cell__explorer") - begin - cs = ConfigurationScript.find_by_id(params[:id]) - AnsibleTowerJobTemplateDialogService.new.create_dialog(cs, @edit[:new][:dialog_name]) - rescue => bang - add_flash(_("Error when creating Service Dialog: %{error_message}") % - {:error_message => bang.message}, :error) - javascript_flash - else - add_flash(_("Service Dialog \"%{name}\" was successfully created") % - {:name => @edit[:new][:dialog_name]}, :success) - @in_a_form = false - @edit = @record = nil - replace_right_cell - end - end - - def cs_edit_get_form_vars - @edit[:new][:name] = params[:name] if params[:name] - @edit[:new][:description] = params[:description] if params[:description] - @edit[:new][:draft] = params[:draft] == "true" if params[:draft] - @edit[:new][:dialog_name] = params[:dialog_name] if params[:dialog_name] - end - menu_section :conf end diff --git a/app/decorators/manageiq/providers/configuration_manager/inventory_group_decorator.rb b/app/decorators/manageiq/providers/automation_manager/inventory_group_decorator.rb similarity index 100% rename from app/decorators/manageiq/providers/configuration_manager/inventory_group_decorator.rb rename to app/decorators/manageiq/providers/automation_manager/inventory_group_decorator.rb diff --git a/app/decorators/manageiq/providers/configuration_manager/inventory_root_group_decorator.rb b/app/decorators/manageiq/providers/automation_manager/inventory_root_group_decorator.rb similarity index 100% rename from app/decorators/manageiq/providers/configuration_manager/inventory_root_group_decorator.rb rename to app/decorators/manageiq/providers/automation_manager/inventory_root_group_decorator.rb diff --git a/app/decorators/manageiq/providers/automation_manager_decorator.rb b/app/decorators/manageiq/providers/automation_manager_decorator.rb new file mode 100644 index 00000000000..8f6d3b0d22a --- /dev/null +++ b/app/decorators/manageiq/providers/automation_manager_decorator.rb @@ -0,0 +1,13 @@ +module ManageIQ::Providers + class AutomationManagerDecorator < Draper::Decorator + delegate_all + + def fonticon + nil + end + + def listicon_image + "svg/vendor-#{image_name.downcase}.svg" + end + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index de6fd09b481..599af6496e7 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -260,7 +260,10 @@ def view_to_url(view, parent = nil) elsif %w(ConfigurationProfile EmsFolder).include?(view.db) && request.parameters[:controller] == "provider_foreman" return url_for(:action => action, :id => nil) + "/" - elsif %w(ConfiguredSystem).include?(view.db) && request.parameters[:controller] == "provider_foreman" + elsif %w(ManageIQ::Providers::AutomationManager::InventoryGroup EmsFolder).include?(view.db) && + request.parameters[:controller] == "automation_manager" + return url_for(:action => action, :id => nil) + "/" + elsif %w(ConfiguredSystem).include?(view.db) && (request.parameters[:controller] == "provider_foreman" || request.parameters[:controller] == "automation_manager") return url_for(:action => action, :id => nil) + "/" else return url_for(:action => action) + "/" # In explorer, don't jump to other controllers @@ -814,6 +817,7 @@ def display_back_button? def display_adv_search? %w(auth_key_pair_cloud availability_zone + automation_manager cim_base_storage_extent cloud_network cloud_object_store_container @@ -1458,6 +1462,7 @@ def show_adv_search? show_search = %w( auth_key_pair_cloud availability_zone + automation_manager cim_base_storage_extent cloud_network cloud_object_store_container @@ -1596,9 +1601,11 @@ def miq_tab_content(id, active = nil, options = {}, &_block) end def tree_with_advanced_search? - %i(containers + %i(automation_manager_providers + automation_manager_cs_filter + containers containers_filter - cs_filter + configuration_manager_cs_filter configuration_scripts configuration_manager_providers images diff --git a/app/helpers/application_helper/toolbar/automation_manager_provider_center.rb b/app/helpers/application_helper/toolbar/automation_manager_provider_center.rb new file mode 100644 index 00000000000..a2294a06c63 --- /dev/null +++ b/app/helpers/application_helper/toolbar/automation_manager_provider_center.rb @@ -0,0 +1,38 @@ +class ApplicationHelper::Toolbar::AutomationManagerProviderCenter < ApplicationHelper::Toolbar::Basic + button_group('provider_vmdb', [ + select( + :provider_vmdb_choice, + 'fa fa-cog fa-lg', + t = N_('Configuration'), + t, + :enabled => true, + :items => [ + button( + :automation_manager_refresh_provider, + 'fa fa-refresh fa-lg', + N_('Refresh relationships for all items related to this Provider'), + N_('Refresh Relationships and Power states'), + :url => "refresh", + :confirm => N_("Refresh relationships for all items related to this Provider?") + ), + separator, + button( + :automation_manager_edit_provider, + 'pficon pficon-edit fa-lg', + t = N_('Edit this Provider'), + t, + :url => "edit" + ), + button( + :automation_manager_delete_provider, + 'pficon pficon-delete fa-lg', + t = N_('Remove this Provider'), + t, + :url => "delete", + :confirm => N_("Warning: The selected Provider and ALL of their components will be permanently removed!") + ) + ] + ), + ] + ) +end diff --git a/app/helpers/application_helper/toolbar/automation_manager_providers_center.rb b/app/helpers/application_helper/toolbar/automation_manager_providers_center.rb new file mode 100644 index 00000000000..377fe0e38e0 --- /dev/null +++ b/app/helpers/application_helper/toolbar/automation_manager_providers_center.rb @@ -0,0 +1,56 @@ +class ApplicationHelper::Toolbar::AutomationManagerProvidersCenter < ApplicationHelper::Toolbar::Basic + button_group('provider_vmdb', [ + select( + :provider_vmdb_choice, + 'fa fa-cog fa-lg', + t = N_('Configuration'), + t, + :enabled => true, + :items => [ + button( + :automation_manager_refresh_provider, + 'fa fa-refresh fa-lg', + N_('Refresh relationships for all items related to the selected items'), + N_('Refresh Relationships and Power states'), + :url => "refresh", + :url_parms => "main_div", + :confirm => N_("Refresh relationships for all items related to the selected items?"), + :enabled => false, + :onwhen => "1+" + ), + separator, + button( + :automation_manager_add_provider, + 'pficon pficon-add-circle-o fa-lg', + t = N_('Add a new Provider'), + t, + :enabled => true, + :url => "new" + ), + button( + :automation_manager_edit_provider, + 'pficon pficon-edit fa-lg', + N_('Select a single item to edit'), + N_('Edit Selected item'), + :url => "edit", + :url_parms => "main_div", + :enabled => false, + :onwhen => "1" + ), + button( + :automation_manager_delete_provider, + 'pficon pficon-delete fa-lg', + t = N_('Remove selected items'), + t, + :url => "delete", + :url_parms => "main_div", + :confirm => N_("Warning: The selected items and ALL of their components will be permanently removed!"), + :enabled => false, + :onwhen => "1+" + ), + separator, + ] + ), + ] + ) +end diff --git a/app/helpers/application_helper/toolbar/configuration_script_center.rb b/app/helpers/application_helper/toolbar/configuration_script_center.rb index 0ea23551a25..081c8e4a17f 100644 --- a/app/helpers/application_helper/toolbar/configuration_script_center.rb +++ b/app/helpers/application_helper/toolbar/configuration_script_center.rb @@ -14,7 +14,7 @@ class ApplicationHelper::Toolbar::ConfigurationScriptCenter < ApplicationHelper: ] ), select( - :provider_foreman_policy_choice, + :automation_manager_policy_choice, 'fa fa-shield fa-lg', t = N_('Policy'), t, diff --git a/app/helpers/application_helper/toolbar/configured_system/automation_policy_mixin.rb b/app/helpers/application_helper/toolbar/configured_system/automation_policy_mixin.rb new file mode 100644 index 00000000000..cd7fd939447 --- /dev/null +++ b/app/helpers/application_helper/toolbar/configured_system/automation_policy_mixin.rb @@ -0,0 +1,24 @@ +module ApplicationHelper::Toolbar::ConfiguredSystem::AutomationPolicyMixin + def self.included(included_class) + included_class.button_group('automation_manager_policy', [ + included_class.select( + :automation_manager_policy_choice, + 'fa fa-shield fa-lg', + t = N_('Policy'), + t, + :enabled => true, + :items => [ + included_class.button( + :automation_manager_configured_system_tag, + 'pficon pficon-edit fa-lg', + N_('Edit Tags for this Configured System'), + N_('Edit Tags'), + :url => "tagging", + :url_parms => "main_div", + :enabled => true + ), + ] + ), + ]) + end +end diff --git a/app/helpers/application_helper/toolbar/inventory_group_center.rb b/app/helpers/application_helper/toolbar/inventory_group_center.rb index 7588c72476d..48cd9003e00 100644 --- a/app/helpers/application_helper/toolbar/inventory_group_center.rb +++ b/app/helpers/application_helper/toolbar/inventory_group_center.rb @@ -8,7 +8,7 @@ class ApplicationHelper::Toolbar::InventoryGroupCenter < ApplicationHelper::Tool :enabled => true, :items => [ button( - :provider_foreman_refresh_provider, + :automation_manager_refresh, 'fa fa-refresh fa-lg', N_('Refresh relationships for all items related to this Provider'), N_('Refresh Relationships and Power states'), @@ -16,13 +16,13 @@ class ApplicationHelper::Toolbar::InventoryGroupCenter < ApplicationHelper::Tool :confirm => N_("Refresh relationships for all items related to this Provider?")), separator, button( - :provider_foreman_edit_provider, + :automation_manager_edit, 'pficon pficon-edit fa-lg', t = N_('Edit this Provider'), t, :url => "edit"), button( - :provider_foreman_delete_provider, + :automation_manager_delete, 'pficon pficon-delete fa-lg', t = N_('Remove this Provider'), t, diff --git a/app/helpers/application_helper/toolbar/x_ansible_tower_configured_system_center.rb b/app/helpers/application_helper/toolbar/x_ansible_tower_configured_system_center.rb index b73a29e2c4a..f8d7bbcf363 100644 --- a/app/helpers/application_helper/toolbar/x_ansible_tower_configured_system_center.rb +++ b/app/helpers/application_helper/toolbar/x_ansible_tower_configured_system_center.rb @@ -1,21 +1,3 @@ class ApplicationHelper::Toolbar::XAnsibleTowerConfiguredSystemCenter < ApplicationHelper::Toolbar::Basic - button_group('record_summary', [ - select( - :provider_foreman_policy_choice, - 'fa fa-shield fa-lg', - t = N_('Policy'), - t, - :enabled => true, - :items => [ - button( - :provider_foreman_configured_system_tag, - 'pficon pficon-edit fa-lg', - N_('Edit Tags for this Configured System'), - N_('Edit Tags'), - :url => "tagging", - :url_parms => "main_div", - :enabled => true), - ] - ), - ]) + include ApplicationHelper::Toolbar::ConfiguredSystem::AutomationPolicyMixin end diff --git a/app/helpers/application_helper/toolbar/x_automation_manager_ansible_tower_configured_system_center.rb b/app/helpers/application_helper/toolbar/x_automation_manager_ansible_tower_configured_system_center.rb new file mode 100644 index 00000000000..320eca900c0 --- /dev/null +++ b/app/helpers/application_helper/toolbar/x_automation_manager_ansible_tower_configured_system_center.rb @@ -0,0 +1,3 @@ +class ApplicationHelper::Toolbar::XAutomationManagerAnsibleTowerConfiguredSystemCenter < ApplicationHelper::Toolbar::Basic + include ApplicationHelper::Toolbar::ConfiguredSystem::AutomationPolicyMixin +end diff --git a/app/helpers/application_helper/toolbar/x_automation_manager_configured_system_center.rb b/app/helpers/application_helper/toolbar/x_automation_manager_configured_system_center.rb new file mode 100644 index 00000000000..121a78911c9 --- /dev/null +++ b/app/helpers/application_helper/toolbar/x_automation_manager_configured_system_center.rb @@ -0,0 +1,3 @@ +class ApplicationHelper::Toolbar::XAutomationManagerConfiguredSystemCenter < ApplicationHelper::Toolbar::Basic + include ApplicationHelper::Toolbar::ConfiguredSystem::AutomationPolicyMixin +end diff --git a/app/helpers/application_helper/toolbar/x_configuration_script_center.rb b/app/helpers/application_helper/toolbar/x_configuration_script_center.rb index 9b66309c440..a1960adf46f 100644 --- a/app/helpers/application_helper/toolbar/x_configuration_script_center.rb +++ b/app/helpers/application_helper/toolbar/x_configuration_script_center.rb @@ -14,7 +14,7 @@ class ApplicationHelper::Toolbar::XConfigurationScriptCenter < ApplicationHelper ] ), select( - :provider_foreman_policy_choice, + :automation_manager_policy_choice, 'fa fa-shield fa-lg', t = N_('Policy'), t, diff --git a/app/helpers/application_helper/toolbar/x_provider_foreman_ansible_tower_configured_system_center.rb b/app/helpers/application_helper/toolbar/x_provider_foreman_ansible_tower_configured_system_center.rb deleted file mode 100644 index c7b6b538869..00000000000 --- a/app/helpers/application_helper/toolbar/x_provider_foreman_ansible_tower_configured_system_center.rb +++ /dev/null @@ -1,21 +0,0 @@ -class ApplicationHelper::Toolbar::XProviderForemanAnsibleTowerConfiguredSystemCenter < ApplicationHelper::Toolbar::Basic - button_group('record_summary', [ - select( - :provider_foreman_policy_choice, - 'fa fa-shield fa-lg', - t = N_('Policy'), - t, - :enabled => true, - :items => [ - button( - :provider_foreman_configured_system_tag, - 'pficon pficon-edit fa-lg', - N_('Edit Tags for this Configured System'), - N_('Edit Tags'), - :url => "tagging", - :url_parms => "main_div", - :enabled => true), - ] - ), - ]) -end diff --git a/app/helpers/application_helper/toolbar_chooser.rb b/app/helpers/application_helper/toolbar_chooser.rb index 3b5831d78c7..e2742b85a59 100644 --- a/app/helpers/application_helper/toolbar_chooser.rb +++ b/app/helpers/application_helper/toolbar_chooser.rb @@ -99,8 +99,10 @@ def center_toolbar_filename_explorer when :vms_instances_filter_tree then "vms_center_tb" end end - elsif @layout == "provider_foreman" && [:configuration_manager_providers_tree, :cs_filter_tree, :configuration_scripts_tree].include?(x_active_tree) + elsif @layout == "provider_foreman" && [:configuration_manager_providers_tree, :configuration_manager_cs_filter_tree].include?(x_active_tree) return center_toolbar_filename_configuration_manager_providers + elsif @layout == "automation_manager" + return center_toolbar_filename_automation_manager elsif [:infra_networking_tree].include?(x_active_tree) return center_toolbar_filename_infra_networking else @@ -509,13 +511,24 @@ def center_toolbar_filename_configuration_manager_providers nodes = x_node.split('-') if x_active_tree == :configuration_manager_providers_tree configuration_manager_providers_tree_center_tb(nodes) - elsif x_active_tree == :cs_filter_tree + elsif x_active_tree == :configuration_manager_cs_filter_tree cs_filter_tree_center_tb(nodes) elsif x_active_tree == :configuration_scripts_tree configuration_scripts_tree_center_tb(nodes) end end + def center_toolbar_filename_automation_manager + nodes = x_node.split('-') + if x_active_tree == :automation_manager_providers_tree + automation_manager_providers_tree_center_tb(nodes) + elsif x_active_tree == :automation_manager_cs_filter_tree + automation_manager_cs_filter_tree_center_tb(nodes) + elsif x_active_tree == :configuration_scripts_tree + automation_manager_configuration_scripts_tree_center_tb(nodes) + end + end + def center_toolbar_filename_infra_networking nodes = x_node.split('-') infra_networking_tree_center_tb(nodes) @@ -551,6 +564,29 @@ def configuration_scripts_tree_center_tb(nodes) end end + def automation_manager_providers_tree_center_tb(nodes) + case nodes.first + when "root" then "automation_manager_providers_center_tb" + when "at" then "automation_manager_provider_center_tb" + when "f" then inventory_group_center_tb + when "xx" then "configured_systems_ansible_center_tb" + end + end + + def automation_manager_cs_filter_tree_center_tb(nodes) + case nodes.first + when "root", "ms", "xx", "csa" then "configured_systems_ansible_center_tb" + end + end + + def automation_manager_configuration_scripts_tree_center_tb(nodes) + if %w(root at).include?(nodes.first) + "configuration_scripts_center_tb" + else + "configuration_script_center_tb" + end + end + def infra_networking_tree_center_tb(nodes) if %w(root e h c).include?(nodes.first) "infra_networkings_center_tb" diff --git a/app/helpers/automation_manager_helper.rb b/app/helpers/automation_manager_helper.rb new file mode 100644 index 00000000000..fb3db97e95a --- /dev/null +++ b/app/helpers/automation_manager_helper.rb @@ -0,0 +1,134 @@ +module AutomationManagerHelper + include TextualMixins::TextualGroupTags + + def textual_group_properties + %i(hostname + ipmi_present + ipaddress + mac_address + provider_name + zone) + end + + def textual_hostname + {:label => _("Hostname"), + :icon => "product product-configured_system", + :value => @record.hostname} + end + + def textual_ipmi_present + {:label => _("IPMI Present"), :value => @record.ipmi_present} + end + + def textual_ipaddress + {:label => _("IP Address"), :value => @record.ipaddress} + end + + def textual_mac_address + {:label => _("Mac address"), :value => @record.mac_address} + end + + def textual_provider_name + {:label => _("Provider"), + :image => "svg/vendor-#{@record.configuration_manager.image_name}.svg", + :value => @record.configuration_manager.try(:name), + :explorer => true} + end + + def textual_zone + {:label => _("Zone"), :value => @record.configuration_manager.my_zone} + end + + def textual_inventory_group_properties + %i(inventory_group_name + inventory_group_region) + end + + def textual_inventory_group_name + {:label => _("Name"), :value => @record.name} + end + + def textual_inventory_group_region + {:label => _("Region"), :value => @record.region_description} + end + + def textual_inventory_group_architecture + {:label => _("Architecture"), :value => @record.configuration_architecture_name} + end + + def textual__inventory_group_os + {:label => _("OS"), :value => @record.operating_system_flavor_name} + end + + def textual_inventory_group_medium + {:label => _("Medium"), :value => @record.customization_script_medium_name} + end + + def textual_inventory_group_partition_table + {:label => _("Partition Table"), :value => @record.customization_script_ptable_name} + end + + def textual_configuration_script_group_properties + %i(configuration_script_name + configuration_script_region) + end + + def textual_configuration_script_name + {:label => _("Name"), :value => @record.name} + end + + def textual_configuration_script_region + {:label => _("Region"), :value => @record.region_description} + end + + def textual_configuration_script_variables + textual_variables(@record.variables) + end + + def textual_configuration_script_survey + textual_survey_group(@record.survey_spec['spec']) + end + + def textual_configuration_script_group_os + %i(configuration_script_medium + configuration_script_partition_table) + end + + def textual_survey_group(items) + return unless items + h = {:label => _("Questions"), + :headers => [_('Question Name'), _('Question Description'), _('Variable'), + _('Type'), _('Min'), _('Max'), _('Default'), _('Required'), _('Choices')], + :col_order => %w(question_name question_description variable type min max default required choices)} + h[:value] = items.collect do |item| + { + :title => item['index'], + :question_name => item['question_name'], + :question_description => item['question_description'], + :variable => item['variable'], + :type => item['type'], + :min => item['min'], + :max => item['max'], + :default => item['default'], + :required => item['required'], + :choices => item['choices'] + } + end + h + end + + def textual_variables(vars) + return unless vars + h = {:label => _("Variables"), + :headers => [_('Name'), _('Value')], + :col_order => %w(name value)} + h[:value] = vars.collect do |item| + { + :name => item[0].to_s, + :value => item[1].to_s + } + end + h + end +end +# diff --git a/app/helpers/configuration_job_helper/textual_summary.rb b/app/helpers/configuration_job_helper/textual_summary.rb index 06e1db3fd46..69bf1475a40 100644 --- a/app/helpers/configuration_job_helper/textual_summary.rb +++ b/app/helpers/configuration_job_helper/textual_summary.rb @@ -43,7 +43,7 @@ def textual_service end def textual_provider - h = {:label => _("Provider"), :image => "svg/vendor-ansible_tower_configuration.svg"} + h = {:label => _("Provider"), :image => "svg/vendor-automation_manager_configuration.svg"} provider = @record.ext_management_system if provider.nil? h[:value] = _("None") diff --git a/app/presenters/menu/default_menu.rb b/app/presenters/menu/default_menu.rb index 6a07bcb7fa0..d25b4b13f97 100644 --- a/app/presenters/menu/default_menu.rb +++ b/app/presenters/menu/default_menu.rb @@ -12,7 +12,6 @@ def compute_menu_section def configuration_menu_section Menu::Section.new(:conf, N_("Configuration"), 'fa fa-cog fa-2x', [ Menu::Item.new('provider_foreman', N_('Management'), 'provider_foreman_explorer', {:feature => 'provider_foreman_explorer', :any => true}, '/provider_foreman/explorer'), - Menu::Item.new('configuration_job', N_('Jobs'), 'configuration_job', {:feature => 'configuration_job_show_list'}, '/configuration_job'), ]) end @@ -215,8 +214,14 @@ def control_menu_section end def automation_menu_section - Menu::Section.new(:aut, N_("Automation"), 'fa fa-recycle fa-2x', [ - automate_menu_section + Menu::Section.new(:aut, N_("Automation"), 'fa fa-recycle fa-2x', [automate_menu_section, + automation_manager_menu_section]) + end + + def automation_manager_menu_section + Menu::Section.new(:at, N_("Ansible Tower"), 'fa fa-cog fa-2x', [ + Menu::Item.new('automation_manager', N_('Explorer'), 'automation_manager', {:feature => 'automation_manager', :any => true}, '/automation_manager/explorer'), + Menu::Item.new('configuration_job', N_('Jobs'), 'configuration_job', {:feature => 'configuration_job_show_list'}, '/configuration_job') ]) end diff --git a/app/presenters/tree_builder.rb b/app/presenters/tree_builder.rb index 7a214c6c052..ce91b6ce51c 100644 --- a/app/presenters/tree_builder.rb +++ b/app/presenters/tree_builder.rb @@ -355,8 +355,7 @@ def resolve_object_lambdas(count_only, objects) X_TREE_NODE_CLASSES = { # Catalog explorer trees :configuration_manager_providers => "TreeBuilderConfigurationManager", - :cs_filter => "TreeBuilderConfigurationManagerConfiguredSystems", - :configuration_scripts => "TreeBuilderConfigurationManagerConfigurationScripts", + :configuration_manager_cs_filter => "TreeBuilderConfigurationManagerConfiguredSystems", # Catalog explorer trees :ot => "TreeBuilderOrchestrationTemplates", @@ -441,6 +440,12 @@ def resolve_object_lambdas(count_only, objects) :network => "TreeBuilderNetwork", :df => "TreeBuilderDefaultFilters", + + # Automation trees + :automation_manager_providers => "TreeBuilderAutomationManagerProviders", + :automation_manager_cs_filter => "TreeBuilderAutomationManagerConfiguredSystems", + :configuration_scripts => "TreeBuilderAutomationManagerConfigurationScripts", + } # Tree node prefixes for generic explorers diff --git a/app/presenters/tree_builder_configuration_manager_configuration_scripts.rb b/app/presenters/tree_builder_automation_manager_configuration_scripts.rb similarity index 93% rename from app/presenters/tree_builder_configuration_manager_configuration_scripts.rb rename to app/presenters/tree_builder_automation_manager_configuration_scripts.rb index 1ec0800c0a1..ce7448c85e4 100644 --- a/app/presenters/tree_builder_configuration_manager_configuration_scripts.rb +++ b/app/presenters/tree_builder_automation_manager_configuration_scripts.rb @@ -1,4 +1,4 @@ -class TreeBuilderConfigurationManagerConfigurationScripts < TreeBuilder +class TreeBuilderAutomationManagerConfigurationScripts < TreeBuilder has_kids_for ManageIQ::Providers::AnsibleTower::AutomationManager, [:x_get_tree_cmat_kids] attr_reader :tree_nodes diff --git a/app/presenters/tree_builder_automation_manager_configured_systems.rb b/app/presenters/tree_builder_automation_manager_configured_systems.rb new file mode 100644 index 00000000000..3c1fa4243b9 --- /dev/null +++ b/app/presenters/tree_builder_automation_manager_configured_systems.rb @@ -0,0 +1,64 @@ +class TreeBuilderAutomationManagerConfiguredSystems < TreeBuilder + attr_reader :tree_nodes + + private + + def tree_init_options(_tree_name) + {:leaf => "ManageIQ::Providers::AnsibleTower::AutomationManager::ConfiguredSystem"} + end + + def set_locals_for_render + locals = super + locals.merge!(:autoload => true) + end + + def root_options + { + :title => t = _("All Ansible Tower Configured Systems"), + :tooltip => t + } + end + + # Get root nodes count/array for explorer tree + def x_get_tree_roots(count_only, _options) + objects = [] + objects.push(:id => "csa", + :text => _("Ansible Tower Configured Systems"), + :icon => "pficon pficon-folder-close", + :tip => _("Ansible Tower Configured Systems"), + :load_children => true) + objects.push(:id => "global", + :text => _("Global Filters"), + :icon => "pficon pficon-folder-close", + :tip => _("Global Shared Filters"), + :cfmeNoClick => true) + objects.push(:id => "my", + :text => _("My Filters"), + :icon => "pficon pficon-folder-close", + :tip => _("My Personal Filters"), + :cfmeNoClick => true) + count_only_or_objects(count_only, objects) + end + + def x_get_tree_custom_kids(object, count_only, options) + count_only_or_objects(count_only, x_get_search_results(object, options[:leaf])) + end + + def x_get_search_results(object, leaf) + case object[:id] + when "global" # Global filters + x_get_global_filter_search_results(leaf) + when "my" # My filters + x_get_my_filter_search_results(leaf) + end + end + + def x_get_global_filter_search_results(leaf) + MiqSearch.where(:db => leaf).visible_to_all.sort_by { |a| a.description.downcase } + end + + def x_get_my_filter_search_results(leaf) + MiqSearch.where(:db => leaf, :search_type => "user", :search_key => User.current_user.userid) + .sort_by { |a| a.description.downcase } + end +end diff --git a/app/presenters/tree_builder_automation_manager_providers.rb b/app/presenters/tree_builder_automation_manager_providers.rb new file mode 100644 index 00000000000..a0e2d937853 --- /dev/null +++ b/app/presenters/tree_builder_automation_manager_providers.rb @@ -0,0 +1,39 @@ +class TreeBuilderAutomationManagerProviders < TreeBuilder + has_kids_for ManageIQ::Providers::AnsibleTower::AutomationManager, [:x_get_tree_cmat_kids] + has_kids_for ManageIQ::Providers::AutomationManager::InventoryRootGroup, [:x_get_tree_igf_kids] + + private + + def tree_init_options(_tree_name) + {:leaf => "ManageIQ::Providers::AnsibleTower::AutomationManager"} + end + + def set_locals_for_render + locals = super + locals.merge!(:autoload => true) + end + + def root_options + { + :title => t = _("All Ansible Tower Providers"), + :tooltip => t + } + end + + # Get root nodes count/array for explorer tree + def x_get_tree_roots(count_only, _options) + count_only_or_objects_filtered(count_only, ManageIQ::Providers::AnsibleTower::AutomationManager, "name", :match_via_descendants => ConfiguredSystem) + end + + def x_get_tree_cmat_kids(object, count_only) + count_only_or_objects_filtered(count_only, + ManageIQ::Providers::AutomationManager::InventoryGroup.where(:ems_id => object[:id]), + "name", :match_via_descendants => ConfiguredSystem) + end + + def x_get_tree_igf_kids(object, count_only) + count_only_or_objects_filtered(count_only, + ConfiguredSystem.where(:inventory_root_group_id=> object[:id]), + "hostname", :match_via_descendants => ConfiguredSystem) + end +end diff --git a/app/presenters/tree_builder_configuration_manager.rb b/app/presenters/tree_builder_configuration_manager.rb index f9a47a778f7..09dcd4414e9 100644 --- a/app/presenters/tree_builder_configuration_manager.rb +++ b/app/presenters/tree_builder_configuration_manager.rb @@ -1,7 +1,5 @@ class TreeBuilderConfigurationManager < TreeBuilder has_kids_for ManageIQ::Providers::Foreman::ConfigurationManager, [:x_get_tree_cmf_kids] - has_kids_for ManageIQ::Providers::AnsibleTower::AutomationManager, [:x_get_tree_cmat_kids] - has_kids_for ManageIQ::Providers::AutomationManager::InventoryRootGroup, [:x_get_tree_igf_kids] has_kids_for ConfigurationProfile, [:x_get_tree_cpf_kids] private @@ -31,21 +29,9 @@ def x_get_tree_roots(count_only, _options) :icon => "pficon pficon-folder-close", :tip => _("%{name} Providers") % {:name => ui_lookup(:ui_title => 'foreman')}, :load_children => true) - objects.push(:id => "at", - :tree => "at_tree", - :text => _("Ansible Tower Providers"), - :icon => "pficon pficon-folder-close", - :tip => _("Ansible Tower Providers"), - :load_children => true) count_only_or_objects(count_only, objects) end - def x_get_tree_cmat_kids(object, count_only) - count_only_or_objects_filtered(count_only, - ManageIQ::Providers::AutomationManager::InventoryGroup.where(:ems_id => object[:id]), - "name", :match_via_descendants => ConfiguredSystem) - end - def x_get_tree_cmf_kids(object, count_only) assigned_configuration_profile_objs = count_only_or_objects_filtered(count_only, @@ -79,17 +65,10 @@ def x_get_tree_cpf_kids(object, count_only) "hostname", :match_via_descendants => ConfiguredSystem) end - def x_get_tree_igf_kids(object, count_only) - count_only_or_objects_filtered(count_only, - ConfiguredSystem.where(:inventory_root_group_id=> object[:id]), - "hostname", :match_via_descendants => ConfiguredSystem) - end - def x_get_tree_custom_kids(object_hash, count_only, _options) objects = case object_hash[:id] when "fr" then ManageIQ::Providers::Foreman::ConfigurationManager - when "at" then ManageIQ::Providers::AnsibleTower::AutomationManager end count_only_or_objects_filtered(count_only, objects, "name", :match_via_descendants => ConfiguredSystem) end diff --git a/app/presenters/tree_builder_configuration_manager_configured_systems.rb b/app/presenters/tree_builder_configuration_manager_configured_systems.rb index f557c88485d..c91a274fee6 100644 --- a/app/presenters/tree_builder_configuration_manager_configured_systems.rb +++ b/app/presenters/tree_builder_configuration_manager_configured_systems.rb @@ -4,7 +4,7 @@ class TreeBuilderConfigurationManagerConfiguredSystems < TreeBuilder private def tree_init_options(_tree_name) - {:leaf => "ConfiguredSystem"} + {:leaf => "ManageIQ::Providers::ForemanProvider::ConfigurationManager::ConfiguredSystem"} end def set_locals_for_render @@ -27,11 +27,6 @@ def x_get_tree_roots(count_only, _options) :icon => "pficon pficon-folder-close", :tip => _("%{name} Configured Systems") % {:name => ui_lookup(:ui_title => 'foreman')}, :load_children => true) - objects.push(:id => "csa", - :text => _("Ansible Tower Configured Systems"), - :icon => "pficon pficon-folder-close", - :tip => _("Ansible Tower Configured Systems"), - :load_children => true) objects.push(:id => "global", :text => _("Global Filters"), :icon => "pficon pficon-folder-close", diff --git a/app/views/automation_manager/_configscript_service_dialog.html.haml b/app/views/automation_manager/_configscript_service_dialog.html.haml new file mode 100644 index 00000000000..afbee068486 --- /dev/null +++ b/app/views/automation_manager/_configscript_service_dialog.html.haml @@ -0,0 +1,17 @@ +#form_div + #basic_info_div + = render :partial => "layouts/flash_msg" + - url = url_for(:action => "cs_form_field_changed", :id => @edit[:rec_id]) + .form-horizontal + .form-group + %label.col-md-2.control-label + = _('Service Dialog Name') + .col-md-8 + = text_field_tag("dialog_name", + "", + :autocomplete => 'off', + :diabled => false, + :class => "form-control", + :maxlength => 255, + "data-miq_observe" => {:interval => '.5', + :url => url}.to_json) diff --git a/app/views/automation_manager/_configuration_script.html.haml b/app/views/automation_manager/_configuration_script.html.haml new file mode 100644 index 00000000000..3194f857860 --- /dev/null +++ b/app/views/automation_manager/_configuration_script.html.haml @@ -0,0 +1,9 @@ += render :partial => "layouts/flash_msg" +.row + .col-md-12.col-lg-8 + = render :partial => "shared/summary/textual", :locals => {:title => _("Properties"), :items => textual_configuration_script_group_properties} + .col-md-12.col-lg-8 + = render :partial => "shared/summary/textual_listview", :locals => {:title => _("Variables"), :items => textual_configuration_script_variables} + .col-md-12.col-lg-8 + - if @record.survey_spec['spec'] + = render :partial => "shared/summary/textual_listview", :locals => {:title => _("Surveys"), :items => textual_configuration_script_survey} diff --git a/app/views/automation_manager/_form.html.haml b/app/views/automation_manager/_form.html.haml new file mode 100644 index 00000000000..8fefb8b620b --- /dev/null +++ b/app/views/automation_manager/_form.html.haml @@ -0,0 +1,93 @@ +- @angular_form = true + +.form-horizontal{:id => "start_form_div", :style => "display:none"} + %form#form_div{:name => "angularForm", + 'ng-controller' => "automationManagerFormController", + 'ng-show' => "afterGet", + :novalidate => true} + = render :partial => "layouts/flash_msg" + %br + .form-group{"ng-class" => "{'has-error': angularForm.name.$invalid}"} + %label.col-md-2.control-label + = _("Name") + .col-md-8 + %input.form-control{:type => "text", + :name => "name", + 'ng-model' => "automationManagerModel.name", + :maxlength => MAX_NAME_LEN, + :required => "", + :checkchange => true, + "auto-focus" => "", + "start-form-div" => "start_form_div"} + %span.help-block{"ng-show" => "angularForm.name.$error.required"} + = _("Required") + + .form-group{"ng-class" => "{'has-error': angularForm.zone.$invalid}"} + %label.col-md-2.control-label{"for" => "prov_zone"} + = _("Zone") + .col-md-8 + - if @server_zones.length <= 1 + %input.form-control{"type" => "text", + "id" => "prov_zone", + "name" => "zone", + "ng-model" => "automationManagerModel.zone", + "maxlength" => 15, + "required" => "", + "checkchange" => "", + "readonly" => true, + "style" => "color: black;"} + - else + = select_tag('zone', + options_for_select(@server_zones.sort_by { |name, _name| name }), + "ng-model" => "automationManagerModel.zone", + "checkchange" => "", + "required" => "", + "selectpicker-for-select-tag" => "") + + .form-group{"ng-class" => "{'has-error': angularForm.url.$invalid}"} + %label.col-md-2.control-label{"for" => "provider_url"} + = _("Url") + .col-md-8 + %input.form-control{:type => "text", + :name => "url", + 'ng-model' => "automationManagerModel.url", + :maxlength => MAX_DESC_LEN, + "id" => "url", + :required => "", + "ng-trim" => false, + "detect_spaces" => "", + :checkchange => true} + %span.help-block{"ng-show" => "angularForm.url.$error.required"} + = _("Required") + %span.help-block{"ng-show" => "angularForm.url.$error.detectedSpaces"} + = _("Spaces are prohibited") + .form-group + %label.col-md-2.control-label + = _("Verify Peer Certificate") + .col-md-8 + %input{:type => "checkbox", + :name => "verify_ssl", + 'ng-model' => "automationManagerModel.verify_ssl", + :checkchange => true} + + + %hr + %h3 + = _("Credentials") + = render :partial => "layouts/angular-bootstrap/auth_credentials_angular_bootstrap", + :locals => {:ng_show => true, + :ng_model => "automationManagerModel", + :ng_reqd_userid => true, + :ng_reqd_password => true, + :ng_reqd_verify => true, + :validate_url => "authentication_validate", + :id => @provider_manager.id || "new", + :valtype => nil, + :basic_info_needed => true} + + = render :partial => "layouts/angular/x_edit_buttons_angular" + %span{:style => "color:black"}= _("Required. Should have privileged access, such as root or administrator.") + +:javascript + ManageIQ.angular.app.value('automationManagerFormId', '#{@provider_manager.id || "new"}'); + miq_bootstrap('#form_div'); diff --git a/app/views/automation_manager/_inventory_group.html.haml b/app/views/automation_manager/_inventory_group.html.haml new file mode 100644 index 00000000000..152988749b2 --- /dev/null +++ b/app/views/automation_manager/_inventory_group.html.haml @@ -0,0 +1,18 @@ +#inventory_group_form_tabs + %ul.nav.nav-tabs + = miq_tab_header('summary', @sb[:active_tab]) do + = _("Summary") + = miq_tab_header('configured_systems', @sb[:active_tab]) do + = _("Configured Systems") + .tab-content + = miq_tab_content('configured_systems', @sb[:active_tab]) do + - if @sb[:active_tab] == "configured_systems" + = render :partial => "layouts/x_gtl" + :javascript + ManageIQ.afterOnload = "if (miqDomElementExists('adv_searchbox_div')) $('#adv_searchbox_div').show();" + = miq_tab_content('summary', @sb[:active_tab]) do + - if @sb[:active_tab] == "summary" + = render :partial => "main_inventory_group" + +:javascript + miq_tabs_init('#inventory_group_form_tabs', '/automation_manager/change_tab'); diff --git a/app/views/automation_manager/_main.html.haml b/app/views/automation_manager/_main.html.haml new file mode 100644 index 00000000000..62cdaa15f7a --- /dev/null +++ b/app/views/automation_manager/_main.html.haml @@ -0,0 +1,6 @@ += render :partial => "layouts/flash_msg" +.row + .col-md-12.col-lg-6 + = render :partial => "shared/summary/textual", :locals => {:title => _("Properties"), :items => textual_group_properties} + .col-md-12.col-lg-6 + = render :partial => "shared/summary/textual_tags", :locals => {:title => _("Smart Management"), :items => textual_group_tags} diff --git a/app/views/automation_manager/_main_inventory_group.html.haml b/app/views/automation_manager/_main_inventory_group.html.haml new file mode 100644 index 00000000000..46e13bfe8ef --- /dev/null +++ b/app/views/automation_manager/_main_inventory_group.html.haml @@ -0,0 +1,4 @@ += render :partial => "layouts/flash_msg" +.row + .col-md-12.col-lg-6 + = render :partial => "shared/summary/textual", :locals => {:title => _("Properties"), :items => textual_inventory_group_properties} diff --git a/app/views/automation_manager/explorer.html.haml b/app/views/automation_manager/explorer.html.haml new file mode 100644 index 00000000000..8c63c02a127 --- /dev/null +++ b/app/views/automation_manager/explorer.html.haml @@ -0,0 +1,20 @@ +- content_for :search do + = render(:partial => "layouts/x_adv_searchbox", :locals => {:nameonly => x_active_tree == :configuration_manager_providers_tree}) + = render(:partial => 'layouts/quick_search') + +-# These are the initial divs that will go inside center_cell_div +- if @inventory_group_record + #main_div + - @pages = nil if @sb[:active_tab] == 'summary' + = render(:partial => 'automation_manager/inventory_group') + +- elsif @configured_system_record + #main_div + = render(:partial => 'automation_manager/main', :locals => {:controller => "automation_manager"}) +- elsif @configuration_script_record + #main_div + = render(:partial => 'automation_manager/configuration_script', :locals => {:controller => "automation_manager"}) +- else + #main_div + = render(:partial => 'layouts/x_gtl') + diff --git a/app/views/provider_foreman/_form.html.haml b/app/views/provider_foreman/_form.html.haml index 2575123db89..5585a3bbd47 100644 --- a/app/views/provider_foreman/_form.html.haml +++ b/app/views/provider_foreman/_form.html.haml @@ -103,7 +103,7 @@ :ng_reqd_password => true, :ng_reqd_verify => true, :validate_url => "authentication_validate", - :id => @provider_cfgmgmt.id || "new", + :id => @provider_manager.id || "new", :valtype => nil, :basic_info_needed => true} @@ -111,5 +111,5 @@ %span{:style => "color:black"}= _("Required. Should have privileged access, such as root or administrator.") :javascript - ManageIQ.angular.app.value('providerForemanFormId', '#{@provider_cfgmgmt.id || "new"}'); + ManageIQ.angular.app.value('providerForemanFormId', '#{@provider_manager.id || "new"}'); miq_bootstrap('#form_div'); diff --git a/config/routes.rb b/config/routes.rb index 8e0c13eb12b..462efc3d157 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -155,6 +155,48 @@ ) + adv_search_post + compare_post + exp_post + save_post }, + :automation_manager => { + :get => %w( + download_data + explorer + automation_manager_form_fields + show + show_list + tagging_edit + ), + :post => %w( + accordion_select + authentication_validate + button + change_tab + delete + edit + explorer + exp_button + exp_changed + exp_token_pressed + form_field_changed + new + provision + quick_search + refresh + reload + show + show_list + tagging + tagging_edit + tag_edit_form_field_changed + tree_autoload + tree_select + configscript_service_dialog_submit + cs_form_field_changed + users + wait_for_task + ) + + adv_search_post + + x_post + }, + :availability_zone => { :get => %w( download_data diff --git a/spec/controllers/automation_manager_controller_spec.rb b/spec/controllers/automation_manager_controller_spec.rb new file mode 100644 index 00000000000..fa011044833 --- /dev/null +++ b/spec/controllers/automation_manager_controller_spec.rb @@ -0,0 +1,594 @@ +describe AutomationManagerController do + render_views + + let(:zone) { EvmSpecHelper.local_miq_server.zone } + let(:tags) { ["/managed/quota_max_memory/2048"] } + let(:automation_provider1) { FactoryGirl.create(:provider_ansible_tower, :name => "ansibletest", :url => "10.8.96.107", :zone => zone) } + let(:automation_provider2) { FactoryGirl.create(:provider_ansible_tower, :name => "ansibletest2", :url => "10.8.96.108", :zone => zone) } + + before(:each) do + Tag.find_or_create_by(:name => tags.first) + @automation_manager1 = ManageIQ::Providers::AnsibleTower::AutomationManager.find_by(:provider_id => automation_provider1.id) + @automation_manager2 = ManageIQ::Providers::AnsibleTower::AutomationManager.find_by(:provider_id => automation_provider2.id) + + @inventory_group = ManageIQ::Providers::AutomationManager::InventoryRootGroup.create(:name => "testinvgroup", :ems_id => @automation_manager1.id) + @inventory_group2 = ManageIQ::Providers::AutomationManager::InventoryRootGroup.create(:name => "testinvgroup2", :ems_id => @automation_manager2.id) + @ans_configured_system = ManageIQ::Providers::AnsibleTower::AutomationManager::ConfiguredSystem.create(:hostname => "ans_test_configured_system", + :inventory_root_group_id => @inventory_group.id, + :manager_id => @automation_manager1.id) + + @ans_configured_system2a = ManageIQ::Providers::AnsibleTower::AutomationManager::ConfiguredSystem.create(:hostname => "test2a_ans_configured_system", + :inventory_root_group_id => @inventory_group.id, + :manager_id => @automation_manager1.id) + @ans_configured_system2b = ManageIQ::Providers::AnsibleTower::AutomationManager::ConfiguredSystem.create(:hostname => "test2b_ans_configured_system", + :inventory_root_group_id => @inventory_group2.id, + :manager_id => @automation_manager2.id) + controller.instance_variable_set(:@sb, :active_tree => :automation_manager_providers_tree) + + [@ans_configured_system, @ans_configured_system2a, @ans_configured_system2b].each do |cs| + cs.tag_with(tags, :namespace => '') + end + + @ans_job_template1 = FactoryGirl.create(:ansible_configuration_script, :name => "ConfigScript1", :manager_id => @automation_manager1.id) + @ans_job_template2 = FactoryGirl.create(:ansible_configuration_script, :name => "ConfigScript2", :manager_id => @automation_manager2.id) + @ans_job_template3 = FactoryGirl.create(:ansible_configuration_script, :name => "ConfigScript3", :manager_id => @automation_manager1.id) + end + + it "renders index" do + stub_user(:features => :all) + get :index + expect(response.status).to eq(302) + expect(response).to redirect_to(:action => 'explorer') + end + + it "renders explorer" do + login_as user_with_feature(%w(automation_manager_providers automation_manager_configured_system automation_manager_configuration_scripts_accord)) + + get :explorer + accords = controller.instance_variable_get(:@accords) + expect(accords.size).to eq(3) + breadcrumbs = controller.instance_variable_get(:@breadcrumbs) + expect(breadcrumbs[0]).to include(:url => '/automation_manager/show_list') + expect(response.status).to eq(200) + expect(response.body).to_not be_empty + end + + context "renders the explorer based on RBAC" do + it "renders explorer based on RBAC access to feature 'automation_manager_configured_system_tag'" do + login_as user_with_feature %w(automation_manager_configured_system_tag) + + get :explorer + accords = controller.instance_variable_get(:@accords) + expect(accords.size).to eq(1) + expect(accords[0][:name]).to eq("automation_manager_cs_filter") + expect(response.status).to eq(200) + expect(response.body).to_not be_empty + end + + it "renders explorer based on RBAC access to feature 'automation_manager_add_provider'" do + login_as user_with_feature %w(automation_manager_add_provider) + + get :explorer + accords = controller.instance_variable_get(:@accords) + expect(accords.size).to eq(1) + expect(accords[0][:name]).to eq("automation_manager_providers") + expect(response.status).to eq(200) + expect(response.body).to_not be_empty + end + end + + context "asserts correct privileges" do + before do + login_as user_with_feature %w(automation_manager_provider_configured_system_tag) + end + + it "should raise an error for feature that user has no access to" do + expect { controller.send(:assert_privileges, "automation_manager_add_provider") } + .to raise_error(MiqException::RbacPrivilegeException) + end + end + + it "renders show_list" do + stub_user(:features => :all) + get :show_list + expect(response.status).to eq(302) + expect(response.body).to_not be_empty + end + + it "renders a new page" do + post :new, :format => :js + expect(response.status).to eq(200) + end + + it "#automation_manager_save_provider save does not accept a duplicate name" do + ManageIQ::Providers::AnsibleTower::Provider.create(:name => "test2Ansible", :url => "server1", :zone => zone) + provider2 = ManageIQ::Providers::AnsibleTower::Provider.new(:name => "test2Ansible", :url => "server2", :zone => zone) + controller.instance_variable_set(:@provider, provider2) + allow(controller).to receive(:render_flash) + controller.save_provider + expect(assigns(:flash_array).first[:message]).to include("has already been taken") + end + + context "#edit" do + before do + stub_user(:features => :all) + end + + it "renders the edit page when the manager id is supplied" do + post :edit, :params => { :id => @automation_manager1.id } + expect(response.status).to eq(200) + right_cell_text = controller.instance_variable_get(:@right_cell_text) + expect(right_cell_text).to eq(_("Edit Provider")) + end + + it "should display the zone field" do + new_zone = FactoryGirl.create(:zone, :name => "TestZone") + controller.instance_variable_set(:@provider, automation_provider1) + post :edit, :params => { :id => @automation_manager1.id } + expect(response.status).to eq(200) + expect(response.body).to include("option value=\\\"#{new_zone.name}\\\"") + end + + it "should save the zone field" do + new_zone = FactoryGirl.create(:zone, :name => "TestZone") + controller.instance_variable_set(:@provider, automation_provider1) + allow(controller).to receive(:leaf_record).and_return(false) + post :edit, :params => { :button => 'save', + :id => @automation_manager1.id, + :zone => new_zone.name, + :url => automation_provider1.url, + :verify_ssl => automation_provider1.verify_ssl } + expect(response.status).to eq(200) + expect(automation_provider1.zone).to eq(new_zone) + end + + it "renders the edit page when the manager id is selected from a list view" do + post :edit, :params => { :miq_grid_checks => @automation_manager1.id } + expect(response.status).to eq(200) + end + + it "renders the edit page when the ansible tower manager id is selected from a grid/tile" do + post :edit, :params => { "check_#{ApplicationRecord.compress_id(@automation_manager1.id)}" => "1" } + expect(response.status).to eq(200) + end + end + + context "#refresh" do + before do + stub_user(:features => :all) + allow(controller).to receive(:x_node).and_return("root") + allow(controller).to receive(:rebuild_toolbars).and_return("true") + end + + it "renders the refresh flash message for Ansible Tower" do + post :refresh, :params => {:miq_grid_checks => @automation_manager1.id} + expect(response.status).to eq(200) + expect(assigns(:flash_array).first[:message]).to include("Refresh Provider initiated for 1 provider") + end + + it "refreshes the provider when the manager id is supplied" do + allow(controller).to receive(:replace_right_cell) + post :refresh, :params => { :id => @automation_manager1.id } + expect(assigns(:flash_array).first[:message]).to include("Refresh Provider initiated for 1 provider") + end + + it "it refreshes a provider when the manager id is selected from a grid/tile" do + allow(controller).to receive(:replace_right_cell) + post :refresh, :params => { "check_#{ApplicationRecord.compress_id(@automation_manager1.id)}" => "1", + "check_#{ApplicationRecord.compress_id(@automation_manager2.id)}" => "1" } + expect(assigns(:flash_array).first[:message]).to include("Refresh Provider initiated for 2 providers") + end + end + + context "#delete" do + before do + stub_user(:features => :all) + end + + it "deletes the provider when the manager id is supplied" do + allow(controller).to receive(:replace_right_cell) + post :delete, :params => { :id => @automation_manager1.id } + expect(assigns(:flash_array).first[:message]).to include("Delete initiated for 1 Provider") + end + + it "it deletes a provider when the manager id is selected from a list view" do + allow(controller).to receive(:replace_right_cell) + post :delete, :params => { :miq_grid_checks => "#{@automation_manager1.id}, #{@automation_manager2.id}"} + expect(assigns(:flash_array).first[:message]).to include("Delete initiated for 2 Providers") + end + + it "it deletes a provider when the manager id is selected from a grid/tile" do + allow(controller).to receive(:replace_right_cell) + post :delete, :params => { "check_#{ApplicationRecord.compress_id(@automation_manager1.id)}" => "1" } + expect(assigns(:flash_array).first[:message]).to include("Delete initiated for 1 Provider") + end + end + + context "renders right cell text" do + before do + right_cell_text = nil + login_as user_with_feature(%w(automation_manager_providers automation_manager_configured_system automation_manager_configuration_scripts_accord)) + controller.instance_variable_set(:@right_cell_text, right_cell_text) + allow(controller).to receive(:get_view_calculate_gtl_type) + allow(controller).to receive(:get_view_pages) + allow(controller).to receive(:build_listnav_search_list) + allow(controller).to receive(:load_or_clear_adv_search) + allow(controller).to receive(:replace_search_box) + allow(controller).to receive(:update_partials) + allow(controller).to receive(:render) + + allow(controller).to receive(:items_per_page).and_return(20) + allow(controller).to receive(:gtl_type).and_return("list") + allow(controller).to receive(:current_page).and_return(1) + controller.send(:build_accordions_and_trees) + end + it "renders right cell text for root node" do + controller.send(:get_node_info, "root") + right_cell_text = controller.instance_variable_get(:@right_cell_text) + expect(right_cell_text).to eq("All Ansible Tower Providers") + end + end + + it "builds ansible tower child tree" do + controller.send(:build_automation_manager_tree, :automation_manager_providers, :automation_manager_providers_tree) + tree_builder = TreeBuilderAutomationManagerProviders.new("root", "", {}) + objects = tree_builder.send(:x_get_tree_roots, false, {}) + expected_objects = [@automation_manager1, @automation_manager2] + expect(objects).to match_array(expected_objects) + end + + it "constructs the ansible tower inventory tree node" do + controller.send(:build_automation_manager_tree, :automation_manager_providers, :automation_manager_providers_tree) + tree_builder = TreeBuilderAutomationManagerProviders.new("root", "", {}) + objects = tree_builder.send(:x_get_tree_objects, @inventory_group, nil, false, nil) + expected_objects = [@ans_configured_system, @ans_configured_system2a] + expect(objects).to match_array(expected_objects) + end + + it "builds ansible tower job templates tree" do + controller.send(:build_automation_manager_tree, :configuration_scripts, :configuration_scripts_tree) + tree_builder = TreeBuilderAutomationManagerConfigurationScripts.new("root", "", {}) + objects = tree_builder.send(:x_get_tree_roots, false, {}) + expected_objects = [@automation_manager1, @automation_manager2] + expect(objects).to match_array(expected_objects) + end + + it "constructs the ansible tower job templates tree node" do + login_as user_with_feature(%w(providers_accord automation_manager_configured_system automation_manager_configuration_scripts_accord)) + controller.send(:build_automation_manager_tree, :configuration_scripts, :configuration_scripts_tree) + tree_builder = TreeBuilderAutomationManagerConfigurationScripts.new("root", "", {}) + objects = tree_builder.send(:x_get_tree_roots, false, {}) + objects = tree_builder.send(:x_get_tree_cmat_kids, objects[0], false) + expected_objects = [@ans_job_template1, @ans_job_template3] + expect(objects).to match_array(expected_objects) + end + + context "renders tree_select" do + before do + get :explorer + right_cell_text = nil + login_as user_with_feature(%w(automation_manager_providers automation_manager_configured_system automation_manager_configuration_scripts_accord)) + controller.instance_variable_set(:@right_cell_text, right_cell_text) + allow(controller).to receive(:get_view_calculate_gtl_type) + allow(controller).to receive(:get_view_pages) + allow(controller).to receive(:build_listnav_search_list) + allow(controller).to receive(:load_or_clear_adv_search) + allow(controller).to receive(:replace_search_box) + allow(controller).to receive(:update_partials) + allow(controller).to receive(:render) + + allow(controller).to receive(:items_per_page).and_return(20) + allow(controller).to receive(:gtl_type).and_return("list") + allow(controller).to receive(:current_page).and_return(1) + controller.send(:build_accordions_and_trees) + end + + it "renders the list view based on the nodetype(root,provider) and the search associated with it" do + controller.instance_variable_set(:@_params, :id => "root") + controller.instance_variable_set(:@search_text, "manager") + controller.send(:tree_select) + view = controller.instance_variable_get(:@view) + expect(view.table.data.size).to eq(2) + + ems_id = ems_key_for_provider(automation_provider1) + controller.instance_variable_set(:@_params, :id => ems_id) + controller.send(:tree_select) + view = controller.instance_variable_get(:@view) + expect(view.table.data[0].name).to eq("testinvgroup") + + controller.instance_variable_set(:@_params, :id => "at") + controller.instance_variable_set(:@search_text, "2") + controller.send(:tree_select) + view = controller.instance_variable_get(:@view) + expect(view.table.data[0].name).to eq("ansibletest2 Automation Manager") + + invgroup_id2 = inventory_group_key(@inventory_group2) + controller.instance_variable_set(:@_params, :id => invgroup_id2) + controller.send(:tree_select) + view = controller.instance_variable_get(:@view) + expect(view.table.data[0].hostname).to eq("test2b_ans_configured_system") + + controller.instance_variable_set(:@search_text, "2b") + controller.send(:tree_select) + view = controller.instance_variable_get(:@view) + expect(view.table.data[0].hostname).to eq("test2b_ans_configured_system") + + allow(controller).to receive(:x_node).and_return("root") + allow(controller).to receive(:x_tree).and_return(:type => :filter) + controller.instance_variable_set(:@_params, :id => "automation_manager_cs_filter") + controller.send(:accordion_select) + controller.instance_variable_set(:@search_text, "brew") + allow(controller).to receive(:x_tree).and_return(:type => :providers) + controller.instance_variable_set(:@_params, :id => "automation_manager_providers") + controller.send(:accordion_select) + + controller.instance_variable_set(:@_params, :id => "root") + controller.send(:tree_select) + search_text = controller.instance_variable_get(:@search_text) + expect(search_text).to eq("manager") + view = controller.instance_variable_get(:@view) + expect(view.table.data.size).to eq(2) + end + + it "renders tree_select for ansible tower job templates tree node" do + allow(controller).to receive(:x_active_tree).and_return(:configuration_scripts_tree) + controller.instance_variable_set(:@_params, :id => "configuration_scripts") + controller.send(:accordion_select) + controller.instance_variable_set(:@_params, :id => "at-" + ApplicationRecord.compress_id(@automation_manager1.id)) + controller.send(:tree_select) + view = controller.instance_variable_get(:@view) + expect(view.table.data[0].name).to eq("ConfigScript1") + expect(view.table.data[1].name).to eq("ConfigScript3") + end + + it "calls get_view with the associated dbname for the Ansible Tower Providers accordion" do + stub_user(:features => :all) + allow(controller).to receive(:x_active_tree).and_return(:automation_manager_providers_tree) + allow(controller).to receive(:x_active_accord).and_return(:automation_manager_providers) + allow(controller).to receive(:build_listnav_search_list) + controller.instance_variable_set(:@_params, :id => "automation_manager_providers") + expect(controller).to receive(:get_view).with("ManageIQ::Providers::AnsibleTower::AutomationManager", :dbname => :automation_manager_providers).and_call_original + controller.send(:accordion_select) + end + + it "calls get_view with the associated dbname for the Configured Systems accordion" do + stub_user(:features => :all) + allow(controller).to receive(:x_node).and_return("root") + allow(controller).to receive(:x_tree).and_return(:type => :filter) + controller.instance_variable_set(:@_params, :id => "automation_manager_cs_filter") + expect(controller).to receive(:get_view).with("ManageIQ::Providers::AnsibleTower::AutomationManager::ConfiguredSystem", :dbname => :automation_manager_configured_systems).and_call_original + allow(controller).to receive(:build_listnav_search_list) + controller.send(:accordion_select) + end + + it "calls get_view with the associated dbname for the Configuration Scripts accordion" do + stub_user(:features => :all) + allow(controller).to receive(:x_active_tree).and_return(:configuration_scripts_tree) + allow(controller).to receive(:x_active_accord).and_return(:configuration_scripts) + controller.instance_variable_set(:@_params, :id => "configuration_scripts") + expect(controller).to receive(:get_view).with("ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript", :dbname => :configuration_scripts).and_call_original + controller.send(:accordion_select) + end + end + + it "singularizes breadcrumb name" do + expect(controller.send(:breadcrumb_name, nil)).to eq("#{ui_lookup(:ui_title => "foreman")} Provider") + end + + it "renders tagging editor for a configured system" do + session[:tag_items] = [@ans_configured_system.id] + session[:assigned_filters] = [] + allow(controller).to receive(:x_active_accord).and_return(:automation_manager_cs_filter) + parent = FactoryGirl.create(:classification, :name => "test_category") + FactoryGirl.create(:classification_tag, :name => "test_entry", :parent => parent) + FactoryGirl.create(:classification_tag, :name => "another_test_entry", :parent => parent) + post :tagging, :params => { :id => @ans_configured_system.id, :format => :js } + expect(response.status).to eq(200) + end + + it "renders tree_select as js" do + controller.send(:build_automation_manager_tree, :automation_manager_providers, :automation_manager_providers_tree) + + allow(controller).to receive(:process_show_list) + allow(controller).to receive(:replace_explorer_trees) + allow(controller).to receive(:build_listnav_search_list) + allow(controller).to receive(:rebuild_toolbars) + allow(controller).to receive(:replace_search_box) + allow(controller).to receive(:update_partials) + + stub_user(:features => :all) + + key = ems_key_for_provider(automation_provider1) + post :tree_select, :params => { :id => key, :format => :js } + expect(response.status).to eq(200) + end + + context "tree_select on ansible tower provider node" do + before do + login_as user_with_feature %w(automation_manager_refresh_provider automation_manager_edit_provider automation_manager_delete_provider) + + allow(controller).to receive(:check_privileges) + allow(controller).to receive(:process_show_list) + allow(controller).to receive(:replace_explorer_trees) + allow(controller).to receive(:build_listnav_search_list) + allow(controller).to receive(:replace_search_box) + allow(controller).to receive(:x_active_tree).and_return(:automation_manager_providers_tree) + end + + it "does not hide Configuration button in the toolbar" do + controller.send(:build_automation_manager_tree, :automation_manager_provider, :automation_manager_providers_tree) + key = ems_key_for_provider(automation_provider1) + post :tree_select, :params => { :id => key, :format => :js } + expect(response.status).to eq(200) + expect(response.body).not_to include('