Skip to content

Commit

Permalink
Merge pull request ManageIQ#385 from fdupont-redhat/v2v_specs_restore…
Browse files Browse the repository at this point in the history
…vmattributes

Add specs for Transformation - RestoreVmAttributes
  • Loading branch information
mkanoor authored Aug 2, 2018
2 parents 3f65939 + 2bec65e commit 5111136
Show file tree
Hide file tree
Showing 2 changed files with 211 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,57 @@ module Infrastructure
module VM
module Common
class RestoreVmAttributes
IDENTITY_ITEMS = %w(service tags custom_attributes).freeze

def initialize(handle = $evm)
@handle = handle
end

def main
task = @handle.root['service_template_transformation_plan_task']
source_vm = task.source
destination_vm = @handle.vmdb(:vm).find_by(:id => task.get_option(:destination_vm_id))
@handle.log(:info, "VM: #{destination_vm.name} [#{destination_vm.id}]")
def log_and_raise(message)
@handle.log(:error, message)
raise "ERROR - #{message}"
end

def task
@task ||= @handle.root["service_template_transformation_plan_task"].tap do |task|
log_and_raise('A service_template_transformation_plan_task is needed for this method to continue') if task.nil?
end
end

def source_vm
@vm ||= task.source.tap do |vm|
log_and_raise('Source VM has not been defined in the task') if vm.nil?
end
end

# Reconnect destination VM to service
def destination_vm
log_and_raise('destination_vm_id is blank') if task.get_option(:destination_vm_id).blank?
@destination_vm ||= @handle.vmdb(:vm).find_by(:id => task.get_option(:destination_vm_id)).tap do |vm|
log_and_raise('Destination VM not found in the database after migration') if vm.nil?
end
end

def vm_restore_service(source_vm, destination_vm)
if source_vm.service
destination_vm.add_to_service(source_vm.service)
source_vm.remove_from_service
end
end

# Restore tags of the source VM
def vm_restore_tags(source_vm, destination_vm)
source_vm.tags.each do |tag|
destination_vm.tag_assign(tag) unless tag =~ /^folder_path_/
end
end

# Restore custom attributes of the source VM
def vm_restore_custom_attributes(source_vm, destination_vm)
source_vm.custom_keys.each do |ca|
destination_vm.custom_set(ca, source_vm.custom_get(ca))
end
end

def main
IDENTITY_ITEMS.each { |item| send("vm_restore_#{item}", source_vm, destination_vm) }
rescue => e
@handle.set_state_var(:ae_state_progress, 'message' => e.message)
raise
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
require domain_file

describe ManageIQ::Automate::Transformation::Infrastructure::VM::Common::RestoreVmAttributes do
let(:user) { FactoryGirl.create(:user_with_email_and_group) }
let(:task) { FactoryGirl.create(:service_template_transformation_plan_task) }
let(:src_vm_vmware) { FactoryGirl.create(:vm_vmware) }
let(:dst_vm_redhat) { FactoryGirl.create(:vm_redhat) }
let(:dst_vm_openstack) { FactoryGirl.create(:vm_openstack) }
let(:service) { FactoryGirl.create(:service) }
let!(:parent_classification) { FactoryGirl.create(:classification, :name => "environment", :description => "Environment") }
let!(:classification) { FactoryGirl.create(:classification, :name => "prod", :description => "Production", :parent => parent_classification) }

let(:svc_model_user) { MiqAeMethodService::MiqAeServiceUser.find(user.id) }
let(:svc_model_task) { MiqAeMethodService::MiqAeServiceServiceTemplateTransformationPlanTask.find(task.id) }
let(:svc_model_src_vm_vmware) { MiqAeMethodService::MiqAeServiceManageIQ_Providers_Vmware_InfraManager_Vm.find(src_vm_vmware.id) }
let(:svc_model_dst_vm_redhat) { MiqAeMethodService::MiqAeServiceManageIQ_Providers_Redhat_InfraManager_Vm.find(dst_vm_redhat.id) }
let(:svc_model_dst_vm_openstack) { MiqAeMethodService::MiqAeServiceManageIQ_Providers_Openstack_CloudManager_Vm.find(dst_vm_openstack.id) }
let(:svc_model_service) { MiqAeMethodService::MiqAeServiceService.find(service.id) }

let(:root) do
Spec::Support::MiqAeMockObject.new(
'current' => current_object,
'user' => svc_model_user,
)
end

let(:current_object) { Spec::Support::MiqAeMockObject.new }
let(:ae_service) do
Spec::Support::MiqAeMockService.new(root).tap do |service|
current_object.parent = root
service.current_object = current_object
end
end

def set_vm_identity
svc_model_src_vm.add_to_service(svc_model_service)
src_vm.tag_with("prod", :ns => "/managed", :cat => "environment")
svc_model_src_vm.custom_set('attr', 'value')
end

context "validate task" do
it "when task is nil" do
errormsg = 'ERROR - A service_template_transformation_plan_task is needed for this method to continue'
expect { described_class.new(ae_service).task }.to raise_error(errormsg)
end

it "when task is present" do
ae_service.root['service_template_transformation_plan_task'] = svc_model_task
expect(described_class.new(ae_service).task.id).to eq(svc_model_task.id)
end
end

shared_examples_for "validate source and destination vms" do
let(:svc_vmdb_handle) { MiqAeMethodService::MiqAeServiceVm }

