mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
Merge pull request #1272 from ohadlevy/vmware
VMWare vsphere provider refactor
This commit is contained in:
commit
f9b729eb69
50 changed files with 1526 additions and 462 deletions
|
@ -11,19 +11,50 @@ module Fog
|
|||
model_path 'fog/vsphere/models/compute'
|
||||
model :server
|
||||
collection :servers
|
||||
model :datacenter
|
||||
collection :datacenters
|
||||
model :interface
|
||||
collection :interfaces
|
||||
model :volume
|
||||
collection :volumes
|
||||
model :template
|
||||
collection :templates
|
||||
model :cluster
|
||||
collection :clusters
|
||||
model :resource_pool
|
||||
collection :resource_pools
|
||||
model :network
|
||||
collection :networks
|
||||
model :datastore
|
||||
collection :datastores
|
||||
model :folder
|
||||
collection :folders
|
||||
|
||||
request_path 'fog/vsphere/requests/compute'
|
||||
request :current_time
|
||||
request :find_vm_by_ref
|
||||
request :list_virtual_machines
|
||||
request :vm_power_off
|
||||
request :vm_power_on
|
||||
request :vm_reboot
|
||||
request :vm_clone
|
||||
request :vm_create
|
||||
request :vm_destroy
|
||||
request :vm_migrate
|
||||
request :datacenters
|
||||
request :list_datacenters
|
||||
request :get_datacenter
|
||||
request :list_clusters
|
||||
request :get_cluster
|
||||
request :list_resource_pools
|
||||
request :get_resource_pool
|
||||
request :list_networks
|
||||
request :get_network
|
||||
request :list_datastores
|
||||
request :get_datastore
|
||||
request :get_folder
|
||||
request :list_folders
|
||||
request :create_vm
|
||||
request :list_vm_interfaces
|
||||
request :list_vm_volumes
|
||||
request :get_virtual_machine
|
||||
request :vm_reconfig_hardware
|
||||
request :vm_reconfig_memory
|
||||
request :vm_reconfig_cpus
|
||||
|
@ -36,11 +67,12 @@ module Fog
|
|||
attr_reader :vsphere_server
|
||||
attr_reader :vsphere_username
|
||||
|
||||
protected
|
||||
|
||||
ATTR_TO_PROP = {
|
||||
:id => 'config.instanceUuid',
|
||||
:name => 'name',
|
||||
:uuid => 'config.uuid',
|
||||
:instance_uuid => 'config.instanceUuid',
|
||||
:hostname => 'summary.guest.hostName',
|
||||
:operatingsystem => 'summary.guest.guestFullName',
|
||||
:ipaddress => 'guest.ipAddress',
|
||||
|
@ -49,9 +81,10 @@ module Fog
|
|||
:hypervisor => 'runtime.host',
|
||||
:tools_state => 'guest.toolsStatus',
|
||||
:tools_version => 'guest.toolsVersionStatus',
|
||||
:is_a_template => 'config.template',
|
||||
:memory_mb => 'config.hardware.memoryMB',
|
||||
:cpus => 'config.hardware.numCPU',
|
||||
:overall_status => 'overallStatus',
|
||||
:guest_id => 'summary.guest.guestId',
|
||||
}
|
||||
|
||||
# Utility method to convert a VMware managed object into an attribute hash.
|
||||
|
@ -75,9 +108,17 @@ module Fog
|
|||
attrs['mo_ref'] = vm_mob_ref._ref
|
||||
# The name method "magically" appears after a VM is ready and
|
||||
# finished cloning.
|
||||
if attrs['hypervisor'].kind_of?(RbVmomi::VIM::HostSystem) then
|
||||
# If it's not ready, set the hypervisor to nil
|
||||
attrs['hypervisor'] = attrs['hypervisor'].name rescue nil
|
||||
if attrs['hypervisor'].kind_of?(RbVmomi::VIM::HostSystem)
|
||||
begin
|
||||
host = attrs['hypervisor']
|
||||
attrs['datacenter'] = parent_attribute(host.path, :datacenter)[1]
|
||||
attrs['cluster'] = parent_attribute(host.path, :cluster)[1]
|
||||
attrs['hypervisor'] = host.name
|
||||
attrs['resource_pool'] = (vm_mob_ref.resourcePool || host.resourcePool).name rescue nil
|
||||
rescue
|
||||
# If it's not ready, set the hypervisor to nil
|
||||
attrs['hypervisor'] = nil
|
||||
end
|
||||
end
|
||||
# This inline rescue catches any standard error. While a VM is
|
||||
# cloning, a call to the macs method will throw and NoMethodError
|
||||
|
@ -86,6 +127,31 @@ module Fog
|
|||
end
|
||||
end
|
||||
|
||||
# returns the parent object based on a type
|
||||
# provides both real RbVmomi object and its name.
|
||||
# e.g.
|
||||
#[Datacenter("datacenter-2"), "dc-name"]
|
||||
def parent_attribute path, type
|
||||
element = case type
|
||||
when :datacenter
|
||||
RbVmomi::VIM::Datacenter
|
||||
when :cluster
|
||||
RbVmomi::VIM::ClusterComputeResource
|
||||
when :host
|
||||
RbVmomi::VIM::HostSystem
|
||||
else
|
||||
raise "Unknown type"
|
||||
end
|
||||
path.select {|x| x[0].is_a? element}.flatten
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
|
||||
# returns vmware managed obj id string
|
||||
def managed_obj_id obj
|
||||
obj.to_s.match(/\("(\S+)"\)/)[1]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
|
|
31
lib/fog/vsphere/models/compute/cluster.rb
Normal file
31
lib/fog/vsphere/models/compute/cluster.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Cluster < Fog::Model
|
||||
|
||||
identity :id
|
||||
|
||||
attribute :name
|
||||
attribute :datacenter
|
||||
attribute :num_host
|
||||
attribute :num_cpu_cores
|
||||
attribute :overall_status
|
||||
|
||||
def resource_pools(filters = { })
|
||||
self.attributes[:resource_pools] ||= id.nil? ? [] : connection.resource_pools({
|
||||
:connection => connection,
|
||||
:cluster => name,
|
||||
:datacenter => datacenter
|
||||
}.merge(filters))
|
||||
end
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
26
lib/fog/vsphere/models/compute/clusters.rb
Normal file
26
lib/fog/vsphere/models/compute/clusters.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/vsphere/models/compute/cluster'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Clusters < Fog::Collection
|
||||
|
||||
model Fog::Compute::Vsphere::Cluster
|
||||
attr_accessor :datacenter
|
||||
|
||||
def all(filters = {})
|
||||
requires :datacenter
|
||||
load connection.list_clusters(filters.merge(:datacenter => datacenter))
|
||||
end
|
||||
|
||||
def get(id)
|
||||
requires :datacenter
|
||||
new connection.get_cluster(id, datacenter)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
35
lib/fog/vsphere/models/compute/datacenter.rb
Normal file
35
lib/fog/vsphere/models/compute/datacenter.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Datacenter < Fog::Model
|
||||
|
||||
identity :id
|
||||
attribute :name
|
||||
attribute :status
|
||||
|
||||
def clusters filters = { }
|
||||
connection.clusters({ :datacenter => name }.merge(filters))
|
||||
end
|
||||
|
||||
def networks filters = { }
|
||||
connection.networks({ :datacenter => name }.merge(filters))
|
||||
end
|
||||
|
||||
def datastores filters = { }
|
||||
connection.datastores({ :datacenter => name }.merge(filters))
|
||||
end
|
||||
|
||||
def vm_folders filters = { }
|
||||
connection.folders({ :datacenter => name, :type => :vm }.merge(filters))
|
||||
end
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
23
lib/fog/vsphere/models/compute/datacenters.rb
Normal file
23
lib/fog/vsphere/models/compute/datacenters.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/vsphere/models/compute/datacenter'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Datacenters < Fog::Collection
|
||||
|
||||
model Fog::Compute::Vsphere::Datacenter
|
||||
|
||||
def all(filters = {})
|
||||
load connection.list_datacenters(filters)
|
||||
end
|
||||
|
||||
def get(name)
|
||||
new connection.get_datacenter(name)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
24
lib/fog/vsphere/models/compute/datastore.rb
Normal file
24
lib/fog/vsphere/models/compute/datastore.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Datastore < Fog::Model
|
||||
|
||||
identity :id
|
||||
|
||||
attribute :name
|
||||
attribute :datacenter
|
||||
attribute :type
|
||||
attribute :freespace
|
||||
attribute :accessible # reachable by at least one hypervisor
|
||||
attribute :capacity
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
25
lib/fog/vsphere/models/compute/datastores.rb
Normal file
25
lib/fog/vsphere/models/compute/datastores.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/vsphere/models/compute/datastore'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Datastores < Fog::Collection
|
||||
|
||||
model Fog::Compute::Vsphere::Datastore
|
||||
attr_accessor :datacenter
|
||||
|
||||
def all(filters = {})
|
||||
load connection.list_datastores(filters.merge(:datacenter => datacenter))
|
||||
end
|
||||
|
||||
def get(id)
|
||||
requires :datacenter
|
||||
new connection.get_datastore(id, datacenter)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
28
lib/fog/vsphere/models/compute/folder.rb
Normal file
28
lib/fog/vsphere/models/compute/folder.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Folder < Fog::Model
|
||||
|
||||
identity :id
|
||||
|
||||
attribute :name
|
||||
attribute :parent
|
||||
attribute :datacenter
|
||||
attribute :path
|
||||
attribute :type
|
||||
|
||||
def vms
|
||||
return [] if type.to_s != 'vm'
|
||||
connection.servers(:folder => path, :datacenter => datacenter)
|
||||
end
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
27
lib/fog/vsphere/models/compute/folders.rb
Normal file
27
lib/fog/vsphere/models/compute/folders.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/vsphere/models/compute/folder'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Folders < Fog::Collection
|
||||
|
||||
model Fog::Compute::Vsphere::Folder
|
||||
attr_accessor :datacenter, :type, :path
|
||||
|
||||
def all(filters = { })
|
||||
requires :datacenter
|
||||
requires :type
|
||||
load connection.list_folders(filters.merge(:datacenter => datacenter, :type => type, :path => path))
|
||||
end
|
||||
|
||||
def get(id)
|
||||
requires :datacenter
|
||||
new connection.get_folder(id, datacenter, type)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
39
lib/fog/vsphere/models/compute/interface.rb
Normal file
39
lib/fog/vsphere/models/compute/interface.rb
Normal file
|
@ -0,0 +1,39 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Interface < Fog::Model
|
||||
|
||||
identity :mac
|
||||
|
||||
attribute :network
|
||||
attribute :name
|
||||
attribute :status
|
||||
attribute :summary
|
||||
attribute :type
|
||||
|
||||
def initialize(attributes={} )
|
||||
super defaults.merge(attributes)
|
||||
end
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def defaults
|
||||
{
|
||||
:name=>"Network adapter",
|
||||
:network=>"VM Network",
|
||||
:summary=>"VM Network",
|
||||
:type=> RbVmomi::VIM::VirtualE1000,
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
33
lib/fog/vsphere/models/compute/interfaces.rb
Normal file
33
lib/fog/vsphere/models/compute/interfaces.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/vsphere/models/compute/interface'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Interfaces < Fog::Collection
|
||||
|
||||
model Fog::Compute::Vsphere::Interface
|
||||
|
||||
attr_accessor :vm
|
||||
|
||||
def all(filters = {})
|
||||
requires :vm
|
||||
case vm
|
||||
when Fog::Compute::Vsphere::Server
|
||||
load connection.list_vm_interfaces(vm.id)
|
||||
when Fog::Compute::Vsphere::Template
|
||||
load connection.list_template_interfaces(vm.id)
|
||||
else
|
||||
raise 'interfaces should have vm or template'
|
||||
end
|
||||
end
|
||||
|
||||
def get(id)
|
||||
new connection.get_interface(id)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
21
lib/fog/vsphere/models/compute/network.rb
Normal file
21
lib/fog/vsphere/models/compute/network.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Network < Fog::Model
|
||||
|
||||
identity :id
|
||||
|
||||
attribute :name
|
||||
attribute :datacenter
|
||||
attribute :accessible # reachable by at least one hypervisor
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
25
lib/fog/vsphere/models/compute/networks.rb
Normal file
25
lib/fog/vsphere/models/compute/networks.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/vsphere/models/compute/network'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Networks < Fog::Collection
|
||||
|
||||
model Fog::Compute::Vsphere::Network
|
||||
attr_accessor :datacenter
|
||||
|
||||
def all(filters = {})
|
||||
load connection.list_networks(filters.merge(:datacenter => datacenter))
|
||||
end
|
||||
|
||||
def get(id)
|
||||
requires :datacenter
|
||||
new connection.get_network(id, datacenter)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
23
lib/fog/vsphere/models/compute/resource_pool.rb
Normal file
23
lib/fog/vsphere/models/compute/resource_pool.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class ResourcePool < Fog::Model
|
||||
|
||||
identity :id
|
||||
|
||||
attribute :name
|
||||
attribute :cluster
|
||||
attribute :datacenter
|
||||
attribute :configured_memory_mb
|
||||
attribute :overall_status
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
26
lib/fog/vsphere/models/compute/resource_pools.rb
Normal file
26
lib/fog/vsphere/models/compute/resource_pools.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/vsphere/models/compute/resource_pool'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class ResourcePools < Fog::Collection
|
||||
|
||||
model Fog::Compute::Vsphere::ResourcePool
|
||||
attr_accessor :datacenter, :cluster
|
||||
|
||||
def all(filters = {})
|
||||
load connection.list_resource_pools(filters.merge(:datacenter => datacenter, :cluster => cluster))
|
||||
end
|
||||
|
||||
def get(id)
|
||||
requires :datacenter
|
||||
requires :cluster
|
||||
new connection.get_resource_pool(id, cluster, datacenter)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -20,8 +20,6 @@ module Fog
|
|||
attribute :name
|
||||
# UUID may be the same from VM to VM if the user does not select (I copied it)
|
||||
attribute :uuid
|
||||
# Instance UUID should be unique across a vCenter deployment.
|
||||
attribute :instance_uuid
|
||||
attribute :hostname
|
||||
attribute :operatingsystem
|
||||
attribute :ipaddress, :aliases => 'public_ip_address'
|
||||
|
@ -30,12 +28,26 @@ module Fog
|
|||
attribute :tools_version
|
||||
attribute :mac_addresses, :aliases => 'macs'
|
||||
attribute :hypervisor, :aliases => 'host'
|
||||
attribute :is_a_template
|
||||
attribute :connection_state
|
||||
attribute :mo_ref
|
||||
attribute :path
|
||||
attribute :memory_mb
|
||||
attribute :cpus
|
||||
attribute :interfaces
|
||||
attribute :volumes
|
||||
attribute :overall_status, :aliases => 'status'
|
||||
attribute :cluster
|
||||
attribute :datacenter
|
||||
attribute :resource_pool
|
||||
attribute :instance_uuid # move this --> id
|
||||
attribute :guest_id
|
||||
|
||||
def initialize(attributes={} )
|
||||
super defaults.merge(attributes)
|
||||
self.instance_uuid ||= id # TODO: remvoe instance_uuid as it can be replaced with simple id
|
||||
initialize_interfaces
|
||||
initialize_volumes
|
||||
end
|
||||
|
||||
def vm_reconfig_memory(options = {})
|
||||
requires :instance_uuid, :memory
|
||||
|
@ -81,16 +93,8 @@ module Fog
|
|||
connection.vm_migrate('instance_uuid' => instance_uuid, 'priority' => options[:priority])
|
||||
end
|
||||
|
||||
def create(options ={})
|
||||
requires :name, :path
|
||||
new_vm = self.class.new(create_results['vm_attributes'])
|
||||
new_vm.collection = self.collection
|
||||
new_vm.connection = self.connection
|
||||
new_vm
|
||||
end
|
||||
|
||||
def clone(options = {})
|
||||
requires :name, :path
|
||||
requires :name, :datacenter
|
||||
# Convert symbols to strings
|
||||
req_options = options.inject({}) { |hsh, (k,v)| hsh[k.to_s] = v; hsh }
|
||||
# Give our path to the request
|
||||
|
@ -131,6 +135,60 @@ module Fog
|
|||
memory_mb * 1024 * 1024
|
||||
end
|
||||
|
||||
def mac
|
||||
interfaces.first.mac unless interfaces.empty?
|
||||
end
|
||||
|
||||
def interfaces
|
||||
attributes[:interfaces] ||= id.nil? ? [] : connection.interfaces( :vm => self )
|
||||
end
|
||||
|
||||
def volumes
|
||||
attributes[:volumes] ||= id.nil? ? [] : connection.volumes( :vm => self )
|
||||
end
|
||||
|
||||
def folder
|
||||
return nil unless datacenter and path
|
||||
attributes[:folder] ||= connection.folders(:datacenter => datacenter, :type => :vm).get(path)
|
||||
end
|
||||
|
||||
def save
|
||||
requires :name, :cluster, :datacenter
|
||||
if identity
|
||||
raise "update is not supported yet"
|
||||
# connection.update_vm(attributes)
|
||||
else
|
||||
self.id = connection.create_vm(attributes)
|
||||
end
|
||||
reload
|
||||
end
|
||||
|
||||
def new?
|
||||
id.nil?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def defaults
|
||||
{
|
||||
:cpus => 1,
|
||||
:memory_mb => 512,
|
||||
:guest_id => 'otherGuest',
|
||||
:path => '/'
|
||||
}
|
||||
end
|
||||
|
||||
def initialize_interfaces
|
||||
if attributes[:interfaces] and attributes[:interfaces].is_a?(Array)
|
||||
self.attributes[:interfaces].map! { |nic| nic.is_a?(Hash) ? connection.interfaces.new(nic) : nic }
|
||||
end
|
||||
end
|
||||
|
||||
def initialize_volumes
|
||||
if attributes[:volumes] and attributes[:volumes].is_a?(Array)
|
||||
self.attributes[:volumes].map! { |vol| vol.is_a?(Hash) ? connection.volumes.new(vol) : vol }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -8,30 +8,26 @@ module Fog
|
|||
class Servers < Fog::Collection
|
||||
|
||||
model Fog::Compute::Vsphere::Server
|
||||
attr_accessor :datacenter
|
||||
attr_accessor :network
|
||||
attr_accessor :cluster
|
||||
attr_accessor :resource_pool
|
||||
attr_accessor :folder
|
||||
|
||||
# 'path' => '/Datacenters/vm/Jeff/Templates' will be MUCH faster.
|
||||
# 'folder' => '/Datacenters/vm/Jeff/Templates' will be MUCH faster.
|
||||
# than simply listing everything.
|
||||
def all(filters = {})
|
||||
# REVISIT: I'm not sure if this is the best way to implement search
|
||||
# filters on a collection but it does work. I need to study the AWS
|
||||
# code more to make sure this matches up.
|
||||
filters['folder'] ||= attributes['folder']
|
||||
response = connection.list_virtual_machines(filters)
|
||||
load(response['virtual_machines'])
|
||||
def all(filters = { })
|
||||
load connection.list_virtual_machines(filters.merge(
|
||||
:datacenter => datacenter,
|
||||
:cluster => cluster,
|
||||
:network => network,
|
||||
:resource_pool => resource_pool,
|
||||
:folder => folder
|
||||
))
|
||||
end
|
||||
|
||||
def get(id)
|
||||
# Is the id a managed_object_reference? This may be the case if we're reloading
|
||||
# a model of a VM in the process of being cloned, since it
|
||||
# will not have a instance_uuid yet.
|
||||
if id =~ /^vm-/
|
||||
response = connection.find_vm_by_ref('vm_ref' => id)
|
||||
server_attributes = response['virtual_machine']
|
||||
else
|
||||
response = connection.list_virtual_machines('instance_uuid' => id)
|
||||
server_attributes = response['virtual_machines'].first
|
||||
end
|
||||
new(server_attributes)
|
||||
def get(id, datacenter = nil)
|
||||
new connection.get_virtual_machine id, datacenter
|
||||
rescue Fog::Compute::Vsphere::NotFound
|
||||
nil
|
||||
end
|
||||
|
|
13
lib/fog/vsphere/models/compute/template.rb
Normal file
13
lib/fog/vsphere/models/compute/template.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Template < Fog::Model
|
||||
|
||||
identity :id
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
23
lib/fog/vsphere/models/compute/templates.rb
Normal file
23
lib/fog/vsphere/models/compute/templates.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/vsphere/models/compute/template'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Templates < Fog::Collection
|
||||
|
||||
model Fog::Compute::Vsphere::Template
|
||||
|
||||
def all(filters = {})
|
||||
load connection.list_templates(filters)
|
||||
end
|
||||
|
||||
def get(id)
|
||||
new connection.get_template(id)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
45
lib/fog/vsphere/models/compute/volume.rb
Normal file
45
lib/fog/vsphere/models/compute/volume.rb
Normal file
|
@ -0,0 +1,45 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Volume < Fog::Model
|
||||
DISK_SIZE_TO_GB = 1048576
|
||||
identity :id
|
||||
|
||||
attribute :datastore
|
||||
attribute :mode
|
||||
attribute :size
|
||||
attribute :thin
|
||||
attribute :name
|
||||
attribute :filename
|
||||
attribute :size_gb
|
||||
|
||||
def initialize(attributes={} )
|
||||
super defaults.merge(attributes)
|
||||
end
|
||||
|
||||
def size_gb
|
||||
attributes[:size_gb] ||= attributes[:size].to_i / DISK_SIZE_TO_GB if attributes[:size]
|
||||
end
|
||||
|
||||
def size_gb= s
|
||||
attributes[:size] = s.to_i * DISK_SIZE_TO_GB if s
|
||||
end
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def defaults
|
||||
{
|
||||
:thin=>true,
|
||||
:name=>"Hard disk",
|
||||
:mode=>"persistent"
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
33
lib/fog/vsphere/models/compute/volumes.rb
Normal file
33
lib/fog/vsphere/models/compute/volumes.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
require 'fog/core/collection'
|
||||
require 'fog/vsphere/models/compute/volume'
|
||||
|
||||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
class Volumes < Fog::Collection
|
||||
|
||||
model Fog::Compute::Vsphere::Volume
|
||||
|
||||
attr_accessor :vm
|
||||
|
||||
def all(filters = {})
|
||||
requires :vm
|
||||
case vm
|
||||
when Fog::Compute::Vsphere::Server
|
||||
load connection.list_vm_volumes(vm.id)
|
||||
when Fog::Compute::Vsphere::Template
|
||||
load connection.list_template_volumes(vm.id)
|
||||
else
|
||||
raise 'volumes should have vm or template'
|
||||
end
|
||||
end
|
||||
|
||||
def get(id)
|
||||
new connection.get_volume(id)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
114
lib/fog/vsphere/requests/compute/create_vm.rb
Normal file
114
lib/fog/vsphere/requests/compute/create_vm.rb
Normal file
|
@ -0,0 +1,114 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def create_vm attributes = { }
|
||||
# build up vm configuration
|
||||
|
||||
vm_cfg = {
|
||||
:name => attributes[:name],
|
||||
:guestId => attributes[:guest_id],
|
||||
:files => { :vmPathName => vm_path_name(attributes) },
|
||||
:numCPUs => attributes[:cpus],
|
||||
:memoryMB => attributes[:memory_mb],
|
||||
:deviceChange => device_change(attributes),
|
||||
:extraConfig => extra_config(attributes),
|
||||
}
|
||||
resource_pool = if attributes[:resource_pool]
|
||||
get_raw_resource_pool(attributes[:resource_pool], attributes[:cluster], attributes[:datacenter])
|
||||
else
|
||||
get_raw_cluster(attributes[:cluster], attributes[:datacenter]).resourcePool
|
||||
end
|
||||
vmFolder = get_raw_vmfolder(attributes[:path], attributes[:datacenter])
|
||||
vm = vmFolder.CreateVM_Task(:config => vm_cfg, :pool => resource_pool).wait_for_completion
|
||||
vm.config.instanceUuid
|
||||
rescue => e
|
||||
raise e, "failed to create vm: #{e}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# this methods defines where the vm config files would be located,
|
||||
# by default we prefer to keep it at the same place the (first) vmdk is located
|
||||
def vm_path_name attributes
|
||||
datastore = attributes[:volumes].first.datastore unless attributes[:volumes].empty?
|
||||
datastore ||= 'datastore1'
|
||||
"[#{datastore}]"
|
||||
end
|
||||
|
||||
def device_change attributes
|
||||
devices = []
|
||||
if (nics = attributes[:interfaces])
|
||||
devices << nics.map { |nic| create_interface(nic, nics.index(nic)) }
|
||||
end
|
||||
|
||||
if (disks = attributes[:volumes])
|
||||
devices << create_controller
|
||||
devices << disks.map { |disk| create_disk(disk, disks.index(disk)) }
|
||||
end
|
||||
devices.flatten
|
||||
end
|
||||
|
||||
def create_interface nic, index = 0, operation = :add
|
||||
{
|
||||
:operation => operation,
|
||||
:device => nic.type.new(
|
||||
:key => index,
|
||||
:deviceInfo =>
|
||||
{
|
||||
:label => nic.name,
|
||||
:summary => nic.summary,
|
||||
},
|
||||
:backing => RbVmomi::VIM.VirtualEthernetCardNetworkBackingInfo(:deviceName => nic.network),
|
||||
:addressType => 'generated')
|
||||
}
|
||||
end
|
||||
|
||||
def create_controller operation = :add, controller_key = 1000, bus_id = 0
|
||||
{
|
||||
:operation => operation,
|
||||
:device => RbVmomi::VIM.VirtualLsiLogicController(
|
||||
:key => controller_key,
|
||||
:busNumber => bus_id,
|
||||
:sharedBus => :noSharing
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
def create_disk disk, index = 0, operation = :add, controller_key = 1000, unit_id = 0
|
||||
{
|
||||
:operation => operation,
|
||||
:fileOperation => :create,
|
||||
:device => RbVmomi::VIM.VirtualDisk(
|
||||
:key => index,
|
||||
:backing => RbVmomi::VIM.VirtualDiskFlatVer2BackingInfo(
|
||||
:fileName => "[#{disk.datastore}]",
|
||||
:diskMode => disk.mode.to_sym,
|
||||
:thinProvisioned => disk.thin
|
||||
),
|
||||
:controllerKey => controller_key,
|
||||
:unitNumber => unit_id,
|
||||
:capacityInKB => disk.size
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
def extra_config attributes
|
||||
[
|
||||
{
|
||||
:key => 'bios.bootOrder',
|
||||
:value => 'ethernet0'
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock
|
||||
def create_vm attributes = { }
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,34 +0,0 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def datacenters
|
||||
@datacenters ||= datacenters_reload
|
||||
# Hide the values which are the RbVmomi instances
|
||||
@datacenters.keys
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def datacenters_reload
|
||||
@rootfolder ||= @connection.rootFolder
|
||||
inventory = @rootfolder.inventory(:Datacenter => [ 'name' ])[@rootfolder]
|
||||
# Convert the inventory into a Hash of the form: We remove the
|
||||
# property selectors. { "<dc_name>" => #<RbVmomi::VIM::Datacenter> }
|
||||
# The Datacenter instance itself is at index 0 and the properties we
|
||||
# collected are at index 1.
|
||||
inventory.inject({}) do |memo, (name,dc_ary)|
|
||||
memo[name] = dc_ary[0]
|
||||
memo
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def datacenters
|
||||
[ "Solutions", "Solutions2", "Solutions3" ]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,41 +0,0 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
module Shared
|
||||
|
||||
# REVISIT: This is a naive implementation and not very efficient since
|
||||
# we find ALL VM's and then iterate over them looking for the managed object
|
||||
# reference id... There should be an easier way to obtain a reference to a
|
||||
# VM using only the name or the _ref. This request is primarily intended to
|
||||
# reload the attributes of a cloning VM which does not yet have an instance_uuid
|
||||
def find_vm_by_ref(options = {})
|
||||
raise ArgumentError, "Must pass a vm_ref option" unless options['vm_ref']
|
||||
|
||||
# This is the inefficient call
|
||||
all_vm_attributes = list_virtual_machines['virtual_machines']
|
||||
# Find the VM attributes of the reference
|
||||
if vm_attributes = all_vm_attributes.find { |vm| vm['mo_ref'] == options['vm_ref'] }
|
||||
response = { 'virtual_machine' => vm_attributes }
|
||||
else
|
||||
raise Fog::Compute::Vsphere::NotFound, "VirtualMachine with Managed Object Reference #{options['vm_ref']} could not be found."
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# The Real and Mock classes share the same method
|
||||
# because list_virtual_machines will be properly mocked for us
|
||||
|
||||
class Real
|
||||
include Shared
|
||||
end
|
||||
|
||||
class Mock
|
||||
include Shared
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
25
lib/fog/vsphere/requests/compute/get_cluster.rb
Normal file
25
lib/fog/vsphere/requests/compute/get_cluster.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def get_cluster(name, datacenter_name)
|
||||
cluster = get_raw_cluster(name, datacenter_name)
|
||||
raise(Fog::Compute::Vsphere::NotFound) unless cluster
|
||||
cluster_attributes(cluster, datacenter_name)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def get_raw_cluster(name, datacenter_name)
|
||||
dc = find_raw_datacenter(datacenter_name)
|
||||
dc.find_compute_resource(name)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def get_cluster(id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
29
lib/fog/vsphere/requests/compute/get_datacenter.rb
Normal file
29
lib/fog/vsphere/requests/compute/get_datacenter.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def get_datacenter name
|
||||
dc = find_raw_datacenter(name)
|
||||
raise(Fog::Compute::Vsphere::NotFound) unless dc
|
||||
{:name => dc.name, :status => dc.overallStatus}
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def find_raw_datacenter name
|
||||
raw_datacenters.find {|d| d.name == name} || get_raw_datacenter(name)
|
||||
end
|
||||
|
||||
def get_raw_datacenter name
|
||||
@connection.serviceInstance.find_datacenter(name)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def get_datacenter name
|
||||
{:name => "Solutions", :status => "grey"}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
25
lib/fog/vsphere/requests/compute/get_datastore.rb
Normal file
25
lib/fog/vsphere/requests/compute/get_datastore.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def get_datastore(name, datacenter_name)
|
||||
datastore = get_raw_datastore(name, datacenter_name)
|
||||
raise(Fog::Compute::Vsphere::NotFound) unless datastore
|
||||
datastore_attributes(datastore, datacenter_name)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def get_raw_datastore(name, datacenter_name)
|
||||
dc = find_raw_datacenter(datacenter_name)
|
||||
dc.datastoreFolder.find(name)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def get_datastore(name, datacenter_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
73
lib/fog/vsphere/requests/compute/get_folder.rb
Normal file
73
lib/fog/vsphere/requests/compute/get_folder.rb
Normal file
|
@ -0,0 +1,73 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def get_folder(path, datacenter_name, type = nil)
|
||||
type ||= 'vm'
|
||||
|
||||
# Cycle through all types of folders.
|
||||
case type
|
||||
when 'vm', :vm
|
||||
# if you're a vm then grab the VM.
|
||||
folder = get_raw_vmfolder(path, datacenter_name)
|
||||
raise(Fog::Compute::Vsphere::NotFound) unless folder
|
||||
folder_attributes(folder, datacenter_name)
|
||||
when 'network', :network
|
||||
raise "not implemented"
|
||||
when 'datastore', :datastore
|
||||
raise "not implemented"
|
||||
else
|
||||
raise ArgumentError, "#{type} is unknown"
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def get_raw_vmfolder(path, datacenter_name)
|
||||
# The required path syntax - 'topfolder/subfolder
|
||||
|
||||
# Clean up path to be relative since we're providing datacenter name
|
||||
paths = path.sub(/^\/?Datacenters\/#{datacenter_name}\/vm\/?/, '').split('/')
|
||||
dc = find_raw_datacenter(datacenter_name)
|
||||
dc_root_folder = dc.vmFolder
|
||||
|
||||
return dc_root_folder if paths.empty?
|
||||
# Walk the tree resetting the folder pointer as we go
|
||||
paths.inject(dc_root_folder) do |last_returned_folder, sub_folder|
|
||||
# JJM VIM::Folder#find appears to be quite efficient as it uses the
|
||||
# searchIndex It certainly appears to be faster than
|
||||
# VIM::Folder#inventory since that returns _all_ managed objects of
|
||||
# a certain type _and_ their properties.
|
||||
sub = last_returned_folder.find(sub_folder, RbVmomi::VIM::Folder)
|
||||
raise ArgumentError, "Could not descend into #{sub_folder}. Please check your path. #{path}" unless sub
|
||||
sub
|
||||
end
|
||||
end
|
||||
|
||||
def folder_attributes(folder, datacenter_name)
|
||||
{
|
||||
:id => managed_obj_id(folder),
|
||||
:name => folder.name,
|
||||
:parent => folder.parent.name,
|
||||
:datacenter => datacenter_name,
|
||||
:type => folder_type(folder),
|
||||
:path => folder.path.map(&:last).join('/'),
|
||||
}
|
||||
end
|
||||
|
||||
def folder_type(folder)
|
||||
types = folder.childType
|
||||
return :vm if types.include?('VirtualMachine')
|
||||
return :network if types.include?('Network')
|
||||
return :datastore if types.include?('Datastore')
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def get_folder(path, filters = { })
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
25
lib/fog/vsphere/requests/compute/get_network.rb
Normal file
25
lib/fog/vsphere/requests/compute/get_network.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def get_network(name, datacenter_name)
|
||||
network = get_raw_network(name, datacenter_name)
|
||||
raise(Fog::Compute::Vsphere::NotFound) unless network
|
||||
network_attributes(network, datacenter_name)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def get_raw_network(name, datacenter_name)
|
||||
dc = find_raw_datacenter(datacenter_name)
|
||||
dc.networkFolder.find(name)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def get_network(id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
26
lib/fog/vsphere/requests/compute/get_resource_pool.rb
Normal file
26
lib/fog/vsphere/requests/compute/get_resource_pool.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def get_resource_pool(name, cluster_name, datacenter_name)
|
||||
resource_pool = get_raw_resource_pool(name, cluster_name, datacenter_name)
|
||||
raise(Fog::Compute::Vsphere::NotFound) unless resource_pool
|
||||
resource_pool_attributes(resource_pool, cluster_name, datacenter_name)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def get_raw_resource_pool(name, cluster_name, datacenter_name)
|
||||
dc = get_raw_datacenter(datacenter_name)
|
||||
cluster = dc.find_compute_resource(cluster_name)
|
||||
cluster.resourcePool.find name
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def get_resource_pool(name, cluster_name, datacenter_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
62
lib/fog/vsphere/requests/compute/get_virtual_machine.rb
Normal file
62
lib/fog/vsphere/requests/compute/get_virtual_machine.rb
Normal file
|
@ -0,0 +1,62 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def get_virtual_machine(id, datacenter_name = nil)
|
||||
convert_vm_mob_ref_to_attr_hash(get_vm_ref(id, datacenter_name))
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def get_vm_ref(id, dc = nil)
|
||||
vm = case id
|
||||
# UUID based
|
||||
when /[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}/
|
||||
@connection.searchIndex.FindByUuid :uuid => id, :vmSearch => true, :instanceUuid => true, :datacenter => dc
|
||||
else
|
||||
# try to find based on VM name
|
||||
if dc
|
||||
get_datacenter(dc).find_vm(id)
|
||||
else
|
||||
raw_datacenters.map { |d| d.find_vm(id) }.compact.first
|
||||
end
|
||||
end
|
||||
vm ? vm : raise(Fog::Compute::Vsphere::NotFound, "#{id} was not found")
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def get_virtual_machine(id, datacenter_name = nil)
|
||||
case id
|
||||
when "5032c8a5-9c5e-ba7a-3804-832a03e16381", 'vm-715'
|
||||
{ :resource_pool => "Resources",
|
||||
:memory_mb => 2196,
|
||||
:power_state => "poweredOn",
|
||||
:mac_addresses => { "Network adapter 1" => "00:50:56:b2:00:af" },
|
||||
:hostname => "centos56gm.localdomain",
|
||||
:cpus => 1,
|
||||
:connection_state => "connected",
|
||||
:mo_ref => "vm-715",
|
||||
:overall_status => "green",
|
||||
:datacenter => "Solutions",
|
||||
:instance_uuid => "5029c440-85ee-c2a1-e9dd-b63e39364603",
|
||||
:hypervisor => "gunab.puppetlabs.lan",
|
||||
:guest_id => "rhel6_64Guest",
|
||||
:cluster => "virtlabcluster",
|
||||
:tools_state => "toolsOk",
|
||||
:name => "jefftest",
|
||||
:operatingsystem => "Red Hat Enterprise Linux 6 (64-bit)",
|
||||
:path => "/",
|
||||
:tools_version => "guestToolsUnmanaged",
|
||||
:ipaddress => "192.168.100.187",
|
||||
:id => "5032c8a5-9c5e-ba7a-3804-832a03e16381",
|
||||
:uuid => "42329da7-e8ab-29ec-1892-d6a4a964912a"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
37
lib/fog/vsphere/requests/compute/list_clusters.rb
Normal file
37
lib/fog/vsphere/requests/compute/list_clusters.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def list_clusters(filters = { })
|
||||
datacenter_name = filters[:datacenter]
|
||||
|
||||
raw_clusters(datacenter_name).map do |cluster|
|
||||
cluster_attributes(cluster, datacenter_name)
|
||||
end
|
||||
end
|
||||
|
||||
def raw_clusters(datacenter)
|
||||
find_raw_datacenter(datacenter).hostFolder.childEntity.grep(RbVmomi::VIM::ClusterComputeResource)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def cluster_attributes cluster, datacenter_name
|
||||
{
|
||||
:id => managed_obj_id(cluster),
|
||||
:name => cluster.name,
|
||||
:num_host => cluster.summary.numHosts,
|
||||
:num_cpu_cores => cluster.summary.numCpuCores,
|
||||
:overall_status => cluster.summary.overallStatus,
|
||||
:datacenter => datacenter_name || parent_attribute(cluster.path, :datacenter)[1],
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
class Mock
|
||||
def list_clusters(filters = { })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
34
lib/fog/vsphere/requests/compute/list_datacenters.rb
Normal file
34
lib/fog/vsphere/requests/compute/list_datacenters.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
|
||||
def list_datacenters filters = {}
|
||||
raw_datacenters.map do |dc|
|
||||
{
|
||||
:id => managed_obj_id(dc),
|
||||
:name => dc.name,
|
||||
:status => dc.overallStatus
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def raw_datacenters
|
||||
@raw_datacenters ||= @connection.rootFolder.childEntity.grep(RbVmomi::VIM::Datacenter)
|
||||
end
|
||||
|
||||
def find_datacenters name=nil
|
||||
name ? [get_raw_datacenter(name)] : raw_datacenters
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def list_datacenters filters = {}
|
||||
[ {:name => "Solutions", :status => "grey"}, {:name => "Solutions2", :status => "green" }]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
40
lib/fog/vsphere/requests/compute/list_datastores.rb
Normal file
40
lib/fog/vsphere/requests/compute/list_datastores.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def list_datastores(filters = { })
|
||||
datacenter_name = filters[:datacenter]
|
||||
# default to show all datastores
|
||||
only_active = filters[:accessible] || false
|
||||
raw_datastores(datacenter_name).map do |datastore|
|
||||
next if only_active and !datastore.summary.accessible
|
||||
datastore_attributes(datastore, datacenter_name)
|
||||
end.compact
|
||||
end
|
||||
|
||||
def raw_datastores(datacenter_name)
|
||||
find_raw_datacenter(datacenter_name).datastore
|
||||
end
|
||||
protected
|
||||
|
||||
def datastore_attributes datastore, datacenter
|
||||
{
|
||||
:id => managed_obj_id(datastore),
|
||||
:name => datastore.name,
|
||||
:accessible => datastore.summary.accessible,
|
||||
:type => datastore.summary.type,
|
||||
:freespace => datastore.summary.freeSpace,
|
||||
:capacity => datastore.summary.capacity,
|
||||
:datacenter => datacenter,
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
class Mock
|
||||
def list_datastores(datacenter_name)
|
||||
[]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
45
lib/fog/vsphere/requests/compute/list_folders.rb
Normal file
45
lib/fog/vsphere/requests/compute/list_folders.rb
Normal file
|
@ -0,0 +1,45 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
# Grabs all sub folders within a given path folder.
|
||||
#
|
||||
# ==== Parameters
|
||||
# * filters<~Hash>:
|
||||
# * :datacenter<~String> - *REQUIRED* Your datacenter where you're
|
||||
# looking for folders. Example: 'my-datacenter-name' (passed if you
|
||||
# are using the models/collections)
|
||||
# eg: vspconn.datacenters.first.vm_folders('mypath')
|
||||
# * :path<~String> - Your path where you're looking for
|
||||
# more folders, if return = none you will get an error. If you don't
|
||||
# define it will look in the main datacenter folder for any folders
|
||||
# in that datacenter.
|
||||
#
|
||||
# Example Usage Testing Only:
|
||||
# vspconn = Fog::Compute[:vsphere]
|
||||
# mydc = vspconn.datacenters.first
|
||||
# folders = mydc.vm_folders
|
||||
#
|
||||
def list_folders(filters = { })
|
||||
path = filters[:path] || filters['path'] || ''
|
||||
datacenter_name = filters[:datacenter]
|
||||
get_raw_vmfolders(path, datacenter_name).map do |folder|
|
||||
folder_attributes(folder, datacenter_name)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def get_raw_vmfolders(path, datacenter_name)
|
||||
folder = get_raw_vmfolder(path, datacenter_name)
|
||||
child_folders(folder).flatten.compact
|
||||
end
|
||||
|
||||
def child_folders folder
|
||||
[folder, folder.childEntity.grep(RbVmomi::VIM::Folder).map(&method(:child_folders)).flatten]
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
38
lib/fog/vsphere/requests/compute/list_networks.rb
Normal file
38
lib/fog/vsphere/requests/compute/list_networks.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def list_networks(filters = { })
|
||||
datacenter_name = filters[:datacenter]
|
||||
# default to show all networks
|
||||
only_active = filters[:accessible] || false
|
||||
raw_networks(datacenter_name).map do |network|
|
||||
next if only_active and !network.summary.accessible
|
||||
network_attributes(network, datacenter_name)
|
||||
end.compact
|
||||
end
|
||||
|
||||
def raw_networks(datacenter_name)
|
||||
find_raw_datacenter(datacenter_name).network
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def network_attributes network, datacenter
|
||||
{
|
||||
:id => managed_obj_id(network),
|
||||
:name => network.name,
|
||||
:accessible => network.summary.accessible,
|
||||
:datacenter => datacenter,
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
class Mock
|
||||
def list_networks(datacenter_name)
|
||||
[]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
39
lib/fog/vsphere/requests/compute/list_resource_pools.rb
Normal file
39
lib/fog/vsphere/requests/compute/list_resource_pools.rb
Normal file
|
@ -0,0 +1,39 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def list_resource_pools(filters = { })
|
||||
datacenter_name = filters[:datacenter]
|
||||
cluster_name = filters[:cluster]
|
||||
cluster = get_raw_cluster(cluster_name, datacenter_name)
|
||||
list_raw_resource_pools(cluster).map do |resource_pool|
|
||||
resource_pool_attributes(resource_pool, cluster_name, datacenter_name)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# root ResourcePool + Children if they exists
|
||||
def list_raw_resource_pools(cluster)
|
||||
[cluster.resourcePool, cluster.resourcePool.resourcePool].flatten
|
||||
end
|
||||
|
||||
def resource_pool_attributes resource_pool, cluster, datacenter
|
||||
{
|
||||
:id => managed_obj_id(resource_pool),
|
||||
:name => resource_pool.name,
|
||||
:configured_memory_mb => resource_pool.summary.configuredMemoryMB,
|
||||
:overall_status => resource_pool.overallStatus,
|
||||
:cluster => cluster,
|
||||
:datacenter => datacenter
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
class Mock
|
||||
def list_resource_pools(filters = { })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,97 +2,43 @@ module Fog
|
|||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
def list_virtual_machines(options = {})
|
||||
def list_virtual_machines(options = { })
|
||||
# Listing all VM's can be quite slow and expensive. Try and optimize
|
||||
# based on the available options we have. These conditions are in
|
||||
# ascending order of time to complete for large deployments.
|
||||
# ascending order of time to complete for large deployments.
|
||||
|
||||
options[:folder] ||= options['folder']
|
||||
if options['instance_uuid'] then
|
||||
list_all_virtual_machines_by_instance_uuid(options)
|
||||
elsif options['folder'] then
|
||||
list_all_virtual_machines_in_folder(options)
|
||||
[connection.get_virtual_machine(options['instance_uuid'])]
|
||||
elsif options[:folder] && options[:datacenter] then
|
||||
list_all_virtual_machines_in_folder(options[:folder], options[:datacenter])
|
||||
else
|
||||
list_all_virtual_machines
|
||||
list_all_virtual_machines(options)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def list_all_virtual_machines_in_folder(options = {})
|
||||
# Tap gets rid of the leading empty string and "Datacenters" element
|
||||
# and returns the array.
|
||||
path_elements = options['folder'].split('/').tap { |ary| ary.shift 2 }
|
||||
# The DC name itself.
|
||||
dc_name = path_elements.shift
|
||||
# If the first path element contains "vm" this denotes the vmFolder
|
||||
# and needs to be shifted out since each DC contains only one
|
||||
# vmFolder
|
||||
path_elements.shift if path_elements[0] == 'vm'
|
||||
# Make sure @datacenters is populated (the keys are DataCenter instances)
|
||||
self.datacenters.include? dc_name or raise ArgumentError, "Could not find a Datacenter named #{dc_name}"
|
||||
# Get the datacenter managed object
|
||||
dc = @datacenters[dc_name]
|
||||
def list_all_virtual_machines_in_folder(path, datacenter_name)
|
||||
folder = get_raw_vmfolder(path, datacenter_name)
|
||||
|
||||
# Get the VM Folder (Group) efficiently
|
||||
vm_folder = dc.vmFolder
|
||||
|
||||
# Walk the tree resetting the folder pointer as we go
|
||||
folder = path_elements.inject(vm_folder) do |current_folder, sub_folder_name|
|
||||
# JJM VIM::Folder#find appears to be quite efficient as it uses the
|
||||
# searchIndex It certainly appears to be faster than
|
||||
# VIM::Folder#inventory since that returns _all_ managed objects of
|
||||
# a certain type _and_ their properties.
|
||||
sub_folder = current_folder.find(sub_folder_name, RbVmomi::VIM::Folder)
|
||||
raise ArgumentError, "Could not descend into #{sub_folder_name}. Please check your path." unless sub_folder
|
||||
sub_folder
|
||||
end
|
||||
|
||||
# This should be efficient since we're not obtaining properties
|
||||
virtual_machines = folder.children.inject([]) do |ary, child|
|
||||
if child.is_a? RbVmomi::VIM::VirtualMachine then
|
||||
ary << convert_vm_mob_ref_to_attr_hash(child)
|
||||
end
|
||||
ary
|
||||
end
|
||||
|
||||
# Return the managed objects themselves as an array. These may be converted
|
||||
# to an attribute has using convert_vm_mob_ref_to_attr_hash
|
||||
{ 'virtual_machines' => virtual_machines }
|
||||
folder.children.grep(RbVmomi::VIM::VirtualMachine).map(&method(:convert_vm_mob_ref_to_attr_hash))
|
||||
end
|
||||
|
||||
def list_all_virtual_machines_by_instance_uuid(options = {})
|
||||
uuid = options['instance_uuid']
|
||||
search_filter = { :uuid => uuid, 'vmSearch' => true, 'instanceUuid' => true }
|
||||
vm_mob_ref = @connection.searchIndex.FindAllByUuid(search_filter).first
|
||||
if vm_attribute_hash = convert_vm_mob_ref_to_attr_hash(vm_mob_ref) then
|
||||
virtual_machines = [ vm_attribute_hash ]
|
||||
else
|
||||
virtual_machines = [ ]
|
||||
end
|
||||
{ 'virtual_machines' => virtual_machines }
|
||||
end
|
||||
def list_all_virtual_machines(options = { })
|
||||
datacenters = find_datacenters(options[:datacenter])
|
||||
# TODO: go though nested folders
|
||||
vms = datacenters.map { |dc| dc.vmFolder.childEntity.grep(RbVmomi::VIM::VirtualMachine) }.flatten
|
||||
# remove all template based virtual machines
|
||||
vms.delete_if { |v| v.config.template }
|
||||
|
||||
def list_all_virtual_machines
|
||||
virtual_machines = list_all_virtual_machine_mobs.collect do |vm_mob|
|
||||
vms.map do |vm_mob|
|
||||
convert_vm_mob_ref_to_attr_hash(vm_mob)
|
||||
end
|
||||
{ 'virtual_machines' => virtual_machines }
|
||||
end
|
||||
|
||||
|
||||
# NOTE: This is a private instance method required by the vm_clone
|
||||
# request. It's very hard to get the Managed Object Reference
|
||||
# of a Template because we can't search for it by instance_uuid
|
||||
# As a result, we need a list of all virtual machines, and we
|
||||
# need them in "native" format, not filter attribute format.
|
||||
def list_all_virtual_machine_mobs
|
||||
# Find each datacenter
|
||||
datacenters = @connection.rootFolder.childEntity.grep(RbVmomi::VIM::Datacenter)
|
||||
# Next, search the "vmFolder" inventory of each data center:
|
||||
datacenters.map {|dc| dc.vmFolder.childEntity.grep(RbVmomi::VIM::VirtualMachine) }.flatten
|
||||
end
|
||||
|
||||
def get_folder_path(folder, root = nil)
|
||||
if ( not folder.methods.include?('parent') ) or ( folder == root )
|
||||
if (not folder.methods.include?('parent')) or (folder == root)
|
||||
return
|
||||
end
|
||||
"#{get_folder_path(folder.parent)}/#{folder.name}"
|
||||
|
@ -105,100 +51,120 @@ module Fog
|
|||
nil
|
||||
end
|
||||
|
||||
def list_virtual_machines(options = {})
|
||||
def list_virtual_machines(options = { })
|
||||
case options['instance_uuid']
|
||||
when nil
|
||||
rval = YAML.load <<-'ENDvmLISTING'
|
||||
---
|
||||
virtual_machines:
|
||||
- name: centos56gm
|
||||
hypervisor: gunab.puppetlabs.lan
|
||||
tools_version: guestToolsCurrent
|
||||
ipaddress:
|
||||
mo_ref: vm-698
|
||||
power_state: poweredOff
|
||||
uuid: 42322347-d791-cd34-80b9-e25fe28ad37c
|
||||
is_a_template: true
|
||||
id: 50323f93-6835-1178-8b8f-9e2109890e1a
|
||||
tools_state: toolsNotRunning
|
||||
connection_state: connected
|
||||
instance_uuid: 50323f93-6835-1178-8b8f-9e2109890e1a
|
||||
hostname:
|
||||
mac_addresses:
|
||||
Network adapter 1: 00:50:56:b2:00:a1
|
||||
operatingsystem:
|
||||
- name: centos56gm2
|
||||
hypervisor: gunab.puppetlabs.lan
|
||||
tools_version: guestToolsCurrent
|
||||
ipaddress:
|
||||
mo_ref: vm-640
|
||||
power_state: poweredOff
|
||||
uuid: 564ddcbe-853a-d29a-b329-a0a3693a004d
|
||||
is_a_template: true
|
||||
id: 5257dee8-050c-cbcd-ae25-db0e582ab530
|
||||
tools_state: toolsNotRunning
|
||||
connection_state: connected
|
||||
instance_uuid: 5257dee8-050c-cbcd-ae25-db0e582ab530
|
||||
hostname:
|
||||
mac_addresses:
|
||||
Network adapter 1: 00:0c:29:3a:00:4d
|
||||
operatingsystem:
|
||||
- name: dashboard_gm
|
||||
hypervisor: gunab.puppetlabs.lan
|
||||
tools_version: guestToolsCurrent
|
||||
ipaddress: 192.168.100.184
|
||||
mo_ref: vm-669
|
||||
power_state: poweredOn
|
||||
uuid: 564d3f91-3452-a509-a678-1246f7897979
|
||||
is_a_template: false
|
||||
id: 5032739c-c871-c0d2-034f-9700a0b5383e
|
||||
tools_state: toolsOk
|
||||
connection_state: connected
|
||||
instance_uuid: 5032739c-c871-c0d2-034f-9700a0b5383e
|
||||
hostname: compliance.puppetlabs.vm
|
||||
mac_addresses:
|
||||
Network adapter 1: 00:50:56:b2:00:96
|
||||
operatingsystem: Red Hat Enterprise Linux 6 (64-bit)
|
||||
- name: jefftest
|
||||
hypervisor: gunab.puppetlabs.lan
|
||||
tools_version: guestToolsCurrent
|
||||
ipaddress: 192.168.100.187
|
||||
mo_ref: vm-715
|
||||
power_state: poweredOn
|
||||
uuid: 42329da7-e8ab-29ec-1892-d6a4a964912a
|
||||
is_a_template: false
|
||||
id: 5032c8a5-9c5e-ba7a-3804-832a03e16381
|
||||
tools_state: toolsOk
|
||||
connection_state: connected
|
||||
instance_uuid: 5032c8a5-9c5e-ba7a-3804-832a03e16381
|
||||
hostname: centos56gm.localdomain
|
||||
mac_addresses:
|
||||
Network adapter 1: 00:50:56:b2:00:af
|
||||
operatingsystem: CentOS 4/5 (32-bit)
|
||||
ENDvmLISTING
|
||||
when '5032c8a5-9c5e-ba7a-3804-832a03e16381'
|
||||
YAML.load <<-'5032c8a5-9c5e-ba7a-3804-832a03e16381'
|
||||
---
|
||||
virtual_machines:
|
||||
- name: jefftest
|
||||
hypervisor: gunab.puppetlabs.lan
|
||||
tools_version: guestToolsCurrent
|
||||
ipaddress: 192.168.100.187
|
||||
mo_ref: vm-715
|
||||
power_state: poweredOn
|
||||
uuid: 42329da7-e8ab-29ec-1892-d6a4a964912a
|
||||
is_a_template: false
|
||||
id: 5032c8a5-9c5e-ba7a-3804-832a03e16381
|
||||
tools_state: toolsOk
|
||||
connection_state: connected
|
||||
instance_uuid: 5032c8a5-9c5e-ba7a-3804-832a03e16381
|
||||
hostname: centos56gm.localdomain
|
||||
mac_addresses:
|
||||
Network adapter 1: 00:50:56:b2:00:af
|
||||
operatingsystem: CentOS 4/5 (32-bit)
|
||||
5032c8a5-9c5e-ba7a-3804-832a03e16381
|
||||
when 'does-not-exist-and-is-not-a-uuid', '50323f93-6835-1178-8b8f-9e2109890e1a'
|
||||
{ 'virtual_machines' => [] }
|
||||
when nil
|
||||
|
||||
[
|
||||
{ :resource_pool => "Resources",
|
||||
:memory_mb => 2196,
|
||||
:mac_addresses => { "Network adapter 1" => "00:50:56:a9:00:28" },
|
||||
:power_state => "poweredOn",
|
||||
:cpus => 1,
|
||||
:hostname => "dhcp75-197.virt.bos.redhat.com",
|
||||
:mo_ref => "vm-562",
|
||||
:connection_state => "connected",
|
||||
:overall_status => "green",
|
||||
:datacenter => "Solutions",
|
||||
:volumes =>
|
||||
[{
|
||||
:id => "6000C29c-a47d-4cd9-5249-c371de775f06",
|
||||
:datastore => "Storage1",
|
||||
:mode => "persistent",
|
||||
:size => 8388608,
|
||||
:thin => true,
|
||||
:name => "Hard disk 1",
|
||||
:filename => "[Storage1] rhel6-mfojtik/rhel6-mfojtik.vmdk",
|
||||
:size_gb => 8
|
||||
}],
|
||||
:interfaces =>
|
||||
[{ :mac => "00:50:56:a9:00:28",
|
||||
:network => "VM Network",
|
||||
:name => "Network adapter 1",
|
||||
:status => "ok",
|
||||
:summary => "VM Network",
|
||||
}],
|
||||
:hypervisor => "gunab.puppetlabs.lan",
|
||||
:guest_id => "rhel6_64Guest",
|
||||
:tools_state => "toolsOk",
|
||||
:cluster => "Solutionscluster",
|
||||
:name => "rhel64",
|
||||
:operatingsystem => "Red Hat Enterprise Linux 6 (64-bit)",
|
||||
:uuid => "4229f0e9-bfdc-d9a7-7bac-12070772e6dc",
|
||||
:path => "/Datacenters/Solutions/vm",
|
||||
:id => "5029c440-85ee-c2a1-e9dd-b63e39364603",
|
||||
:tools_version => "guestToolsUnmanaged",
|
||||
:ipaddress => "192.168.100.184",
|
||||
},
|
||||
{ :resource_pool => "Resources",
|
||||
:memory_mb => 512,
|
||||
:power_state => "poweredOn",
|
||||
:mac_addresses => { "Network adapter 1" => "00:50:56:a9:00:00" },
|
||||
:hostname => nil,
|
||||
:cpus => 1,
|
||||
:connection_state => "connected",
|
||||
:mo_ref => "vm-621",
|
||||
:overall_status => "green",
|
||||
:datacenter => "Solutions",
|
||||
:volumes =>
|
||||
[{ :thin => false,
|
||||
:size_gb => 10,
|
||||
:datastore => "datastore1",
|
||||
:filename => "[datastore1] i-1342439683/i-1342439683.vmdk",
|
||||
:size => 10485762,
|
||||
:name => "Hard disk 1",
|
||||
:mode => "persistent",
|
||||
:id => "6000C29b-f364-d073-8316-8e98ac0a0eae" }],
|
||||
:interfaces =>
|
||||
[{ :summary => "VM Network",
|
||||
:mac => "00:50:56:a9:00:00",
|
||||
:status => "ok",
|
||||
:network => "VM Network",
|
||||
:name => "Network adapter 1" }],
|
||||
:instance_uuid => "502916a3-b42e-17c7-43ce-b3206e9524dc",
|
||||
:hypervisor => "gunab.puppetlabs.lan",
|
||||
:guest_id => nil,
|
||||
:cluster => "Solutionscluster",
|
||||
:tools_state => "toolsNotInstalled",
|
||||
:uuid => "4229e0de-30cb-ceb2-21f9-4d8d8beabb52",
|
||||
:name => "i-1342439683",
|
||||
:operatingsystem => nil,
|
||||
:path => "/",
|
||||
:tools_version => "guestToolsNotInstalled",
|
||||
:id => "502916a3-b42e-17c7-43ce-b3206e9524dc",
|
||||
:ipaddress => nil }
|
||||
|
||||
|
||||
]
|
||||
when '5032c8a5-9c5e-ba7a-3804-832a03e16381'
|
||||
[{ :resource_pool => "Resources",
|
||||
:memory_mb => 2196,
|
||||
:power_state => "poweredOn",
|
||||
:mac_addresses => { "Network adapter 1" => "00:50:56:b2:00:af" },
|
||||
:hostname => "centos56gm.localdomain",
|
||||
:cpus => 1,
|
||||
:connection_state => "connected",
|
||||
:mo_ref => "vm-715",
|
||||
:overall_status => "green",
|
||||
:datacenter => "Solutions",
|
||||
:instance_uuid => "5029c440-85ee-c2a1-e9dd-b63e39364603",
|
||||
:hypervisor => "gunab.puppetlabs.lan",
|
||||
:guest_id => "rhel6_64Guest",
|
||||
:cluster => "Solutionscluster",
|
||||
:tools_state => "toolsOk",
|
||||
:name => "jefftest",
|
||||
:operatingsystem => "Red Hat Enterprise Linux 6 (64-bit)",
|
||||
:path => "/",
|
||||
:tools_version => "guestToolsUnmanaged",
|
||||
:ipaddress => "192.168.100.187",
|
||||
:id => "5032c8a5-9c5e-ba7a-3804-832a03e16381",
|
||||
:uuid => "42329da7-e8ab-29ec-1892-d6a4a964912a"
|
||||
|
||||
}
|
||||
|
||||
]
|
||||
when 'does-not-exist-and-is-not-a-uuid', '50323f93-6835-1178-8b8f-9e2109890e1a'
|
||||
[]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
52
lib/fog/vsphere/requests/compute/list_vm_interfaces.rb
Normal file
52
lib/fog/vsphere/requests/compute/list_vm_interfaces.rb
Normal file
|
@ -0,0 +1,52 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
# => VirtualE1000(
|
||||
#addressType: "assigned",
|
||||
#backing: VirtualEthernetCardNetworkBackingInfo(
|
||||
# deviceName: "VM Network",
|
||||
# dynamicProperty: [],
|
||||
# network: Network("network-163"),
|
||||
# useAutoDetect: false
|
||||
#),
|
||||
#connectable: VirtualDeviceConnectInfo(
|
||||
# allowGuestControl: true,
|
||||
# connected: true,
|
||||
# dynamicProperty: [],
|
||||
# startConnected: true,
|
||||
# status: "ok"
|
||||
#),
|
||||
#controllerKey: 100,
|
||||
#deviceInfo: Description(
|
||||
# dynamicProperty: [],
|
||||
# label: "Network adapter 1",
|
||||
# summary: "VM Network"
|
||||
#),
|
||||
#dynamicProperty: [],
|
||||
#key: 4000,
|
||||
#macAddress: "00:50:56:a9:00:28",
|
||||
#unitNumber: 7,
|
||||
#
|
||||
def list_vm_interfaces(vm_id)
|
||||
get_vm_ref(vm_id).config.hardware.device.grep(RbVmomi::VIM::VirtualEthernetCard).map do |nic|
|
||||
{
|
||||
:name => nic.deviceInfo.label,
|
||||
:mac => nic.macAddress,
|
||||
:network => nic.backing.network.name,
|
||||
:status => nic.connectable.status,
|
||||
:summary => nic.deviceInfo.summary,
|
||||
:type => nic.class,
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
class Mock
|
||||
def list_vm_interfaces(vm_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
51
lib/fog/vsphere/requests/compute/list_vm_volumes.rb
Normal file
51
lib/fog/vsphere/requests/compute/list_vm_volumes.rb
Normal file
|
@ -0,0 +1,51 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
class Real
|
||||
# [VirtualDisk(
|
||||
# backing: VirtualDiskFlatVer2BackingInfo(
|
||||
# contentId: "a172d19487e878e17d6b16ff2505d7eb",
|
||||
# datastore: Datastore("datastore-162"),
|
||||
# diskMode: "persistent",
|
||||
# dynamicProperty: [],
|
||||
# fileName: "[Storage1] rhel6-mfojtik/rhel6-mfojtik.vmdk",
|
||||
# split: false,
|
||||
# thinProvisioned: true,
|
||||
# uuid: "6000C29c-a47d-4cd9-5249-c371de775f06",
|
||||
# writeThrough: false
|
||||
# ),
|
||||
# capacityInKB: 8388608,
|
||||
# controllerKey: 1000,
|
||||
# deviceInfo: Description(
|
||||
# dynamicProperty: [],
|
||||
# label: "Hard disk 1",
|
||||
# summary: "8,388,608 KB"
|
||||
# ),
|
||||
# dynamicProperty: [],
|
||||
# key: 2001,
|
||||
# shares: SharesInfo( dynamicProperty: [], level: "normal", shares: 1000 ),
|
||||
# unitNumber: 1
|
||||
#)]
|
||||
|
||||
def list_vm_volumes(vm_id)
|
||||
get_vm_ref(vm_id).disks.map do |vol|
|
||||
{
|
||||
:id => vol.backing.uuid,
|
||||
:thin => vol.backing.thinProvisioned,
|
||||
:mode => vol.backing.diskMode,
|
||||
:filename => vol.backing.fileName,
|
||||
:datastore => (vol.backing.datastore.name rescue(nil)),
|
||||
:size => vol.capacityInKB,
|
||||
:name => vol.deviceInfo.label
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
class Mock
|
||||
def list_vm_volumes(vm_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -21,8 +21,8 @@ module Fog
|
|||
raise ArgumentError, "vm_clone path option must start with /Datacenters. Got: #{options['path']}"
|
||||
end
|
||||
dc_name = path_elements.shift
|
||||
if not self.datacenters.include? dc_name then
|
||||
raise ArgumentError, "Datacenter #{dc_name} does not exist, only datacenters #{self.datacenters.join(",")} are accessible."
|
||||
if not datacenters.get dc_name then
|
||||
raise ArgumentError, "Datacenter #{dc_name} does not exist, only datacenters #{datacenters.all.map(:name).join(",")} are accessible."
|
||||
end
|
||||
options
|
||||
end
|
||||
|
@ -75,10 +75,8 @@ module Fog
|
|||
# The template name. The remaining elements are the folders in the
|
||||
# datacenter.
|
||||
template_name = path_elements.pop
|
||||
# Make sure @datacenters is populated. We need the instances from the Hash keys.
|
||||
self.datacenters
|
||||
# Get the datacenter managed object from the hash
|
||||
dc = @datacenters[template_dc]
|
||||
|
||||
dc = find_raw_datacenter(template_dc)
|
||||
# Get the VM Folder (Group) efficiently
|
||||
vm_folder = dc.vmFolder
|
||||
# Walk the tree resetting the folder pointer as we go
|
||||
|
@ -195,8 +193,8 @@ module Fog
|
|||
# Option handling
|
||||
options = vm_clone_check_options(options)
|
||||
notfound = lambda { raise Fog::Compute::Vsphere::NotFound, "Could not find VM template" }
|
||||
vm_mob_ref = list_virtual_machines['virtual_machines'].find(notfound) do |vm|
|
||||
vm['name'] == options['path'].split("/")[-1]
|
||||
list_virtual_machines.find(notfound) do |vm|
|
||||
vm[:name] == options['path'].split("/")[-1]
|
||||
end
|
||||
{
|
||||
'vm_ref' => 'vm-123',
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
module Fog
|
||||
module Compute
|
||||
class Vsphere
|
||||
|
||||
module Shared
|
||||
private
|
||||
def vm_create_check_options(options)
|
||||
options = { 'force' => false }.merge(options)
|
||||
required_options = %w{ path name cluster }
|
||||
required_options.each do |param|
|
||||
raise ArgumentError, "#{required_options.join(', ')} are required" unless options.has_key? param
|
||||
end
|
||||
# The tap removes the leading empty string
|
||||
path_elements = options['path'].split('/').tap { |o| o.shift }
|
||||
first_folder = path_elements.shift
|
||||
if first_folder != 'Datacenters' then
|
||||
raise ArgumentError, "vm_create path option must start with /Datacenters. Got: #{options['path']}"
|
||||
end
|
||||
dc_name = path_elements.shift
|
||||
if not self.datacenters.include? dc_name then
|
||||
raise ArgumentError, "Datacenter #{dc_name} does not exist, only datacenters #{self.datacenters.join(",")} are accessible."
|
||||
end
|
||||
options
|
||||
end
|
||||
end
|
||||
|
||||
class Real
|
||||
include Shared
|
||||
def vm_create(options = {})
|
||||
# Option handling
|
||||
options = vm_create_check_options(options)
|
||||
path_elements = options['path'].split('/').tap { |ary| ary.shift 2 }
|
||||
dc_name = path_elements.shift
|
||||
vm_cfg = {
|
||||
:name => options['name'],
|
||||
:guestId => options['guest_id'] ? options['guest_id'] : 'otherGuest',
|
||||
:files => { :vmPathName => "[#{options['datastore']}]" },
|
||||
:numCPUs => options['num_cpus'] ? options['num_cpus'] : 1 ,
|
||||
:memoryMB => options['memory'] ? options['memory'] : 512,
|
||||
:memoryHotAddEnabled => options['memory_hot_add_enabled'] ? options['memory_hot_add_enabled'] : 0,
|
||||
:cpuHotAddEnabled => options['cpu_hot_add_enabled'] ? options['cpu_hot_add_enabled'] : 0,
|
||||
:deviceChange => options['device_array'].class == Array ? options['device_array'] : nil,
|
||||
:extraConfig => options['extra_config'].class == Array ? options['extra_config'] : nil,
|
||||
}
|
||||
self.datacenters
|
||||
dc = @datacenters[dc_name]
|
||||
vm_folder = dc.vmFolder
|
||||
folder = path_elements.inject(vm_folder) do |current_folder, sub_folder_name|
|
||||
sub_folder = current_folder.find(sub_folder_name, RbVmomi::VIM::Folder)
|
||||
raise ArgumentError, "Could not descend into #{sub_folder_name}. Please check your path." unless sub_folder
|
||||
sub_folder
|
||||
end
|
||||
clusters = dc.hostFolder.children
|
||||
build_cluster=''
|
||||
clusters.each { |my_cluster|
|
||||
if "#{my_cluster.name}" == "#{options['cluster']}"
|
||||
build_cluster=my_cluster
|
||||
end
|
||||
}
|
||||
resource_pool = build_cluster.resourcePool
|
||||
task=folder.CreateVM_Task(:config => vm_cfg, :pool => resource_pool)
|
||||
if options['wait'] then
|
||||
new_vm = task.wait_for_completion
|
||||
else
|
||||
tries = 0
|
||||
new_vm = begin
|
||||
folder.find(options['name'], RbVmomi::VIM::VirtualMachine) or raise Fog::Vsphere::Errors::NotFound
|
||||
rescue Fog::Vsphere::Errors::NotFound
|
||||
tries += 1
|
||||
if tries <= 10 then
|
||||
sleep 15
|
||||
retry
|
||||
end
|
||||
nil
|
||||
end
|
||||
end
|
||||
{
|
||||
'vm_ref' => new_vm ? new_vm._ref : nil,
|
||||
'vm_attributes' => new_vm ? convert_vm_mob_ref_to_attr_hash(new_vm) : {},
|
||||
'task_ref' => task._ref
|
||||
}
|
||||
end
|
||||
end
|
||||
class Mock
|
||||
include Shared
|
||||
def vm_create(options = {})
|
||||
# Option handling
|
||||
options = vm_create_check_options(options)
|
||||
{
|
||||
'vm_ref' => 'vm-123',
|
||||
'task_ref' => 'task-1234'
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,14 +6,7 @@ module Fog
|
|||
def vm_destroy(options = {})
|
||||
raise ArgumentError, "instance_uuid is a required parameter" unless options.has_key? 'instance_uuid'
|
||||
|
||||
# Find the VM Object
|
||||
search_filter = { :uuid => options['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true }
|
||||
vm_mob_ref = @connection.searchIndex.FindAllByUuid(search_filter).first
|
||||
|
||||
unless vm_mob_ref.kind_of? RbVmomi::VIM::VirtualMachine
|
||||
raise Fog::Vsphere::Errors::NotFound,
|
||||
"Could not find VirtualMachine with instance uuid #{options['instance_uuid']}"
|
||||
end
|
||||
vm_mob_ref = get_vm_ref(options['instance_uuid'])
|
||||
task = vm_mob_ref.Destroy_Task
|
||||
task.wait_for_completion
|
||||
{ 'task_state' => task.info.state }
|
||||
|
|
|
@ -5,8 +5,7 @@ module Fog
|
|||
def vm_reconfig_hardware(options = {})
|
||||
raise ArgumentError, "hardware_spec is a required parameter" unless options.has_key? 'hardware_spec'
|
||||
raise ArgumentError, "instance_uuid is a required parameter" unless options.has_key? 'instance_uuid'
|
||||
search_filter = { :uuid => options['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true }
|
||||
vm_mob_ref = @connection.searchIndex.FindAllByUuid(search_filter).first
|
||||
vm_mob_ref = get_vm_by_ref(options['instance_uuid'])
|
||||
task = vm_mob_ref.ReconfigVM_Task(:spec => RbVmomi::VIM.VirtualMachineConfigSpec(options['hardware_spec']))
|
||||
task.wait_for_completion
|
||||
{ 'task_state' => task.info.state }
|
||||
|
|
|
@ -21,10 +21,10 @@ Shindo.tests('Fog::Compute[:vsphere]', ['vsphere']) do
|
|||
|
||||
tests("When converting an incomplete vm object") do
|
||||
test("it should return a Hash") do
|
||||
compute.convert_vm_mob_ref_to_attr_hash(fake_vm_mob_ref).kind_of? Hash
|
||||
compute.send(:convert_vm_mob_ref_to_attr_hash, fake_vm_mob_ref).kind_of? Hash
|
||||
end
|
||||
tests("The converted Hash should") do
|
||||
attr_hash = compute.convert_vm_mob_ref_to_attr_hash(fake_vm_mob_ref)
|
||||
attr_hash = compute.send(:convert_vm_mob_ref_to_attr_hash, fake_vm_mob_ref)
|
||||
test("have a name") { attr_hash['name'] == 'fakevm' }
|
||||
test("have a mo_ref") {attr_hash['mo_ref'] == 'vm-123' }
|
||||
test("have an id") { attr_hash['id'] == 'vm-123' }
|
||||
|
@ -33,7 +33,7 @@ Shindo.tests('Fog::Compute[:vsphere]', ['vsphere']) do
|
|||
end
|
||||
|
||||
tests("When passed a nil object") do
|
||||
attr_hash = compute.convert_vm_mob_ref_to_attr_hash(nil)
|
||||
attr_hash = compute.send :convert_vm_mob_ref_to_attr_hash, nil
|
||||
test("it should return a nil object") do
|
||||
attr_hash.nil?
|
||||
end
|
||||
|
|
|
@ -26,8 +26,7 @@ Shindo.tests('Fog::Compute[:vsphere] | server model', ['vsphere']) do
|
|||
:connection_state,
|
||||
:hypervisor,
|
||||
:name,
|
||||
:ipaddress,
|
||||
:is_a_template]
|
||||
:ipaddress]
|
||||
tests("The server model should respond to") do
|
||||
attributes.each do |attribute|
|
||||
test("#{attribute}") { server.respond_to? attribute }
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
Shindo.tests('Fog::Compute[:vsphere] | find_vm_by_ref request', ['vsphere']) do
|
||||
|
||||
compute = Fog::Compute[:vsphere]
|
||||
|
||||
tests("When missing arguments") do
|
||||
raises(ArgumentError, "Should raise ArgumentError when missing :vm_ref") do
|
||||
compute.find_vm_by_ref
|
||||
end
|
||||
raises(Fog::Compute::Vsphere::NotFound, "Should raise Fog::Compute::Vsphere::NotFound when the vm does not exist") do
|
||||
compute.find_vm_by_ref('vm_ref' => 'vm-000')
|
||||
end
|
||||
end
|
||||
|
||||
# centos56gm is a template
|
||||
existing_vms = { 'vm-715' => 'jefftest', 'vm-698' => 'centos56gm' }
|
||||
|
||||
tests("When looking for existing VM's the response") do
|
||||
existing_vms.each do |ref,name|
|
||||
response = compute.find_vm_by_ref('vm_ref' => ref)
|
||||
test("should be a kind of Hash") { response.kind_of? Hash }
|
||||
test("should have virtual_machine key") { response.has_key? 'virtual_machine' }
|
||||
returns(name, "#{ref} should return #{name}") { response['virtual_machine']['name'] }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,19 +1,11 @@
|
|||
Shindo.tests('Fog::Compute[:vsphere] | list_virtual_machines request', ['vsphere']) do
|
||||
|
||||
key = 'virtual_machines'
|
||||
|
||||
tests("When listing all machines") do
|
||||
|
||||
response = Fog::Compute[:vsphere].list_virtual_machines
|
||||
|
||||
tests("The response data format ...") do
|
||||
test("be a kind of Hash") { response.kind_of? Hash }
|
||||
test("have a #{key} key") do
|
||||
response.has_key? key
|
||||
end
|
||||
test("it should be a kind of Array") do
|
||||
response[key].kind_of? Array
|
||||
end
|
||||
test("be a kind of Hash") { response.kind_of? Array }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -26,9 +18,9 @@ Shindo.tests('Fog::Compute[:vsphere] | list_virtual_machines request', ['vsphere
|
|||
response = Fog::Compute[:vsphere].list_virtual_machines({'instance_uuid' => uuid})
|
||||
|
||||
tests("The response should") do
|
||||
test("contain one vm") { response[key].length == 1 }
|
||||
test("contain that is an attribute hash") { response[key][0].kind_of? Hash }
|
||||
test("find jefftest") { response[key].first['name'] == 'jefftest' }
|
||||
test("contain one vm") { response.length == 1 }
|
||||
test("contain that is an attribute hash") { response[0].kind_of? Hash }
|
||||
test("find jefftest") { response.first[:name] == 'jefftest' }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -37,7 +29,7 @@ Shindo.tests('Fog::Compute[:vsphere] | list_virtual_machines request', ['vsphere
|
|||
response = Fog::Compute[:vsphere].list_virtual_machines({'instance_uuid' => uuid})
|
||||
|
||||
tests("The response should") do
|
||||
test("be empty") { response[key].empty? }
|
||||
test("be empty") { response.empty? }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ Shindo.tests("Fog::Compute[:vsphere] | vm_clone request", 'vsphere') do
|
|||
response = nil
|
||||
response_linked = nil
|
||||
|
||||
template = "/Datacenters/Solutions/vm/Jeff/Templates/centos56gm2"
|
||||
template = "/Datacenters/Solutions/vm/rhel64"
|
||||
tests("Standard Clone | The return value should") do
|
||||
response = compute.vm_clone('path' => template, 'name' => 'cloning_vm', 'wait' => 1)
|
||||
test("be a kind of Hash") { response.kind_of? Hash }
|
||||
|
@ -13,7 +13,7 @@ Shindo.tests("Fog::Compute[:vsphere] | vm_clone request", 'vsphere') do
|
|||
end
|
||||
end
|
||||
|
||||
template = "/Datacenters/Solutions/vm/Jeff/Templates/centos56gm2"
|
||||
template = "/Datacenters/Solutions/vm/rhel64"
|
||||
tests("Linked Clone | The return value should") do
|
||||
response = compute.vm_clone('path' => template, 'name' => 'cloning_vm_linked', 'wait' => 1, 'linked_clone' => true)
|
||||
test("be a kind of Hash") { response.kind_of? Hash }
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
Shindo.tests("Fog::Compute[:vsphere] | vm_create request", 'vsphere') do
|
||||
#require 'guid'
|
||||
path = "/Datacenters/Solutions"
|
||||
compute = Fog::Compute[:vsphere]
|
||||
|
||||
tests("The return value should") do
|
||||
response = compute.vm_create('path' => path, 'name' => 'fog_test_vm', 'cluster' => 'cluster01')
|
||||
test("be a kind of Hash") { response.kind_of? Hash }
|
||||
%w{ vm_ref task_ref }.each do |key|
|
||||
test("have a #{key} key") { response.has_key? key }
|
||||
end
|
||||
end
|
||||
tests("When invalid input is presented") do
|
||||
raises(ArgumentError, 'it should raise ArgumentError') { compute.vm_create(:foo => 1) }
|
||||
raises(Fog::Compute::Vsphere::NotFound, 'it should raise Fog::Compute::Vsphere::NotFound when the UUID is not a string') do
|
||||
pending # require 'guid'
|
||||
compute.vm_create('instance_uuid' => Guid.from_s(template), 'name' => 'jefftestfoo')
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue