diff --git a/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_amazon.rb b/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_amazon.rb index 8effb9da6..f850615e1 100644 --- a/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_amazon.rb +++ b/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_amazon.rb @@ -24,32 +24,63 @@ # For other instance types EC2 provides the defaults. # This method checks the instance types and sets the VPC and subnet for T2 and C4 instances # +module ManageIQ + module Automate + module Cloud + module VM + module Provisioning + module Placement + class BestFitAmazon + def initialize(handle = $evm) + @handle = handle + end -def set_property(prov, image, list_method, property) - return if prov.get_option(property) - result = prov.send(list_method) - $evm.log("debug", "#{property} #{result.inspect}") - object = result.try(:first) - return unless object + def main + prov, image, flavor = variables - prov.send("set_#{property}", object) - $evm.log("info", "Image=[#{image.name}] #{property}=[#{object.name}]") + if flavor.try(:cloud_subnet_required) + @handle.log("info", "Setting VPC parameters for instance type=[#{flavor.name}]") + set_property(prov, image, :eligible_cloud_networks, :cloud_network) + set_property(prov, image, :eligible_cloud_subnets, :cloud_subnet) + else + @handle.log("info", "Using EC2 for default placement of instance type=[#{flavor.try(:name)}]") + end + end + + private + + def variables + prov = @handle.root["miq_provision"] + image = prov.try(:vm_template) + raise "Image not specified" if image.nil? + + instance_id = prov.get_option(:instance_type) + raise "Instance Type not specified" if instance_id.nil? + + flavor = @handle.vmdb('flavor').find_by(:id => instance_id) + @handle.log("debug", "instance id=#{instance_id} name=#{flavor.try(:name)}") + + return prov, image, flavor + end + + def set_property(prov, image, list_method, property) + return if prov.get_option(property) + result = prov.send(list_method) + @handle.log("debug", "#{property} #{result.inspect}") + object = result.try(:first) + return unless object + + prov.send("set_#{property}", object) + @handle.log("info", "Image=[#{image.name}] #{property}=[#{object.name}]") + end + end + end + end + end + end + end end -# Get variables -prov = $evm.root["miq_provision"] -image = prov.vm_template -raise "Image not specified" if image.nil? - -instance_id = prov.get_option(:instance_type) -raise "Instance Type not specified" if instance_id.nil? -flavor = $evm.vmdb('flavor').find(instance_id) -$evm.log("debug", "instance id=#{instance_id} name=#{flavor.try(:name)}") - -if flavor.try(:cloud_subnet_required) - $evm.log("info", "Setting VPC parameters for instance type=[#{flavor.name}]") - set_property(prov, image, :eligible_cloud_networks, :cloud_network) - set_property(prov, image, :eligible_cloud_subnets, :cloud_subnet) -else - $evm.log("info", "Using EC2 for default placement of instance type=[#{flavor.try(:name)}]") +if __FILE__ == $PROGRAM_NAME + ManageIQ::Automate::Cloud::VM::Provisioning::Placement::BestFitAmazon.new.main end 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.rb new file mode 100644 index 000000000..0f76ec3fc --- /dev/null +++ b/spec/content/automate/ManageIQ/Cloud/VM/Provisioning/Placement.class/__methods__/best_fit_amazon.rb @@ -0,0 +1,44 @@ +require_domain_file + +describe ManageIQ::Automate::Cloud::VM::Provisioning::Placement::BestFitAmazon do + let(:root_object) { Spec::Support::MiqAeMockObject.new.tap { |ro| ro["miq_provision"] = svc_provision } } + let(:flavor) { FactoryGirl.create(:flavor, :name => 'flavor1', :cloud_subnet_required => true) } + let(:ems) { FactoryGirl.create(:ems_amazon_with_authentication) } + let(:network) { FactoryGirl.create(:cloud_network) } + let(:subnet) { FactoryGirl.create(:cloud_subnet) } + let(:prov_options) { { :src_vm_id => vm_template.id, :instance_type => flavor.id } } + let(:miq_provision) { FactoryGirl.create(:miq_provision, :options => prov_options) } + let(:vm_template) { FactoryGirl.create(:template_amazon, :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_flavor) { MiqAeMethodService::MiqAeServiceFlavor.find(flavor.id) } + let(:svc_network) { MiqAeMethodService::MiqAeServiceCloudNetwork.find(network.id) } + let(:svc_subnet) { MiqAeMethodService::MiqAeServiceCloudSubnet.find(subnet.id) } + + it "setting 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(:set_cloud_network).with(svc_network) + expect(svc_provision).to receive(:set_cloud_subnet).with(svc_subnet) + + described_class.new(ae_service).main + 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') + end + + it "should raise 'Instance Type not specified'" do + prov_options[:instance_type] = nil + expect { described_class.new(ae_service).main }.to raise_error('Instance Type not specified') + end +end