From 7e7c7b89753cd281dfad56a6be59b3b7fb12b152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Kom=C3=A1nek?= Date: Tue, 10 Jul 2018 13:27:51 +0200 Subject: [PATCH 1/4] best_fit_azure method refactoring with the new spec. --- .../__methods__/best_fit_azure.rb | 84 +++++++++++++------ .../__methods__/best_fit_azure_spec.rb | 47 +++++++++++ 2 files changed, 105 insertions(+), 26 deletions(-) create mode 100644 spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_azure_spec.rb diff --git a/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_azure.rb b/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_azure.rb index a8386ffa4..03287e80d 100644 --- a/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_azure.rb +++ b/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_azure.rb @@ -1,37 +1,69 @@ ################################################################### -# -# Description: Select the cloud network and availability zone for Azure -# +# # +# Description: Select the cloud network, availability zone # +# and resource group for Azure # +# # ################################################################### +module ManageIQ + module Automate + module Cloud + module VM + module Provisioning + module Placement + class BestFitAzure + def initialize(handle = $evm) + @handle = handle + end -$evm.log("info", "Using Auto Placement for Azure Cloud Provider") -prov = $evm.root["miq_provision"] -image = prov.vm_template -raise "Image not specified" if image.nil? + def main + @handle.log("info", "Using Auto Placement for Azure Cloud Provider") + raise "Image not specified" if prov.try(:vm_template).nil? -if prov.get_option(:cloud_network).nil? - cloud_network = prov.eligible_cloud_networks.first + prov.get_option(:cloud_network) || default_cloud_network + prov.get_option(:cloud_subnet) || default_cloud_subnet + prov.get_option(:resource_group) || default_resource_group + end - if cloud_network - prov.set_cloud_network(cloud_network) - $evm.log("info", "Selected Cloud Network: #{cloud_network.name}") - end -end + private -if prov.get_option(:cloud_subnet).nil? - cloud_subnet = prov.eligible_cloud_subnets.first + def prov + @prov ||= @handle.root["miq_provision"].tap do |req| + raise "miq_provision not provided" unless req + end + end - if cloud_subnet - prov.set_cloud_subnet(cloud_subnet) - $evm.log("info", "Selected Cloud Subnet: #{cloud_subnet.name}") - end -end + def default_cloud_network + cloud_network = prov.eligible_cloud_networks.first -if prov.get_option(:resource_group).nil? - resource_group = prov.eligible_resource_groups.first + if cloud_network + prov.set_cloud_network(cloud_network) + @handle.log("info", "Selected Cloud Network: #{cloud_network.name}") + end + end - if resource_group - prov.set_resource_group(resource_group) - $evm.log("info", "Selected Resource Group: #{resource_group.name}") + def default_cloud_subnet + cloud_subnet = prov.eligible_cloud_subnets.first + + if cloud_subnet + prov.set_cloud_subnet(cloud_subnet) + @handle.log("info", "Selected Cloud Subnet: #{cloud_subnet.name}") + end + end + + def default_resource_group + resource_group = prov.eligible_resource_groups.first + + if resource_group + prov.set_resource_group(resource_group) + @handle.log("info", "Selected Resource Group: #{resource_group.name}") + end + end + end + end + end + end + end end end + +ManageIQ::Automate::Cloud::VM::Provisioning::Placement::BestFitAzure.new.main diff --git a/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_azure_spec.rb b/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_azure_spec.rb new file mode 100644 index 000000000..199b75b82 --- /dev/null +++ b/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_azure_spec.rb @@ -0,0 +1,47 @@ +require_domain_file + +describe ManageIQ::Automate::Cloud::VM::Provisioning::Placement::BestFitAzure do + let(:root_object) { Spec::Support::MiqAeMockObject.new.tap { |ro| ro["miq_provision"] = svc_provision } } + let(:ems) { FactoryGirl.create(:ems_azure_with_authentication) } + let(:network) { FactoryGirl.create(:cloud_network) } + let(:subnet) { FactoryGirl.create(:cloud_subnet) } + let(:prov_options) { { :src_vm_id => vm_template.id } } + let(:miq_provision) { FactoryGirl.create(:miq_provision, :options => prov_options) } + let(:vm_template) { FactoryGirl.create(:template_azure, :ext_management_system => ems) } + let(:resource_group) { FactoryGirl.create(:resource_group) } + + let(:ae_service) do + Spec::Support::MiqAeMockService.new(root_object).tap do |service| + current_object = Spec::Support::MiqAeMockObject.new + current_object.parent = root_object + service.object = current_object + end + end + + let(:svc_provision) { MiqAeMethodService::MiqAeServiceMiqProvision.find(miq_provision.id) } + let(:svc_network) { MiqAeMethodService::MiqAeServiceCloudNetwork.find(network.id) } + let(:svc_subnet) { MiqAeMethodService::MiqAeServiceCloudSubnet.find(subnet.id) } + let(:svc_resource_group) { MiqAeMethodService::MiqAeServiceResourceGroup.find(resource_group.id) } + + it "sets properties" do + expect(svc_provision).to(receive(:eligible_cloud_networks) { [svc_network] }) + expect(svc_provision).to(receive(:eligible_cloud_subnets) { [svc_subnet] }) + expect(svc_provision).to(receive(:eligible_resource_groups) { [svc_resource_group] }) + expect(svc_provision).to(receive(:set_cloud_network).with(svc_network)) + expect(svc_provision).to(receive(:set_cloud_subnet).with(svc_subnet)) + expect(svc_provision).to(receive(:set_resource_group).with(svc_resource_group)) + described_class.new(ae_service).main + end + + context 'raises error' do + it "#'miq_provision not provided'" do + root_object['miq_provision'] = nil + expect { described_class.new(ae_service).main }.to(raise_error('miq_provision not provided')) + end + + it "#'Image not specified'" do + allow(svc_provision).to(receive(:vm_template) { nil }) + expect { described_class.new(ae_service).main }.to(raise_error('Image not specified')) + end + end +end From c9639abc75b252545295a9417e76406ac7892b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Kom=C3=A1nek?= Date: Tue, 10 Jul 2018 13:28:45 +0200 Subject: [PATCH 2/4] best_fit_google method refactoring with the new spec. --- .../__methods__/best_fit_google.rb | 76 +++++++++++++------ .../__methods__/best_fit_google_spec.rb | 44 +++++++++++ 2 files changed, 97 insertions(+), 23 deletions(-) create mode 100644 spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_google_spec.rb diff --git a/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_google.rb b/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_google.rb index f61b9489e..2ac5d8839 100644 --- a/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_google.rb +++ b/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_google.rb @@ -1,27 +1,57 @@ -################################################################### -# -# Description: Select the cloud network and availability zone for Google -# -################################################################### - -prov = $evm.root["miq_provision"] -image = prov.vm_template -raise "Image not specified" if image.nil? - -if prov.get_option(:availability_zone).nil? - availability_zone = prov.eligible_availability_zones.first - - if availability_zone - prov.set_availability_zone(availability_zone) - $evm.log("info", "Image=[#{image.name}] Availability Zone=[#{availability_zone.name}]") - end -end +########################################################################## +# # +# Description: Select the cloud network and availability zone for Google # +# # +########################################################################## +module ManageIQ + module Automate + module Cloud + module VM + module Provisioning + module Placement + class BestFitGoogle + def initialize(handle = $evm) + @handle = handle + end + + def main + raise "Image not specified" if prov.try(:vm_template).nil? + + set_availability_zone if prov.get_option(:availability_zone).nil? + set_cloud_network if prov.get_option(:cloud_network).nil? + end + + private -if prov.get_option(:cloud_network).nil? - cloud_network = prov.eligible_cloud_networks.first + def prov + @prov ||= @handle.root["miq_provision"].tap do |req| + raise "miq_provision not provided" unless req + end + end - if cloud_network - prov.set_cloud_network(cloud_network) - $evm.log("info", "Image=[#{image.name}] Cloud Network=[#{cloud_network.name}]") + def set_availability_zone + availability_zone = prov.eligible_availability_zones.first + + if availability_zone + prov.set_availability_zone(availability_zone) + @handle.log("info", "Image=[#{prov.vm_template.name}] Availability Zone=[#{availability_zone.name}]") + end + end + + def set_cloud_network + cloud_network = prov.eligible_cloud_networks.first + + if cloud_network + prov.set_cloud_network(cloud_network) + @handle.log("info", "Image=[#{prov.vm_template.name}] Cloud Network=[#{cloud_network.name}]") + end + end + end + end + end + end + end end end + +ManageIQ::Automate::Cloud::VM::Provisioning::Placement::BestFitGoogle.new.main diff --git a/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_google_spec.rb b/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_google_spec.rb new file mode 100644 index 000000000..bb25e1798 --- /dev/null +++ b/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_google_spec.rb @@ -0,0 +1,44 @@ +require_domain_file + +describe ManageIQ::Automate::Cloud::VM::Provisioning::Placement::BestFitGoogle do + let(:root_object) { Spec::Support::MiqAeMockObject.new.tap { |ro| ro["miq_provision"] = svc_provision } } + let(:ems) { FactoryGirl.create(:ems_google_with_authentication) } + let(:network) { FactoryGirl.create(:cloud_network) } + let(:prov_options) { { :src_vm_id => vm_template.id } } + let(:miq_provision) { FactoryGirl.create(:miq_provision, :options => prov_options) } + let(:vm_template) { FactoryGirl.create(:template_google, :ext_management_system => ems) } + let(:availability_zone) { FactoryGirl.create(:availability_zone) } + + let(:ae_service) do + Spec::Support::MiqAeMockService.new(root_object).tap do |service| + current_object = Spec::Support::MiqAeMockObject.new + current_object.parent = root_object + service.object = current_object + end + end + + let(:svc_provision) { MiqAeMethodService::MiqAeServiceMiqProvision.find(miq_provision.id) } + let(:svc_network) { MiqAeMethodService::MiqAeServiceCloudNetwork.find(network.id) } + let(:svc_zone) { MiqAeMethodService::MiqAeServiceAvailabilityZone.find(availability_zone.id) } + + it "sets properties" do + expect(svc_provision).to receive(:eligible_cloud_networks) { [svc_network] } + expect(svc_provision).to receive(:eligible_availability_zones) { [svc_zone] } + expect(svc_provision).to receive(:set_cloud_network).with(svc_network) + expect(svc_provision).to receive(:set_availability_zone).with(svc_zone) + + described_class.new(ae_service).main + end + + context 'raises exception' do + it '#miq_provision not provided' do + ae_service.root["miq_provision"] = nil + expect { described_class.new(ae_service).main }.to(raise_error('miq_provision not provided')) + end + + it '#Image not specified' do + allow(svc_provision).to(receive(:vm_template) { nil }) + expect { described_class.new(ae_service).main }.to(raise_error('Image not specified')) + end + end +end From 238f696930a996a4c039db3f921affe0437e8005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Kom=C3=A1nek?= Date: Tue, 10 Jul 2018 13:29:34 +0200 Subject: [PATCH 3/4] bets_fit_openstack method refactoring with the new spec. --- .../__methods__/best_fit_openstack.rb | 54 ++++++++++++++----- .../__methods__/best_fit_openstack_spec.rb | 40 ++++++++++++++ 2 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_openstack_spec.rb diff --git a/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_openstack.rb b/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_openstack.rb index 785305a58..bc90ee30f 100644 --- a/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_openstack.rb +++ b/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_openstack.rb @@ -1,19 +1,47 @@ ################################################################### -# -# Description: select the cloud network -# Default availability zone is provided by Openstack -# +# # +# Description: Select the cloud network # +# Default availability zone is provided by Openstack # +# # ################################################################### +module ManageIQ + module Automate + module Cloud + module VM + module Provisioning + module Placement + class BestFitOpenStack + def initialize(handle = $evm) + @handle = handle + end -# Get variables -prov = $evm.root["miq_provision"] -image = prov.vm_template -raise "Image not specified" if image.nil? + def main + raise "Image not specified" if prov.try(:vm_template).nil? + set_cloud_network if prov.get_option(:cloud_network).nil? + end -if prov.get_option(:cloud_network).nil? - cloud_network = prov.eligible_cloud_networks.first - if cloud_network - prov.set_cloud_network(cloud_network) - $evm.log("info", "Image=[#{image.name}] Cloud Network=[#{cloud_network.name}]") + private + + def prov + @prov ||= @handle.root["miq_provision"].tap do |req| + raise "miq_provision not provided" unless req + end + end + + def set_cloud_network + cloud_network = prov.eligible_cloud_networks.first + + if cloud_network + prov.set_cloud_network(cloud_network) + @handle.log("info", "Image=[#{prov.vm_template.name}] Cloud Network=[#{cloud_network.name}]") + end + end + end + end + end + end + end end end + +ManageIQ::Automate::Cloud::VM::Provisioning::Placement::BestFitOpenStack.new.main diff --git a/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_openstack_spec.rb b/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_openstack_spec.rb new file mode 100644 index 000000000..cd35f38b5 --- /dev/null +++ b/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_openstack_spec.rb @@ -0,0 +1,40 @@ +require_domain_file + +describe ManageIQ::Automate::Cloud::VM::Provisioning::Placement::BestFitOpenStack do + let(:root_object) { Spec::Support::MiqAeMockObject.new.tap { |ro| ro["miq_provision"] = svc_provision } } + let(:ems) { FactoryGirl.create(:ems_google_with_authentication) } + let(:network) { FactoryGirl.create(:cloud_network) } + let(:prov_options) { { :src_vm_id => vm_template.id } } + let(:miq_provision) { FactoryGirl.create(:miq_provision, :options => prov_options) } + let(:vm_template) { FactoryGirl.create(:template_google, :ext_management_system => ems) } + + let(:ae_service) do + Spec::Support::MiqAeMockService.new(root_object).tap do |service| + current_object = Spec::Support::MiqAeMockObject.new + current_object.parent = root_object + service.object = current_object + end + end + + let(:svc_provision) { MiqAeMethodService::MiqAeServiceMiqProvision.find(miq_provision.id) } + let(:svc_network) { MiqAeMethodService::MiqAeServiceCloudNetwork.find(network.id) } + + it "sets cloud_network" do + expect(svc_provision).to(receive(:eligible_cloud_networks) { [svc_network] }) + expect(svc_provision).to(receive(:set_cloud_network).with(svc_network)) + + described_class.new(ae_service).main + end + + context 'raises exception' do + it '#miq_provision not provided' do + ae_service.root["miq_provision"] = nil + expect { described_class.new(ae_service).main }.to(raise_error('miq_provision not provided')) + end + + it '#Image not specified' do + allow(svc_provision).to(receive(:vm_template) { nil }) + expect { described_class.new(ae_service).main }.to(raise_error('Image not specified')) + end + end +end From a86d5c260f1c059730c5211fcdb6f76b72de1df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Kom=C3=A1nek?= Date: Tue, 10 Jul 2018 13:31:33 +0200 Subject: [PATCH 4/4] best_fit_amazon spec rename and adding a missing test. --- .../{best_fit_amazon.rb => best_fit_amazon_spec.rb} | 11 +++++++++++ 1 file changed, 11 insertions(+) rename spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/{best_fit_amazon.rb => best_fit_amazon_spec.rb} (81%) diff --git a/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_amazon.rb b/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_amazon_spec.rb similarity index 81% rename from spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_amazon.rb rename to spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_amazon_spec.rb index 0f76ec3fc..bcdbc010a 100644 --- a/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_amazon.rb +++ b/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_amazon_spec.rb @@ -32,6 +32,17 @@ described_class.new(ae_service).main end + context 'skips setting properties' do + let(:flavor) { FactoryGirl.create(:flavor, :name => 'flavor1', :cloud_subnet_required => false) } + + it '#cloud subnet is not required' do + expect(ae_service).to(receive(:log).with("debug", "instance id=#{svc_flavor.id} name=#{svc_flavor.name}")) + expect(ae_service).to(receive(:log).with("info", "Using EC2 for default placement of instance type=[#{svc_flavor.name}]")) + + described_class.new(ae_service).main + end + end + it "should raise 'Image not specified'" do allow(svc_provision).to receive(:vm_template) { nil } expect { described_class.new(ae_service).main }.to raise_error('Image not specified')