diff --git a/app/controllers/application_controller/ci_processing.rb b/app/controllers/application_controller/ci_processing.rb index e35a2bf4cdc..3ab3280a67f 100644 --- a/app/controllers/application_controller/ci_processing.rb +++ b/app/controllers/application_controller/ci_processing.rb @@ -852,8 +852,13 @@ def delete_flavors end # Delete all selected or single displayed RP(s) - def deleteresourcepools - assert_privileges("resource_pool_delete") + def deletecloudresourcepools + assert_privileges("resource_pool_cloud_delete") + delete_elements(ResourcePool, :process_resourcepools) + end + + def deleteinfraresourcepools + assert_privileges("resource_pool_infra_delete") delete_elements(ResourcePool, :process_resourcepools) end diff --git a/app/controllers/mixins/ems_common.rb b/app/controllers/mixins/ems_common.rb index 88aca9caab6..59c8daee6bf 100644 --- a/app/controllers/mixins/ems_common.rb +++ b/app/controllers/mixins/ems_common.rb @@ -105,6 +105,7 @@ def display_methods physical_switches physical_storages placement_groups + resource_pools_cloud security_groups security_policies security_policy_rules diff --git a/app/controllers/mixins/generic_show_mixin.rb b/app/controllers/mixins/generic_show_mixin.rb index 0bacb3ff5ef..c997734ed04 100644 --- a/app/controllers/mixins/generic_show_mixin.rb +++ b/app/controllers/mixins/generic_show_mixin.rb @@ -151,8 +151,8 @@ def display_custom_button_events nested_list(CustomButtonEvent, :breadcrumb_title => _('Custom Button Events'), :clickable => false, :parent_method => 'custom_button_events') end - def display_resource_pools - nested_list(ResourcePool) + def display_resource_pools_cloud + nested_list(ManageIQ::Providers::CloudManager::ResourcePool, :breadcrumb_title => _('Resource Pools')) end def display_instances diff --git a/app/controllers/resource_pool_cloud_controller.rb b/app/controllers/resource_pool_cloud_controller.rb new file mode 100644 index 00000000000..44892132def --- /dev/null +++ b/app/controllers/resource_pool_cloud_controller.rb @@ -0,0 +1,102 @@ +class ResourcePoolCloudController < ApplicationController + before_action :check_privileges + before_action :get_session_data + after_action :cleanup_action + after_action :set_session_data + + include Mixins::GenericButtonMixin + include Mixins::GenericListMixin + include Mixins::GenericSessionMixin + include Mixins::GenericShowMixin + include Mixins::BreadcrumbsMixin + + def self.display_methods + %w[vms all_vms resource_pools] + end + + # handle buttons pressed on the button bar + def button + @edit = session[:edit] # Restore @edit for adv search box + params[:display] = @display if %w[all_vms vms resource_pools].include?(@display) # Were we displaying sub-items + + @refresh_div = 'main_div' unless @display # Default div for button.rjs to refresh + case params[:pressed] + when 'resource_pool_cloud_delete' + deletecloudresourcepools + if @refresh_div == 'main_div' && @lastaction == 'show_list' + replace_gtl_main_div + else + render_flash unless performed? + end + when 'resource_pool_cloud_protect' + assign_policies(ResourcePool) + when 'resource_pool_cloud_tag' + tag(self.class.model) + else + super + end + end + + def self.model + ManageIQ::Providers::CloudManager::ResourcePool + end + + def download_data + assert_privileges('resource_pool_cloud_view') + super + end + + def download_summary_pdf + assert_privileges('resource_pool_cloud_view') + super + end + + def breadcrumb_name(_model) + _("Cloud Resource Pools") + end + + def self.table_name + @table_name ||= "resource_pool" + end + + def index + redirect_to(:action => 'show_list') + end + + def show_list + assert_privileges('resource_pool_cloud_show_list') + @center_toolbar = "resource_pool_clouds" + super + end + + def show + assert_privileges('resource_pool_cloud_show') + @center_toolbar = "resource_pool_cloud" + super + end + + private + + def record_class + %w[all_vms vms].include?(params[:display]) ? VmOrTemplate : ResourcePool + end + + def textual_group_list + [%i[properties relationships], %i[configuration smart_management]] + end + + helper_method :textual_group_list + + def breadcrumbs_options + { + :breadcrumbs => [ + {:title => _("Compute")}, + {:title => _("Clouds")}, + {:title => _("Resource Pools"), :url => controller_url}, + ], + } + end + + menu_section :resource_pool_cloud + feature_for_actions "#{controller_name}_show_list", *ADV_SEARCH_ACTIONS +end diff --git a/app/controllers/resource_pool_controller.rb b/app/controllers/resource_pool_infra_controller.rb similarity index 63% rename from app/controllers/resource_pool_controller.rb rename to app/controllers/resource_pool_infra_controller.rb index 49a9d7a86e2..935243f8d2c 100644 --- a/app/controllers/resource_pool_controller.rb +++ b/app/controllers/resource_pool_infra_controller.rb @@ -1,4 +1,4 @@ -class ResourcePoolController < ApplicationController +class ResourcePoolInfraController < ApplicationController before_action :check_privileges before_action :get_session_data after_action :cleanup_action @@ -21,27 +21,57 @@ def button @refresh_div = 'main_div' unless @display # Default div for button.rjs to refresh case params[:pressed] - when 'resource_pool_delete' - deleteresourcepools + when 'resource_pool_infra_delete' + deleteinfraresourcepools if @refresh_div == 'main_div' && @lastaction == 'show_list' replace_gtl_main_div else render_flash unless performed? end - when 'resource_pool_protect' + when 'resource_pool_infra_protect' assign_policies(ResourcePool) + when 'resource_pool_infra_tag' + tag(self.class.model) else super end end + def self.model + ManageIQ::Providers::InfraManager::ResourcePool + end + + def self.table_name + @table_name ||= "resource_pool" + end + + def breadcrumb_name(_model) + _("Infrastructure Resource Pools") + end + def download_data - assert_privileges('resource_pool_show_list') + assert_privileges('resource_pool_infra_view') super end def download_summary_pdf - assert_privileges('resource_pool_show') + assert_privileges('resource_pool_infra_view') + super + end + + def index + redirect_to(:action => 'show_list') + end + + def show_list + assert_privileges('resource_pool_infra_show_list') + @center_toolbar = "resource_pool_infras" + super + end + + def show + assert_privileges('resource_pool_infra_show') + @center_toolbar = "resource_pool_infra" super end @@ -54,6 +84,7 @@ def record_class def textual_group_list [%i[properties relationships], %i[configuration smart_management]] end + helper_method :textual_group_list def breadcrumbs_options @@ -66,6 +97,6 @@ def breadcrumbs_options } end - menu_section :inf + menu_section :resource_pool_infra feature_for_actions "#{controller_name}_show_list", *ADV_SEARCH_ACTIONS end diff --git a/app/controllers/vm_common.rb b/app/controllers/vm_common.rb index 67fc9b1f84b..1f8241b5c1f 100644 --- a/app/controllers/vm_common.rb +++ b/app/controllers/vm_common.rb @@ -362,6 +362,10 @@ def placement_group show_association('placement_groups', _('Placement Groups'), :placement_groups, PlacementGroup) end + def resource_pool + show_association('resource_pools', _('Resource Pools'), :resource_pools, ResourcePool) + end + def cloud_subnets show_association('cloud_subnets', _('Subnets'), :cloud_subnets, CloudSubnet) end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b79781784d3..bc297db6617 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -394,6 +394,10 @@ def db_to_controller(db, action = "show") when "PlacementGroup" controller = "placement_group" action = "show" + when "ManageIQ::Providers::CloudManager::ResourcePool" + controller = "resource_pool_cloud" + when "ManageIQ::Providers::InfraManager::ResourcePool" + controller = "resource_pool_infra" when "SecurityGroup" controller = "security_group" action = "show" @@ -788,7 +792,8 @@ def display_adv_search? physical_server placement_group provider_foreman - resource_pool + resource_pool_cloud + resource_pool_infra retired security_group security_policy diff --git a/app/helpers/application_helper/listnav.rb b/app/helpers/application_helper/listnav.rb index 30ad516da28..fd856001f12 100644 --- a/app/helpers/application_helper/listnav.rb +++ b/app/helpers/application_helper/listnav.rb @@ -61,7 +61,8 @@ def render_listnav_filename physical_server physical_storage physical_switch - resource_pool + resource_pool_cloud + resource_pool_infra security_group security_policy security_policy_rule diff --git a/app/helpers/application_helper/page_layouts.rb b/app/helpers/application_helper/page_layouts.rb index 13cc6e7515f..c94fe06ac45 100644 --- a/app/helpers/application_helper/page_layouts.rb +++ b/app/helpers/application_helper/page_layouts.rb @@ -220,7 +220,8 @@ def show_adv_search? physical_server physical_storage placement_group - resource_pool + resource_pool_cloud + resource_pool_infra retired security_group security_policy diff --git a/app/helpers/application_helper/toolbar/resource_pool_cloud_center.rb b/app/helpers/application_helper/toolbar/resource_pool_cloud_center.rb new file mode 100644 index 00000000000..bfe803ed758 --- /dev/null +++ b/app/helpers/application_helper/toolbar/resource_pool_cloud_center.rb @@ -0,0 +1,39 @@ +class ApplicationHelper::Toolbar::ResourcePoolCloudCenter < ApplicationHelper::Toolbar::Basic + button_group('resource_pool_vmdb', [ + select( + :resource_pool_vmdb_choice, + nil, + t = N_('Configuration'), + t, + :items => [ + button( + :resource_pool_cloud_delete, + 'pficon pficon-delete fa-lg', + N_('Remove this Resource Pool from Inventory'), + N_('Remove Resource Pool from Inventory'), + :url_parms => "&refresh=y", + :confirm => N_("Warning: This Resource Pool and ALL of its components will be permanently removed!")), + ] + ), + ]) + button_group('resource_pool_cloud_policy', [ + select( + :resource_pool_policy_choice, + nil, + t = N_('Policy'), + t, + :items => [ + button( + :resource_pool_cloud_protect, + 'pficon pficon-edit fa-lg', + N_('Manage Policies for this Resource Pool'), + N_('Manage Policies')), + button( + :resource_pool_cloud_tag, + 'pficon pficon-edit fa-lg', + N_('Edit Tags for this Resource Pool'), + N_('Edit Tags')), + ] + ), + ]) +end diff --git a/app/helpers/application_helper/toolbar/resource_pools_center.rb b/app/helpers/application_helper/toolbar/resource_pool_clouds_center.rb similarity index 87% rename from app/helpers/application_helper/toolbar/resource_pools_center.rb rename to app/helpers/application_helper/toolbar/resource_pool_clouds_center.rb index 181f1c0419e..53559a8b067 100644 --- a/app/helpers/application_helper/toolbar/resource_pools_center.rb +++ b/app/helpers/application_helper/toolbar/resource_pool_clouds_center.rb @@ -1,4 +1,4 @@ -class ApplicationHelper::Toolbar::ResourcePoolsCenter < ApplicationHelper::Toolbar::Basic +class ApplicationHelper::Toolbar::ResourcePoolCloudsCenter < ApplicationHelper::Toolbar::Basic button_group('resource_pool_vmdb', [ select( :resource_pool_vmdb_choice, @@ -9,7 +9,7 @@ class ApplicationHelper::Toolbar::ResourcePoolsCenter < ApplicationHelper::Toolb :onwhen => "1+", :items => [ button( - :resource_pool_delete, + :resource_pool_cloud_delete, 'pficon pficon-delete fa-lg', N_('Remove selected Resource Pools from Inventory'), N_('Remove Resource Pools from Inventory'), @@ -31,7 +31,7 @@ class ApplicationHelper::Toolbar::ResourcePoolsCenter < ApplicationHelper::Toolb :onwhen => "1+", :items => [ button( - :resource_pool_protect, + :resource_pool_cloud_protect, 'pficon pficon-edit fa-lg', N_('Manage Policies for the selected Resource Pools'), N_('Manage Policies'), @@ -40,7 +40,7 @@ class ApplicationHelper::Toolbar::ResourcePoolsCenter < ApplicationHelper::Toolb :enabled => false, :onwhen => "1+"), button( - :resource_pool_tag, + :resource_pool_cloud_tag, 'pficon pficon-edit fa-lg', N_('Edit Tags for the selected Resource Pools'), N_('Edit Tags'), diff --git a/app/helpers/application_helper/toolbar/resource_pool_center.rb b/app/helpers/application_helper/toolbar/resource_pool_infra_center.rb similarity index 81% rename from app/helpers/application_helper/toolbar/resource_pool_center.rb rename to app/helpers/application_helper/toolbar/resource_pool_infra_center.rb index 6127c85404f..7777c6b0cf1 100644 --- a/app/helpers/application_helper/toolbar/resource_pool_center.rb +++ b/app/helpers/application_helper/toolbar/resource_pool_infra_center.rb @@ -1,4 +1,4 @@ -class ApplicationHelper::Toolbar::ResourcePoolCenter < ApplicationHelper::Toolbar::Basic +class ApplicationHelper::Toolbar::ResourcePoolInfraCenter < ApplicationHelper::Toolbar::Basic button_group('resource_pool_vmdb', [ select( :resource_pool_vmdb_choice, @@ -7,7 +7,7 @@ class ApplicationHelper::Toolbar::ResourcePoolCenter < ApplicationHelper::Toolba t, :items => [ button( - :resource_pool_delete, + :resource_pool_infra_delete, 'pficon pficon-delete fa-lg', N_('Remove this Resource Pool from Inventory'), N_('Remove Resource Pool from Inventory'), @@ -24,12 +24,12 @@ class ApplicationHelper::Toolbar::ResourcePoolCenter < ApplicationHelper::Toolba t, :items => [ button( - :resource_pool_protect, + :resource_pool_infra_protect, 'pficon pficon-edit fa-lg', N_('Manage Policies for this Resource Pool'), N_('Manage Policies')), button( - :resource_pool_tag, + :resource_pool_infra_tag, 'pficon pficon-edit fa-lg', N_('Edit Tags for this Resource Pool'), N_('Edit Tags')), diff --git a/app/helpers/application_helper/toolbar/resource_pool_infras_center.rb b/app/helpers/application_helper/toolbar/resource_pool_infras_center.rb new file mode 100644 index 00000000000..20d4e1214a4 --- /dev/null +++ b/app/helpers/application_helper/toolbar/resource_pool_infras_center.rb @@ -0,0 +1,54 @@ +class ApplicationHelper::Toolbar::ResourcePoolInfrasCenter < ApplicationHelper::Toolbar::Basic + button_group('resource_pool_vmdb', [ + select( + :resource_pool_vmdb_choice, + nil, + t = N_('Configuration'), + t, + :enabled => false, + :onwhen => "1+", + :items => [ + button( + :resource_pool_infra_delete, + 'pficon pficon-delete fa-lg', + N_('Remove selected Resource Pools from Inventory'), + N_('Remove Resource Pools from Inventory'), + :url_parms => "main_div", + :send_checked => true, + :confirm => N_("Warning: The selected Resource Pools and ALL of their components will be permanently removed!"), + :enabled => false, + :onwhen => "1+"), + ] + ), + ]) + button_group('resource_pool_policy', [ + select( + :resource_pool_policy_choice, + nil, + t = N_('Policy'), + t, + :enabled => false, + :onwhen => "1+", + :items => [ + button( + :resource_pool_infra_protect, + 'pficon pficon-edit fa-lg', + N_('Manage Policies for the selected Resource Pools'), + N_('Manage Policies'), + :url_parms => "main_div", + :send_checked => true, + :enabled => false, + :onwhen => "1+"), + button( + :resource_pool_infra_tag, + 'pficon pficon-edit fa-lg', + N_('Edit Tags for the selected Resource Pools'), + N_('Edit Tags'), + :url_parms => "main_div", + :send_checked => true, + :enabled => false, + :onwhen => "1+"), + ] + ), + ]) +end diff --git a/app/helpers/application_helper/toolbar_chooser.rb b/app/helpers/application_helper/toolbar_chooser.rb index 859a5e60551..73d0ac8eef9 100644 --- a/app/helpers/application_helper/toolbar_chooser.rb +++ b/app/helpers/application_helper/toolbar_chooser.rb @@ -345,7 +345,7 @@ def center_toolbar_filename_classic # toolbar buttons on sub-screens to_display = %w[availability_zones cloud_networks cloud_object_store_containers cloud_subnets configured_systems cloud_tenants cloud_volumes cloud_volume_snapshots ems_clusters flavors floating_ips host_aggregates hosts host_initiators host_initiator_groups - volume_mappings network_ports network_routers network_services orchestration_stacks resource_pools + volume_mappings network_ports network_routers network_services orchestration_stacks resource_pool_clouds resource_pool_infras security_groups security_policies security_policy_rules storages physical_storages storage_services] to_display_center = %w[stack_orchestration_template cloud_object_store_objects generic_objects physical_servers guest_devices] performance_layouts = %w[vm host ems_container] @@ -441,7 +441,8 @@ def center_toolbar_filename_classic placement_group container_template storage_service - resource_pool + resource_pool_cloud + resource_pool_infra timeline usage guest_device diff --git a/app/helpers/ems_cloud_helper/textual_summary.rb b/app/helpers/ems_cloud_helper/textual_summary.rb index b468b72fa0d..f4065f6b0ee 100644 --- a/app/helpers/ems_cloud_helper/textual_summary.rb +++ b/app/helpers/ems_cloud_helper/textual_summary.rb @@ -19,7 +19,7 @@ def textual_group_relationships _("Relationships"), %i[ ems_infra network_manager availability_zones host_aggregates cloud_tenants flavors - security_groups placement_groups instances images cloud_volumes orchestration_stacks storage_managers cloud_databases + security_groups placement_groups resource_pools instances images cloud_volumes orchestration_stacks storage_managers cloud_databases custom_button_events tenant ] ) @@ -131,6 +131,16 @@ def textual_placement_groups h end + def textual_resource_pools + num = @record.try(:resource_pools) ? @record.number_of(:resource_pools) : 0 + h = {:label => _('Resource Pools'), :icon => "pficon pficon-resource-pool", :value => num} + if num.positive? && role_allows?(:feature => "resource_pool_cloud_show_list") + h[:title] = _("Show all Resource Pools") + h[:link] = ems_cloud_path(@record.id, :display => 'resource_pools_cloud') + end + h + end + def textual_cloud_databases num = @record.try(:cloud_databases) ? @record.number_of(:cloud_databases) : 0 h = {:label => _('Cloud Databases'), :icon => "fa fa-database", :value => num} diff --git a/app/helpers/resource_pool_cloud_helper.rb b/app/helpers/resource_pool_cloud_helper.rb new file mode 100644 index 00000000000..c61369e8cca --- /dev/null +++ b/app/helpers/resource_pool_cloud_helper.rb @@ -0,0 +1,4 @@ +module ResourcePoolCloudHelper + include_concern 'TextualSummary' + include ResourcePoolConfigHelper +end diff --git a/app/helpers/resource_pool_cloud_helper/textual_summary.rb b/app/helpers/resource_pool_cloud_helper/textual_summary.rb new file mode 100644 index 00000000000..3ee6c82925c --- /dev/null +++ b/app/helpers/resource_pool_cloud_helper/textual_summary.rb @@ -0,0 +1,220 @@ +module ResourcePoolCloudHelper::TextualSummary + # + # Groups + # + + def textual_ext_management_system + textual_link(@record.ext_management_system) + end + + def textual_group_properties + TextualGroup.new( + _("Properties"), + %i[ + vapp aggregate_cpu_speed aggregate_cpu_memory aggregate_physical_cpus aggregate_cpu_total_cores + aggregate_vm_memory aggregate_vm_cpus + ] + ) + end + + def textual_group_relationships + TextualGroup.new( + _("Relationships"), + %i[ext_management_system parent_datacenter parent_cluster parent_host direct_vms allvms_size resource_pools] + ) + end + + def textual_group_configuration + TextualGroup.new( + _("Configuration"), + %i[ + memory_reserve memory_reserve_expand memory_limit memory_shares memory_shares_level cpu_reserve + cpu_reserve_expand cpu_limit cpu_shares cpu_shares_level cpu_cores_available cpu_cores_reserve cpu_cores_limit + ] + ) + end + + def textual_group_smart_management + TextualTags.new(_("Smart Management"), %i[tags]) + end + + # + # Items + # + + def textual_vapp + {:label => _("vApp"), :value => @record.vapp} + end + + def textual_aggregate_cpu_speed + # TODO: Why aren't we using mhz_to_human_size here? + return nil if @record.aggregate_cpu_speed == 0 + {:label => _("Total Host CPU Resources"), + :value => "#{number_with_delimiter(@record.aggregate_cpu_speed)} MHz"} + end + + def textual_aggregate_cpu_memory + return nil if @record.aggregate_memory == 0 + {:label => _("Total Host Memory"), + :value => number_to_human_size(@record.aggregate_memory.megabytes, :precision => 0)} + end + + def textual_aggregate_physical_cpus + return nil if @record.aggregate_physical_cpus == 0 + {:label => _("Total Host CPUs"), + :value => number_with_delimiter(@record.aggregate_physical_cpus)} + end + + def textual_aggregate_cpu_total_cores + return nil if @record.aggregate_cpu_total_cores == 0 + {:label => _("Total Host CPU Cores"), + :value => number_with_delimiter(@record.aggregate_cpu_total_cores)} + end + + def textual_aggregate_vm_memory + {:label => _("Total Configured VM Memory"), :value => number_to_human_size(@record.aggregate_vm_memory.megabytes)} + end + + def textual_aggregate_vm_cpus + {:label => _("Total Configured VM CPUs"), :value => number_with_delimiter(@record.aggregate_vm_cpus)} + end + + def textual_parent_datacenter + return nil if @record.v_parent_datacenter.nil? + {:label => _("Parent Datacenter"), :icon => "fa fa-building-o", :value => @record.v_parent_datacenter || _("None")} + end + + def textual_parent_cluster + cluster = @record.parent_cluster + return nil if cluster.nil? + h = {:label => _("Parent Cluster"), + :icon => "pficon pficon-cluster", + :value => (cluster.nil? ? _("None") : cluster.name)} + if cluster && role_allows?(:feature => "ems_cluster_show") + h[:title] = _("Show Parent Cluster '%{name}'") % {:name => cluster.name} + h[:link] = url_for_only_path(:controller => 'ems_cluster', :action => 'show', :id => cluster) + end + h + end + + def textual_parent_host + host = @record.parent_host + return nil if host.nil? + h = {:label => _("Parent Host"), + :icon => "pficon pficon-container-node", + :value => (host.nil? ? _("None") : host.name)} + if host && role_allows?(:feature => "host_show") + h[:title] = _("Show Parent Host '%{name}'") % {:name => host.name} + h[:link] = url_for_only_path(:controller => 'host', :action => 'show', :id => host) + end + h + end + + def textual_direct_vms + num = @record.v_direct_vms + h = {:label => _("Direct VMs"), :icon => "pficon pficon-virtual-machine", :value => num} + if num.positive? && role_allows?(:feature => "vm_show_list") + h[:title] = _("Show VMs in this Resource Pool, but not in Resource Pools below") + h[:link] = url_for_only_path(:controller => 'resource_pool_cloud', :action => 'show', :id => @record, :display => 'vms') + end + h + end + + def textual_allvms_size + num = @record.total_vms + h = {:label => _("All VMs"), :icon => "pficon pficon-virtual-machine", :value => num} + if num.positive? && role_allows?(:feature => "vm_show_list") + h[:title] = _("Show all VMs in this Resource Pool") + h[:link] = url_for_only_path(:controller => 'resource_pool_cloud', :action => 'show', :id => @record, :display => 'all_vms') + end + h + end + + def textual_resource_pools + num = @record.number_of(:resource_pools) + h = {:label => _("Resource Pools"), :icon => "pficon pficon-resource-pool", :value => num} + if num.positive? && role_allows?(:feature => "resource_pool_cloud_show_list") + h[:title] = _("Show all Resource Pools in this Cloud") + h[:link] = url_for_only_path(:controller => "resource_pool_cloud", :action => 'show', :id => @record, :display => 'resource_pools') + end + h + end + + def textual_memory_reserve + value = @record.memory_reserve + return nil if value.nil? + {:label => _("Memory Reserve"), :value => value} + end + + def textual_memory_reserve_expand + value = @record.memory_reserve_expand + return nil if value.nil? + {:label => _("Memory Reserve Expand"), :value => value} + end + + def textual_memory_limit + value = @record.memory_limit + return nil if value.nil? + {:label => _("Memory Limit"), :value => (value == -1 ? _("Unlimited") : value)} + end + + def textual_memory_shares + value = @record.memory_shares + return nil if value.nil? + {:label => _("Memory Shares"), :value => value} + end + + def textual_memory_shares_level + value = @record.memory_shares_level + return nil if value.nil? + {:label => _("Memory Shares Level"), :value => value} + end + + def textual_cpu_reserve + value = @record.cpu_reserve + return nil if value.nil? + {:label => _("CPU Reserve"), :value => value} + end + + def textual_cpu_reserve_expand + value = @record.cpu_reserve_expand + return nil if value.nil? + {:label => _("CPU Reserve Expand"), :value => value} + end + + def textual_cpu_limit + value = @record.cpu_limit + return nil if value.nil? + {:label => _("CPU Limit"), :value => (value == -1 ? _("Unlimited") : value)} + end + + def textual_cpu_shares + value = @record.cpu_shares + return nil if value.nil? + {:label => _("CPU Shares"), :value => value} + end + + def textual_cpu_shares_level + value = @record.cpu_shares_level + return nil if value.nil? + {:label => _("CPU Shares Level"), :value => value} + end + + def textual_cpu_cores_available + value = @record.cpu_cores_available + return nil if value.nil? + {:label => _("CPU Cores Available"), :value => value} + end + + def textual_cpu_cores_reserve + value = @record.cpu_cores_reserve + return nil if value.nil? + {:label => _("CPU Cores Reserve"), :value => value} + end + + def textual_cpu_cores_limit + value = @record.cpu_cores_limit + return nil if value.nil? + {:label => _("CPU Cores Limit"), :value => (value == -1 ? _("Unlimited") : value)} + end +end diff --git a/app/helpers/resource_pool_helper.rb b/app/helpers/resource_pool_config_helper.rb similarity index 97% rename from app/helpers/resource_pool_helper.rb rename to app/helpers/resource_pool_config_helper.rb index eaa2cf168d5..6c39885fd66 100644 --- a/app/helpers/resource_pool_helper.rb +++ b/app/helpers/resource_pool_config_helper.rb @@ -1,6 +1,4 @@ -module ResourcePoolHelper - include TextualSummary - +module ResourcePoolConfigHelper def calculate_rp_config(db_record) rp_config = [] unless db_record.memory_reserve.nil? diff --git a/app/helpers/resource_pool_infra_helper.rb b/app/helpers/resource_pool_infra_helper.rb new file mode 100644 index 00000000000..31039ac74aa --- /dev/null +++ b/app/helpers/resource_pool_infra_helper.rb @@ -0,0 +1,4 @@ +module ResourcePoolInfraHelper + include_concern 'TextualSummary' + include ResourcePoolConfigHelper +end diff --git a/app/helpers/resource_pool_helper/textual_summary.rb b/app/helpers/resource_pool_infra_helper/textual_summary.rb similarity index 82% rename from app/helpers/resource_pool_helper/textual_summary.rb rename to app/helpers/resource_pool_infra_helper/textual_summary.rb index 810558f4015..43ad6143856 100644 --- a/app/helpers/resource_pool_helper/textual_summary.rb +++ b/app/helpers/resource_pool_infra_helper/textual_summary.rb @@ -1,4 +1,4 @@ -module ResourcePoolHelper::TextualSummary +module ResourcePoolInfraHelper::TextualSummary # # Groups # @@ -29,7 +29,7 @@ def textual_group_configuration _("Configuration"), %i[ memory_reserve memory_reserve_expand memory_limit memory_shares memory_shares_level cpu_reserve - cpu_reserve_expand cpu_limit cpu_shares cpu_shares_level + cpu_reserve_expand cpu_limit cpu_shares cpu_shares_level cpu_cores_available cpu_cores_reserve cpu_cores_limit ] ) end @@ -48,21 +48,25 @@ def textual_vapp def textual_aggregate_cpu_speed # TODO: Why aren't we using mhz_to_human_size here? + return nil if @record.aggregate_cpu_speed == 0 {:label => _("Total Host CPU Resources"), :value => "#{number_with_delimiter(@record.aggregate_cpu_speed)} MHz"} end def textual_aggregate_cpu_memory + return nil if @record.aggregate_memory == 0 {:label => _("Total Host Memory"), :value => number_to_human_size(@record.aggregate_memory.megabytes, :precision => 0)} end def textual_aggregate_physical_cpus + return nil if @record.aggregate_physical_cpus == 0 {:label => _("Total Host CPUs"), :value => number_with_delimiter(@record.aggregate_physical_cpus)} end def textual_aggregate_cpu_total_cores + return nil if @record.aggregate_cpu_total_cores == 0 {:label => _("Total Host CPU Cores"), :value => number_with_delimiter(@record.aggregate_cpu_total_cores)} end @@ -76,11 +80,13 @@ def textual_aggregate_vm_cpus end def textual_parent_datacenter + return nil if @record.v_parent_datacenter.nil? {:label => _("Parent Datacenter"), :icon => "fa fa-building-o", :value => @record.v_parent_datacenter || _("None")} end def textual_parent_cluster cluster = @record.parent_cluster + return nil if cluster.nil? h = {:label => _("Parent Cluster"), :icon => "pficon pficon-cluster", :value => (cluster.nil? ? _("None") : cluster.name)} @@ -93,6 +99,7 @@ def textual_parent_cluster def textual_parent_host host = @record.parent_host + return nil if host.nil? h = {:label => _("Parent Host"), :icon => "pficon pficon-container-node", :value => (host.nil? ? _("None") : host.name)} @@ -108,7 +115,7 @@ def textual_direct_vms h = {:label => _("Direct VMs"), :icon => "pficon pficon-virtual-machine", :value => num} if num.positive? && role_allows?(:feature => "vm_show_list") h[:title] = _("Show VMs in this Resource Pool, but not in Resource Pools below") - h[:link] = url_for_only_path(:controller => 'resource_pool', :action => 'show', :id => @record, :display => 'vms') + h[:link] = url_for_only_path(:controller => 'resource_pool_infra', :action => 'show', :id => @record, :display => 'vms') end h end @@ -118,7 +125,7 @@ def textual_allvms_size h = {:label => _("All VMs"), :icon => "pficon pficon-virtual-machine", :value => num} if num.positive? && role_allows?(:feature => "vm_show_list") h[:title] = _("Show all VMs in this Resource Pool") - h[:link] = url_for_only_path(:controller => 'resource_pool', :action => 'show', :id => @record, :display => 'all_vms') + h[:link] = url_for_only_path(:controller => 'resource_pool_infra', :action => 'show', :id => @record, :display => 'all_vms') end h end @@ -126,9 +133,9 @@ def textual_allvms_size def textual_resource_pools num = @record.number_of(:resource_pools) h = {:label => _("Resource Pools"), :icon => "pficon pficon-resource-pool", :value => num} - if num.positive? && role_allows?(:feature => "resource_pool_show_list") - h[:title] = _("Show all Resource Pools") - h[:link] = url_for_only_path(:controller => "resource_pool", :action => 'show', :id => @record, :display => 'resource_pools') + if num.positive? && role_allows?(:feature => "resource_pool_infra_show_list") + h[:title] = _("Show all Resource Pools in this Cloud") + h[:link] = url_for_only_path(:controller => "resource_pool_infra", :action => 'show', :id => @record, :display => 'resource_pools') end h end @@ -192,4 +199,22 @@ def textual_cpu_shares_level return nil if value.nil? {:label => _("CPU Shares Level"), :value => value} end + + def textual_cpu_cores_available + value = @record.cpu_cores_available + return nil if value.nil? + {:label => _("CPU Cores Available"), :value => value} + end + + def textual_cpu_cores_reserve + value = @record.cpu_cores_reserve + return nil if value.nil? + {:label => _("CPU Cores Reserve"), :value => value} + end + + def textual_cpu_cores_limit + value = @record.cpu_cores_limit + return nil if value.nil? + {:label => _("CPU Cores Limit"), :value => (value == -1 ? _("Unlimited") : value)} + end end diff --git a/app/helpers/vm_helper/textual_summary.rb b/app/helpers/vm_helper/textual_summary.rb index 136a865754b..c5c35223663 100644 --- a/app/helpers/vm_helper/textual_summary.rb +++ b/app/helpers/vm_helper/textual_summary.rb @@ -59,7 +59,7 @@ def textual_group_relationships TextualGroup.new( _("Relationships"), %i[ - ems cluster host resource_pool storage service parent_vm genealogy drift scan_history + ems cluster host resource_pool_cloud resource_pool_infra storage service parent_vm genealogy drift scan_history cloud_network cloud_subnet custom_button_events ] ) @@ -245,12 +245,22 @@ def textual_host h end - def textual_resource_pool + def textual_resource_pool_cloud rp = @record.parent_resource_pool h = {:label => _("Resource Pool"), :icon => "pficon pficon-resource-pool", :value => (rp.nil? ? _("None") : rp.name)} - if rp && role_allows?(:feature => "resource_pool_show") + if rp && role_allows?(:feature => "resource_pool_cloud_show") h[:title] = _("Show this VM's Resource Pool") - h[:link] = url_for_only_path(:controller => 'resource_pool', :action => 'show', :id => rp) + h[:link] = url_for_only_path(:controller => 'resource_pool_cloud', :action => 'show', :id => rp) + end + h + end + + def textual_resource_pool_infra + rp = @record.parent_resource_pool + h = {:label => _("Resource Pool"), :icon => "pficon pficon-resource-pool", :value => (rp.nil? ? _("None") : rp.name)} + if rp && role_allows?(:feature => "resource_pool_infra_show") + h[:title] = _("Show this VM's Resource Pool") + h[:link] = url_for_only_path(:controller => 'resource_pool_infra', :action => 'show', :id => rp) end h end diff --git a/app/presenters/menu/default_menu.rb b/app/presenters/menu/default_menu.rb index 5a4afb916db..c584800e3e3 100644 --- a/app/presenters/menu/default_menu.rb +++ b/app/presenters/menu/default_menu.rb @@ -84,6 +84,7 @@ def clouds_menu_section Menu::Item.new('orchestration_stack', N_('Stacks'), 'orchestration_stack', {:feature => 'orchestration_stack_show_list'}, '/orchestration_stack/show_list'), Menu::Item.new('auth_key_pair_cloud', N_('Key Pairs'), 'auth_key_pair_cloud', {:feature => 'auth_key_pair_cloud_show_list'}, '/auth_key_pair_cloud/show_list'), Menu::Item.new('placement_group', N_('Placement Groups'), 'placement_group', {:feature => 'placement_group_show_list'}, '/placement_group/show_list'), + Menu::Item.new('resource_pool_cloud', N_('Cloud Resource Pools'), 'resource_pool_cloud', {:feature => 'resource_pool_cloud_show_list'}, '/resource_pool_cloud/show_list'), Menu::Item.new('cloud_databases', N_('Databases'), 'cloud_database', {:feature => 'cloud_database'}, '/cloud_database/show_list'), ]) end @@ -94,7 +95,7 @@ def infrastructure_menu_section Menu::Item.new('ems_cluster', N_("Clusters"), 'ems_cluster', {:feature => 'ems_cluster_show_list'}, '/ems_cluster/show_list'), Menu::Item.new('host', N_("Hosts"), 'host', {:feature => 'host_show_list'}, '/host/show_list'), Menu::Item.new('vm_infra', N_('Virtual Machines'), 'vm_infra_explorer', {:feature => 'vm_infra_explorer', :any => true}, '/vm_infra/explorer'), - Menu::Item.new('resource_pool', N_('Resource Pools'), 'resource_pool', {:feature => 'resource_pool_show_list'}, '/resource_pool/show_list'), + Menu::Item.new('resource_pool_infra', N_('Infrastructure Resource Pools'), 'resource_pool_infra', {:feature => 'resource_pool_infra_show_list'}, '/resource_pool_infra/show_list'), Menu::Item.new('storage', N_('Datastores'), 'storage', {:feature => 'storage_show_list'}, '/storage/explorer'), Menu::Item.new('pxe', N_('PXE'), 'pxe', {:feature => 'pxe', :any => true}, '/pxe/explorer'), Menu::Item.new('switch', N_('Networking'), 'infra_networking', {:feature => 'infra_networking', :any => true}, '/infra_networking/explorer'), diff --git a/app/views/resource_pool/_config.html.haml b/app/views/resource_pool_cloud/_config.html.haml similarity index 87% rename from app/views/resource_pool/_config.html.haml rename to app/views/resource_pool_cloud/_config.html.haml index b84440bb006..e6d057b3a11 100644 --- a/app/views/resource_pool/_config.html.haml +++ b/app/views/resource_pool_cloud/_config.html.haml @@ -8,13 +8,13 @@ %table.table.table-bordered.table-striped - if rp_config.blank? %tr - %td{:width => "495"} + %td{ :width => "495" } %strong= _('Not Available') - else - rp_config.each_slice(2) do |items| %tr - items.each do |item| - %td{:width => "495"} + %td{ :width => "495" } %strong = h(item[:field]) = h(item[:description]) diff --git a/app/views/resource_pool/show.html.haml b/app/views/resource_pool_cloud/show.html.haml similarity index 86% rename from app/views/resource_pool/show.html.haml rename to app/views/resource_pool_cloud/show.html.haml index 60deaee2a60..ad1cefa28ed 100644 --- a/app/views/resource_pool/show.html.haml +++ b/app/views/resource_pool_cloud/show.html.haml @@ -1,5 +1,5 @@ #main_div - - if %w(vms all_vms hosts clusters resource_pools).include?(@display) && @showtype != "compare" + - if %w[vms all_vms hosts clusters resource_pools].include?(@display) && @showtype != "compare" = render :partial => "layouts/gtl", :locals => {:action_url => "show/#{@record.id}"} - else - case @showtype diff --git a/app/views/resource_pool/show_list.html.haml b/app/views/resource_pool_cloud/show_list.html.haml similarity index 100% rename from app/views/resource_pool/show_list.html.haml rename to app/views/resource_pool_cloud/show_list.html.haml diff --git a/app/views/resource_pool_infra/_config.html.haml b/app/views/resource_pool_infra/_config.html.haml new file mode 100644 index 00000000000..e6d057b3a11 --- /dev/null +++ b/app/views/resource_pool_infra/_config.html.haml @@ -0,0 +1,20 @@ +#maincontent + = render :partial => "layouts/flash_msg" + + - if @display == "config_info" + rp_config = calculate_rp_config(@record) + %fieldset + %h3= _('Info') + %table.table.table-bordered.table-striped + - if rp_config.blank? + %tr + %td{ :width => "495" } + %strong= _('Not Available') + - else + - rp_config.each_slice(2) do |items| + %tr + - items.each do |item| + %td{ :width => "495" } + %strong + = h(item[:field]) + = h(item[:description]) diff --git a/app/views/resource_pool_infra/show.html.haml b/app/views/resource_pool_infra/show.html.haml new file mode 100644 index 00000000000..ad1cefa28ed --- /dev/null +++ b/app/views/resource_pool_infra/show.html.haml @@ -0,0 +1,11 @@ +#main_div + - if %w[vms all_vms hosts clusters resource_pools].include?(@display) && @showtype != "compare" + = render :partial => "layouts/gtl", :locals => {:action_url => "show/#{@record.id}"} + - else + - case @showtype + - when "details" + = render :partial => "layouts/gtl", :locals => {:action_url => @lastaction} + - when 'main' + = render :partial => "layouts/textual_groups_generic" + - when 'config' + = render :partial => "config" diff --git a/app/views/resource_pool_infra/show_list.html.haml b/app/views/resource_pool_infra/show_list.html.haml new file mode 100644 index 00000000000..039604839f2 --- /dev/null +++ b/app/views/resource_pool_infra/show_list.html.haml @@ -0,0 +1,2 @@ +#main_div + = render :partial => 'layouts/gtl' diff --git a/config/routes.rb b/config/routes.rb index 7a9b745a340..349f0ca7eaf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2739,7 +2739,35 @@ exp_post }, - :resource_pool => { + :resource_pool_cloud => { + :get => %w[ + download_data + download_summary_pdf + index + protect + show + show_list + tagging_edit + ] + + compare_get, + :post => %w[ + button + listnav_search_selected + protect + sections_field_changed + show + show_list + tagging_edit + tree_autoload + quick_search + ] + + adv_search_post + + compare_post + + exp_post + + save_post + }, + + :resource_pool_infra => { :get => %w[ download_data download_summary_pdf diff --git a/product/views/ManageIQ_Providers_CloudManager_ResourcePool.yaml b/product/views/ManageIQ_Providers_CloudManager_ResourcePool.yaml new file mode 100644 index 00000000000..c292590a021 --- /dev/null +++ b/product/views/ManageIQ_Providers_CloudManager_ResourcePool.yaml @@ -0,0 +1,85 @@ +# +# This is an MIQ Report configuration file +# Single value parameters are specified as: +# single_value_parm: value +# Multiple value parameters are specified as: +# multi_value_parm: +# - value 1 +# - value 2 +# + +# Report title +title: Resource Pools + +# Menu name +name: Resource Pools + +# Main DB table report is based on +db: ManageIQ::Providers::CloudManager::ResourcePool + + +# Columns to fetch from the main table +cols: +- name +- v_direct_vms +- v_total_vms +- v_total_miq_templates +- created_on +- updated_on +- vapp +- region_description + +# Included tables (joined, has_one, has_many) and columns +include: + +# Order of columns (from all tables) +col_order: +- name +- v_direct_vms +- v_total_vms +- v_total_miq_templates +- created_on +- updated_on +- vapp +- region_description + +# Column titles, in order +headers: +- Name +- Direct VMs +- Total VMs +- Total Templates +- Created On +- Updated On +- vApp +- Region + +# Condition(s) string for the SQL query +conditions: + +# Order string for the SQL query +order: Ascending + +# Columns to sort the report on, in order +sortby: +- name + +# Group rows (y=yes,n=no,c=count) +group: n + +# Graph type +# Bar +# Column +# ColumnThreed +# ParallelThreedColumn +# Pie +# PieThreed +# StackedBar +# StackedColumn +# StackedThreedColumn + +graph: + +# Dimensions of graph (1 or 2) +# Note: specifying 2 for a single dimension graph may not return expected results +dims: diff --git a/product/views/ManageIQ_Providers_InfraManager_ResourcePool.yaml b/product/views/ManageIQ_Providers_InfraManager_ResourcePool.yaml new file mode 100644 index 00000000000..b4bf452931c --- /dev/null +++ b/product/views/ManageIQ_Providers_InfraManager_ResourcePool.yaml @@ -0,0 +1,85 @@ +# +# This is an MIQ Report configuration file +# Single value parameters are specified as: +# single_value_parm: value +# Multiple value parameters are specified as: +# multi_value_parm: +# - value 1 +# - value 2 +# + +# Report title +title: Resource Pools + +# Menu name +name: Resource Pools + +# Main DB table report is based on +db: ManageIQ::Providers::InfraManager::ResourcePool + + +# Columns to fetch from the main table +cols: +- name +- v_direct_vms +- v_total_vms +- v_total_miq_templates +- created_on +- updated_on +- vapp +- region_description + +# Included tables (joined, has_one, has_many) and columns +include: + +# Order of columns (from all tables) +col_order: +- name +- v_direct_vms +- v_total_vms +- v_total_miq_templates +- created_on +- updated_on +- vapp +- region_description + +# Column titles, in order +headers: +- Name +- Direct VMs +- Total VMs +- Total Templates +- Created On +- Updated On +- vApp +- Region + +# Condition(s) string for the SQL query +conditions: + +# Order string for the SQL query +order: Ascending + +# Columns to sort the report on, in order +sortby: +- name + +# Group rows (y=yes,n=no,c=count) +group: n + +# Graph type +# Bar +# Column +# ColumnThreed +# ParallelThreedColumn +# Pie +# PieThreed +# StackedBar +# StackedColumn +# StackedThreedColumn + +graph: + +# Dimensions of graph (1 or 2) +# Note: specifying 2 for a single dimension graph may not return expected results +dims: diff --git a/spec/config/routes.pending.yml b/spec/config/routes.pending.yml index 584b037a351..286ac81d2fd 100644 --- a/spec/config/routes.pending.yml +++ b/spec/config/routes.pending.yml @@ -1053,7 +1053,50 @@ ReportController: - wait_for_task - x_history - x_show -ResourcePoolController: +ResourcePoolCloudController: +- adv_search_button +- adv_search_clear +- adv_search_load_choice +- adv_search_name +- adv_search_name_typed +- adv_search_toggle +- compare_cancel +- compare_choose_base +- compare_compress +- compare_miq +- compare_miq_all +- compare_miq_differences +- compare_miq_same +- compare_mode +- compare_remove +- compare_set_state +- compare_to_csv +- compare_to_pdf +- compare_to_txt +- download_data +- download_summary_pdf +- exp_button +- exp_changed +- exp_token_pressed +- index +- listnav_search_selected +- protect +- quick_search +- report_data +- save_default_search +- search_clear +- sections_field_changed +- show +- show_list +- tagging_edit +- tree_autoload +ResourcePoolInfraController: +- adv_search_button +- adv_search_clear +- adv_search_load_choice +- adv_search_name +- adv_search_name_typed +- adv_search_toggle - compare_cancel - compare_choose_base - compare_compress @@ -1067,8 +1110,22 @@ ResourcePoolController: - compare_to_csv - compare_to_pdf - compare_to_txt +- download_data +- download_summary_pdf +- exp_button +- exp_changed +- exp_token_pressed - index +- listnav_search_selected +- protect +- quick_search +- report_data +- save_default_search +- search_clear - sections_field_changed +- show +- show_list +- tagging_edit - tree_autoload RestfulRedirectController: - index diff --git a/spec/controllers/resource_pool_controller_spec.rb b/spec/controllers/resource_pool_cloud_controller_spec.rb similarity index 88% rename from spec/controllers/resource_pool_controller_spec.rb rename to spec/controllers/resource_pool_cloud_controller_spec.rb index 529316323b1..cbb0b2b4c8a 100644 --- a/spec/controllers/resource_pool_controller_spec.rb +++ b/spec/controllers/resource_pool_cloud_controller_spec.rb @@ -1,6 +1,13 @@ -describe ResourcePoolController do +describe ResourcePoolCloudController do + let(:resource_pool) { FactoryBot.create(:resource_pool) } + let(:vm) { FactoryBot.create(:vm_vmware) } + describe "#button" do - before { controller.instance_variable_set(:@display, "vms") } + before do + controller.params = {:id => resource_pool.id} + allow(controller).to receive(:render).and_return(true) + allow(controller).to receive(:performed?) + end it "when VM Right Size Recommendations is pressed" do controller.params = {:pressed => "vm_right_size"} @@ -61,15 +68,13 @@ end context 'Check Compliance action on VMs of a Resource Pool' do - let(:vm) { FactoryBot.create(:vm_vmware) } - let(:resource_pool) { FactoryBot.create(:resource_pool) } before do allow(controller).to receive(:assert_privileges) - allow(controller).to receive(:drop_breadcrumb) - allow(controller).to receive(:performed?) allow(controller).to receive(:render) - controller.params = {:miq_grid_checks => vm.id.to_s, :pressed => 'vm_check_compliance', :id => resource_pool.id.to_s, :controller => 'resource_pool'} + allow(controller).to receive(:show) + controller.instance_variable_set(:@display, 'vms') + controller.params = {:miq_grid_checks => vm.id.to_s, :pressed => 'vm_check_compliance', :id => resource_pool.id.to_s, :controller => 'resource_pool_cloud'} end it 'does not initiate Check Compliance because of missing Compliance policies' do @@ -91,11 +96,6 @@ expect(controller.instance_variable_get(:@flash_array)).to eq([{:message => 'Check Compliance initiated for 1 VM and Instance from the ManageIQ Database', :level => :success}]) end end - - it 'calls check_compliance_vms' do - expect(controller).to receive(:check_compliance_vms) - controller.send(:button) - end end context 'reconfigure VMs' do @@ -108,14 +108,13 @@ end context 'Extract Running Processes for selected VMs' do - let(:vm) { FactoryBot.create(:vm_vmware) } - before do allow(controller).to receive(:assert_privileges) allow(controller).to receive(:show) allow(controller).to receive(:performed?).and_return(true) allow(controller).to receive(:render) controller.params = {:pressed => 'vm_collect_running_processes', :miq_grid_checks => vm.id.to_s} + allow(controller).to receive(:find_records_with_rbac).and_return([vm]) end it 'calls getprocessesvms' do @@ -262,18 +261,18 @@ allow(controller).to receive(:performed?).and_return(true) controller.instance_variable_set(:@lastaction, 'show_list') controller.instance_variable_set(:@display, nil) - controller.params = {:pressed => 'resource_pool_delete'} + controller.params = {:pressed => 'resource_pool_cloud_delete'} end - it 'calls deleteresourcepools and replace_gtl_main_div' do - expect(controller).to receive(:deleteresourcepools) + it 'calls deletecloudresourcepools and replace_gtl_main_div' do + expect(controller).to receive(:deletecloudresourcepools) expect(controller).to receive(:replace_gtl_main_div) controller.send(:button) end context 'default div to refresh' do before do - allow(controller).to receive(:deleteresourcepools) + allow(controller).to receive(:deletecloudresourcepools) allow(controller).to receive(:replace_gtl_main_div) end @@ -289,8 +288,8 @@ controller.instance_variable_set(:@display, 'resource_pools') end - it 'calls deleteresourcepools and render_flash' do - expect(controller).to receive(:deleteresourcepools) + it 'calls deletecloudresourcepools and render_flash' do + expect(controller).to receive(:deletecloudresourcepools) expect(controller).to receive(:render_flash) controller.send(:button) end @@ -300,7 +299,7 @@ context 'managing policies of Resource Pools' do before do controller.instance_variable_set(:@display, nil) - controller.params = {:pressed => 'resource_pool_protect'} + controller.params = {:pressed => 'resource_pool_cloud_protect'} end it 'calls assign_policies' do @@ -321,11 +320,11 @@ context 'tagging Resource Pool' do before do controller.instance_variable_set(:@display, nil) - controller.params = {:pressed => 'resource_pool_tag'} + controller.params = {:pressed => 'resource_pool_cloud_tag'} end it 'calls tag method' do - expect(controller).to receive(:tag).with(ResourcePool) + expect(controller).to receive(:tag).with(ManageIQ::Providers::CloudManager::ResourcePool) controller.send(:button) end end @@ -335,17 +334,17 @@ before do EvmSpecHelper.create_guid_miq_server_zone login_as FactoryBot.create(:user, :features => "none") - @resource_pool = FactoryBot.create(:resource_pool) + allow(controller).to receive(:assert_privileges) + allow(controller).to receive(:response).and_return(ActionDispatch::TestResponse.new(200)) end let(:url_params) { {} } - subject { get :show, :params => { :id => @resource_pool.id }.merge(url_params) } + subject { get :show, :params => {:id => resource_pool.id}.merge(url_params) } context "main" do it "renders" do expect(subject).to have_http_status(200) - expect(subject).to render_template("resource_pool/show") end end diff --git a/spec/controllers/resource_pool_infra_controller_spec.rb b/spec/controllers/resource_pool_infra_controller_spec.rb new file mode 100644 index 00000000000..3418fc82365 --- /dev/null +++ b/spec/controllers/resource_pool_infra_controller_spec.rb @@ -0,0 +1,377 @@ +describe ResourcePoolInfraController do + let(:resource_pool) { FactoryBot.create(:resource_pool) } + let(:vm) { FactoryBot.create(:vm_vmware) } + + describe "#button" do + before do + controller.params = {:id => resource_pool.id} + allow(controller).to receive(:render).and_return(true) + allow(controller).to receive(:performed?) + end + + it "when VM Right Size Recommendations is pressed" do + controller.params = {:pressed => "vm_right_size"} + expect(controller).to receive(:vm_right_size) + controller.button + expect(controller.send(:flash_errors?)).not_to be_truthy + end + + it "when VM Migrate is pressed" do + controller.params = {:pressed => "vm_migrate"} + controller.instance_variable_set(:@refresh_partial, "layouts/gtl") + expect(controller).to receive(:prov_redirect).with("migrate") + expect(controller).to receive(:render) + controller.button + expect(controller.send(:flash_errors?)).not_to be_truthy + end + + it "when VM Manage Policies is pressed" do + controller.params = {:pressed => "vm_protect"} + expect(controller).to receive(:assign_policies).with(VmOrTemplate) + controller.button + expect(controller.send(:flash_errors?)).not_to be_truthy + end + + it "when MiqTemplate Manage Policies is pressed" do + controller.params = {:pressed => "miq_template_protect"} + expect(controller).to receive(:assign_policies).with(VmOrTemplate) + controller.button + expect(controller.send(:flash_errors?)).not_to be_truthy + end + + it "when VM Tag is pressed" do + controller.params = {:pressed => "vm_tag"} + expect(controller).to receive(:tag).with(VmOrTemplate) + controller.button + expect(controller.send(:flash_errors?)).not_to be_truthy + end + + it "when MiqTemplate Tag is pressed" do + controller.params = {:pressed => "miq_template_tag"} + expect(controller).to receive(:tag).with(VmOrTemplate) + controller.button + expect(controller.send(:flash_errors?)).not_to be_truthy + end + + it 'returns proper record class' do + expect(controller.send(:record_class)).to eq(ResourcePool) + end + + context 'VMs displayed through Relationships of a Resource Pool' do + %w[all_vms vms].each do |display| + before { controller.params = {:display => display} } + + it 'returns proper record class' do + expect(controller.send(:record_class)).to eq(VmOrTemplate) + end + end + end + + context 'Check Compliance action on VMs of a Resource Pool' do + before do + allow(controller).to receive(:assert_privileges) + allow(controller).to receive(:render) + allow(controller).to receive(:show) + controller.instance_variable_set(:@display, 'vms') + controller.params = {:miq_grid_checks => vm.id.to_s, :pressed => 'vm_check_compliance', :id => resource_pool.id.to_s, :controller => 'resource_pool_infra'} + end + + it 'does not initiate Check Compliance because of missing Compliance policies' do + controller.send(:button) + expect(controller.instance_variable_get(:@flash_array)).to eq([{:message => 'No Compliance Policies assigned to one or more of the selected items', :level => :error}]) + end + + context 'VM Compliance policy set' do + let(:policy) { FactoryBot.create(:miq_policy, :mode => 'compliance', :towhat => 'Vm', :active => true) } + + before do + EvmSpecHelper.create_guid_miq_server_zone + vm.add_policy(policy) + allow(MiqPolicy).to receive(:policy_for_event?).and_return(true) + end + + it 'initiates Check Compliance action' do + controller.send(:button) + expect(controller.instance_variable_get(:@flash_array)).to eq([{:message => 'Check Compliance initiated for 1 VM and Instance from the ManageIQ Database', :level => :success}]) + end + end + end + + context 'reconfigure VMs' do + before { controller.params = {:pressed => 'vm_reconfigure'} } + + it 'calls vm_reconfigure' do + expect(controller).to receive(:vm_reconfigure) + controller.send(:button) + end + end + + context 'Extract Running Processes for selected VMs' do + before do + allow(controller).to receive(:assert_privileges) + allow(controller).to receive(:show) + allow(controller).to receive(:performed?).and_return(true) + allow(controller).to receive(:render) + controller.params = {:pressed => 'vm_collect_running_processes', :miq_grid_checks => vm.id.to_s} + allow(controller).to receive(:find_records_with_rbac).and_return([vm]) + end + + it 'calls getprocessesvms' do + expect(controller).to receive(:getprocessesvms) + controller.send(:button) + end + + it 'sets error flash message' do + controller.send(:button) + expect(controller.instance_variable_get(:@flash_array)).to eq([{:message => 'Collect Running Processes action does not apply to selected items', :level => :error}]) + end + end + + context 'Compare selected VMs' do + before { controller.params = {:pressed => 'vm_compare'} } + + it 'calls comparemiq' do + expect(controller).to receive(:comparemiq) + controller.send(:button) + end + end + + context 'Edit selected VM' do + before do + allow(controller).to receive(:render_or_redirect_partial) + controller.params = {:pressed => 'vm_edit'} + end + + it 'calls edit_record' do + expect(controller).to receive(:edit_record) + controller.send(:button) + end + end + + context 'Set ownership for selected VMs' do + before { controller.params = {:pressed => 'vm_ownership'} } + + it 'calls set_ownership' do + expect(controller).to receive(:set_ownership) + controller.send(:button) + end + end + + context 'Policy Simulation for selected VMs' do + before { controller.params = {:pressed => 'vm_policy_sim'} } + + it 'calls polsimvms' do + expect(controller).to receive(:polsimvms) + controller.send(:button) + end + end + + context 'Provision VMs' do + before do + allow(controller).to receive(:render_or_redirect_partial) + controller.params = {:pressed => 'vm_miq_request_new'} + end + + it 'calls prov_redirect' do + expect(controller).to receive(:prov_redirect).with(no_args) + controller.send(:button) + end + end + + context 'Clone VMs' do + before do + allow(controller).to receive(:render_or_redirect_partial) + controller.params = {:pressed => 'vm_clone'} + end + + it 'calls prov_redirect with appropriate argument' do + expect(controller).to receive(:prov_redirect).with('clone') + controller.send(:button) + end + end + + context 'Publish VM to a Template' do + before do + allow(controller).to receive(:render_or_redirect_partial) + controller.params = {:pressed => 'vm_publish'} + end + + it 'calls prov_redirect with appropriate argument' do + expect(controller).to receive(:prov_redirect).with('publish') + controller.send(:button) + end + end + + context 'Retire VMs' do + before do + allow(controller).to receive(:performed?).and_return(true) + allow(controller).to receive(:show) + controller.params = {:pressed => 'vm_retire_now'} + end + + it 'calls retirevms_now' do + expect(controller).to receive(:retirevms_now) + controller.send(:button) + end + end + + context 'Shutdown Guest of a VM' do + before do + allow(controller).to receive(:performed?).and_return(true) + allow(controller).to receive(:show) + controller.params = {:pressed => 'vm_guest_shutdown'} + end + + it 'calls guestshutdown' do + expect(controller).to receive(:guestshutdown) + controller.send(:button) + end + end + + context 'Restart Guest of a VM' do + before do + allow(controller).to receive(:performed?).and_return(true) + allow(controller).to receive(:show) + controller.params = {:pressed => 'vm_guest_restart'} + end + + it 'calls guestshutdown' do + expect(controller).to receive(:guestreboot) + controller.send(:button) + end + end + + %w[delete refresh reset retire scan start stop suspend].each do |action| + context "#{action} for selected VMs displayed in a nested list" do + before { controller.params = {:pressed => "vm_#{action}"} } + + it "calls #{"#{action}vms"} method" do + allow(controller).to receive(:show) + allow(controller).to receive(:performed?).and_return(true) + expect(controller).to receive("#{action}vms".to_sym) + controller.send(:button) + expect(controller.send(:flash_errors?)).not_to be_truthy + end + end + end + + context 'deleting Resource Pool' do + before do + allow(controller).to receive(:performed?).and_return(true) + controller.instance_variable_set(:@lastaction, 'show_list') + controller.instance_variable_set(:@display, nil) + controller.params = {:pressed => 'resource_pool_infra_delete'} + end + + it 'calls deleteinfraresourcepools and replace_gtl_main_div' do + expect(controller).to receive(:deleteinfraresourcepools) + expect(controller).to receive(:replace_gtl_main_div) + controller.send(:button) + end + + context 'default div to refresh' do + before do + allow(controller).to receive(:deleteinfraresourcepools) + allow(controller).to receive(:replace_gtl_main_div) + end + + it 'sets @refresh_div to main div' do + controller.send(:button) + expect(controller.instance_variable_get(:@refresh_div)).to eq('main_div') + end + end + + context 'nested list of Resource Pools' do + before do + allow(controller).to receive(:performed?).and_return(false) + controller.instance_variable_set(:@display, 'resource_pools') + end + + it 'calls deleteinfraresourcepools and render_flash' do + expect(controller).to receive(:deleteinfraresourcepools) + expect(controller).to receive(:render_flash) + controller.send(:button) + end + end + end + + context 'managing policies of Resource Pools' do + before do + controller.instance_variable_set(:@display, nil) + controller.params = {:pressed => 'resource_pool_infra_protect'} + end + + it 'calls assign_policies' do + expect(controller).to receive(:assign_policies).with(ResourcePool) + controller.send(:button) + end + + context 'default div to refresh' do + before { allow(controller).to receive(:assign_policies) } + + it 'sets @refresh_div to main div' do + controller.send(:button) + expect(controller.instance_variable_get(:@refresh_div)).to eq('main_div') + end + end + end + + context 'tagging Resource Pool' do + before do + controller.instance_variable_set(:@display, nil) + controller.params = {:pressed => 'resource_pool_infra_tag'} + end + + it 'calls tag method' do + expect(controller).to receive(:tag).with(ManageIQ::Providers::InfraManager::ResourcePool) + controller.send(:button) + end + end + end + + describe "#show" do + before do + EvmSpecHelper.create_guid_miq_server_zone + login_as FactoryBot.create(:user, :features => "none") + allow(controller).to receive(:assert_privileges) + allow(controller).to receive(:response).and_return(ActionDispatch::TestResponse.new(200)) + end + + let(:url_params) { {} } + + subject { get :show, :params => {:id => resource_pool.id}.merge(url_params) } + + context "main" do + it "renders" do + expect(subject).to have_http_status(200) + end + end + + context "Direct VMs" do + let(:url_params) { {:display => "vms"} } + + it "renders" do + bypass_rescue + expect(subject).to have_http_status(200) + end + end + + context "All VMs" do + let(:url_params) { {:display => "all_vms"} } + + it "renders" do + bypass_rescue + expect(subject).to have_http_status(200) + end + end + + context "Nested Resource Pools" do + let(:url_params) { {:display => "resource_pools"} } + + it "renders" do + bypass_rescue + expect(subject).to have_http_status(200) + end + end + end +end diff --git a/spec/helpers/ems_cloud_helper/textual_summary_spec.rb b/spec/helpers/ems_cloud_helper/textual_summary_spec.rb index 7ba31f7f899..bf962bd484f 100644 --- a/spec/helpers/ems_cloud_helper/textual_summary_spec.rb +++ b/spec/helpers/ems_cloud_helper/textual_summary_spec.rb @@ -42,6 +42,7 @@ flavors security_groups placement_groups + resource_pools instances images cloud_volumes diff --git a/spec/helpers/resource_pool_helper/textual_summary_spec.rb b/spec/helpers/resource_pool_cloud_helper/textual_summary_spec.rb similarity index 86% rename from spec/helpers/resource_pool_helper/textual_summary_spec.rb rename to spec/helpers/resource_pool_cloud_helper/textual_summary_spec.rb index d3ddf99df95..022fbb2eec7 100644 --- a/spec/helpers/resource_pool_helper/textual_summary_spec.rb +++ b/spec/helpers/resource_pool_cloud_helper/textual_summary_spec.rb @@ -1,4 +1,4 @@ -describe ResourcePoolHelper::TextualSummary do +describe ResourcePoolCloudHelper::TextualSummary do include_examples "textual_group", "Properties", %i( vapp aggregate_cpu_speed @@ -30,6 +30,9 @@ cpu_limit cpu_shares cpu_shares_level + cpu_cores_available + cpu_cores_reserve + cpu_cores_limit ) include_examples "textual_group_smart_management" diff --git a/spec/helpers/resource_pool_infra_helper/textual_summary_spec.rb b/spec/helpers/resource_pool_infra_helper/textual_summary_spec.rb new file mode 100644 index 00000000000..98b4da949d5 --- /dev/null +++ b/spec/helpers/resource_pool_infra_helper/textual_summary_spec.rb @@ -0,0 +1,39 @@ +describe ResourcePoolInfraHelper::TextualSummary do + include_examples "textual_group", "Properties", %i[ + vapp + aggregate_cpu_speed + aggregate_cpu_memory + aggregate_physical_cpus + aggregate_cpu_total_cores + aggregate_vm_memory + aggregate_vm_cpus + ] + + include_examples "textual_group", "Relationships", %i[ + ext_management_system + parent_datacenter + parent_cluster + parent_host + direct_vms + allvms_size + resource_pools + ] + + include_examples "textual_group", "Configuration", %i[ + memory_reserve + memory_reserve_expand + memory_limit + memory_shares + memory_shares_level + cpu_reserve + cpu_reserve_expand + cpu_limit + cpu_shares + cpu_shares_level + cpu_cores_available + cpu_cores_reserve + cpu_cores_limit + ] + + include_examples "textual_group_smart_management" +end diff --git a/spec/helpers/vm_helper/textual_summary_spec.rb b/spec/helpers/vm_helper/textual_summary_spec.rb index 5d911b8e639..3ede309974e 100644 --- a/spec/helpers/vm_helper/textual_summary_spec.rb +++ b/spec/helpers/vm_helper/textual_summary_spec.rb @@ -51,7 +51,8 @@ ems cluster host - resource_pool + resource_pool_cloud + resource_pool_infra storage service parent_vm diff --git a/spec/presenters/menu/default_menu_spec.rb b/spec/presenters/menu/default_menu_spec.rb index dd718bf4c0d..bef05bf9780 100644 --- a/spec/presenters/menu/default_menu_spec.rb +++ b/spec/presenters/menu/default_menu_spec.rb @@ -23,7 +23,7 @@ it "shows correct titles for Hosts & Clusters" do menu = Menu::DefaultMenu.infrastructure_menu_section.items.map(&:name) - result = ["Providers", "Clusters", "Hosts", "Virtual Machines", "Resource Pools", + result = ["Providers", "Clusters", "Hosts", "Virtual Machines", "Infrastructure Resource Pools", "Datastores", "PXE", "Networking"] expect(menu).to eq(result) end diff --git a/spec/routing/resource_pool_routing_spec.rb b/spec/routing/resource_pool_cloud_routing_spec.rb similarity index 89% rename from spec/routing/resource_pool_routing_spec.rb rename to spec/routing/resource_pool_cloud_routing_spec.rb index f951120ae64..5b2cb0d7718 100644 --- a/spec/routing/resource_pool_routing_spec.rb +++ b/spec/routing/resource_pool_cloud_routing_spec.rb @@ -1,7 +1,7 @@ require "routing/shared_examples" -describe "routes for AvailabilityZoneController" do - let(:controller_name) { "resource_pool" } +describe "routes for ResourcePoolCloudController" do + let(:controller_name) { "resource_pool_cloud" } it_behaves_like "A controller that has advanced search routes" it_behaves_like "A controller that has download_data routes" diff --git a/spec/routing/resource_pool_infra_routing_spec.rb b/spec/routing/resource_pool_infra_routing_spec.rb new file mode 100644 index 00000000000..8109f2affce --- /dev/null +++ b/spec/routing/resource_pool_infra_routing_spec.rb @@ -0,0 +1,35 @@ +require "routing/shared_examples" + +describe "routes for ResourcePoolInfraController" do + let(:controller_name) { "resource_pool_infra" } + + it_behaves_like "A controller that has advanced search routes" + it_behaves_like "A controller that has download_data routes" + it_behaves_like "A controller that has show list routes" + it_behaves_like "A controller that has tagging routes" + it_behaves_like "A controller that has policy protect routes" + + %w[ + index + show + ].each do |task| + describe "##{task}" do + it 'routes with GET' do + expect(get("/#{controller_name}/#{task}")).to route_to("#{controller_name}##{task}") + end + end + end + + %w[ + button + listnav_search_selected + save_default_search + show + ].each do |task| + describe "##{task}" do + it 'routes with POST' do + expect(post("/#{controller_name}/#{task}")).to route_to("#{controller_name}##{task}") + end + end + end +end