Skip to content

Commit

Permalink
Merge pull request #19240 from fdupont-redhat/v2v_state_machine_resto…
Browse files Browse the repository at this point in the history
…re_vm_attributes

[V2V] Add restoring_vm_attributes state to InfraConversionJob
  • Loading branch information
agrare authored Sep 10, 2019
2 parents 7a820ad + 9f57a48 commit 399ea75
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 12 deletions.
48 changes: 46 additions & 2 deletions app/models/infra_conversion_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ def load_transitions
'waiting_for_inventory_refresh' => 'waiting_for_inventory_refresh'
},
:apply_right_sizing => {'waiting_for_inventory_refresh' => 'applying_right_sizing'},
:restore_vm_attributes => {'applying_right_sizing' => 'restoring_vm_attributes'},
:poll_automate_state_machine => {
'applying_right_sizing' => 'running_in_automate',
'running_in_automate' => 'running_in_automate'
'restoring_vm_attributes' => 'running_in_automate',
'running_in_automate' => 'running_in_automate'
},
:finish => {'*' => 'finished'},
:abort_job => {'*' => 'aborting'},
Expand Down Expand Up @@ -98,6 +99,10 @@ def state_settings
:description => "Apply Right-Sizing Recommendation",
:weight => 1
},
:restoring_vm_attributes => {
:description => "Restore VM Attributes",
:weight => 1
},
:running_in_automate => {
:max_retries => 36.hours / state_retry_interval
}
Expand Down Expand Up @@ -445,6 +450,45 @@ def apply_right_sizing
send("apply_right_sizing_#{item}", right_sizing_mode) if right_sizing_mode.present?
end

update_migration_task_progress(:on_exit)
queue_signal(:restore_vm_attributes)
rescue StandardError
update_migration_task_progress(:on_error)
queue_signal(:restore_vm_attributes)
end

def restore_vm_attributes
update_migration_task_progress(:on_entry)

# Transfer service link to destination VM
if source_vm.service
destination_vm.add_to_service(source_vm.service)
source_vm.direct_service.try(:remove_resource, source_vm)
end

# Copy tags and custom attributes from source VM
source_vm.tags.each do |tag|
next if tag.name =~ /^\/managed\/folder_path_/

tag_as_array = tag.name.split('/')
namespace = tag_as_array.shift
value = tag_as_array.pop
category = tag_as_array.join('/')
destination_vm.tag_add("#{category}/#{value}", :ns => namespace)
end
source_vm.miq_custom_keys.each { |ca| destination_vm.miq_custom_set(ca, source_vm.miq_custom_get(ca)) }

# Copy ownership from source VM
destination_vm.evm_owner = source_vm.evm_owner if source_vm.present?
destination_vm.miq_group = source_vm.miq_group if source_vm.miq_group.present?

# Copy retirement settings from source VM
destination_vm.retires_on = source_vm.retires_on if source_vm.retires_on.present?
destination_vm.retirement_warn = source_vm.retirement_warn if source_vm.retirement_warn.present?

# Save destination_vm in VMDB
destination_vm.save

update_migration_task_progress(:on_exit)
handover_to_automate
queue_signal(:poll_automate_state_machine)
Expand Down
107 changes: 97 additions & 10 deletions spec/models/infra_conversion_job_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
RSpec.describe InfraConversionJob, :v2v do
let(:user) { FactoryBot.create(:user_with_group) }
let(:user_admin) { FactoryBot.create(:user_admin) }
let(:group) { FactoryBot.create(:miq_group) }
let(:zone) { FactoryBot.create(:zone) }

let(:ems_vmware) { FactoryBot.create(:ems_vmware, :zone => zone) }
Expand All @@ -15,13 +17,14 @@
:ems_cluster => ems_cluster_vmware,
:host => host_vmware,
:hardware => hardware_vmware,
:evm_owner => user)
:evm_owner => user,
:miq_group => group)
end

let(:ems_redhat) { FactoryBot.create(:ems_redhat, :zone => zone) }
let(:ems_cluster_redhat) { FactoryBot.create(:ems_cluster, :ext_management_system => ems_redhat) }
let(:host_redhat) { FactoryBot.create(:host, :ext_management_system => ems_redhat, :ems_cluster => ems_cluster_redhat) }
let(:vm_redhat) { FactoryBot.create(:vm_vmware, :ext_management_system => ems_redhat, :ems_cluster => ems_cluster_redhat, :host => host_redhat, :evm_owner => user) }
let(:vm_redhat) { FactoryBot.create(:vm_vmware, :ext_management_system => ems_redhat, :ems_cluster => ems_cluster_redhat, :host => host_redhat, :evm_owner => user_admin) }

