fog-vsphere 0.2.0 → 0.3.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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -4
  3. data/CHANGELOG.md +8 -0
  4. data/CONTRIBUTORS.md +6 -0
  5. data/fog-vsphere.gemspec +1 -1
  6. data/lib/fog/vsphere/compute.rb +47 -3
  7. data/lib/fog/vsphere/models/compute/cdrom.rb +65 -0
  8. data/lib/fog/vsphere/models/compute/cdroms.rb +18 -0
  9. data/lib/fog/vsphere/models/compute/datacenter.rb +4 -0
  10. data/lib/fog/vsphere/models/compute/folder.rb +4 -0
  11. data/lib/fog/vsphere/models/compute/server.rb +8 -0
  12. data/lib/fog/vsphere/models/compute/storage_pod.rb +19 -0
  13. data/lib/fog/vsphere/models/compute/storage_pods.rb +22 -0
  14. data/lib/fog/vsphere/models/compute/volume.rb +1 -0
  15. data/lib/fog/vsphere/requests/compute/create_folder.rb +10 -0
  16. data/lib/fog/vsphere/requests/compute/create_vm.rb +163 -4
  17. data/lib/fog/vsphere/requests/compute/folder_destroy.rb +26 -0
  18. data/lib/fog/vsphere/requests/compute/get_folder.rb +4 -2
  19. data/lib/fog/vsphere/requests/compute/get_storage_pod.rb +31 -0
  20. data/lib/fog/vsphere/requests/compute/list_datacenters.rb +1 -1
  21. data/lib/fog/vsphere/requests/compute/list_datastores.rb +2 -1
  22. data/lib/fog/vsphere/requests/compute/list_networks.rb +2 -1
  23. data/lib/fog/vsphere/requests/compute/list_storage_pods.rb +45 -0
  24. data/lib/fog/vsphere/requests/compute/list_virtual_machines.rb +8 -4
  25. data/lib/fog/vsphere/requests/compute/list_vm_cdroms.rb +30 -0
  26. data/lib/fog/vsphere/requests/compute/list_vm_interfaces.rb +34 -13
  27. data/lib/fog/vsphere/requests/compute/list_vm_snapshots.rb +5 -1
  28. data/lib/fog/vsphere/requests/compute/modify_vm_cdrom.rb +25 -0
  29. data/lib/fog/vsphere/requests/compute/modify_vm_interface.rb +19 -2
  30. data/lib/fog/vsphere/requests/compute/modify_vm_volume.rb +1 -1
  31. data/lib/fog/vsphere/requests/compute/upload_iso.rb +34 -0
  32. data/lib/fog/vsphere/requests/compute/vm_clone.rb +68 -25
  33. data/lib/fog/vsphere/requests/compute/vm_reconfig_cdrom.rb +68 -0
  34. data/lib/fog/vsphere/version.rb +1 -1
  35. data/tests/models/compute/servers_tests.rb +1 -1
  36. data/tests/requests/compute/folder_destroy_tests.rb +21 -0
  37. data/tests/requests/compute/list_storage_pods_test.rb +10 -0
  38. data/tests/requests/compute/list_vm_cdroms_tests.rb +10 -0
  39. data/tests/requests/compute/modify_vm_cdrom_tests.rb +21 -0
  40. data/tests/requests/compute/vm_reconfig_cdrom_tests.rb +15 -0
  41. metadata +28 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a75eea9b7c7c8861cbdd259740a3be4910ab46d
4
- data.tar.gz: a7cc4a8d5fc471e589fada237661d54064480236
3
+ metadata.gz: 4f0eaac527da91308fec5066b89407f48b10c7ec
4
+ data.tar.gz: 150e3dc5e72cb0c27d617bf65b2d7db259edb609
5
5
  SHA512:
