Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[V2V] Add VM validation for warm migration eligibility and updated specs to … #19401

Merged
merged 11 commits into from
Oct 29, 2019
Merged
1 change: 1 addition & 0 deletions app/models/mixins/supports_feature_mixin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ module SupportsFeatureMixin
:launch_vmrc_console => 'Launch VMRC Console',
:admin_ui => 'Open Admin UI for a Provider',
:live_migrate => 'Live Migration',
:warm_migrate => 'Warm Migration',
:migrate => 'Migration',
:capture => 'Capture of Capacity & Utilization Metrics',
:openscap_scan => 'OpenSCAP security scan',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def validate_config_info(options)
raise _("Invalid VM found #{vm_obj.name}") if vm_obj.invalid?

vm_options = {}
vm_options[:warm_migration_compatible] = vm_obj.supports_warm_migrate?
vm_options[:pre_ansible_playbook_service_template_id] = pre_service_id if vm_hash[:pre_service]
vm_options[:post_ansible_playbook_service_template_id] = post_service_id if vm_hash[:post_service]
vm_options[:cpu_right_sizing_mode] = vm_hash[:cpu_right_sizing_mode] if vm_hash[:cpu_right_sizing_mode].present?
Expand Down
43 changes: 28 additions & 15 deletions spec/models/service_template_transformation_plan_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
RSpec.describe ServiceTemplateTransformationPlan, :v2v do
before { EvmSpecHelper.local_miq_server } # required for creating snapshots needed for warm migration testing
subject { FactoryBot.create(:service_template_transformation_plan) }

describe '#request_class' do
Expand All @@ -10,9 +11,9 @@
end

