diff --git a/app/models/transformation_mapping_item.rb b/app/models/transformation_mapping_item.rb index 8e57c5e7e98..de97223fe06 100644 --- a/app/models/transformation_mapping_item.rb +++ b/app/models/transformation_mapping_item.rb @@ -11,6 +11,9 @@ class TransformationMappingItem < ApplicationRecord validate :validate_source_datastore, :if => -> { source.kind_of?(Storage) } validate :validate_destination_datastore, :if => -> { destination.kind_of?(Storage) || destination.kind_of?(CloudVolume) } + validate :validate_source_network, :if => -> { source.kind_of?(Lan) } + validate :validate_destination_network, :if => -> { destination.kind_of?(Lan) || destination.kind_of?(CloudNetwork) } + VALID_SOURCE_CLUSTER_PROVIDERS = %w[vmwarews].freeze VALID_DESTINATION_CLUSTER_PROVIDERS = %w[rhevm openstack].freeze @@ -55,4 +58,32 @@ def validate_destination_datastore errors.add(:destination, "Destination cluster storages must include destination storage: #{destination_storage}") end end + + def validate_source_network + tm = transformation_mapping + tmin = tm.transformation_mapping_items.where(:source_type => "EmsCluster") + src_cluster_lans = tmin.collect(&:source).flat_map(&:lans) + source_lan = source + + unless src_cluster_lans.include?(source_lan) + errors.add(:source, "Source cluster lans must include source lan: #{source_lan}") + end + end + + def validate_destination_network + tm = transformation_mapping + destination_lan = destination + + if destination.kind_of?(Lan) # red hat + tmin = tm.transformation_mapping_items.where(:destination_type=> "EmsCluster") + dst_cluster_lans = tmin.collect(&:destination).flat_map(&:lans) + elsif destination.kind_of?(CloudNetwork) # Openstack, lans are of 'CloudNetwork' type + tmin = tm.transformation_mapping_items.where(:destination_type => "CloudTenant") + dst_cluster_lans = tmin.collect(&:destination).flat_map(&:cloud_networks) + end + + unless dst_cluster_lans.include?(destination_lan) + errors.add(:destination, "Destination cluster lans must include destination lan: #{destination_lan}") + end + end end diff --git a/spec/models/transformation_mapping_item_spec.rb b/spec/models/transformation_mapping_item_spec.rb index a2df80dcac9..f4b529e2cf4 100644 --- a/spec/models/transformation_mapping_item_spec.rb +++ b/spec/models/transformation_mapping_item_spec.rb @@ -8,6 +8,9 @@ let(:ems_openstack) { FactoryBot.create(:ems_openstack) } let(:openstack_cluster) { FactoryBot.create(:ems_cluster_openstack, :ext_management_system => ems_openstack) } + # --------------------------------------------------------------------------- + # Cluster Validation + # --------------------------------------------------------------------------- context "source cluster validation" do let(:valid_mapping_item) do FactoryBot.build(:transformation_mapping_item, :source => vmware_cluster, :destination => openstack_cluster) @@ -46,13 +49,10 @@ end end + # --------------------------------------------------------------------------- + # Datastore Validation + # --------------------------------------------------------------------------- context "datastore validation" do - let(:ems_vmware) { FactoryBot.create(:ems_vmware) } - let(:vmware_cluster) { FactoryBot.create(:ems_cluster, :ext_management_system => ems_vmware) } - - let(:ems_redhat) { FactoryBot.create(:ems_redhat) } - let(:redhat_cluster) { FactoryBot.create(:ems_cluster, :ext_management_system => ems_redhat) } - let(:ems_ops) { FactoryBot.create(:ems_openstack) } let(:cloud_tenant) { FactoryBot.create(:cloud_tenant_openstack, :ext_management_system => ems_ops) } @@ -100,4 +100,58 @@ end end end + + # --------------------------------------------------------------------------- + # Network Validation + # --------------------------------------------------------------------------- + context "Network validation" do + let(:ems_ops) { FactoryBot.create(:ems_openstack) } + let(:cloud_tenant) { FactoryBot.create(:cloud_tenant_openstack, :ext_management_system => ems_ops) } + + # source network + context "source vmware network" do + let(:src_vmware_host) { FactoryBot.create(:host_vmware, :ems_cluster => vmware_cluster) } + let(:src_switch) { FactoryBot.create(:switch, :hosts => [src_vmware_host]) } + let(:src_lan) { FactoryBot.create(:lan, :switch => src_switch) } + + context "destination openstack" do + let(:dst_cloud_network) { FactoryBot.create(:cloud_network, :cloud_tenant => cloud_tenant) } + + let(:tmi_ops_cluster) { FactoryBot.create(:transformation_mapping_item, :source => vmware_cluster, :destination => cloud_tenant) } + let(:ops_mapping) { FactoryBot.create(:transformation_mapping, :transformation_mapping_items => [tmi_ops_cluster]) } + + let(:valid_source) { FactoryBot.create(:transformation_mapping_item, :source => src_lan, :destination => dst_cloud_network, :transformation_mapping_id => ops_mapping.id) } + let(:invalid_source) { FactoryBot.build(:transformation_mapping_item, :source => dst_cloud_network, :destination => src_lan, :transformation_mapping_id => ops_mapping.id) } + + it "valid source" do + expect(valid_source.valid?).to be(true) + end + it "invalid source" do + expect(invalid_source.valid?).to be(false) + end + end + + context "destination red hat" do + let(:dst_rh_host) { FactoryBot.create(:host_redhat, :ems_cluster => redhat_cluster) } + let(:dst_rh_switch) { FactoryBot.create(:switch, :hosts => [dst_rh_host]) } + let(:dst_rh_lan) { FactoryBot.create(:lan, :switch=> dst_rh_switch) } + + let(:tmi_cluster) { FactoryBot.create(:transformation_mapping_item, :source => vmware_cluster, :destination => redhat_cluster) } + + let(:rh_mapping) { FactoryBot.create(:transformation_mapping, :transformation_mapping_items => [tmi_cluster]) } + + context "source validation" do + let(:valid_lan) { FactoryBot.create(:transformation_mapping_item, :source => src_lan, :destination => dst_rh_lan, :transformation_mapping_id => rh_mapping.id) } + let(:invalid_lan) { FactoryBot.build(:transformation_mapping_item, :source => dst_rh_lan, :destination => src_lan, :transformation_mapping_id => rh_mapping.id) } + + it "valid rhev lan" do + expect(valid_lan.valid?).to be(true) + end + it "invalid rhev lan" do + expect(invalid_lan.valid?).to be(false) + end + end + end + end + end end diff --git a/spec/models/transformation_mapping_spec.rb b/spec/models/transformation_mapping_spec.rb index c74e61e9fe8..7b5f299d15b 100644 --- a/spec/models/transformation_mapping_spec.rb +++ b/spec/models/transformation_mapping_spec.rb @@ -12,8 +12,11 @@ let(:src_storages_vmware) { FactoryBot.create_list(:storage, 1, :hosts => src_hosts_vmware) } let(:dst_storages_redhat) { FactoryBot.create_list(:storage, 1, :hosts => dst_hosts_redhat) } - let(:src_lan_vmware) { FactoryBot.create(:lan) } - let(:dst_lan_redhat) { FactoryBot.create(:lan) } + let(:src_switches_vmware) { FactoryBot.create_list(:switch, 1, :hosts => src_hosts_vmware) } + let(:dst_switches_redhat) { FactoryBot.create_list(:switch, 1, :hosts => dst_hosts_redhat) } + + let(:src_lans_vmware) { FactoryBot.create_list(:lan, 1, :switch => src_switches_vmware.first) } + let(:dst_lans_redhat) { FactoryBot.create_list(:lan, 1, :switch => dst_switches_redhat.first) } let(:dst_cloud_tenant_openstack) { FactoryBot.create(:cloud_tenant, :ext_management_system => dst_ems_openstack) } @@ -30,8 +33,8 @@ :transformation_mapping => tm ) FactoryBot.create(:transformation_mapping_item, - :source => src_lan_vmware, - :destination => dst_lan_redhat, + :source => src_lans_vmware.first, + :destination => dst_lans_redhat.first, :transformation_mapping => tm ) end @@ -69,7 +72,7 @@ end context '#search_vms_and_validate' do - let(:nics) { FactoryBot.create_list(:guest_device_nic, 1, :lan => src_lan_vmware) } + let(:nics) { FactoryBot.create_list(:guest_device_nic, 1, :lan => src_lans_vmware.first) } let(:hardware) { FactoryBot.create(:hardware, :guest_devices => nics) } let!(:vm) do