before do
ae_service.root['service_template_transformation_plan_task'] = svc_model_task
end

it "when task.source is nil" do
errormsg = 'ERROR - Source VM has not been defined in the task'
expect { described_class.new(ae_service).source_vm }.to raise_error(errormsg)
end

it "when task.source is present" do
ae_service.root['service_template_transformation_plan_task'] = svc_model_task
allow(svc_model_task).to receive(:source) { svc_model_src_vm }
expect(described_class.new(ae_service).source_vm.id).to eq(svc_model_src_vm.id)
end

it "when destination_vm_id option is absent" do
ae_service.root['service_template_transformation_plan_task'] = svc_model_task
errormsg = "ERROR - destination_vm_id is blank"
expect { described_class.new(ae_service).destination_vm }.to raise_error(errormsg)
end

it "when destination_vm is nil" do
allow(svc_model_task).to receive(:get_option).with(:destination_vm_id).and_return(svc_model_dst_vm.id)
allow(ae_service).to receive(:vmdb).with(:vm).and_return(svc_vmdb_handle)
allow(svc_vmdb_handle).to receive(:find_by).with(:id => svc_model_dst_vm.id).and_return(nil)
errormsg = 'ERROR - Destination VM not found in the database after migration'
expect { described_class.new(ae_service).destination_vm }.to raise_error(errormsg)
end

it "when destination_vm present" do
allow(svc_model_task).to receive(:get_option).with(:destination_vm_id).and_return(svc_model_dst_vm.id)
allow(ae_service).to receive(:vmdb).with(:vm).and_return(svc_vmdb_handle)
allow(svc_vmdb_handle).to receive(:find_by).with(:id => svc_model_dst_vm.id).and_return(svc_model_dst_vm)
expect(described_class.new(ae_service).destination_vm.id).to eq(svc_model_dst_vm.id)
end
end

context "validate when source is vmware and destination redhat" do
let(:src_vm) { src_vm_vmware }
let(:dst_vm) { dst_vm_redhat }
let(:svc_model_src_vm) { svc_model_src_vm_vmware }
let(:svc_model_dst_vm) { svc_model_dst_vm_redhat }

it_behaves_like "validate source and destination vms"
end

context "validate when source is vmware and destination openstack" do
let(:src_vm) { src_vm_vmware }
let(:dst_vm) { dst_vm_openstack }
let(:svc_model_src_vm) { svc_model_src_vm_vmware }
let(:svc_model_dst_vm) { svc_model_dst_vm_openstack }

it_behaves_like "validate source and destination vms"
end

shared_examples_for "restore identity" do
let(:svc_vmdb_handle) { MiqAeMethodService::MiqAeServiceVm }

before do
ae_service.root['service_template_transformation_plan_task'] = svc_model_task
allow(svc_model_task).to receive(:source) { svc_model_src_vm }
allow(svc_model_task).to receive(:get_option).with(:destination_vm_id).and_return(svc_model_dst_vm.id)
allow(ae_service).to receive(:vmdb).with(:vm).and_return(svc_vmdb_handle)
allow(svc_vmdb_handle).to receive(:find_by).with(:id => svc_model_dst_vm.id).and_return(svc_model_dst_vm)
set_vm_identity
end

it "restore service" do
described_class.new(ae_service).vm_restore_service(svc_model_src_vm, svc_model_dst_vm)
expect(svc_model_src_vm.service).to be_nil
expect(svc_model_dst_vm.service.id).to eq(svc_model_service.id)
end

it "restore tags" do
described_class.new(ae_service).vm_restore_tags(svc_model_src_vm, svc_model_dst_vm)
expect(svc_model_dst_vm.tags).to eq(["environment/prod"])
end

it "restore customer attributes" do
described_class.new(ae_service).vm_restore_custom_attributes(svc_model_src_vm, svc_model_dst_vm)
expect(svc_model_dst_vm.custom_get('attr')).to eq('value')
end

it "restore identity" do
described_class.new(ae_service).main
expect(svc_model_src_vm.service).to be_nil
expect(svc_model_dst_vm.service.id).to eq(svc_model_service.id)
expect(svc_model_dst_vm.tags).to eq(["environment/prod"])
expect(svc_model_dst_vm.custom_get('attr')).to eq('value')
end
end

context "restore when source is vmware and destination redhat" do
let(:src_vm) { src_vm_vmware }
let(:dst_vm) { dst_vm_redhat }
let(:svc_model_src_vm) { svc_model_src_vm_vmware }
let(:svc_model_dst_vm) { svc_model_dst_vm_redhat }

it_behaves_like "restore identity"
end

context "restore when source is vmware and destination openstack" do
let(:src_vm) { src_vm_vmware }
let(:dst_vm) { dst_vm_openstack }
let(:svc_model_src_vm) { svc_model_src_vm_vmware }
let(:svc_model_dst_vm) { svc_model_dst_vm_openstack }

it_behaves_like "restore identity"
end

context "catchall exception rescue" do
before do
allow(svc_model_task).to receive(:source).and_raise(StandardError.new('kaboom'))
end

it "forcefully raise" do
errormsg = 'ERROR - A service_template_transformation_plan_task is needed for this method to continue'
expect { described_class.new(ae_service).main }.to raise_error(errormsg)
expect(ae_service.get_state_var(:ae_state_progress)).to eq('message' => errormsg)
end
end
end

0 comments on commit 5111136

Please sign in to comment.