1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00
fog--fog/lib/fog/vsphere/requests/compute/vm_clone.rb
Jeff McCune 743882f032 Refactor requests to return simple hashes and add unit tests
This massive commit refactors all of the request methods on the
Fog::Compute[:vsphere] instance to return simple hashes.  The behavior
before this commit returned full vmware object references which was a
problem because it was difficult to unit test.

With this patch, it is much easier to add and maintain Mock
implementations of the request methods.  This makes adding behavior
tests for the server model much easier.

In addition, test coverage using Shindo has been added.  Previously
there was little test coverage of the behavior.

To run the tests:

    shindont tests/vsphere/
2011-09-10 15:11:18 -07:00

91 lines
3.5 KiB
Ruby

module Fog
module Compute
class Vsphere
module Shared
private
def vm_clone_check_options(options)
options = { 'force' => false }.merge(options)
required_options = %w{ instance_uuid name }
required_options.each do |param|
raise ArgumentError, "#{required_options.join(', ')} are required" unless options.has_key? param
end
# First, figure out if there's already a VM of the same name.
all_virtual_machines = list_virtual_machines['virtual_machines']
if not options['force'] and all_virtual_machines.detect { |vm| vm['name'] == options['name'] } then
raise Fog::Vsphere::Errors::ServiceError, "A VM already exists with name #{options['name']}"
end
options
end
end
class Real
include Shared
def vm_clone(options = {})
# Option handling
options = vm_clone_check_options(options)
# REVISIT: This will have horrible performance for large sites.
# Find the Managed Object reference of the template VM (Wish I could do this with the API)
vm_mob_ref = list_all_virtual_machine_mobs.find do |vm|
convert_vm_mob_ref_to_attr_hash(vm)['instance_uuid'] == options['instance_uuid']
end
# We need to locate the datacenter object to find the
# default resource pool.
container = vm_mob_ref.parent
until container.kind_of? RbVmomi::VIM::Datacenter
container = container.parent
end
dc = container
# With the Datacenter Object we can obtain the resource pool
resource_pool = dc.hostFolder.children.first.resourcePool
# Next, create a Relocation Spec instance
relocation_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => resource_pool,
:transform => options['transform'] || 'sparse')
# And the clone specification
clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(:location => relocation_spec,
:powerOn => options['power_on'] || true,
:template => false)
task = vm_mob_ref.CloneVM_Task(:folder => vm_mob_ref.parent, :name => options['name'], :spec => clone_spec)
# REVISIT: The task object contains a reference to the template but does
# not appear to contain a reference to the newly created VM.
# This is a really naive way to find the managed object reference
# of the newly created VM.
tries = 0
new_vm = begin
list_virtual_machines['virtual_machines'].detect(lambda { raise Fog::Vsphere::Errors::NotFound }) do |vm|
vm['name'] == options['name']
end
rescue Fog::Vsphere::Errors::NotFound
tries += 1
if tries <= 10 then
sleep 1
retry
end
nil
end
# Return hash
{
'vm_ref' => new_vm ? new_vm['mo_ref'] : nil,
'task_ref' => task._ref
}
end
end
class Mock
include Shared
def vm_clone(options = {})
# Option handling
options = vm_clone_check_options(options)
{
'vm_ref' => 'vm-123',
'task_ref' => 'task-1234'
}
end
end
end
end
end