let(:apst) { FactoryBot.create(:service_template_ansible_playbook) }
let(:vm1) { FactoryBot.create(:vm_or_template) }
let(:vm2) { FactoryBot.create(:vm_or_template) }
let(:vm3) { FactoryBot.create(:vm_or_template) }
let(:vm1) { FactoryBot.create(:vm_vmware) }
let(:vm2) { FactoryBot.create(:vm_vmware) }
let(:vm3) { FactoryBot.create(:vm_vmware) }
let(:security_group1) { FactoryBot.create(:security_group, :name => "default") }
let(:flavor1) { FactoryBot.create(:flavor, :name => "large") }
let(:security_group2) { FactoryBot.create(:security_group, :name => "default") }
Expand Down Expand Up @@ -277,16 +278,28 @@
expect(service_template.vm_resources.collect(&:resource)).to match_array([vm1, vm2])
expect(service_template.vm_resources.collect(&:status)).to eq([ServiceResource::STATUS_QUEUED, ServiceResource::STATUS_QUEUED])
expect(service_template.vm_resources.find_by(:resource_id => vm1.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id, "warm_migration_compatible" => true)
expect(service_template.vm_resources.find_by(:resource_id => vm2.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "post_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "post_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id, "warm_migration_compatible" => true)
expect(service_template.config_info).to eq(catalog_item_options[:config_info])
expect(service_template.resource_actions.first).to have_attributes(
:action => 'Provision',
:fqname => described_class.default_provisioning_entry_point(nil)
)
end

it 'creates and returns a transformation plan with VMs containing snapshots' do
FactoryBot.create_list(:snapshot, 2, :create_time => 1.minute.ago, :vm_or_template => vm1)
FactoryBot.create_list(:snapshot, 2, :create_time => 1.minute.ago, :vm_or_template => vm2)

service_template = described_class.create_catalog_item(catalog_item_options)

expect(service_template.vm_resources.find_by(:resource_id => vm1.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id, "warm_migration_compatible" => false)
expect(service_template.vm_resources.find_by(:resource_id => vm2.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "post_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id, "warm_migration_compatible" => false)
end

it 'requires a transformation mapping' do
catalog_item_options[:config_info].delete(:transformation_mapping_id)

Expand Down Expand Up @@ -355,11 +368,11 @@
expect(service_template.vm_resources.collect(&:resource)).to match_array([vm1, vm2, vm3])
expect(service_template.vm_resources.collect(&:status)).to eq([ServiceResource::STATUS_QUEUED, ServiceResource::STATUS_QUEUED, ServiceResource::STATUS_QUEUED])
expect(service_template.vm_resources.find_by(:resource_id => vm1.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id, "warm_migration_compatible" => true)
expect(service_template.vm_resources.find_by(:resource_id => vm2.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "post_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "post_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id, "warm_migration_compatible" => true)
expect(service_template.vm_resources.find_by(:resource_id => vm3.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "post_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group2.id, "osp_flavor_id" => flavor2.id)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "post_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group2.id, "osp_flavor_id" => flavor2.id, "warm_migration_compatible" => true)
expect(service_template.config_info).to eq(updated_catalog_item_options_with_vms_added[:config_info])
expect(service_template.resource_actions.first).to have_attributes(
:action => 'Provision',
Expand All @@ -377,7 +390,7 @@
expect(service_template.vm_resources.collect(&:resource)).to match_array([vm1])
expect(service_template.vm_resources.collect(&:status)).to eq([ServiceResource::STATUS_QUEUED])
expect(service_template.vm_resources.find_by(:resource_id => vm1.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "warm_migration_compatible" => true)
expect(service_template.config_info).to eq(updated_catalog_item_options_with_vms_removed[:config_info])
expect(service_template.resource_actions.first).to have_attributes(
:action => 'Provision',
Expand All @@ -395,9 +408,9 @@
expect(service_template.vm_resources.collect(&:resource)).to match_array([vm1, vm3])
expect(service_template.vm_resources.collect(&:status)).to eq([ServiceResource::STATUS_QUEUED, ServiceResource::STATUS_QUEUED])
expect(service_template.vm_resources.find_by(:resource_id => vm1.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "warm_migration_compatible" => true)
expect(service_template.vm_resources.find_by(:resource_id => vm3.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "post_ansible_playbook_service_template_id" => apst.id)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "post_ansible_playbook_service_template_id" => apst.id, "warm_migration_compatible" => true)
expect(service_template.config_info).to eq(updated_catalog_item_options_with_vms_added_and_removed[:config_info])
expect(service_template.resource_actions.first).to have_attributes(
:action => 'Provision',
Expand All @@ -416,9 +429,9 @@
expect(service_template.vm_resources.collect(&:resource)).to match_array([vm1, vm2])
expect(service_template.vm_resources.collect(&:status)).to eq([ServiceResource::STATUS_QUEUED, ServiceResource::STATUS_QUEUED])
expect(service_template.vm_resources.find_by(:resource_id => vm1.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id, "warm_migration_compatible" => true)
expect(service_template.vm_resources.find_by(:resource_id => vm2.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "post_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "post_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id, "warm_migration_compatible" => true)
expect(service_template.config_info).to eq(catalog_item_options[:config_info])
expect(service_template.resource_actions.first).to have_attributes(
:action => 'Provision',
Expand All @@ -436,9 +449,9 @@
expect(service_template.transformation_mapping).to eq(transformation_mapping)
expect(service_template.vm_resources.collect(&:resource)).to match_array([vm1, vm2])
expect(service_template.vm_resources.find_by(:resource_id => vm1.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id, "warm_migration_compatible" => true)
expect(service_template.vm_resources.find_by(:resource_id => vm2.id).options)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "post_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id)
.to eq("pre_ansible_playbook_service_template_id" => apst.id, "post_ansible_playbook_service_template_id" => apst.id, "osp_security_group_id" => security_group1.id, "osp_flavor_id" => flavor1.id, "warm_migration_compatible" => true)
expect(service_template.config_info).to eq(catalog_item_options[:config_info])
expect(service_template.resource_actions.first).to have_attributes(
:action => 'Provision',
Expand Down