fog-vsphere 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.travis.yml +32 -0
- data/CONTRIBUTING.md +18 -0
- data/CONTRIBUTORS.md +59 -0
- data/Gemfile +5 -0
- data/LICENSE.md +20 -0
- data/README.md +31 -0
- data/Rakefile +8 -0
- data/fog-vsphere.gemspec +32 -0
- data/gemfiles/Gemfile.1.9.2+ +8 -0
- data/gemfiles/Gemfile.1.9.2- +11 -0
- data/lib/fog/vsphere.rb +41 -0
- data/lib/fog/vsphere/compute.rb +473 -0
- data/lib/fog/vsphere/models/compute/cluster.rb +28 -0
- data/lib/fog/vsphere/models/compute/clusters.rb +22 -0
- data/lib/fog/vsphere/models/compute/customfield.rb +16 -0
- data/lib/fog/vsphere/models/compute/customfields.rb +23 -0
- data/lib/fog/vsphere/models/compute/customvalue.rb +14 -0
- data/lib/fog/vsphere/models/compute/customvalues.rb +33 -0
- data/lib/fog/vsphere/models/compute/datacenter.rb +44 -0
- data/lib/fog/vsphere/models/compute/datacenters.rb +19 -0
- data/lib/fog/vsphere/models/compute/datastore.rb +21 -0
- data/lib/fog/vsphere/models/compute/datastores.rb +21 -0
- data/lib/fog/vsphere/models/compute/folder.rb +24 -0
- data/lib/fog/vsphere/models/compute/folders.rb +23 -0
- data/lib/fog/vsphere/models/compute/interface.rb +91 -0
- data/lib/fog/vsphere/models/compute/interfaces.rb +66 -0
- data/lib/fog/vsphere/models/compute/interfacetype.rb +22 -0
- data/lib/fog/vsphere/models/compute/interfacetypes.rb +34 -0
- data/lib/fog/vsphere/models/compute/network.rb +18 -0
- data/lib/fog/vsphere/models/compute/networks.rb +22 -0
- data/lib/fog/vsphere/models/compute/process.rb +17 -0
- data/lib/fog/vsphere/models/compute/resource_pool.rb +19 -0
- data/lib/fog/vsphere/models/compute/resource_pools.rb +22 -0
- data/lib/fog/vsphere/models/compute/scsicontroller.rb +16 -0
- data/lib/fog/vsphere/models/compute/server.rb +325 -0
- data/lib/fog/vsphere/models/compute/servers.rb +36 -0
- data/lib/fog/vsphere/models/compute/servertype.rb +36 -0
- data/lib/fog/vsphere/models/compute/servertypes.rb +23 -0
- data/lib/fog/vsphere/models/compute/snapshot.rb +35 -0
- data/lib/fog/vsphere/models/compute/snapshots.rb +27 -0
- data/lib/fog/vsphere/models/compute/template.rb +11 -0
- data/lib/fog/vsphere/models/compute/templates.rb +19 -0
- data/lib/fog/vsphere/models/compute/volume.rb +99 -0
- data/lib/fog/vsphere/models/compute/volumes.rb +53 -0
- data/lib/fog/vsphere/requests/compute/cloudinit_to_customspec.rb +65 -0
- data/lib/fog/vsphere/requests/compute/create_folder.rb +22 -0
- data/lib/fog/vsphere/requests/compute/create_vm.rb +169 -0
- data/lib/fog/vsphere/requests/compute/current_time.rb +18 -0
- data/lib/fog/vsphere/requests/compute/get_cluster.rb +25 -0
- data/lib/fog/vsphere/requests/compute/get_compute_resource.rb +41 -0
- data/lib/fog/vsphere/requests/compute/get_datacenter.rb +31 -0
- data/lib/fog/vsphere/requests/compute/get_datastore.rb +30 -0
- data/lib/fog/vsphere/requests/compute/get_folder.rb +74 -0
- data/lib/fog/vsphere/requests/compute/get_interface_type.rb +15 -0
- data/lib/fog/vsphere/requests/compute/get_network.rb +59 -0
- data/lib/fog/vsphere/requests/compute/get_resource_pool.rb +26 -0
- data/lib/fog/vsphere/requests/compute/get_server_type.rb +32 -0
- data/lib/fog/vsphere/requests/compute/get_template.rb +16 -0
- data/lib/fog/vsphere/requests/compute/get_virtual_machine.rb +57 -0
- data/lib/fog/vsphere/requests/compute/get_vm_first_scsi_controller.rb +26 -0
- data/lib/fog/vsphere/requests/compute/list_child_snapshots.rb +71 -0
- data/lib/fog/vsphere/requests/compute/list_clusters.rb +72 -0
- data/lib/fog/vsphere/requests/compute/list_compute_resources.rb +92 -0
- data/lib/fog/vsphere/requests/compute/list_customfields.rb +21 -0
- data/lib/fog/vsphere/requests/compute/list_datacenters.rb +53 -0
- data/lib/fog/vsphere/requests/compute/list_datastores.rb +40 -0
- data/lib/fog/vsphere/requests/compute/list_folders.rb +44 -0
- data/lib/fog/vsphere/requests/compute/list_interface_types.rb +25 -0
- data/lib/fog/vsphere/requests/compute/list_networks.rb +38 -0
- data/lib/fog/vsphere/requests/compute/list_processes.rb +40 -0
- data/lib/fog/vsphere/requests/compute/list_resource_pools.rb +38 -0
- data/lib/fog/vsphere/requests/compute/list_server_types.rb +54 -0
- data/lib/fog/vsphere/requests/compute/list_templates.rb +48 -0
- data/lib/fog/vsphere/requests/compute/list_virtual_machines.rb +80 -0
- data/lib/fog/vsphere/requests/compute/list_vm_customvalues.rb +20 -0
- data/lib/fog/vsphere/requests/compute/list_vm_interfaces.rb +63 -0
- data/lib/fog/vsphere/requests/compute/list_vm_snapshots.rb +66 -0
- data/lib/fog/vsphere/requests/compute/list_vm_volumes.rb +52 -0
- data/lib/fog/vsphere/requests/compute/modify_vm_interface.rb +59 -0
- data/lib/fog/vsphere/requests/compute/modify_vm_volume.rb +25 -0
- data/lib/fog/vsphere/requests/compute/revert_to_snapshot.rb +30 -0
- data/lib/fog/vsphere/requests/compute/set_vm_customvalue.rb +17 -0
- data/lib/fog/vsphere/requests/compute/vm_clone.rb +727 -0
- data/lib/fog/vsphere/requests/compute/vm_config_vnc.rb +45 -0
- data/lib/fog/vsphere/requests/compute/vm_destroy.rb +23 -0
- data/lib/fog/vsphere/requests/compute/vm_execute.rb +47 -0
- data/lib/fog/vsphere/requests/compute/vm_migrate.rb +33 -0
- data/lib/fog/vsphere/requests/compute/vm_power_off.rb +39 -0
- data/lib/fog/vsphere/requests/compute/vm_power_on.rb +26 -0
- data/lib/fog/vsphere/requests/compute/vm_reboot.rb +31 -0
- data/lib/fog/vsphere/requests/compute/vm_reconfig_cpus.rb +23 -0
- data/lib/fog/vsphere/requests/compute/vm_reconfig_hardware.rb +24 -0
- data/lib/fog/vsphere/requests/compute/vm_reconfig_memory.rb +23 -0
- data/lib/fog/vsphere/requests/compute/vm_take_snapshot.rb +37 -0
- data/lib/fog/vsphere/version.rb +5 -0
- data/tests/compute_tests.rb +53 -0
- data/tests/helper.rb +8 -0
- data/tests/helpers/mock_helper.rb +9 -0
- data/tests/helpers/succeeds_helper.rb +9 -0
- data/tests/models/compute/server_tests.rb +70 -0
- data/tests/models/compute/servers_tests.rb +15 -0
- data/tests/requests/compute/current_time_tests.rb +12 -0
- data/tests/requests/compute/get_network_tests.rb +50 -0
- data/tests/requests/compute/list_child_snapshots_tests.rb +10 -0
- data/tests/requests/compute/list_clusters_tests.rb +11 -0
- data/tests/requests/compute/list_virtual_machines_tests.rb +38 -0
- data/tests/requests/compute/list_vm_snapshots_tests.rb +10 -0
- data/tests/requests/compute/revert_to_snapshot_tests.rb +15 -0
- data/tests/requests/compute/set_vm_customvalue_tests.rb +20 -0
- data/tests/requests/compute/vm_clone_tests.rb +50 -0
- data/tests/requests/compute/vm_config_vnc_tests.rb +19 -0
- data/tests/requests/compute/vm_destroy_tests.rb +17 -0
- data/tests/requests/compute/vm_migrate_tests.rb +16 -0
- data/tests/requests/compute/vm_power_off_tests.rb +26 -0
- data/tests/requests/compute/vm_power_on_tests.rb +17 -0
- data/tests/requests/compute/vm_reboot_tests.rb +26 -0
- data/tests/requests/compute/vm_reconfig_cpus_tests.rb +19 -0
- data/tests/requests/compute/vm_reconfig_hardware_tests.rb +19 -0
- data/tests/requests/compute/vm_reconfig_memory_tests.rb +19 -0
- data/tests/requests/compute/vm_take_snapshot_tests.rb +19 -0
- metadata +289 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Fog
|
|
2
|
+
module Compute
|
|
3
|
+
class Vsphere
|
|
4
|
+
class Servers < Fog::Collection
|
|
5
|
+
autoload :Server, File.expand_path('../server', __FILE__)
|
|
6
|
+
|
|
7
|
+
model Fog::Compute::Vsphere::Server
|
|
8
|
+
attr_accessor :datacenter
|
|
9
|
+
attr_accessor :network
|
|
10
|
+
attr_accessor :cluster
|
|
11
|
+
attr_accessor :resource_pool
|
|
12
|
+
attr_accessor :folder
|
|
13
|
+
|
|
14
|
+
# 'folder' => '/Datacenters/vm/Jeff/Templates' will be MUCH faster.
|
|
15
|
+
# than simply listing everything.
|
|
16
|
+
def all(filters = { })
|
|
17
|
+
f = {
|
|
18
|
+
:datacenter => datacenter,
|
|
19
|
+
:cluster => cluster,
|
|
20
|
+
:network => network,
|
|
21
|
+
:resource_pool => resource_pool,
|
|
22
|
+
:folder => folder
|
|
23
|
+
}.merge(filters)
|
|
24
|
+
|
|
25
|
+
load service.list_virtual_machines(f)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def get(id, datacenter = nil)
|
|
29
|
+
new service.get_virtual_machine id, datacenter
|
|
30
|
+
rescue Fog::Compute::Vsphere::NotFound
|
|
31
|
+
nil
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Fog
|
|
2
|
+
module Compute
|
|
3
|
+
class Vsphere
|
|
4
|
+
class Servertype < Fog::Model
|
|
5
|
+
identity :id
|
|
6
|
+
|
|
7
|
+
attribute :family
|
|
8
|
+
attribute :fullname
|
|
9
|
+
attribute :datacenter
|
|
10
|
+
attribute :interfacetypes
|
|
11
|
+
|
|
12
|
+
def initialize(attributes={} )
|
|
13
|
+
super defaults.merge(attributes)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def to_s
|
|
17
|
+
id
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def interfacetypes filters={}
|
|
21
|
+
attributes[:interfacetypes] ||= service.interfacetypes({ :datacenter => datacenter, :servertype => self }.merge(filters))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def defaults
|
|
27
|
+
{
|
|
28
|
+
:id=>"otherGuest64",
|
|
29
|
+
:family=>"otherGuestFamily",
|
|
30
|
+
:interfacetypes => nil,
|
|
31
|
+
}
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Fog
|
|
2
|
+
module Compute
|
|
3
|
+
class Vsphere
|
|
4
|
+
class Servertypes < Fog::Collection
|
|
5
|
+
autoload :Servertype, File.expand_path('../servertype', __FILE__)
|
|
6
|
+
|
|
7
|
+
model Fog::Compute::Vsphere::Servertype
|
|
8
|
+
attr_accessor :datacenter, :id, :fullname
|
|
9
|
+
|
|
10
|
+
def all(filters = { })
|
|
11
|
+
load service.list_server_types(filters.merge({:datacenter => datacenter}))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def get(id)
|
|
15
|
+
requires :datacenter
|
|
16
|
+
new service.get_server_type(id, datacenter)
|
|
17
|
+
rescue Fog::Compute::Vsphere::NotFound
|
|
18
|
+
nil
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'fog/compute/models/server'
|
|
2
|
+
|
|
3
|
+
module Fog
|
|
4
|
+
module Compute
|
|
5
|
+
class Vsphere
|
|
6
|
+
class Snapshot < Fog::Model
|
|
7
|
+
|
|
8
|
+
identity :ref
|
|
9
|
+
attribute :server_id
|
|
10
|
+
|
|
11
|
+
attribute :name
|
|
12
|
+
attribute :quiescedi, :default => false
|
|
13
|
+
attribute :description, :default => ''
|
|
14
|
+
attribute :create_time
|
|
15
|
+
attribute :power_state, :default => 'none'
|
|
16
|
+
attribute :ref
|
|
17
|
+
attribute :mo_ref
|
|
18
|
+
attribute :tree_node
|
|
19
|
+
attribute :snapshot_name_chain
|
|
20
|
+
attribute :ref_chain
|
|
21
|
+
|
|
22
|
+
def child_snapshots(filters = {})
|
|
23
|
+
service.snapshots(
|
|
24
|
+
{ :server_id => server_id, :parent_snapshot => self }.update(filters)
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def get_child(snapshot_ref)
|
|
29
|
+
return self if ref == snapshot_ref
|
|
30
|
+
child_snapshots().get(snapshot_ref)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'fog/core/collection'
|
|
2
|
+
require 'fog/vsphere/models/compute/snapshot'
|
|
3
|
+
|
|
4
|
+
module Fog
|
|
5
|
+
module Compute
|
|
6
|
+
class Vsphere
|
|
7
|
+
class Snapshots < Fog::Collection
|
|
8
|
+
attribute :server_id, :alias => :instance_uuid
|
|
9
|
+
attribute :parent_snapshot
|
|
10
|
+
model Fog::Compute::Vsphere::Snapshot
|
|
11
|
+
|
|
12
|
+
def all(filters = {})
|
|
13
|
+
if parent_snapshot
|
|
14
|
+
load service.list_child_snapshots(parent_snapshot, filters)
|
|
15
|
+
else
|
|
16
|
+
requires :server_id
|
|
17
|
+
load service.list_vm_snapshots(server_id, filters)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def get(snapshot_ref)
|
|
22
|
+
all.find { |snapshot| snapshot.get_child(snapshot_ref) }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Fog
|
|
2
|
+
module Compute
|
|
3
|
+
class Vsphere
|
|
4
|
+
class Templates < Fog::Collection
|
|
5
|
+
autoload :Template, File.expand_path('../template', __FILE__)
|
|
6
|
+
|
|
7
|
+
model Fog::Compute::Vsphere::Template
|
|
8
|
+
|
|
9
|
+
def all(filters = {})
|
|
10
|
+
load service.list_templates(filters)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get(id)
|
|
14
|
+
new service.get_template(id)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
module Fog
|
|
2
|
+
module Compute
|
|
3
|
+
class Vsphere
|
|
4
|
+
class Volume < Fog::Model
|
|
5
|
+
DISK_SIZE_TO_GB = 1048576
|
|
6
|
+
identity :id
|
|
7
|
+
|
|
8
|
+
attribute :datastore
|
|
9
|
+
attribute :mode
|
|
10
|
+
attribute :size
|
|
11
|
+
attribute :thin
|
|
12
|
+
attribute :eager_zero
|
|
13
|
+
attribute :name
|
|
14
|
+
attribute :filename
|
|
15
|
+
attribute :size_gb
|
|
16
|
+
attribute :key
|
|
17
|
+
attribute :unit_number
|
|
18
|
+
attribute :server_id
|
|
19
|
+
|
|
20
|
+
def initialize(attributes={} )
|
|
21
|
+
# Assign server first to prevent race condition with persisted?
|
|
22
|
+
self.server_id = attributes.delete(:server_id)
|
|
23
|
+
|
|
24
|
+
super defaults.merge(attributes)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def size_gb
|
|
28
|
+
attributes[:size_gb] ||= attributes[:size].to_i / DISK_SIZE_TO_GB if attributes[:size]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def size_gb= s
|
|
32
|
+
attributes[:size] = s.to_i * DISK_SIZE_TO_GB if s
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_s
|
|
36
|
+
name
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def destroy
|
|
40
|
+
requires :server_id, :key, :unit_number
|
|
41
|
+
|
|
42
|
+
service.destroy_vm_volume(self)
|
|
43
|
+
true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def save
|
|
47
|
+
raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
|
|
48
|
+
requires :server_id, :size, :datastore
|
|
49
|
+
|
|
50
|
+
if unit_number.nil?
|
|
51
|
+
used_unit_numbers = server.volumes.map { |volume| volume.unit_number }
|
|
52
|
+
max_unit_number = used_unit_numbers.max
|
|
53
|
+
|
|
54
|
+
if max_unit_number > server.volumes.size
|
|
55
|
+
# If the max ID exceeds the number of volumes, there must be a hole in the range. Find a hole and use it.
|
|
56
|
+
self.unit_number = max_unit_number.times.to_a.find { |i| used_unit_numbers.exclude?(i) }
|
|
57
|
+
else
|
|
58
|
+
self.unit_number = max_unit_number + 1
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
if server.volumes.any? { |volume| volume.unit_number == self.unit_number && volume.id != self.id }
|
|
62
|
+
raise "A volume already exists with that unit_number, so we can't save the new volume"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
data = service.add_vm_volume(self)
|
|
67
|
+
|
|
68
|
+
if data['task_state'] == 'success'
|
|
69
|
+
# We have to query vSphere to get the volume attributes since the task handle doesn't include that info.
|
|
70
|
+
created = server.volumes.all.find { |volume| volume.unit_number == self.unit_number }
|
|
71
|
+
|
|
72
|
+
self.id = created.id
|
|
73
|
+
self.key = created.key
|
|
74
|
+
self.filename = created.filename
|
|
75
|
+
|
|
76
|
+
true
|
|
77
|
+
else
|
|
78
|
+
false
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def server
|
|
83
|
+
requires :server_id
|
|
84
|
+
service.servers.get(server_id)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
def defaults
|
|
90
|
+
{
|
|
91
|
+
:thin => true,
|
|
92
|
+
:name => "Hard disk",
|
|
93
|
+
:mode => "persistent"
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Fog
|
|
2
|
+
module Compute
|
|
3
|
+
class Vsphere
|
|
4
|
+
class Volumes < Fog::Collection
|
|
5
|
+
autoload :Volume, File.expand_path('../volume', __FILE__)
|
|
6
|
+
|
|
7
|
+
attribute :server_id
|
|
8
|
+
|
|
9
|
+
model Fog::Compute::Vsphere::Volume
|
|
10
|
+
|
|
11
|
+
def all(filters = {})
|
|
12
|
+
requires :server_id
|
|
13
|
+
|
|
14
|
+
case server
|
|
15
|
+
when Fog::Compute::Vsphere::Server
|
|
16
|
+
load service.list_vm_volumes(server.id)
|
|
17
|
+
when Fog::Compute::Vsphere::Template
|
|
18
|
+
load service.list_template_volumes(server.id)
|
|
19
|
+
else
|
|
20
|
+
raise 'volumes should have vm or template'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
self.each { |volume| volume.server_id = server.id }
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def get(id)
|
|
28
|
+
new service.get_volume(id)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def new(attributes = {})
|
|
32
|
+
if server_id
|
|
33
|
+
# Default to the root volume datastore if one is not configured.
|
|
34
|
+
datastore = ! attributes.key?(:datastore) && self.any? ? self.first.datastore : nil
|
|
35
|
+
|
|
36
|
+
super({ :server_id => server_id, :datastore => datastore }.merge!(attributes))
|
|
37
|
+
else
|
|
38
|
+
super
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def server
|
|
43
|
+
return nil if server_id.nil?
|
|
44
|
+
service.servers.get(server_id)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def server=(new_server)
|
|
48
|
+
server_id = new_server.id
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Fog
|
|
2
|
+
module Compute
|
|
3
|
+
class Vsphere
|
|
4
|
+
class Real
|
|
5
|
+
def cloudinit_to_customspec(user_data)
|
|
6
|
+
raise ArgumentError, "user_data can't be nil" if user_data.nil?
|
|
7
|
+
custom_spec = { 'customization_spec' => Hash.new }
|
|
8
|
+
user_data = YAML.load(user_data)
|
|
9
|
+
# https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vim.vm.customization.Specification.html
|
|
10
|
+
# encryptionKey expects an array
|
|
11
|
+
# globalIPSettings expects a hash, REQUIRED
|
|
12
|
+
# identity expects an hash, REQUIRED
|
|
13
|
+
# nicSettingMap expects an array
|
|
14
|
+
# options expects an hash
|
|
15
|
+
|
|
16
|
+
custom_spec['encryptionKey'] = user_data['encryptionKey'] if user_data.key?('encryptionKey')
|
|
17
|
+
custom_spec['globalIPSettings'] = user_data['globalIPSettings'] if user_data.key?('globalIPSettings')
|
|
18
|
+
custom_spec['identity'] = user_data['identity'] if user_data.key?('identity')
|
|
19
|
+
custom_spec['nicSettingMap'] = user_data['nicSettingMap'] if user_data.key?('nicSettingMap')
|
|
20
|
+
custom_spec['options'] = user_data['options'] if user_data.key?('options')
|
|
21
|
+
|
|
22
|
+
# for backwards compatability
|
|
23
|
+
# hostname expects a string, REQUIRED
|
|
24
|
+
# netmask expects a string
|
|
25
|
+
# dns expects an array
|
|
26
|
+
# gateway expects an array
|
|
27
|
+
# domain expects a string, REQUIRED
|
|
28
|
+
# domainsuffixlist expects an array, REQUIRED
|
|
29
|
+
# timezone expects a string, for example Europe/Copenhagen, REQUIRED
|
|
30
|
+
custom_spec['hostname'] = user_data['hostname'] if user_data.key?('hostname')
|
|
31
|
+
custom_spec['ipsettings'] = { 'ip' => user_data['ip'] } if user_data.key?('ip')
|
|
32
|
+
custom_spec['ipsettings']['subnetMask'] = user_data['netmask'] if user_data.key?('netmask')
|
|
33
|
+
custom_spec['ipsettings']['dnsServerList'] = user_data['dns'] if user_data.key?('dns')
|
|
34
|
+
custom_spec['ipsettings']['gateway'] = user_data['gateway'] if user_data.key?('gateway')
|
|
35
|
+
custom_spec['domain'] = user_data['domain'] if user_data.key?('domain')
|
|
36
|
+
custom_spec['dnsSuffixList'] = user_data['domainsuffixlist'] if user_data.key?('domainsuffixlist')
|
|
37
|
+
custom_spec['time_zone'] = user_data['timezone'] if user_data.key?('timezone')
|
|
38
|
+
custom_spec
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class Mock
|
|
43
|
+
def cloudinit_to_customspec(user_data)
|
|
44
|
+
raise ArgumentError, "user_data can't be nil" if user_data.nil?
|
|
45
|
+
custom_spec = { 'customization_spec' => Hash.new }
|
|
46
|
+
user_data = YAML.load(user_data)
|
|
47
|
+
custom_spec['encryptionKey'] = user_data['encryptionKey'] if user_data.key?('encryptionKey')
|
|
48
|
+
custom_spec['globalIPSettings'] = user_data['globalIPSettings'] if user_data.key?('globalIPSettings')
|
|
49
|
+
custom_spec['identity'] = user_data['identity'] if user_data.key?('identity')
|
|
50
|
+
custom_spec['nicSettingMap'] = user_data['nicSettingMap'] if user_data.key?('nicSettingMap')
|
|
51
|
+
custom_spec['options'] = user_data['options'] if user_data.key?('options')
|
|
52
|
+
custom_spec['hostname'] = user_data['hostname'] if user_data.key?('hostname')
|
|
53
|
+
custom_spec['ipsettings'] = { 'ip' => user_data['ip'] } if user_data.key?('ip')
|
|
54
|
+
custom_spec['ipsettings']['subnetMask'] = user_data['netmask'] if user_data.key?('netmask')
|
|
55
|
+
custom_spec['ipsettings']['dnsServerList'] = user_data['dns'] if user_data.key?('dns')
|
|
56
|
+
custom_spec['ipsettings']['gateway'] = user_data['gateway'] if user_data.key?('gateway')
|
|
57
|
+
custom_spec['domain'] = user_data['domain'] if user_data.key?('domain')
|
|
58
|
+
custom_spec['dnsSuffixList'] = user_data['domainsuffixlist'] if user_data.key?('domainsuffixlist')
|
|
59
|
+
custom_spec['time_zone'] = user_data['timezone'] if user_data.key?('timezone')
|
|
60
|
+
custom_spec
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Fog
|
|
2
|
+
module Compute
|
|
3
|
+
class Vsphere
|
|
4
|
+
class Real
|
|
5
|
+
def create_folder(datacenter, path, name)
|
|
6
|
+
#Path cannot be nil but it can be an empty string
|
|
7
|
+
raise ArgumentError, "Path cannot be nil" if path.nil?
|
|
8
|
+
|
|
9
|
+
parent_folder = get_raw_vmfolder(path, datacenter)
|
|
10
|
+
begin
|
|
11
|
+
new_folder = parent_folder.CreateFolder(:name => name)
|
|
12
|
+
# output is cleaned up to return the new path
|
|
13
|
+
# new path will be path/name, example: "Production/Pool1"
|
|
14
|
+
new_folder.path.reject { |a| a.first.class == "Folder" }.map { |a| a.first.name }.join("/").sub(/^\/?Datacenters\/#{datacenter}\/vm\/?/, '')
|
|
15
|
+
rescue => e
|
|
16
|
+
raise e, "failed to create folder: #{e}"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
module Fog
|
|
2
|
+
module Compute
|
|
3
|
+
class Vsphere
|
|
4
|
+
class Real
|
|
5
|
+
def create_vm attributes = { }
|
|
6
|
+
# build up vm configuration
|
|
7
|
+
|
|
8
|
+
vm_cfg = {
|
|
9
|
+
:name => attributes[:name],
|
|
10
|
+
:guestId => attributes[:guest_id],
|
|
11
|
+
:version => attributes[:hardware_version],
|
|
12
|
+
:files => { :vmPathName => vm_path_name(attributes) },
|
|
13
|
+
:numCPUs => attributes[:cpus],
|
|
14
|
+
:numCoresPerSocket => attributes[:corespersocket],
|
|
15
|
+
:memoryMB => attributes[:memory_mb],
|
|
16
|
+
:deviceChange => device_change(attributes),
|
|
17
|
+
:extraConfig => extra_config(attributes),
|
|
18
|
+
}
|
|
19
|
+
vm_cfg[:cpuHotAddEnabled] = attributes[:cpuHotAddEnabled] if attributes.key?(:cpuHotAddEnabled)
|
|
20
|
+
vm_cfg[:memoryHotAddEnabled] = attributes[:memoryHotAddEnabled] if attributes.key?(:memoryHotAddEnabled)
|
|
21
|
+
vm_cfg[:firmware] = attributes[:firmware] if attributes.key?(:firmware)
|
|
22
|
+
resource_pool = if attributes[:resource_pool]
|
|
23
|
+
get_raw_resource_pool(attributes[:resource_pool], attributes[:cluster], attributes[:datacenter])
|
|
24
|
+
else
|
|
25
|
+
get_raw_cluster(attributes[:cluster], attributes[:datacenter]).resourcePool
|
|
26
|
+
end
|
|
27
|
+
vmFolder = get_raw_vmfolder(attributes[:path], attributes[:datacenter])
|
|
28
|
+
vm = vmFolder.CreateVM_Task(:config => vm_cfg, :pool => resource_pool).wait_for_completion
|
|
29
|
+
vm.config.instanceUuid
|
|
30
|
+
rescue => e
|
|
31
|
+
raise e, "failed to create vm: #{e}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# this methods defines where the vm config files would be located,
|
|
37
|
+
# by default we prefer to keep it at the same place the (first) vmdk is located
|
|
38
|
+
def vm_path_name attributes
|
|
39
|
+
datastore = attributes[:volumes].first.datastore unless attributes[:volumes].empty?
|
|
40
|
+
datastore ||= 'datastore1'
|
|
41
|
+
"[#{datastore}]"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def device_change attributes
|
|
45
|
+
devices = []
|
|
46
|
+
if (nics = attributes[:interfaces])
|
|
47
|
+
devices << nics.map { |nic| create_interface(nic, nics.index(nic), :add, attributes) }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if (disks = attributes[:volumes])
|
|
51
|
+
devices << create_controller(attributes[:scsi_controller]||attributes["scsi_controller"]||{})
|
|
52
|
+
devices << disks.map { |disk| create_disk(disk, disks.index(disk)) }
|
|
53
|
+
end
|
|
54
|
+
devices.flatten
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def create_nic_backing nic, attributes
|
|
58
|
+
raw_network = get_raw_network(nic.network, attributes[:datacenter], if nic.virtualswitch then nic.virtualswitch end)
|
|
59
|
+
|
|
60
|
+
if raw_network.kind_of? RbVmomi::VIM::DistributedVirtualPortgroup
|
|
61
|
+
RbVmomi::VIM.VirtualEthernetCardDistributedVirtualPortBackingInfo(
|
|
62
|
+
:port => RbVmomi::VIM.DistributedVirtualSwitchPortConnection(
|
|
63
|
+
:portgroupKey => raw_network.key,
|
|
64
|
+
:switchUuid => raw_network.config.distributedVirtualSwitch.uuid
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
else
|
|
68
|
+
RbVmomi::VIM.VirtualEthernetCardNetworkBackingInfo(:deviceName => nic.network)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def create_interface nic, index = 0, operation = :add, attributes = {}
|
|
73
|
+
{
|
|
74
|
+
:operation => operation,
|
|
75
|
+
:device => nic.type.new(
|
|
76
|
+
:key => index,
|
|
77
|
+
:deviceInfo =>
|
|
78
|
+
{
|
|
79
|
+
:label => nic.name,
|
|
80
|
+
:summary => nic.summary,
|
|
81
|
+
},
|
|
82
|
+
:backing => create_nic_backing(nic, attributes),
|
|
83
|
+
:addressType => 'generated')
|
|
84
|
+
}
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def create_controller options=nil
|
|
88
|
+
options=if options
|
|
89
|
+
controller_default_options.merge(Hash[options.map{|k,v| [k.to_sym,v] }])
|
|
90
|
+
else
|
|
91
|
+
controller_default_options
|
|
92
|
+
end
|
|
93
|
+
controller_class=if options[:type].is_a? String then
|
|
94
|
+
Fog::Vsphere.class_from_string options[:type], "RbVmomi::VIM"
|
|
95
|
+
else
|
|
96
|
+
options[:type]
|
|
97
|
+
end
|
|
98
|
+
{
|
|
99
|
+
:operation => options[:operation],
|
|
100
|
+
:device => controller_class.new({
|
|
101
|
+
:key => options[:key],
|
|
102
|
+
:busNumber => options[:bus_id],
|
|
103
|
+
:sharedBus => controller_get_shared_from_options(options),
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def controller_default_options
|
|
109
|
+
{:operation => "add", :type => RbVmomi::VIM.VirtualLsiLogicController.class, :key => 1000, :bus_id => 0, :shared => false }
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def controller_get_shared_from_options options
|
|
113
|
+
if (options.key? :shared and options[:shared]==false) or not options.key? :shared then
|
|
114
|
+
:noSharing
|
|
115
|
+
elsif options[:shared]==true then
|
|
116
|
+
:virtualSharing
|
|
117
|
+
elsif options[:shared].is_a? String
|
|
118
|
+
options[:shared]
|
|
119
|
+
else
|
|
120
|
+
:noSharing
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def create_disk disk, index = 0, operation = :add, controller_key = 1000
|
|
125
|
+
if (index > 6) then
|
|
126
|
+
_index = index + 1
|
|
127
|
+
else
|
|
128
|
+
_index = index
|
|
129
|
+
end
|
|
130
|
+
payload = {
|
|
131
|
+
:operation => operation,
|
|
132
|
+
:fileOperation => operation == :add ? :create : :destroy,
|
|
133
|
+
:device => RbVmomi::VIM.VirtualDisk(
|
|
134
|
+
:key => disk.key || _index,
|
|
135
|
+
:backing => RbVmomi::VIM.VirtualDiskFlatVer2BackingInfo(
|
|
136
|
+
:fileName => "[#{disk.datastore}]",
|
|
137
|
+
:diskMode => disk.mode.to_sym,
|
|
138
|
+
:thinProvisioned => disk.thin
|
|
139
|
+
),
|
|
140
|
+
:controllerKey => controller_key,
|
|
141
|
+
:unitNumber => _index,
|
|
142
|
+
:capacityInKB => disk.size
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if operation == :add && disk.thin == 'false' && disk.eager_zero == 'true'
|
|
147
|
+
payload[:device][:backing][:eagerlyScrub] = disk.eager_zero
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
payload
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def extra_config attributes
|
|
154
|
+
[
|
|
155
|
+
{
|
|
156
|
+
:key => 'bios.bootOrder',
|
|
157
|
+
:value => 'ethernet0'
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
class Mock
|
|
164
|
+
def create_vm attributes = { }
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|