vmesh 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitattributes +1 -0
- data/.gitignore +7 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +62 -0
- data/LICENSE.txt +21 -0
- data/README.md +175 -0
- data/README.rdoc +6 -0
- data/Rakefile +44 -0
- data/bin/vmesh +130 -0
- data/features/step_definitions/vmesh.create_steps.rb +9 -0
- data/features/step_definitions/vmesh.power_steps.rb +3 -0
- data/features/step_definitions/vmesh_steps.rb +9 -0
- data/features/support/env.rb +15 -0
- data/features/vmesh.create.feature +14 -0
- data/features/vmesh.feature +18 -0
- data/features/vmesh.power.feature +12 -0
- data/lib/vmesh/commands/create.rb +65 -0
- data/lib/vmesh/commands/create_helpers.rb +6 -0
- data/lib/vmesh/commands/list.rb +39 -0
- data/lib/vmesh/commands/power.rb +19 -0
- data/lib/vmesh/commands/revert.rb +16 -0
- data/lib/vmesh/create.rb +11 -0
- data/lib/vmesh/custom_spec.rb +25 -0
- data/lib/vmesh/datacenter.rb +42 -0
- data/lib/vmesh/datastore.rb +47 -0
- data/lib/vmesh/list.rb +4 -0
- data/lib/vmesh/logger.rb +14 -0
- data/lib/vmesh/machine.rb +67 -0
- data/lib/vmesh/server_defaults.rb +25 -0
- data/lib/vmesh/version.rb +3 -0
- data/lib/vmesh/vsphere.rb +88 -0
- data/lib/vmesh.rb +20 -0
- data/test/create_test.rb +45 -0
- data/test/datastore_test.rb +44 -0
- data/test/machine_test.rb +93 -0
- data/test/power_test.rb +33 -0
- data/test/test_helper.rb +22 -0
- data/test/vsphere_test.rb +44 -0
- data/vendor/cache/rbvmomi-1.8.2.gem +0 -0
- data/vmesh.gemspec +30 -0
- data/vmesh.rdoc +5 -0
- metadata +240 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
desc 'revert vm to previous snapshot'
|
3
|
+
arg_name 'vm_name'
|
4
|
+
|
5
|
+
command :revert do |c|
|
6
|
+
c.action do |global_options,options,args|
|
7
|
+
ARGV.size >= 1 or abort 'must specify VM'
|
8
|
+
vm_target = ARGV.shift
|
9
|
+
@logger.debug "Revert invoked for #{vm_target}\n\t#{global_options[:host]}\n\t#{options}\n\t#{args}."
|
10
|
+
|
11
|
+
vm_manager = Vmesh::VSphere.new global_options
|
12
|
+
vm = vm_manager.get_machine(vm_target, global_options[:datacenter])
|
13
|
+
Vmesh::logger.debug "Got vm #{vm.name}"
|
14
|
+
vm.revert
|
15
|
+
end
|
16
|
+
end
|
data/lib/vmesh/create.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
module Vmesh
|
2
|
+
def create(vim, datacenter, template_name, new_machine_name, ip_address)
|
3
|
+
# vm get
|
4
|
+
template = Vmesh::Machine::get vim, datacenter, template_name
|
5
|
+
# get spec, I think this is right?
|
6
|
+
spec = Vmesh::CustomSpec::get vim.serviceContent.customizationSpecManager
|
7
|
+
spec.destination_ip_address ip_address
|
8
|
+
# vm clone
|
9
|
+
vm.clone new_machine_name, spec
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rbvmomi'
|
2
|
+
|
3
|
+
module Vmesh
|
4
|
+
class CustomSpec
|
5
|
+
attr_accessor :ip_address, :spec
|
6
|
+
def initialize(spec)
|
7
|
+
@spec = spec
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.get(custom_spec_manager, name)
|
11
|
+
Vmesh::logger.debug "Looking for spec #{name}"
|
12
|
+
spec = custom_spec_manager.GetCustomizationSpec(:name => name).spec or raise "unable to find the custom spec #{name}."
|
13
|
+
CustomSpec.new(spec)
|
14
|
+
end
|
15
|
+
|
16
|
+
def destination_ip_address=(ip)
|
17
|
+
Vmesh::logger.debug "Setting spec ip address to #{ip}"
|
18
|
+
@spec.nicSettingMap.first.adapter.ip = RbVmomi::VIM::CustomizationFixedIp("ipAddress" => ip)
|
19
|
+
end
|
20
|
+
|
21
|
+
def destination_ip_address
|
22
|
+
@spec.nicSettingMap.first.adapter.ip
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Vmesh
|
2
|
+
class Datacenter
|
3
|
+
attr_accessor :dc
|
4
|
+
def initialize(datacenter)
|
5
|
+
@dc = datacenter
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.get(vim, datacenter_name)
|
9
|
+
dc = vim.serviceInstance.find_datacenter(datacenter_name) or abort "datacenter #{datacenter_name} not found"
|
10
|
+
Datacenter.new dc
|
11
|
+
end
|
12
|
+
|
13
|
+
# non wrapped object, gasp!
|
14
|
+
def self.find_pool(vim, name, dcname = nil)
|
15
|
+
Vmesh::logger.debug "Looking for datacenter pool #{name} in datacenter named #{dcname}."
|
16
|
+
dc = vim.serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
|
17
|
+
dc = Datacenter.get(vim, nil).dc
|
18
|
+
baseEntity = dc.hostFolder
|
19
|
+
entityArray = name.split('/')
|
20
|
+
entityArray.each do |entityArrItem|
|
21
|
+
if entityArrItem != ''
|
22
|
+
if baseEntity.is_a? RbVmomi::VIM::Folder
|
23
|
+
baseEntity = baseEntity.childEntity.find { |f| f.name == entityArrItem } or abort "no such pool #{name} while looking for #{entityArrItem}"
|
24
|
+
elsif baseEntity.is_a? RbVmomi::VIM::ClusterComputeResource
|
25
|
+
baseEntity = baseEntity.resourcePool.resourcePool.find { |f| f.name == entityArrItem } or abort "no such pool #{name} while looking for #{entityArrItem}"
|
26
|
+
elsif baseEntity.is_a? RbVmomi::VIM::ResourcePool
|
27
|
+
baseEntity = baseEntity.resourcePool.find { |f| f.name == entityArrItem } or abort "no such pool #{name} while looking for #{entityArrItem}"
|
28
|
+
else
|
29
|
+
abort "Unexpected Object type encountered #{baseEntity.type} while finding resourcePool"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
baseEntity = baseEntity.resourcePool if not baseEntity.is_a?(RbVmomi::VIM::ResourcePool) and baseEntity.respond_to?(:resourcePool)
|
35
|
+
baseEntity
|
36
|
+
end
|
37
|
+
|
38
|
+
def name
|
39
|
+
@dc.name
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rbvmomi'
|
2
|
+
|
3
|
+
module Vmesh
|
4
|
+
class Datastore
|
5
|
+
attr_accessor :ds
|
6
|
+
def initialize(ds)
|
7
|
+
@ds = ds
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.get(vim, name, datacenter)
|
11
|
+
Vmesh::logger.debug "Getting datastore named #{name} at datacenter #{datacenter.name}."
|
12
|
+
stores = self.get_all(vim, datacenter).select{ |ds| ds.name == name }
|
13
|
+
if stores.nil? or stores.empty?
|
14
|
+
Vmesh::logger.info "No exact match found, searching for partial match"
|
15
|
+
stores = self.get_all(vim, datacenter).select{ |ds| ds.name.include? name }
|
16
|
+
Vmesh::logger.debug "Found #{stores.count} datastores."
|
17
|
+
Vmesh::logger.debug "#{stores.map{|ds| "Name #{ds.name}, free space #{ds.free_space}"}}"
|
18
|
+
end
|
19
|
+
stores.sort_by{ |ds| ds.free_space }.reverse.first
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.get_all(vim, datacenter)
|
23
|
+
Vmesh::logger.debug "get_all datastores at #{datacenter.name}."
|
24
|
+
vim.serviceContent.viewManager.CreateContainerView({
|
25
|
+
:container => datacenter.dc.datastoreFolder,
|
26
|
+
:type => ["Datastore"],
|
27
|
+
:recursive => true
|
28
|
+
}).view.map{ |ds| Datastore.new(ds) } #.select{|ds| ds.name == name}.first
|
29
|
+
end
|
30
|
+
|
31
|
+
def name
|
32
|
+
@ds.name
|
33
|
+
end
|
34
|
+
|
35
|
+
def free_space
|
36
|
+
@ds.summary.freeSpace
|
37
|
+
end
|
38
|
+
|
39
|
+
def capacity
|
40
|
+
@ds.summary.capacity
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
"name: #{name}, free_space: #{free_space}, capacity: #{capacity}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/vmesh/list.rb
ADDED
data/lib/vmesh/logger.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'rbvmomi'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module Vmesh
|
5
|
+
class Machine
|
6
|
+
attr_accessor :name, :vm
|
7
|
+
@@states = {'on' => 'PowerOnVM_Task', 'off' => 'PowerOffVM_Task', 'reset' => 'ResetVM_Task', 'suspend' => 'SuspendVM_Task', 'destroy' => 'Destroy_Task' }
|
8
|
+
|
9
|
+
def initialize(vm)
|
10
|
+
Vmesh::logger.debug "New machine wrapper object with #{vm}"
|
11
|
+
@vm = vm
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.get(vs_manager, datacenter_name, name)
|
15
|
+
Vmesh::logger.debug "looking for vm #{name} at dc #{datacenter_name}."
|
16
|
+
vm = vs_manager.vm_root_folder.traverse(name)
|
17
|
+
vm or raise "unable to find machine #{name} at #{datacenter_name}"
|
18
|
+
Machine.new vm
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.valid_states
|
22
|
+
@@states.keys
|
23
|
+
end
|
24
|
+
|
25
|
+
def power(desired_state)
|
26
|
+
p "Found" if @@states.has_key? desired_state
|
27
|
+
p "NOT Found" unless @@states.has_key? desired_state
|
28
|
+
raise ArgumentError, "Invalid desired power state" unless @@states.has_key? desired_state
|
29
|
+
@vm.send(@@states[desired_state])
|
30
|
+
end
|
31
|
+
|
32
|
+
def revert
|
33
|
+
@vm.RevertToCurrentSnapshot_Task.wait_for_completion
|
34
|
+
end
|
35
|
+
|
36
|
+
def command
|
37
|
+
raise NotImplementedError
|
38
|
+
end
|
39
|
+
|
40
|
+
def describe
|
41
|
+
raise NotImplementedError
|
42
|
+
end
|
43
|
+
|
44
|
+
def template?
|
45
|
+
raise NotImplementedError
|
46
|
+
end
|
47
|
+
|
48
|
+
def ipAddress
|
49
|
+
@vm.guest.ipAddress
|
50
|
+
end
|
51
|
+
|
52
|
+
def clone_to (vm_name, vm_folder = @vm.parent, datastore = nil, custom_spec = nil, pool = nil, config = {})
|
53
|
+
Vmesh::logger.info "Cloning #{@name} to a new vm named #{vm_name} in folder #{vm_folder}."
|
54
|
+
ds = datastore.ds unless datastore.nil?
|
55
|
+
relocateSpec = RbVmomi::VIM.VirtualMachineRelocateSpec(:datastore => ds,
|
56
|
+
:diskMoveType => :moveChildMostDiskBacking,
|
57
|
+
:pool => pool)
|
58
|
+
clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(:location => relocateSpec,
|
59
|
+
:powerOn => false,
|
60
|
+
:template => false)
|
61
|
+
clone_spec.customization = custom_spec.spec if custom_spec
|
62
|
+
Vmesh::logger.debug "Custom spec #{custom_spec} supplied, config #{config.inspect}."
|
63
|
+
|
64
|
+
Machine.new(@vm.CloneVM_Task(:folder => vm_folder, :name => vm_name, :spec => clone_spec, :numCPUs => config[:numCPUs], :memoryMB => config[:memoryMB]).wait_for_completion)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Vmesh
|
2
|
+
@template = {
|
3
|
+
:windows_dmz => {
|
4
|
+
:name => 'Templates/W2012_DC',
|
5
|
+
:spec => 'Windows2012R2_DC_DMZ'
|
6
|
+
},
|
7
|
+
:windows => {
|
8
|
+
:name => 'Templates/W2012R2',
|
9
|
+
:spec => 'Win2012R2_DC_Frontend'
|
10
|
+
#:name => 'Templates/W2012R2_DC',
|
11
|
+
},
|
12
|
+
:linux => {
|
13
|
+
:name => 'Templates/CENTOS_6',
|
14
|
+
:spec => 'Linux No Prompt'
|
15
|
+
},
|
16
|
+
:suse => {
|
17
|
+
:name => 'Templates/SLES11-2-WHICS',
|
18
|
+
:spec => 'Linux No Prompt'
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
def self.template
|
23
|
+
@template
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'rbvmomi'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
# VM Manager Class to hand all things VSphere
|
5
|
+
module Vmesh
|
6
|
+
class VSphere
|
7
|
+
attr_accessor :vim, :options
|
8
|
+
def initialize(connection_options)
|
9
|
+
Vmesh::logger.debug "Opening connection to #{connection_options['host']}"
|
10
|
+
@vim = RbVmomi::VIM.connect connection_options
|
11
|
+
@options = connection_options
|
12
|
+
end
|
13
|
+
|
14
|
+
# Can we search through the datacenters for a machine?
|
15
|
+
# Should we get the machine from the datacenters?
|
16
|
+
def get_machine(machine_name, datacenter)
|
17
|
+
Machine::get(self, datacenter, machine_name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def clone_machine(vm_type, vm_target, default_vm_folder, machine_options)
|
21
|
+
Vmesh::template.has_key? vm_type.to_sym or raise "unknown machine type #{vm_type}, known types are #{Vmesh::template.keys.to_s}"
|
22
|
+
config = {}
|
23
|
+
template = Vmesh::template[vm_type.to_sym]
|
24
|
+
vm_dest = VSphere.parse_vm_target vm_target, default_vm_folder
|
25
|
+
vm_template = get_machine(template[:name], @options[:datacenter])
|
26
|
+
# Refactor & pass in options with the get or alternatively add a get and set method
|
27
|
+
spec = get_custom_spec(template[:spec])
|
28
|
+
spec.destination_ip_address = machine_options[:ip_address] if machine_options[:ip_address]
|
29
|
+
config[:numCPUs] = machine_options[:numCPUs] if machine_options[:numCPUs].to_s != ''
|
30
|
+
config[:memoryMB] = machine_options[:memoryMB] if machine_options[:memoryMB].to_s != ''
|
31
|
+
pool = get_resource_pool(@options[:resource_pool], @options[:datacenter])
|
32
|
+
datacenter = get_datacenter(@options[:datacenter])
|
33
|
+
datastore = get_datastore(machine_options[:datastore], datacenter)
|
34
|
+
raise "No datastore found matching #{machine_options[:datastore]}. Exiting." if datastore.nil?
|
35
|
+
Vmesh::logger.debug "Got datastore named #{datastore.name} with free space #{datastore.free_space}."
|
36
|
+
Vmesh::logger.debug "Creating vm in folder #{vm_dest[:folder]} with name #{vm_dest[:name]}."
|
37
|
+
folder = get_folder(vm_dest[:folder], @options[:datacenter])
|
38
|
+
Vmesh::logger.debug "Using folder #{folder.to_s}."
|
39
|
+
vm_template.clone_to(vm_dest[:name], folder, datastore, spec, pool, config)
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_custom_spec(name)
|
43
|
+
spec_mgr = @vim.serviceContent.customizationSpecManager
|
44
|
+
CustomSpec::get(spec_mgr, name)
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_resource_pool(name, datacenter_name)
|
48
|
+
# KRUT this should be a ResourcePool wrapper object instead?
|
49
|
+
Vmesh::logger.debug "Chasing resource pool #{name}"
|
50
|
+
Datacenter::find_pool(@vim, name, datacenter_name)
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_datastore(name, datacenter)
|
54
|
+
Vmesh::logger.debug "Getting datastore #{name}"
|
55
|
+
Datastore::get(@vim, name, datacenter)
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_datacenter(name)
|
59
|
+
Vmesh::Datacenter::get(@vim, name)
|
60
|
+
end
|
61
|
+
|
62
|
+
def root_folder
|
63
|
+
@vim.serviceInstance.content.rootFolder
|
64
|
+
end
|
65
|
+
|
66
|
+
def vm_root_folder
|
67
|
+
@vim.serviceInstance.content.rootFolder.traverse(@options[:datacenter]).vmFolder
|
68
|
+
end
|
69
|
+
|
70
|
+
def get_folder(path, datacenter_name = @options[:datacenter])
|
71
|
+
Vmesh::logger.debug "Looking for folder #{path}."
|
72
|
+
path.to_s == '/' ? vm_root_folder : vm_root_folder.traverse(path)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
def self.parse_vm_target(vm_target, default_vm_path = '/')
|
77
|
+
vm_details = vm_target.match(/(.+)\/(.+)/)
|
78
|
+
vm = Hash.new
|
79
|
+
vm[:folder] = default_vm_path
|
80
|
+
vm[:name] = vm_target
|
81
|
+
if vm_details
|
82
|
+
vm[:folder] = vm_details[1]
|
83
|
+
vm[:name] = vm_details[2]
|
84
|
+
end
|
85
|
+
vm
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/vmesh.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'vmesh/version.rb'
|
2
|
+
|
3
|
+
# Add requires for other files you add to your project here, so
|
4
|
+
# you just need to require this one file in your bin file
|
5
|
+
|
6
|
+
require 'vmesh/server_defaults.rb'
|
7
|
+
require 'vmesh/machine.rb'
|
8
|
+
require 'vmesh/logger.rb'
|
9
|
+
require 'vmesh/create.rb'
|
10
|
+
require 'vmesh/list.rb'
|
11
|
+
require 'vmesh/custom_spec.rb'
|
12
|
+
require 'vmesh/datacenter.rb'
|
13
|
+
require 'vmesh/vsphere.rb'
|
14
|
+
require 'vmesh/datastore.rb'
|
15
|
+
|
16
|
+
module Vmesh
|
17
|
+
def self.logger
|
18
|
+
@logger ||= Logger.new STDOUT
|
19
|
+
end
|
20
|
+
end
|
data/test/create_test.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'vmesh/commands/create_helpers'
|
3
|
+
|
4
|
+
class CreateTest < Test::Unit::TestCase
|
5
|
+
#class CreateTest < Test::Test
|
6
|
+
|
7
|
+
def setup
|
8
|
+
Vmesh::logger = Logger.new(RUBY_PLATFORM =~ /mswin|mingw/ ? 'NUL:' : '/dev/null', 7)
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_parse_vm_target_with_folder
|
15
|
+
#vm_details = Vmesh::parse_vm_target("dummy_folder/dummy_vm_name")
|
16
|
+
#assert vm_details.is_hash?
|
17
|
+
assert true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
=begin
|
22
|
+
def get_raw_vmfolder(path, datacenter_name)
|
23
|
+
# The required path syntax - 'topfolder/subfolder
|
24
|
+
|
25
|
+
# Clean up path to be relative since we're providing datacenter name
|
26
|
+
dc = find_raw_datacenter(datacenter_name)
|
27
|
+
dc_root_folder = dc.vmFolder
|
28
|
+
# Filter the root path for this datacenter not to be used."
|
29
|
+
dc_root_folder_path=dc_root_folder.path.map { | id, name | name }.join("/")
|
30
|
+
paths = path.sub(/^\/?#{Regexp.quote(dc_root_folder_path)}\/?/, '').split('/')
|
31
|
+
|
32
|
+
return dc_root_folder if paths.empty?
|
33
|
+
# Walk the tree resetting the folder pointer as we go
|
34
|
+
paths.inject(dc_root_folder) do |last_returned_folder, sub_folder|
|
35
|
+
# JJM VIM::Folder#find appears to be quite efficient as it uses the
|
36
|
+
# searchIndex It certainly appears to be faster than
|
37
|
+
# VIM::Folder#inventory since that returns _all_ managed objects of
|
38
|
+
# a certain type _and_ their properties.
|
39
|
+
sub = last_returned_folder.find(sub_folder, RbVmomi::VIM::Folder)
|
40
|
+
raise ArgumentError, "Could not descend into #{sub_folder}. Please check your path. #{path}" unless sub
|
41
|
+
sub
|
42
|
+
end
|
43
|
+
end
|
44
|
+
=end
|
45
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
include RbVmomi
|
4
|
+
include Vmesh
|
5
|
+
|
6
|
+
class DatastoreTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
Vmesh::logger = Logger.new(RUBY_PLATFORM =~ /mswin|mingw/ ? 'NUL:' : '/dev/null', 7)
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_gets_exact_match_not_partial
|
16
|
+
fake_ds1,matching_fake,fake_ds2 = mock,mock,mock
|
17
|
+
vim,dc = mock,mock
|
18
|
+
fake_ds1.stubs(:name => "GRAIN_STORE", :free_space => 100)
|
19
|
+
matching_fake = stub(:name => "GRAIN_STORE_1", :free_space => 200)
|
20
|
+
fake_ds2.stubs(:name => "BRAIN_STORE", :free_space => 200)
|
21
|
+
stores = [fake_ds1, matching_fake, fake_ds2]
|
22
|
+
dc.stubs(:name => 'fake_dc')
|
23
|
+
Vmesh::Datastore.stubs(:get_all => stores)
|
24
|
+
|
25
|
+
store = Vmesh::Datastore.get vim,'GRAIN_STORE_1',dc
|
26
|
+
|
27
|
+
assert_equal matching_fake,store
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_gets_partial_with_most_space_when_no_exact_match
|
31
|
+
fake_ds1,matching_fake,fake_ds2 = mock,mock,mock
|
32
|
+
vim,dc = mock,mock
|
33
|
+
fake_ds1.stubs(:name => "GRAIN_STORE", :free_space => 100)
|
34
|
+
matching_fake = stub(:name => "GRAIN_STORE_1", :free_space => 200)
|
35
|
+
fake_ds2.stubs(:name => "BRAIN_STORE", :free_space => 20)
|
36
|
+
stores = [fake_ds1, matching_fake, fake_ds2]
|
37
|
+
dc.stubs(:name => 'fake_dc')
|
38
|
+
Vmesh::Datastore.stubs(:get_all => stores)
|
39
|
+
|
40
|
+
store = Vmesh::Datastore.get vim,'RAIN_STORE',dc
|
41
|
+
|
42
|
+
assert_equal matching_fake,store
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
include RbVmomi
|
4
|
+
include Vmesh
|
5
|
+
|
6
|
+
class MachineTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
Vmesh::logger = Logger.new(RUBY_PLATFORM =~ /mswin|mingw/ ? 'NUL:' : '/dev/null', 7)
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
end
|
14
|
+
|
15
|
+
=begin
|
16
|
+
def test_get_machine_uses_vim_connection
|
17
|
+
connection_options = Hash.new
|
18
|
+
VIM.stubs(:connect).returns("a string")
|
19
|
+
vsphere_vm_manager = VSphere.new(connection_options)
|
20
|
+
#Machine.expects(:get).returns("fake vm")
|
21
|
+
mock_vm = Object.new
|
22
|
+
Machine.stubs( :get ).returns(mock_vm)
|
23
|
+
#returns( stub(:cool? => true) ) # returns an object with just a .cool? method which in turn returns true
|
24
|
+
|
25
|
+
vm = vsphere_vm_manager.get_machine("fake_machine","fake datacenter")
|
26
|
+
|
27
|
+
assert vm == mock_vm
|
28
|
+
end
|
29
|
+
=end
|
30
|
+
|
31
|
+
def test_clone_machine_uses_custom_spec
|
32
|
+
vm_template, fake_task = mock, mock
|
33
|
+
fake_task.expects(:wait_for_completion)
|
34
|
+
vm_template.expects(:CloneVM_Task).returns(fake_task)
|
35
|
+
template = Machine.new(vm_template)
|
36
|
+
mock_custom_spec = mock
|
37
|
+
mock_custom_spec.stubs(:spec)
|
38
|
+
VIM.stubs(:VirtualMachineRelocateSpec)
|
39
|
+
mock_clone_spec = mock
|
40
|
+
mock_clone_spec.expects(:customization=)
|
41
|
+
VIM.stubs(:VirtualMachineCloneSpec).returns(mock_clone_spec)
|
42
|
+
|
43
|
+
template.clone_to 'frank', '/', nil, mock_custom_spec
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_power_on_invokes_PowerOnVMTask
|
47
|
+
fake_vs_vm = mock
|
48
|
+
vm = Machine.new(fake_vs_vm)
|
49
|
+
fake_vs_vm.expects(:PowerOnVM_Task)
|
50
|
+
|
51
|
+
vm.power 'on'
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_power_off_invokes_PowerOffVMTask
|
55
|
+
fake_vs_vm = mock
|
56
|
+
vm = Machine.new(fake_vs_vm)
|
57
|
+
fake_vs_vm.expects(:PowerOffVM_Task)
|
58
|
+
|
59
|
+
vm.power 'off'
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_power_reset_invokes_PowerOnVMTask
|
63
|
+
fake_vs_vm = mock
|
64
|
+
vm = Machine.new(fake_vs_vm)
|
65
|
+
fake_vs_vm.expects(:ResetVM_Task)
|
66
|
+
|
67
|
+
vm.power 'reset'
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_power_suspend_invokes_PowerOnVMTask
|
71
|
+
fake_vs_vm = mock
|
72
|
+
vm = Machine.new(fake_vs_vm)
|
73
|
+
fake_vs_vm.expects(:SuspendVM_Task)
|
74
|
+
|
75
|
+
vm.power 'suspend'
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_power_destroy_invokes_PowerOnVMTask
|
79
|
+
fake_vs_vm = mock
|
80
|
+
vm = Machine.new(fake_vs_vm)
|
81
|
+
fake_vs_vm.expects(:Destroy_Task)
|
82
|
+
|
83
|
+
vm.power 'destroy'
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_power_unknown_raises
|
87
|
+
fake_vs_vm = mock
|
88
|
+
vm = Machine.new(fake_vs_vm)
|
89
|
+
#fake_vs_vm.expects(:PowerOnVM_Task)
|
90
|
+
|
91
|
+
assert_raise(ArgumentError) { vm.power "to the people" }
|
92
|
+
end
|
93
|
+
end
|
data/test/power_test.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'mocha/test_unit'
|
3
|
+
|
4
|
+
include RbVmomi
|
5
|
+
include Vmesh
|
6
|
+
|
7
|
+
class VSphereTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@mock_vim = Object.new
|
11
|
+
#@mock_vim = mock RbVmomi::VIM
|
12
|
+
VIM.stubs(:connect).returns(@mock_vim)
|
13
|
+
@mock_connection_options = Hash.new
|
14
|
+
Vmesh::logger = Logger.new(RUBY_PLATFORM =~ /mswin|mingw/ ? 'NUL:' : '/dev/null', 7)
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_root_folder_gets_from_vim
|
21
|
+
vsphere_vm_manager = VSphere.new(@mock_connection_options)
|
22
|
+
mock_root_folder = Object.new
|
23
|
+
mock_content = Object.new
|
24
|
+
mock_content.expects(:rootFolder).returns(mock_root_folder)
|
25
|
+
mock_service_instance = Object.new
|
26
|
+
mock_service_instance.expects(:content).returns(mock_content)
|
27
|
+
@mock_vim.expects(:serviceInstance).returns(mock_service_instance) #Object.new.expects(:content).expects(:rootFolder).returns('a folder'))
|
28
|
+
|
29
|
+
root_folder = vsphere_vm_manager.root_folder
|
30
|
+
|
31
|
+
assert root_folder == mock_root_folder
|
32
|
+
end
|
33
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#require 'minitest/autorun'
|
2
|
+
require 'test/unit'
|
3
|
+
# At bottom of test_helper.rb
|
4
|
+
#require "mocha/setup"
|
5
|
+
|
6
|
+
|
7
|
+
=begin
|
8
|
+
# Add test libraries you want to use here, e.g. mocha
|
9
|
+
require 'mocha/mini_test'
|
10
|
+
=end
|
11
|
+
require_relative '../lib/vmesh.rb'
|
12
|
+
require 'mocha/setup'
|
13
|
+
require 'mocha/test_unit'
|
14
|
+
|
15
|
+
|
16
|
+
class Test::Unit::TestCase
|
17
|
+
#class Test::Test
|
18
|
+
|
19
|
+
# Add global extensions to the test case class here
|
20
|
+
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'mocha/test_unit'
|
3
|
+
|
4
|
+
include RbVmomi
|
5
|
+
include Vmesh
|
6
|
+
|
7
|
+
class VSphereTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@mock_vim = Object.new
|
11
|
+
VIM.stubs(:connect).returns(@mock_vim)
|
12
|
+
@mock_connection_options = Hash.new
|
13
|
+
Vmesh::logger = Logger.new(RUBY_PLATFORM =~ /mswin|mingw/ ? 'NUL:' : '/dev/null', 7)
|
14
|
+
end
|
15
|
+
|
16
|
+
def teardown
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_get_machine_uses_vim_connection
|
20
|
+
vsphere_vm_manager = VSphere.new(@mock_connection_options)
|
21
|
+
#Machine.expects(:get).returns('fake vm')
|
22
|
+
mock_vm = Object.new
|
23
|
+
Machine.stubs( :get ).returns(mock_vm)
|
24
|
+
#returns( stub(:cool? => true) ) # returns an object with just a .cool? method which in turn returns true
|
25
|
+
|
26
|
+
vm = vsphere_vm_manager.get_machine('fake_machine','fake datacenter')
|
27
|
+
|
28
|
+
assert vm == mock_vm
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_root_folder_gets_from_vim
|
32
|
+
vsphere_vm_manager = VSphere.new(@mock_connection_options)
|
33
|
+
mock_root_folder = Object.new
|
34
|
+
mock_content = Object.new
|
35
|
+
mock_content.expects(:rootFolder).returns(mock_root_folder)
|
36
|
+
mock_service_instance = Object.new
|
37
|
+
mock_service_instance.expects(:content).returns(mock_content)
|
38
|
+
@mock_vim.expects(:serviceInstance).returns(mock_service_instance) #Object.new.expects(:content).expects(:rootFolder).returns('a folder'))
|
39
|
+
|
40
|
+
root_folder = vsphere_vm_manager.root_folder
|
41
|
+
|
42
|
+
assert root_folder == mock_root_folder
|
43
|
+
end
|
44
|
+
end
|
Binary file
|