From 64d12b1bf0693fb03274f8b9b7f92f5598263fcc Mon Sep 17 00:00:00 2001 From: Lucy Fu Date: Fri, 22 Jun 2018 16:09:41 -0400 Subject: [PATCH] Support for v2v pre/post Ansible playbook service. --- .../service_template_transformation_plan.rb | 30 ++++++++++++++----- ...rvice_template_transformation_plan_task.rb | 8 +++++ ...rvice_template_transformation_plan_spec.rb | 14 +++++++-- ..._template_transformation_plan_task_spec.rb | 24 +++++++++++++-- 4 files changed, 64 insertions(+), 12 deletions(-) diff --git a/app/models/service_template_transformation_plan.rb b/app/models/service_template_transformation_plan.rb index 1f8b630a5ca..c7dce1fc3c0 100644 --- a/app/models/service_template_transformation_plan.rb +++ b/app/models/service_template_transformation_plan.rb @@ -38,7 +38,12 @@ def self.default_reconfiguration_entry_point # :description # :config_info # :transformation_mapping_id - # :vm_ids + # :pre_service_id + # :post_service_id + # :actions => [ + # {:vm_id => 1, :pre_service => true, :post_service => false}, + # {:vm_id => 2, :pre_service => true, :post_service => true}, + # ] # def self.create_catalog_item(options, _auth_user = nil) enhanced_config_info = validate_config_info(options) @@ -51,7 +56,7 @@ def self.create_catalog_item(options, _auth_user = nil) transaction do create_from_options(options.merge(default_options)).tap do |service_template| service_template.add_resource(enhanced_config_info[:transformation_mapping]) - enhanced_config_info[:vms].each { |vm| service_template.add_resource(vm, :status => ServiceResource::STATUS_QUEUED) } + enhanced_config_info[:vms].each { |vm_hash| service_template.add_resource(vm_hash[:vm], :status => ServiceResource::STATUS_QUEUED, :options => vm_hash[:options]) } service_template.create_resource_actions(enhanced_config_info) end end @@ -73,11 +78,22 @@ def self.validate_config_info(options) raise _('Must provide an existing transformation mapping') if mapping.blank? - vms = if config_info[:vm_ids] - VmOrTemplate.find(config_info[:vm_ids]) - else - config_info[:vms] - end + pre_service_id = config_info[:pre_service].try(:id) || config_info[:pre_service_id] + post_service_id = config_info[:post_service].try(:id) || config_info[:post_service_id] + + vms = [] + if config_info[:actions] + vm_objects = VmOrTemplate.where(:id => config_info[:actions].collect { |vm_hash| vm_hash[:vm_id] }.compact).group_by(&:id) + config_info[:actions].each do |vm_hash| + vm_obj = vm_objects[vm_hash[:vm_id]].try(:first) || vm_hash[:vm] + next if vm_obj.nil? + + vm_options = {} + 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] + vms << {:vm => vm_obj, :options => vm_options} + end + end raise _('Must select a list of valid vms') if vms.blank? diff --git a/app/models/service_template_transformation_plan_task.rb b/app/models/service_template_transformation_plan_task.rb index 79e88f3d491..3e5f88f623d 100644 --- a/app/models/service_template_transformation_plan_task.rb +++ b/app/models/service_template_transformation_plan_task.rb @@ -20,6 +20,14 @@ def transformation_destination(source_obj) miq_request.transformation_mapping.destination(source_obj) end + def pre_ansible_playbook_service_template + ServiceTemplate.find_by(:id => vm_resource.options["pre_ansible_playbook_service_template_id"]) + end + + def post_ansible_playbook_service_template + ServiceTemplate.find_by(:id => vm_resource.options["post_ansible_playbook_service_template_id"]) + end + def update_transformation_progress(progress) options[:progress] = (options[:progress] || {}).merge(progress) save diff --git a/spec/models/service_template_transformation_plan_spec.rb b/spec/models/service_template_transformation_plan_spec.rb index 3ad62c39640..f05b5d99a90 100644 --- a/spec/models/service_template_transformation_plan_spec.rb +++ b/spec/models/service_template_transformation_plan_spec.rb @@ -17,6 +17,7 @@ end let(:transformation_mapping) { FactoryGirl.create(:transformation_mapping) } + let(:apst) { FactoryGirl.create(:service_template_ansible_playbook) } let(:vm1) { FactoryGirl.create(:vm_or_template) } let(:vm2) { FactoryGirl.create(:vm_or_template) } @@ -26,7 +27,12 @@ :description => 'a description', :config_info => { :transformation_mapping_id => transformation_mapping.id, - :vm_ids => [vm1.id, vm2.id], + :pre_service_id => apst.id, + :post_service_id => apst.id, + :actions => [ + {:vm_id => vm1.id, :pre_service => true, :post_service => false}, + {:vm_id => vm2.id, :pre_service => true, :post_service => true} + ], } } end @@ -39,6 +45,10 @@ 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.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) + 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) expect(service_template.config_info).to eq(catalog_item_options[:config_info]) expect(service_template.resource_actions.first).to have_attributes( :action => 'Provision', @@ -55,7 +65,7 @@ end it 'requires selected vms' do - catalog_item_options[:config_info].delete(:vm_ids) + catalog_item_options[:config_info].delete(:actions) expect do described_class.create_catalog_item(catalog_item_options) diff --git a/spec/models/service_template_transformation_plan_task_spec.rb b/spec/models/service_template_transformation_plan_task_spec.rb index ff32231041a..430cf69d4b0 100644 --- a/spec/models/service_template_transformation_plan_task_spec.rb +++ b/spec/models/service_template_transformation_plan_task_spec.rb @@ -16,6 +16,8 @@ let(:src) { FactoryGirl.create(:ems_cluster) } let(:dst) { FactoryGirl.create(:ems_cluster) } let(:vm) { FactoryGirl.create(:vm_or_template) } + let(:vm2) { FactoryGirl.create(:vm_or_template) } + let(:apst) { FactoryGirl.create(:service_template_ansible_playbook) } let(:mapping) do FactoryGirl.create( :transformation_mapping, @@ -29,7 +31,12 @@ :description => 'a description', :config_info => { :transformation_mapping_id => mapping.id, - :vm_ids => [vm.id], + :pre_service_id => apst.id, + :post_service_id => apst.id, + :actions => [ + {:vm_id => vm.id, :pre_service => true, :post_service => true}, + {:vm_id => vm2.id, :pre_service => false, :post_service => false}, + ], } } end @@ -38,6 +45,7 @@ let(:request) { FactoryGirl.create(:service_template_transformation_plan_request, :source => plan) } let(:task) { FactoryGirl.create(:service_template_transformation_plan_task, :miq_request => request, :request_type => 'transformation_plan', :source => vm) } + let(:task2) { FactoryGirl.create(:service_template_transformation_plan_task, :miq_request => request, :request_type => 'transformation_plan', :source => vm2) } describe '#resource_action' do it 'has a resource action points to the entry point for transformation' do @@ -52,6 +60,16 @@ it { expect(task.transformation_destination(src)).to eq(dst) } end + describe '#pre_ansible_playbook_service_template' do + it { expect(task.pre_ansible_playbook_service_template).to eq(apst) } + it { expect(task2.pre_ansible_playbook_service_template).to be_nil } + end + + describe '#post_ansible_playbook_service_template' do + it { expect(task.post_ansible_playbook_service_template).to eq(apst) } + it { expect(task2.post_ansible_playbook_service_template).to be_nil } + end + describe '#update_transformation_progress' do it 'saves the progress in options' do task.update_transformation_progress(:vm_percent => '80') @@ -62,14 +80,14 @@ describe 'task_active' do it 'sets vm_request status to Started' do task.task_active - expect(plan.vm_resources.first.status).to eq(ServiceResource::STATUS_ACTIVE) + expect(plan.vm_resources.find_by(:resource => task.source).status).to eq(ServiceResource::STATUS_ACTIVE) end end describe 'task_finished' do it 'sets vm_request status to Completed' do task.task_finished - expect(plan.vm_resources.first.status).to eq(ServiceResource::STATUS_COMPLETED) + expect(plan.vm_resources.find_by(:resource => task.source).status).to eq(ServiceResource::STATUS_COMPLETED) end end