let(:embedded_ansible_auth) { FactoryBot.create(:embedded_ansible_credential) }
let(:embedded_ansible_catalog_item_options) do
Expand Down Expand Up @@ -349,7 +352,7 @@
end

context 'state transitions' do
%w[start remove_snapshots poll_remove_snapshots_complete wait_for_ip_address run_migration_playbook poll_run_migration_playbook_complete shutdown_vm poll_shutdown_vm_complete transform_vm poll_transform_vm_complete poll_inventory_refresh_complete apply_right_sizing poll_automate_state_machine finish abort_job cancel error].each do |signal|
%w[start remove_snapshots poll_remove_snapshots_complete wait_for_ip_address run_migration_playbook poll_run_migration_playbook_complete shutdown_vm poll_shutdown_vm_complete transform_vm poll_transform_vm_complete poll_inventory_refresh_complete apply_right_sizing restore_vm_attributes poll_automate_state_machine finish abort_job cancel error].each do |signal|
shared_examples_for "allows #{signal} signal" do
it signal.to_s do
expect(job).to receive(signal.to_sym)
Expand All @@ -358,7 +361,7 @@
end
end

%w[start remove_snapshots poll_remove_snapshots_complete wait_for_ip_address run_migration_playbook poll_run_migration_playbook_complete shutdown_vm poll_shutdown_vm_complete transform_vm poll_transform_vm_complete poll_inventory_refresh_complete apply_right_sizing poll_automate_state_machine].each do |signal|
%w[start remove_snapshots poll_remove_snapshots_complete wait_for_ip_address run_migration_playbook poll_run_migration_playbook_complete shutdown_vm poll_shutdown_vm_complete transform_vm poll_transform_vm_complete poll_inventory_refresh_complete apply_right_sizing restore_vm_attributes poll_automate_state_machine].each do |signal|
shared_examples_for "doesn't allow #{signal} signal" do
it signal.to_s do
expect { job.signal(signal.to_sym) }.to raise_error(RuntimeError, /#{signal} is not permitted at state #{job.state}/)
Expand Down Expand Up @@ -387,6 +390,8 @@
it_behaves_like 'doesn\'t allow transform_vm signal'
it_behaves_like 'doesn\'t allow poll_transform_vm_complete signal'
it_behaves_like 'doesn\'t allow poll_inventory_refresh_complete signal'
it_behaves_like 'doesn\'t allow apply_right_sizing signal'
it_behaves_like 'doesn\'t allow restore_vm_attributes signal'
it_behaves_like 'doesn\'t allow poll_automate_state_machine signal'
end

Expand All @@ -411,6 +416,8 @@
it_behaves_like 'doesn\'t allow transform_vm signal'
it_behaves_like 'doesn\'t allow poll_transform_vm_complete signal'
it_behaves_like 'doesn\'t allow poll_inventory_refresh_complete signal'
it_behaves_like 'doesn\'t allow apply_right_sizing signal'
it_behaves_like 'doesn\'t allow restore_vm_attributes signal'
it_behaves_like 'doesn\'t allow poll_automate_state_machine signal'
end

Expand All @@ -435,6 +442,8 @@
it_behaves_like 'doesn\'t allow transform_vm signal'
it_behaves_like 'doesn\'t allow poll_transform_vm_complete signal'
it_behaves_like 'doesn\'t allow poll_inventory_refresh_complete signal'
it_behaves_like 'doesn\'t allow apply_right_sizing signal'
it_behaves_like 'doesn\'t allow restore_vm_attributes signal'
it_behaves_like 'doesn\'t allow poll_automate_state_machine signal'
end

Expand All @@ -459,6 +468,8 @@
it_behaves_like 'doesn\'t allow transform_vm signal'
it_behaves_like 'doesn\'t allow poll_transform_vm_complete signal'
it_behaves_like 'doesn\'t allow poll_inventory_refresh_complete signal'
it_behaves_like 'doesn\'t allow apply_right_sizing signal'
it_behaves_like 'doesn\'t allow restore_vm_attributes signal'
it_behaves_like 'doesn\'t allow poll_automate_state_machine signal'
end

Expand All @@ -483,6 +494,8 @@
it_behaves_like 'doesn\'t allow transform_vm signal'
it_behaves_like 'doesn\'t allow poll_transform_vm_complete signal'
it_behaves_like 'doesn\'t allow poll_inventory_refresh_complete signal'
it_behaves_like 'doesn\'t allow apply_right_sizing signal'
it_behaves_like 'doesn\'t allow restore_vm_attributes signal'
it_behaves_like 'doesn\'t allow poll_automate_state_machine signal'
end

Expand All @@ -507,6 +520,8 @@
it_behaves_like 'doesn\'t allow shutdown_vm signal'
it_behaves_like 'doesn\'t allow poll_transform_vm_complete signal'
it_behaves_like 'doesn\'t allow poll_inventory_refresh_complete signal'
it_behaves_like 'doesn\'t allow apply_right_sizing signal'
it_behaves_like 'doesn\'t allow restore_vm_attributes signal'
it_behaves_like 'doesn\'t allow poll_automate_state_machine signal'
end

Expand All @@ -531,6 +546,8 @@
it_behaves_like 'doesn\'t allow shutdown_vm signal'
it_behaves_like 'doesn\'t allow poll_shutdown_vm_complete signal'
it_behaves_like 'doesn\'t allow transform_vm signal'
it_behaves_like 'doesn\'t allow apply_right_sizing signal'
it_behaves_like 'doesn\'t allow restore_vm_attributes signal'
it_behaves_like 'doesn\'t allow poll_automate_state_machine signal'
end

Expand All @@ -556,13 +573,39 @@
it_behaves_like 'doesn\'t allow poll_shutdown_vm_complete signal'
it_behaves_like 'doesn\'t allow transform_vm signal'
it_behaves_like 'doesn\'t allow poll_transform_vm_complete signal'
it_behaves_like 'doesn\'t allow restore_vm_attributes signal'
end

context 'applying_right_sizing' do
before do
job.state = 'applying_right_sizing'
end

it_behaves_like 'allows restore_vm_attributes signal'
it_behaves_like 'allows finish signal'
it_behaves_like 'allows abort_job signal'
it_behaves_like 'allows cancel signal'
it_behaves_like 'allows error signal'

it_behaves_like 'doesn\'t allow start signal'
it_behaves_like 'doesn\'t allow remove_snapshots signal'
it_behaves_like 'doesn\'t allow poll_remove_snapshots_complete signal'
it_behaves_like 'doesn\'t allow wait_for_ip_address signal'
it_behaves_like 'doesn\'t allow run_migration_playbook signal'
it_behaves_like 'doesn\'t allow poll_run_migration_playbook_complete signal'
it_behaves_like 'doesn\'t allow shutdown_vm signal'
it_behaves_like 'doesn\'t allow poll_shutdown_vm_complete signal'
it_behaves_like 'doesn\'t allow transform_vm signal'
it_behaves_like 'doesn\'t allow poll_transform_vm_complete signal'
it_behaves_like 'doesn\'t allow poll_inventory_refresh_complete signal'
it_behaves_like 'doesn\'t allow apply_right_sizing signal'
end

context 'restoring_vm_attributes' do
before do
job.state = 'restoring_vm_attributes'
end

it_behaves_like 'allows poll_automate_state_machine signal'
it_behaves_like 'allows finish signal'
it_behaves_like 'allows abort_job signal'
Expand All @@ -581,6 +624,7 @@
it_behaves_like 'doesn\'t allow poll_transform_vm_complete signal'
it_behaves_like 'doesn\'t allow poll_inventory_refresh_complete signal'
it_behaves_like 'doesn\'t allow apply_right_sizing signal'
it_behaves_like 'doesn\'t allow restore_vm_attributes signal'
end

context 'running_in_automate' do
Expand All @@ -606,6 +650,7 @@
it_behaves_like 'doesn\'t allow poll_transform_vm_complete signal'
it_behaves_like 'doesn\'t allow poll_inventory_refresh_complete signal'
it_behaves_like 'doesn\'t allow apply_right_sizing signal'
it_behaves_like 'doesn\'t allow restore_vm_attributes signal'
end
end

Expand Down Expand Up @@ -1020,13 +1065,12 @@
task.update!(:destination => vm_redhat)
end

it "exits to next state in case of failed" do
it "exits to next state in case of failure" do
allow(job.migration_task).to receive(:cpu_right_sizing_mode).and_raise('Fake error message')
expect(job).to receive(:update_migration_task_progress).once.ordered.with(:on_entry)
expect(job).to receive(:update_migration_task_progress).once.ordered.with(:on_error)
expect(job).to receive(:queue_signal).with(:poll_automate_state_machine)
expect(job).to receive(:queue_signal).with(:restore_vm_attributes)
job.signal(:apply_right_sizing)
expect(task.reload.options[:workflow_runner]).to eq('automate')
end

context 'without right_sizing mode' do
Expand All @@ -1038,9 +1082,8 @@
it 'exits if no right-sizing is requested' do
expect(job).to receive(:update_migration_task_progress).once.ordered.with(:on_entry)
expect(job).to receive(:update_migration_task_progress).once.ordered.with(:on_exit)
expect(job).to receive(:queue_signal).with(:poll_automate_state_machine)
expect(job).to receive(:queue_signal).with(:restore_vm_attributes)
job.signal(:apply_right_sizing)
expect(task.reload.options[:workflow_runner]).to eq('automate')
end
end

Expand All @@ -1057,8 +1100,52 @@
expect(job.migration_task.destination).to receive(:set_number_of_cpus).with(1)
expect(job.migration_task.destination).to receive(:set_memory).with(1024)
expect(job).to receive(:update_migration_task_progress).once.ordered.with(:on_exit)
expect(job).to receive(:queue_signal).with(:poll_automate_state_machine)
expect(job).to receive(:queue_signal).with(:restore_vm_attributes)
job.signal(:apply_right_sizing)
end
end
end

context '#restore_vm_attributes' do
let(:service) { FactoryBot.create(:service) }
let(:parent_classification) { FactoryBot.create(:classification, :name => 'environment', :description => 'Environment') }
let(:classification) { FactoryBot.create(:classification, :name => 'prod', :description => 'Production', :parent => parent_classication) }

before do
job.state = 'applying_right_sizing'
task.update!(:destination => vm_redhat)
end

it "exits to next state in case of failure" do
allow(job.migration_task.source).to receive(:service).and_raise('Fake error message')
expect(job).to receive(:update_migration_task_progress).once.ordered.with(:on_entry)
expect(job).to receive(:update_migration_task_progress).once.ordered.with(:on_error)
expect(job).to receive(:queue_signal).with(:poll_automate_state_machine)
job.signal(:restore_vm_attributes)
expect(task.reload.options[:workflow_runner]).to eq('automate')
end

it 'restore VM attributes' do
Timecop.freeze(2019, 2, 6) do
vm_vmware.add_to_service(service)
vm_vmware.tag_with('test', :ns => '/managed', :cat => 'folder_path_spec')
vm_vmware.tag_with('prod', :ns => '/managed', :cat => 'environment')
vm_vmware.miq_custom_set('attr', 'value')
vm_vmware.update!(:retires_on => Time.now.utc + 1.day)
vm_vmware.update!(:retirement_warn => 7)
expect(job).to receive(:update_migration_task_progress).once.ordered.with(:on_entry)
expect(job).to receive(:update_migration_task_progress).once.ordered.with(:on_exit)
expect(job).to receive(:queue_signal).with(:poll_automate_state_machine)
job.signal(:restore_vm_attributes)
vm_redhat.reload
expect(vm_vmware.service).to be_nil
expect(vm_redhat.service.id).to eq(service.id)
expect(vm_redhat.tags).to eq(['/managed/environment/prod'])
expect(vm_redhat.miq_custom_get('attr')).to eq('value')
expect(vm_redhat.evm_owner.id).to eq(user.id)
expect(vm_redhat.miq_group.id).to eq(group.id)
expect(vm_redhat.retires_on).to eq(Time.now.utc + 1.day)
expect(vm_redhat.retirement_warn).to eq(7)
expect(task.reload.options[:workflow_runner]).to eq('automate')
end
end
Expand Down

0 comments on commit 399ea75

Please sign in to comment.