From 5924e116442d7048b2996805e9604afc3b5e81d5 Mon Sep 17 00:00:00 2001 From: Adam Grare Date: Wed, 2 Dec 2020 12:35:03 -0500 Subject: [PATCH] Fix CloudVolume* STI types on older CinderManagers Older Openstack CinderManagers didn't use the subclassed Openstack::StorageManager::CinderManager but rather the base CinderManager. This caused the previous data migration to miss these records because it was querying on active Openstack CinderManagers. --- ...172818_fix_cinder_manager_cloud_volumes.rb | 57 +++++++++++++++++++ ...8_fix_cinder_manager_cloud_volumes_spec.rb | 56 ++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 db/migrate/20201202172818_fix_cinder_manager_cloud_volumes.rb create mode 100644 spec/migrations/20201202172818_fix_cinder_manager_cloud_volumes_spec.rb diff --git a/db/migrate/20201202172818_fix_cinder_manager_cloud_volumes.rb b/db/migrate/20201202172818_fix_cinder_manager_cloud_volumes.rb new file mode 100644 index 000000000..2fb348c1c --- /dev/null +++ b/db/migrate/20201202172818_fix_cinder_manager_cloud_volumes.rb @@ -0,0 +1,57 @@ +class FixCinderManagerCloudVolumes < ActiveRecord::Migration[5.2] + class CloudVolume < ActiveRecord::Base + include ActiveRecord::IdRegions + self.inheritance_column = :_type_disabled + end + + class CloudVolumeBackup < ActiveRecord::Base + include ActiveRecord::IdRegions + self.inheritance_column = :_type_disabled + end + + class CloudVolumeSnapshot < ActiveRecord::Base + include ActiveRecord::IdRegions + self.inheritance_column = :_type_disabled + end + + class CloudVolumeType < ActiveRecord::Base + include ActiveRecord::IdRegions + self.inheritance_column = :_type_disabled + end + + def up + [CloudVolume, CloudVolumeBackup, CloudVolumeSnapshot, CloudVolumeType].each do |klass| + klass_name = klass.name.sub("FixCinderManagerCloudVolumes::", "") + + old_type = "#{openstack_klass}::#{klass_name}" + new_type = "#{cinder_klass}::#{klass_name}" + + say_with_time("Fixing OpenStack #{klass_name} STI class") do + klass.in_my_region.where(:type => old_type).update_all(:type => new_type) + end + end + end + + def down + [CloudVolume, CloudVolumeBackup, CloudVolumeSnapshot, CloudVolumeType].each do |klass| + klass_name = klass.name.sub("FixCinderManagerCloudVolumes::", "") + + old_type = "#{cinder_klass}::#{klass_name}" + new_type = "#{openstack_klass}::#{klass_name}" + + say_with_time("Resetting OpenStack #{klass_name} STI class") do + klass.in_my_region.where(:type => old_type).update_all(:type => new_type) + end + end + end + + private + + def cinder_klass + "ManageIQ::Providers::Openstack::StorageManager::CinderManager".freeze + end + + def openstack_klass + "ManageIQ::Providers::Openstack::CloudManager".freeze + end +end diff --git a/spec/migrations/20201202172818_fix_cinder_manager_cloud_volumes_spec.rb b/spec/migrations/20201202172818_fix_cinder_manager_cloud_volumes_spec.rb new file mode 100644 index 000000000..4a8fb66be --- /dev/null +++ b/spec/migrations/20201202172818_fix_cinder_manager_cloud_volumes_spec.rb @@ -0,0 +1,56 @@ +require_migration + +RSpec.describe FixCinderManagerCloudVolumes do + let(:cloud_volume_stub) { migration_stub(:CloudVolume) } + let(:cloud_volume_snapshot_stub) { migration_stub(:CloudVolumeSnapshot) } + let(:cloud_volume_backup_stub) { migration_stub(:CloudVolumeBackup) } + let(:cloud_volume_type_stub) { migration_stub(:CloudVolumeType) } + + migration_context :up do + it "Fixes the STI class of OpenStack Cloud Volumes, Backups, Snapshots, and Types" do + cloud_volume = cloud_volume_stub.create!( + :type => "ManageIQ::Providers::Openstack::CloudManager::CloudVolume" + ) + cloud_volume_snapshot = cloud_volume_snapshot_stub.create!( + :type => "ManageIQ::Providers::Openstack::CloudManager::CloudVolumeSnapshot" + ) + cloud_volume_backup = cloud_volume_backup_stub.create!( + :type => "ManageIQ::Providers::Openstack::CloudManager::CloudVolumeBackup" + ) + cloud_volume_type = cloud_volume_type_stub.create!( + :type => "ManageIQ::Providers::Openstack::CloudManager::CloudVolumeType" + ) + + migrate + + expect(cloud_volume.reload.type).to eq("ManageIQ::Providers::Openstack::StorageManager::CinderManager::CloudVolume") + expect(cloud_volume_snapshot.reload.type).to eq("ManageIQ::Providers::Openstack::StorageManager::CinderManager::CloudVolumeSnapshot") + expect(cloud_volume_backup.reload.type).to eq("ManageIQ::Providers::Openstack::StorageManager::CinderManager::CloudVolumeBackup") + expect(cloud_volume_type.reload.type).to eq("ManageIQ::Providers::Openstack::StorageManager::CinderManager::CloudVolumeType") + end + end + + migration_context :down do + it "Resets the STI class of OpenStack Cloud Volumes, Backups, Snapshots, and Types" do + cloud_volume = cloud_volume_stub.create!( + :type => "ManageIQ::Providers::Openstack::StorageManager::CinderManager::CloudVolume" + ) + cloud_volume_snapshot = cloud_volume_snapshot_stub.create!( + :type => "ManageIQ::Providers::Openstack::StorageManager::CinderManager::CloudVolumeSnapshot" + ) + cloud_volume_backup = cloud_volume_backup_stub.create!( + :type => "ManageIQ::Providers::Openstack::StorageManager::CinderManager::CloudVolumeBackup" + ) + cloud_volume_type = cloud_volume_type_stub.create!( + :type => "ManageIQ::Providers::Openstack::StorageManager::CinderManager::CloudVolumeType" + ) + + migrate + + expect(cloud_volume.reload.type).to eq("ManageIQ::Providers::Openstack::CloudManager::CloudVolume") + expect(cloud_volume_snapshot.reload.type).to eq("ManageIQ::Providers::Openstack::CloudManager::CloudVolumeSnapshot") + expect(cloud_volume_backup.reload.type).to eq("ManageIQ::Providers::Openstack::CloudManager::CloudVolumeBackup") + expect(cloud_volume_type.reload.type).to eq("ManageIQ::Providers::Openstack::CloudManager::CloudVolumeType") + end + end +end