diff --git a/app/models/manageiq/providers/network_manager.rb b/app/models/manageiq/providers/network_manager.rb index 4775271cabc..bfa9a5f1de2 100644 --- a/app/models/manageiq/providers/network_manager.rb +++ b/app/models/manageiq/providers/network_manager.rb @@ -28,28 +28,6 @@ class << model_name has_many :load_balancer_health_checks, :foreign_key => :ems_id, :dependent => :destroy has_many :load_balancer_health_check_members, :through => :load_balancer_health_checks - # Uses "ext_management_systems"."parent_ems_id" instead of "ext_management_systems"."id" - # - # ORDER BY (( - # SELECT COUNT(*) - # FROM "vms" - # WHERE "ext_management_systems"."parent_ems_id" = "vms"."ems_id" - # )) - # - # So unlike the parent class definition, this looks at "ext_management_systems"."parent_ems_id" instead of - # "ext_management_systems"."id" - # If we are able to define a has_many :vms, :through => :parent_manager, that does actual join, this code should - # not be needed. - virtual_total :total_vms, :vms, { - :arel => lambda do |t| - foreign_table = Vm.arel_table - local_key = :parent_ems_id - foreign_key = :ems_id - arel_column = Arel.star.count - t.grouping(foreign_table.project(arel_column).where(t[local_key].eq(foreign_table[foreign_key]))) - end - } - alias all_cloud_networks cloud_networks belongs_to :parent_manager, @@ -57,30 +35,38 @@ class << model_name :class_name => "ManageIQ::Providers::BaseManager", :autosave => true - has_many :availability_zones, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :availability_zones, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :flavors, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :cloud_tenants, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :cloud_database_flavors, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :cloud_tenants, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :cloud_resource_quotas, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :cloud_volumes, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :cloud_volume_types, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :cloud_volume_backups, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :cloud_volume_snapshots, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :cloud_object_store_containers, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :cloud_object_store_objects, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :cloud_services, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :cloud_databases, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :key_pairs, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id, :class_name => "AuthKeyPair", :as => :resource + has_many :hosts, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :vms, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :miq_templates, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + has_many :vms_and_templates, -> { where.not(:ems_id => nil) }, :primary_key => :parent_ems_id, :foreign_key => :ems_id + + virtual_total :total_vms, :vms + virtual_total :total_miq_templates, :miq_templates + virtual_total :total_vms_and_templates, :vms_and_templates # Relationships delegated to parent manager - delegate :cloud_tenants, - :flavors, - :cloud_resource_quotas, - :cloud_volumes, - :cloud_volume_snapshots, - :cloud_object_store_containers, - :cloud_object_store_objects, - :key_pairs, - :orchestration_stacks, - :orchestration_stacks_resources, - :direct_orchestration_stacks, - :resource_groups, - :vms, - :total_vms, - :vms_and_templates, - :total_vms_and_templates, - :miq_templates, - :total_miq_templates, - :hosts, - :to => :parent_manager, - :allow_nil => true + virtual_delegate :orchestration_stacks, + :orchestration_stacks_resources, + :direct_orchestration_stacks, + :resource_groups, + :to => :parent_manager, + :allow_nil => true, + :default => [] def self.supported_types_and_descriptions_hash supported_subclasses.select(&:supports_ems_network_new?).each_with_object({}) do |klass, hash| diff --git a/spec/models/manageiq/providers/network_manager_spec.rb b/spec/models/manageiq/providers/network_manager_spec.rb index ecabbbb771c..752ebeaf9fe 100644 --- a/spec/models/manageiq/providers/network_manager_spec.rb +++ b/spec/models/manageiq/providers/network_manager_spec.rb @@ -2,15 +2,36 @@ let(:vms) { FactoryBot.create(:vm) } let(:template) { FactoryBot.create(:miq_template) } - let(:ems) { FactoryBot.create(:ems_openstack, :vms => [vms], :miq_templates => [template]) } + let(:parent) { FactoryBot.create(:ems_openstack, :vms => [vms], :miq_templates => [template]) } + let(:child) { parent.network_manager } it "delegates vms and templates to parent manager (ExtManagementSystem)" do - expect(ems.id).not_to eq(ems.network_manager.id) - expect(ems.vms).to match_array([vms]) - expect(ems.network_manager.vms).to match_array([vms]) - expect(ems.miq_templates).to match_array([template]) - expect(ems.network_manager.miq_templates).to match_array([template]) - expect(ems.vms_and_templates).to match_array([vms, template]) - expect(ems.network_manager.vms_and_templates).to match_array([vms, template]) + expect(parent.id).not_to eq(child.id) + + [parent, child].each do |ems| + expect(ems.vms).to match_array([vms]) + expect(ems.total_vms).to eq(1) + expect(ems.miq_templates).to match_array([template]) + expect(ems.total_miq_templates).to eq(1) + expect(ems.vms_and_templates).to match_array([vms, template]) + expect(ems.total_vms_and_templates).to eq(2) + end + end + + it "delegates orchestration stacks to parent manager" do + os = parent.orchestration_stacks.create(:ems_ref => "1") + + expect(child.orchestration_stacks).to eq([os]) + end + + it "delegates vms and templates to parent manager (when no manager)" do + ems = FactoryBot.create(:ems_openstack_network, :parent => nil) + + expect(ems.vms).to eq([]) + expect(ems.total_vms).to eq(0) + expect(ems.miq_templates).to eq([]) + expect(ems.total_miq_templates).to eq(0) + expect(ems.vms_and_templates).to eq([]) + expect(ems.total_vms_and_templates).to eq(0) end end