Skip to content

Commit

Permalink
Merge pull request #63 from pkomanek/refactoring_cloud_vm_provisionin…
Browse files Browse the repository at this point in the history
…g_placement/best_fit_amazon_method

Refactoring and fixing cloud/vm/provisioning/placement/best_fit_amazon method.
  • Loading branch information
mkanoor authored Mar 7, 2017
2 parents 48c7a21 + a522fc9 commit 018e6b5
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 018e6b5

Please sign in to comment.