6
- metadata.gz: 75979dcdf4fc9f215bb473b46a83480f73ce6992a1c36b9a9d527f471118b62b5f6844ce10a509007a48d7696636ad5a734a528e66c2c1fed32d1cead471808f
7
- data.tar.gz: 0a22422a0bca780cb478dddef9b47b186848fb3a051a09c972002762cb04c800f22c4847cf7b5e95233ec9483470f32d50317153f962cd5d135c22da00c50109
6
+ metadata.gz: c03d49413d12ba37d6a02365932583cafc87634cafaf55c8bceadc687ef08a9e0f9134b7928eb2aed94099ef01ee395340d5b10f76351e3870c0e7e409baec5a
7
+ data.tar.gz: 2d78b5e76edff6315f2601fc1830ae395c2419b3e159632a3ad0261d2309c7271d3a303c16ad1b5883fa40ef73e43bfa8958ec92c868d1e0c32d3e78e7124da1
data/.travis.yml CHANGED
@@ -6,8 +6,6 @@ matrix:
6
6
  - rvm: jruby-head
7
7
  fast_finish: true
8
8
  include:
9
- - rvm: 1.8.7
10
- gemfile: gemfiles/Gemfile.1.9.2-
11
9
  - rvm: 1.9.3
12
10
  gemfile: gemfiles/Gemfile.1.9.2+
13
11
  - rvm: 2.0.0
@@ -18,8 +16,6 @@ matrix:
18
16
  gemfile: Gemfile
19
17
  - rvm: 2.2.0
20
18
  gemfile: Gemfile
21
- - rvm: jruby-18mode
22
- gemfile: gemfiles/Gemfile.1.9.2-
23
19
  - rvm: jruby-19mode
24
20
  gemfile: gemfiles/Gemfile.1.9.2+
25
21
  - rvm: jruby-head
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ * Fix update_vm_interface
2
+ * Add add folder.destroy
3
+ * Implement CD-ROM options
4
+ * Implement storage pods
5
+ * Fix nil error when snapshots is called on a VM without snapshots
6
+ * No longer support Ruby 1.8
7
+ * Allow setting of boot order when using api > 5.0
8
+ * Select the most recent API version instead of 4.1
data/CONTRIBUTORS.md CHANGED
@@ -4,6 +4,7 @@
4
4
  * Carlos Sanchez <csanchez@maestrodev.com>
5
5
  * Chris Thompson <chris.thompson@govdelivery.com>
6
6
  * Chris Thompson <teaforthecat@gmail.com>
7
+ * Christopher Oliver <coliver@datapipe.com>
7
8
  * Cyrus Team <cyrusteam@cyruslists.com>
8
9
  * Darren Foo <stonith@users.noreply.github.com>
9
10
  * Dominic Cleal <dcleal@redhat.com>
@@ -14,6 +15,8 @@
14
15
  * Francois Herbert <francois@herbert.org.nz>
15
16
  * Ivan Nečas <inecas@redhat.com>
16
17
  * Ivo Reznicek <ireznice@googlemail.com>
18
+ * J.R. Garcia <jr@garciaole.com>
19
+ * J.R. Garcia <jrg@vmware.com>
17
20
  * James Herdman <james.herdman@me.com>
18
21
  * Jeff McCune <jeff@puppetlabs.com>
19
22
  * Justin Clayton <justin.clayton@gettyimages.com>
@@ -42,11 +45,14 @@
42
45
  * Oscar Elfving <sofam84@gmail.com>
43
46
  * Paul Thornthwaite <paul@brightbox.co.uk>
44
47
  * Paul Thornthwaite <tokengeek@gmail.com>
48
+ * Paulo Henrique Lopes Ribeiro <plribeiro3000@gmail.com>
49
+ * Rich Daley <rdaley@williamhill.co.uk>
45
50
  * Rich Lane <rlane@club.cc.cmu.edu>
46
51
  * Samuel Keeley <samuel@dropbox.com>
47
52
  * Shlomi Zadok <shlomi@ben-hanna.com>
48
53
  * Simon Josi <me@yokto.net>
49
54
  * Tejas Ravindra Mandke <tejas@identified.com>
55
+ * Timo Goebel <timo.goebel@dm.de>
50
56
  * Timur Alperovich <timur@maginatics.com>
51
57
  * Wesley Beary <geemus+github@gmail.com>
52
58
  * Wesley Beary <geemus@gmail.com>
data/fog-vsphere.gemspec CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.required_ruby_version = '>= 1.8.7'
23
23
 
24
- spec.add_runtime_dependency 'fog-core', '~> 1.32'
24
+ spec.add_runtime_dependency 'fog-core'
25
25
  spec.add_runtime_dependency 'rbvmomi', '~> 1.8'
26
26
 
27
27
  spec.add_development_dependency 'bundler', '~> 1.10'
@@ -33,6 +33,8 @@ module Fog
33
33
  collection :networks
34
34
  model :datastore
35
35
  collection :datastores
36
+ model :storage_pod
37
+ collection :storage_pods
36
38
  model :folder
37
39
  collection :folders
38
40
  model :customvalue
@@ -41,6 +43,8 @@ module Fog
41
43
  collection :customfields
42
44
  model :scsicontroller
43
45
  model :process
46
+ model :cdrom
47
+ collection :cdroms
44
48
 
45
49
  request_path 'fog/vsphere/requests/compute'
46
50
  request :current_time
@@ -63,6 +67,8 @@ module Fog
63
67
  request :get_network
64
68
  request :list_datastores
65
69
  request :get_datastore
70
+ request :list_storage_pods
71
+ request :get_storage_pod
66
72
  request :list_compute_resources
67
73
  request :get_compute_resource
68
74
  request :list_templates
@@ -73,11 +79,14 @@ module Fog
73
79
  request :list_vm_interfaces
74
80
  request :modify_vm_interface
75
81
  request :modify_vm_volume
82
+ request :modify_vm_cdrom
76
83
  request :list_vm_volumes
84
+ request :list_vm_cdroms
77
85
  request :get_virtual_machine
78
86
  request :vm_reconfig_hardware
79
87
  request :vm_reconfig_memory
80
88
  request :vm_reconfig_cpus
89
+ request :vm_reconfig_cdrom
81
90
  request :vm_config_vnc
82
91
  request :create_folder
83
92
  request :list_server_types
@@ -93,6 +102,8 @@ module Fog
93
102
  request :list_child_snapshots
94
103
  request :revert_to_snapshot
95
104
  request :list_processes
105
+ request :upload_iso
106
+ request :folder_destroy
96
107
 
97
108
  module Shared
98
109
  attr_reader :vsphere_is_vcenter
@@ -237,6 +248,17 @@ module Fog
237
248
  "status" => "ok",
238
249
  "summary" => "VM Network",
239
250
  }],
251
+ "cdroms" =>
252
+ [{
253
+ "name" => "CD-/DVD-Drive 1",
254
+ "filename" => nil,
255
+ "key" => 3000,
256
+ "controller_key" => 200,
257
+ "unit_number" => 0,
258
+ "start_connected" => false,
259
+ "allow_guest_control" => true,
260
+ "connected" => false,
261
+ }],
240
262
  "hypervisor" => "gunab.puppetlabs.lan",
241
263
  "guest_id" => "rhel6_64Guest",
242
264
  "tools_state" => "toolsOk",
@@ -308,7 +330,7 @@ module Fog
308
330
  "tools_state" => "toolsOk",
309
331
  "name" => "jefftest",
310
332
  "operatingsystem" => "Red Hat Enterprise Linux 6 (64-bit)",
311
- "path" => "/",
333
+ "path" => "/Solutions/wibble",
312
334
  "tools_version" => "guestToolsUnmanaged",
313
335
  "ipaddress" => "192.168.100.187",
314
336
  "uuid" => "42329da7-e8ab-29ec-1892-d6a4a964912a",
@@ -318,8 +340,30 @@ module Fog
318
340
  }
319
341
  },
320
342
  :datacenters => {
321
- "Solutions" => {:name => "Solutions", :status => "grey"}
343
+ "Solutions" => {:name => "Solutions", :status => "grey", :path => ['Solutions']}
344
+ },
345
+ :folders => {
346
+ 'wibble' => {
347
+ 'name' => 'wibble',
348
+ 'datacenter' => 'Solutions',
349
+ 'path' => '/Solutions/wibble',
350
+ 'type' => 'vm'
351
+ },
352
+ 'empty' => {
353
+ 'name' => 'empty',
354
+ 'datacenter' => 'Solutions',
355
+ 'path' => '/Solutions/empty',
356
+ 'type' => 'vm'
357
+ }
322
358
  },
359
+ :storage_pods =>
360
+ [{:id => "group-p123456",
361
+ :name => "Datastore Cluster 1",
362
+ :freespace => "4856891834368",
363
+ :capacity => "7132061630464",
364
+ :datacenter => "Solutions",
365
+ },
366
+ ],
323
367
  :clusters =>
324
368
  [{:id => "1d4d9a3f-e4e8-4c40-b7fc-263850068fa4",
325
369
  :name => "Solutionscluster",
@@ -417,7 +461,7 @@ module Fog
417
461
  # Negotiate the API revision
418
462
  if not revision
419
463
  rev = @connection.serviceContent.about.apiVersion
420
- @connection.rev = [ rev, ENV['FOG_VSPHERE_REV'] || '4.1' ].min
464
+ @connection.rev = [ rev, ENV['FOG_VSPHERE_REV'] || '4.1' ].max
421
465
  end
422
466
 
423
467
  @vsphere_is_vcenter = @connection.serviceContent.about.apiType == "VirtualCenter"
@@ -0,0 +1,65 @@
1
+ module Fog
2
+ module Compute
3
+ class Vsphere
4
+ class Cdrom < Fog::Model
5
+ identity :key
6
+
7
+ attribute :filename
8
+ attribute :name, :default => "CD-/DVD-ROM Drive"
9
+ attribute :controller_key
10
+ attribute :unit_number
11
+ attribute :start_connected
12
+ attribute :allow_guest_control
13
+ attribute :connected
14
+
15
+ has_one_identity :server, :servers, :aliases => :instance_uuid
16
+
17
+ def to_s
18
+ name
19
+ end
20
+
21
+ def destroy
22
+ requires :instance_uuid, :key, :unit_number
23
+
24
+ service.destroy_vm_cdrom(self)
25
+ true
26
+ end
27
+
28
+ def save
29
+ requires :instance_uuid
30
+
31
+ if unit_number.nil?
32
+ used_unit_numbers = server.cdroms.map { |cdrom| cdrom.unit_number }
33
+ max_unit_number = used_unit_numbers.max
34
+
35
+ if max_unit_number > server.cdroms.size
36
+ # If the max ID exceeds the number of cdroms, there must be a hole in the range. Find a hole and use it.
37
+ self.unit_number = max_unit_number.times.to_a.find { |i| used_unit_numbers.exclude?(i) }
38
+ else
39
+ self.unit_number = max_unit_number + 1
40
+ end
41
+ else
42
+ if server.cdroms.any? { |cdrom| cdrom.unit_number == self.unit_number && cdrom.id != self.id }
43
+ raise "A cdrom already exists with that unit_number, so we can't save the new cdrom"
44
+ end
45
+ end
46
+
47
+ data = service.add_vm_cdrom(self)
48
+
49
+ if data['task_state'] == 'success'
50
+ # We have to query vSphere to get the cdrom attributes since the task handle doesn't include that info.
51
+ created = server.cdroms.get(unit_number)
52
+
53
+ self.key = created.key
54
+ self.filename = created.filename
55
+ self.unit_number = created.unit_number
56
+
57
+ true
58
+ else
59
+ false
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,18 @@
1
+ module Fog
2
+ module Compute
3
+ class Vsphere
4
+ class Cdroms < Fog::Collection
5
+ attribute :instance_uuid, :alias => :server_id
6
+ model Fog::Compute::Vsphere::Cdrom
7
+
8
+ def all(filters = {})
9
+ load service.list_vm_cdroms(instance_uuid)
10
+ end
11
+
12
+ def get(unit_number)
13
+ all.find { |cdrom| cdrom.unit_number == unit_number }
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -19,6 +19,10 @@ module Fog
19
19
  service.datastores({ :datacenter => path.join("/") }.merge(filters))
20
20
  end
21
21
 
22
+ def storage_pods filters = { }
23
+ service.storage_pods({ :datacenter => path.join("/") }.merge(filters))
24
+ end
25
+
22
26
  def vm_folders filters = { }
23
27
  service.folders({ :datacenter => path.join("/"), :type => :vm }.merge(filters))
24
28
  end
@@ -18,6 +18,10 @@ module Fog
18
18
  def to_s
19
19
  name
20
20
  end
21
+
22
+ def destroy
23
+ service.folder_destroy(path, datacenter)
24
+ end
21
25
  end
22
26
  end
23
27
  end
@@ -237,6 +237,14 @@ module Fog
237
237
  end
238
238
  end
239
239
 
240
+ def cdroms(opts = {})
241
+ service.cdroms(:instance_uuid => self.id).all(opts)
242
+ end
243
+
244
+ def cdrom(key)
245
+ cdroms.get(key)
246
+ end
247
+
240
248
  def guest_processes(opts = {})
241
249
  fail 'VM tools must be running' unless tools_running?
242
250
  service.list_processes(self.id, opts)
@@ -0,0 +1,19 @@
1
+ module Fog
2
+ module Compute
3
+ class Vsphere
4
+ class StoragePod < Fog::Model
5
+ identity :id
6
+
7
+ attribute :name
8
+ attribute :datacenter
9
+ attribute :type
10
+ attribute :freespace
11
+ attribute :capacity
12
+
13
+ def to_s
14
+ name
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/vsphere/models/compute/storage_pod'
3
+
4
+ module Fog
5
+ module Compute
6
+ class Vsphere
7
+ class StoragePods < Fog::Collection
8
+ model Fog::Compute::Vsphere::StoragePod
9
+ attribute :datacenter
10
+
11
+ def all(filters = {})
12
+ load service.list_storage_pods(filters.merge(datacenter: datacenter))
13
+ end
14
+
15
+ def get(id)
16
+ requires :datacenter
17
+ new service.get_storage_pod(id, datacenter)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -6,6 +6,7 @@ module Fog
6
6
  identity :id
7
7
 
8
8
  attribute :datastore
9
+ attribute :storage_pod
9
10
  attribute :mode
10
11
  attribute :size
11
12
  attribute :thin
@@ -17,6 +17,16 @@ module Fog
17
17
  end
18
18
  end
19
19
  end
20
+ class Mock
21
+ def create_folder(datacenter, path, name)
22
+ self.data[:folders][name] = {
23
+ 'name' => name,
24
+ 'datacenter' => datacenter,
25
+ 'path' => "#{path}/#{name}",
26
+ 'type' => 'vm'
27
+ }
28
+ end
29
+ end
20
30
  end
21
31
  end
22
32
  end
@@ -19,13 +19,20 @@ module Fog
19
19
  vm_cfg[:cpuHotAddEnabled] = attributes[:cpuHotAddEnabled] if attributes.key?(:cpuHotAddEnabled)
20
20
  vm_cfg[:memoryHotAddEnabled] = attributes[:memoryHotAddEnabled] if attributes.key?(:memoryHotAddEnabled)
21
21
  vm_cfg[:firmware] = attributes[:firmware] if attributes.key?(:firmware)
22
+ vm_cfg[:bootOptions] = boot_options(attributes) if attributes.key?(:boot_order)
22
23
  resource_pool = if attributes[:resource_pool]
23
24
  get_raw_resource_pool(attributes[:resource_pool], attributes[:cluster], attributes[:datacenter])
24
25
  else
25
26
  get_raw_cluster(attributes[:cluster], attributes[:datacenter]).resourcePool
26
27
  end
27
28
  vmFolder = get_raw_vmfolder(attributes[:path], attributes[:datacenter])
28
- vm = vmFolder.CreateVM_Task(:config => vm_cfg, :pool => resource_pool).wait_for_completion
29
+ # if any volume has a storage_pod set, we deploy the vm on a storage pod instead of the defined datastores
30
+ pod = get_storage_pod(attributes)
31
+ if pod
32
+ vm = create_vm_on_storage_pod(pod, vm_cfg, vmFolder, resource_pool, attributes[:datacenter])
33
+ else
34
+ vm = create_vm_on_datastore(vm_cfg, vmFolder, resource_pool)
35
+ end
29
36
  vm.config.instanceUuid
30
37
  rescue => e
31
38
  raise e, "failed to create vm: #{e}"
@@ -33,9 +40,47 @@ module Fog
33
40
 
34
41
  private
35
42
 
43
+ def create_vm_on_datastore(vm_cfg, vmFolder, resource_pool)
44
+ vm = vmFolder.CreateVM_Task(:config => vm_cfg, :pool => resource_pool).wait_for_completion
45
+ end
46
+
47
+ def create_vm_on_storage_pod(storage_pod, vm_cfg, vmFolder, resource_pool, datacenter)
48
+ pod_spec = RbVmomi::VIM::StorageDrsPodSelectionSpec.new(
49
+ :storagePod => get_raw_storage_pod(storage_pod, datacenter),
50
+ )
51
+ storage_spec = RbVmomi::VIM::StoragePlacementSpec.new(
52
+ :type => 'create',
53
+ :folder => vmFolder,
54
+ :resourcePool => resource_pool,
55
+ :podSelectionSpec => pod_spec,
56
+ :configSpec => vm_cfg,
57
+ )
58
+ srm = @connection.serviceContent.storageResourceManager
59
+ result = srm.RecommendDatastores(:storageSpec => storage_spec)
60
+
61
+ # if result array contains recommendation, we can apply it
62
+ if key = result.recommendations.first.key
63
+ result = srm.ApplyStorageDrsRecommendation_Task(:key => [key]).wait_for_completion
64
+ vm = result.vm
65
+ else
66
+ raise "Could not create vm on storage pod, did not get a storage recommendation"
67
+ end
68
+ vm
69
+ end
70
+
71
+ # check if a storage pool is set on any of the volumes and return the first result found or nil
72
+ # return early if vsphere revision is lower than 5 as this is not supported
73
+ def get_storage_pod attributes
74
+ return unless @vsphere_rev.to_f >= 5
75
+ volume = attributes[:volumes].detect {|volume| !( volume.storage_pod.nil? || volume.storage_pod.empty? ) }
76
+ volume.storage_pod if volume
77
+ end
78
+
36
79
  # this methods defines where the vm config files would be located,
37
80
  # by default we prefer to keep it at the same place the (first) vmdk is located
81
+ # if we deploy the vm on a storage pool, we have to return an empty string
38
82
  def vm_path_name attributes
83
+ return '' if get_storage_pod(attributes)
39
84
  datastore = attributes[:volumes].first.datastore unless attributes[:volumes].empty?
40
85
  datastore ||= 'datastore1'
41
86
  "[#{datastore}]"
@@ -49,11 +94,73 @@ module Fog
49
94
 
50
95
  if (disks = attributes[:volumes])
51
96
  devices << create_controller(attributes[:scsi_controller]||attributes["scsi_controller"]||{})
52
- devices << disks.map { |disk| create_disk(disk, disks.index(disk)) }
97
+ devices << disks.map { |disk| create_disk(disk, disks.index(disk), :add, 1000, get_storage_pod(attributes)) }
98
+ end
99
+
100
+ if (cdroms = attributes[:cdroms])
101
+ devices << cdroms.map { |cdrom| create_cdrom(cdrom, cdroms.index(cdrom)) }
53
102
  end
54
103
  devices.flatten
55
104
  end
56
105
 
106
+ def boot_options attributes
107
+ # NOTE: you must be using vsphere_rev 5.0 or greater to set boot_order
108
+ # e.g. Fog::Compute.new(provider: "vsphere", vsphere_rev: "5.5", etc)
109
+ return unless @vsphere_rev.to_f >= 5
110
+ RbVmomi::VIM::VirtualMachineBootOptions.new(
111
+ :bootOrder => boot_order(attributes)
112
+ )
113
+ end
114
+
115
+ def boot_order attributes
116
+ # attributes[:boot_order] may be an array like this ['network', 'disk']
117
+ # stating, that we want to prefer network boots over disk boots
118
+ boot_order = []
119
+ attributes[:boot_order].each do |boot_device|
120
+ case boot_device
121
+ when 'network'
122
+ if nics = attributes[:interfaces]
123
+ # key is based on 4000 + the interface index
124
+ # we allow booting from all network interfaces, the first interface has the highest priority
125
+ nics.each do |nic|
126
+ boot_order << RbVmomi::VIM::VirtualMachineBootOptionsBootableEthernetDevice.new(
127
+ :deviceKey => 4000 + nics.index(nic),
128
+ )
129
+ end
130
+ end
131
+ when 'disk'
132
+ if disks = attributes[:volumes]
133
+ disks.each do |disk|
134
+ # we allow booting from all harddisks, the first disk has the highest priority
135
+ boot_order << RbVmomi::VIM::VirtualMachineBootOptionsBootableDiskDevice.new(
136
+ :deviceKey => disk.key || get_disk_device_key(disks.index(disk)),
137
+ )
138
+ end
139
+ end
140
+ when 'cdrom'
141
+ boot_order << RbVmomi::VIM::VirtualMachineBootOptionsBootableCdromDevice.new()
142
+ when 'floppy'
143
+ boot_order << RbVmomi::VIM::VirtualMachineBootOptionsBootableFloppyDevice.new()
144
+ else
145
+ raise "failed to create boot device because \"#{boot_device}\" is unknown"
146
+ end
147
+ end
148
+ boot_order
149
+ end
150
+
151
+ def get_disk_device_key(index)
152
+ # disk key is based on 2000 + the SCSI ID + the controller bus * 16
153
+ # the scsi host adapter appears as SCSI ID 7, so we have to skip that
154
+ # host adapter key is based on 1000 + bus id
155
+ # fog assumes that there is only a single scsi controller, see device_change()
156
+ if (index > 6) then
157
+ _index = index + 1
158
+ else
159
+ _index = index
160
+ end
161
+ 2000 + _index
162
+ end
163
+
57
164
  def create_nic_backing nic, attributes
58
165
  raw_network = get_raw_network(nic.network, attributes[:datacenter], if nic.virtualswitch then nic.virtualswitch end)
59
166
 
@@ -121,19 +228,25 @@ module Fog
121
228
  end
122
229
  end
123
230
 
124
- def create_disk disk, index = 0, operation = :add, controller_key = 1000
231
+ def create_disk disk, index = 0, operation = :add, controller_key = 1000, storage_pod = nil
125
232
  if (index > 6) then
126
233
  _index = index + 1
127
234
  else
128
235
  _index = index
129
236
  end
237
+ # If we deploy the vm on a storage pod, datastore has to be an empty string
238
+ if storage_pod
239
+ datastore ''
240
+ else
241
+ datastore = "[#{disk.datastore}]"
242
+ end
130
243
  payload = {
131
244
  :operation => operation,
132
245
  :fileOperation => operation == :add ? :create : :destroy,
133
246
  :device => RbVmomi::VIM.VirtualDisk(
134
247
  :key => disk.key || _index,
135
248
  :backing => RbVmomi::VIM.VirtualDiskFlatVer2BackingInfo(
136
- :fileName => "[#{disk.datastore}]",
249
+ :fileName => datastore,
137
250
  :diskMode => disk.mode.to_sym,
138
251
  :thinProvisioned => disk.thin
139
252
  ),
@@ -150,6 +263,22 @@ module Fog
150
263
  payload
151
264
  end
152
265
 
266
+ def create_cdrom cdrom, index = 0, operation = :add, controller_key = 200
267
+ {
268
+ :operation => operation,
269
+ :device => RbVmomi::VIM.VirtualCdrom(
270
+ :key => cdrom.key || index,
271
+ :backing => RbVmomi::VIM::VirtualCdromRemoteAtapiBackingInfo(deviceName: ''),
272
+ :controllerKey => controller_key,
273
+ connectable: RbVmomi::VIM::VirtualDeviceConnectInfo(
274
+ startConnected: false,
275
+ connected: false,
276
+ allowGuestControl: true,
277
+ ),
278
+ )
279
+ }
280
+ end
281
+
153
282
  def extra_config attributes
154
283
  [
155
284
  {
@@ -162,6 +291,36 @@ module Fog
162
291
 
163
292
  class Mock
164
293
  def create_vm attributes = { }
294
+ id = SecureRandom.uuid
295
+ vm = {
296
+ 'id' => id,
297
+ 'uuid' => id,
298
+ 'instance_uuid' => id,
299
+ 'mo_ref' => "vm-#{rand 99999}",
300
+ 'datacenter' => attributes[:datacenter],
301
+ 'name' => attributes[:name],
302
+ 'interfaces' => attributes[:interfaces].map {{
303
+ 'mac' => 'f2:b5:46:b5:d8:d7'
304
+ }}
305
+ }
306
+ self.data[:servers][id] = vm
307
+ id
308
+ end
309
+
310
+ def create_cdrom cdrom, index = 0, operation = :add, controller_key = 200
311
+ {
312
+ :operation => operation,
313
+ :device => {
314
+ :key => cdrom.key || index,
315
+ :backing => { deviceName: '' },
316
+ :controllerKey => controller_key,
317
+ connectable: {
318
+ startConnected: false,
319
+ connected: false,
320
+ allowGuestControl: true,
321
+ },
322
+ }
323
+ }
165
324
  end
166
325
  end
167
326
  end