fog-vsphere 1.7.0 → 1.7.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -1
  3. data/.rubocop.yml +8 -0
  4. data/.rubocop_todo.yml +217 -0
  5. data/.travis.yml +6 -7
  6. data/CHANGELOG.md +2 -6
  7. data/CONTRIBUTORS.md +10 -0
  8. data/Rakefile +10 -1
  9. data/lib/fog/vsphere/compute.rb +0 -2
  10. data/lib/fog/vsphere/models/compute/scsicontroller.rb +1 -6
  11. data/lib/fog/vsphere/models/compute/server.rb +7 -29
  12. data/lib/fog/vsphere/models/compute/ticket.rb +16 -0
  13. data/lib/fog/vsphere/models/compute/tickets.rb +25 -0
  14. data/lib/fog/vsphere/models/compute/volume.rb +28 -46
  15. data/lib/fog/vsphere/models/compute/volumes.rb +1 -1
  16. data/lib/fog/vsphere/requests/compute/create_vm.rb +44 -32
  17. data/lib/fog/vsphere/requests/compute/host_finish_maintenance.rb +14 -0
  18. data/lib/fog/vsphere/requests/compute/host_shutdown.rb +14 -0
  19. data/lib/fog/vsphere/requests/compute/host_start_maintenance.rb +14 -0
  20. data/lib/fog/vsphere/requests/compute/list_vm_scsi_controllers.rb +11 -4
  21. data/lib/fog/vsphere/requests/compute/list_vm_volumes.rb +1 -2
  22. data/lib/fog/vsphere/requests/compute/modify_vm_controller.rb +14 -2
  23. data/lib/fog/vsphere/requests/compute/modify_vm_volume.rb +3 -3
  24. data/lib/fog/vsphere/requests/compute/vm_acquire_ticket.rb +34 -0
  25. data/lib/fog/vsphere/requests/compute/vm_reconfig_volumes.rb +15 -26
  26. data/lib/fog/vsphere/requests/compute/vm_relocate.rb +54 -0
  27. data/lib/fog/vsphere/requests/compute/vm_remove_snapshot.rb +29 -0
  28. data/lib/fog/vsphere/requests/compute/vm_rename.rb +24 -0
  29. data/lib/fog/vsphere/requests/compute/vm_revert_snapshot.rb +29 -0
  30. data/lib/fog/vsphere/requests/compute/vm_suspend.rb +54 -0
  31. data/lib/fog/vsphere/version.rb +1 -1
  32. data/tests/class_from_string_tests.rb +3 -3
  33. data/tests/compute_tests.rb +16 -17
  34. data/tests/helpers/mock_helper.rb +3 -3
  35. data/tests/models/compute/cluster_tests.rb +4 -5
  36. data/tests/models/compute/hosts_tests.rb +2 -4
  37. data/tests/models/compute/rules_tests.rb +10 -16
  38. data/tests/models/compute/server_tests.rb +33 -29
  39. data/tests/models/compute/servers_tests.rb +2 -4
  40. data/tests/models/compute/ticket_tests.rb +12 -0
  41. data/tests/models/compute/tickets_tests.rb +8 -0
  42. data/tests/requests/compute/current_time_tests.rb +2 -4
  43. data/tests/requests/compute/folder_destroy_tests.rb +5 -7
  44. data/tests/requests/compute/get_network_tests.rb +18 -22
  45. data/tests/requests/compute/list_child_snapshots_tests.rb +1 -2
  46. data/tests/requests/compute/list_clusters_tests.rb +5 -6
  47. data/tests/requests/compute/list_datastores_tests.rb +6 -7
  48. data/tests/requests/compute/list_hosts_tests.rb +3 -4
  49. data/tests/requests/compute/list_networks_tests.rb +6 -7
  50. data/tests/requests/compute/list_storage_pods_test.rb +3 -4
  51. data/tests/requests/compute/list_virtual_machines_tests.rb +16 -20
  52. data/tests/requests/compute/list_vm_cdroms_tests.rb +1 -2
  53. data/tests/requests/compute/list_vm_snapshots_tests.rb +1 -2
  54. data/tests/requests/compute/modify_vm_cdrom_tests.rb +3 -4
  55. data/tests/requests/compute/revert_to_snapshot_tests.rb +2 -4
  56. data/tests/requests/compute/set_vm_customvalue_tests.rb +0 -2
  57. data/tests/requests/compute/vm_clone_tests.rb +20 -20
  58. data/tests/requests/compute/vm_config_vnc_tests.rb +3 -4
  59. data/tests/requests/compute/vm_destroy_tests.rb +1 -4
  60. data/tests/requests/compute/vm_migrate_tests.rb +1 -2
  61. data/tests/requests/compute/vm_power_off_tests.rb +2 -4
  62. data/tests/requests/compute/vm_power_on_tests.rb +1 -3
  63. data/tests/requests/compute/vm_reboot_tests.rb +2 -4
  64. data/tests/requests/compute/vm_reconfig_cdrom_tests.rb +2 -3
  65. data/tests/requests/compute/vm_reconfig_cpus_tests.rb +1 -3
  66. data/tests/requests/compute/vm_reconfig_hardware_tests.rb +2 -4
  67. data/tests/requests/compute/vm_reconfig_memory_tests.rb +1 -3
  68. data/tests/requests/compute/vm_suspend_tests.rb +23 -0
  69. data/tests/requests/compute/vm_take_snapshot_tests.rb +1 -3
  70. metadata +22 -4
  71. data/gemfiles/Gemfile.1.9.2+ +0 -9
@@ -3,17 +3,17 @@ module Fog
3
3
  class Vsphere
4
4
  class Real
5
5
  def add_vm_volume(volume)
6
- vm_reconfig_hardware('instance_uuid' => volume.server_id, 'hardware_spec' => {'deviceChange'=>[create_disk(volume, :add)]})
6
+ vm_reconfig_hardware('instance_uuid' => volume.server_id, 'hardware_spec' => {'deviceChange'=>[create_disk(volume, volume.unit_number, :add)]})
7
7
  end
8
8
 
9
9
  def destroy_vm_volume(volume)
10
- vm_reconfig_hardware('instance_uuid' => volume.server_id, 'hardware_spec' => {'deviceChange'=>[create_disk(volume, :remove)]})
10
+ vm_reconfig_hardware('instance_uuid' => volume.server_id, 'hardware_spec' => {'deviceChange'=>[create_disk(volume, volume.unit_number, :remove)]})
11
11
  end
12
12
  end
13
13
 
14
14
  class Mock
15
15
  def add_vm_volume(volume)
16
- vm_reconfig_hardware('instance_uuid' => volume.server_id, 'hardware_spec' => {'deviceChange'=>[create_cdrom(volume, :add)]})
16
+ vm_reconfig_hardware('instance_uuid' => volume.server_id, 'hardware_spec' => {'deviceChange'=>[create_cdrom(volume, volume.unit_number, :add)]})
17
17
  end
18
18
 
19
19
  def destroy_vm_volume(volume)
@@ -0,0 +1,34 @@
1
+ module Fog
2
+ module Compute
3
+ class Vsphere
4
+ class Real
5
+ def vm_acquire_ticket(options = {})
6
+ raise ArgumentError, 'instance_uuid is a required parameter' unless options.key?('instance_uuid')
7
+ ticket_type = options['ticket_type'] || 'webmks'
8
+
9
+ vm_mob_ref = get_vm_ref(options['instance_uuid'])
10
+
11
+ ticket = vm_mob_ref.AcquireTicket(ticketType: ticket_type)
12
+ {
13
+ 'ticket' => ticket.ticket,
14
+ 'host' => ticket.host,
15
+ 'port' => ticket.port,
16
+ 'ssl_thumbprint' => ticket.sslThumbprint
17
+ }
18
+ end
19
+ end
20
+
21
+ class Mock
22
+ def vm_acquire_ticket(options = {})
23
+ raise ArgumentError, 'instance_uuid is a required parameter' unless options.key?('instance_uuid')
24
+ {
25
+ 'ticket' => 'fdsfdsf',
26
+ 'host' => 'esxi.example.com',
27
+ 'port' => 443,
28
+ 'ssl_thumbprint' => '1C:63:E1:BD:56:03:EB:44:85:12:12:FC:DA:40:11:65:0E:30:A1:B8'
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -3,47 +3,36 @@ module Fog
3
3
  class Vsphere
4
4
  class Real
5
5
  def vm_reconfig_volumes(options = {})
6
- raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid'
7
- raise ArgumentError, "volumes is a required parameter" unless options.key? 'volumes'
6
+ raise ArgumentError, 'instance_uuid is a required parameter' unless options.key? 'instance_uuid'
7
+ raise ArgumentError, 'volumes is a required parameter' unless options.key? 'volumes'
8
8
  hardware_spec = {
9
9
  deviceChange: []
10
10
  }
11
11
  options['volumes'].each do |volume|
12
- hardware_spec[:deviceChange].push({
13
- :operation=>:edit,
14
- device: RbVmomi::VIM::VirtualDisk(
15
- backing: RbVmomi::VIM::VirtualDiskFlatVer2BackingInfo( diskMode: volume.mode, fileName: volume.filename ),
16
- unitNumber: volume.unit_number,
17
- key: volume.key,
18
- controllerKey: volume.controller_key,
19
- capacityInKB: volume.size,
20
- )
21
- })
12
+ hardware_spec[:deviceChange].push(create_disk(volume, :edit, filename: volume.filename))
22
13
  end
23
- vm_reconfig_hardware('instance_uuid' => options['instance_uuid'], 'hardware_spec' => hardware_spec )
14
+ vm_reconfig_hardware('instance_uuid' => options['instance_uuid'], 'hardware_spec' => hardware_spec)
24
15
  end
25
16
  end
26
17
 
27
18
  class Mock
28
19
  def vm_reconfig_volumes(options = {})
29
- raise ArgumentError, "instance_uuid is a required parameter" unless options.key? 'instance_uuid'
30
- raise ArgumentError, "volumes is a required parameter" unless options.key? 'volumes'
20
+ raise ArgumentError, 'instance_uuid is a required parameter' unless options.key? 'instance_uuid'
21
+ raise ArgumentError, 'volumes is a required parameter' unless options.key? 'volumes'
31
22
  hardware_spec = {
32
23
  deviceChange: []
33
24
  }
34
25
  options['volumes'].each do |volume|
35
- hardware_spec[:deviceChange].push({
36
- :operation=>:edit,
37
- device: {
38
- backing: { diskMode: volume.mode, fileName: volume.filename },
39
- unitNumber: volume.unit_number,
40
- key: volume.key,
41
- controllerKey: volume.controller_key,
42
- capacityInKB: volume.size,
43
- }
44
- })
26
+ hardware_spec[:deviceChange].push(operation: :edit,
27
+ device: {
28
+ backing: { diskMode: volume.mode, fileName: volume.filename },
29
+ unitNumber: volume.unit_number,
30
+ key: volume.key,
31
+ controllerKey: volume.controller_key,
32
+ capacityInKB: volume.size
33
+ })
45
34
  end
46
- vm_reconfig_hardware('instance_uuid' => options['instance_uuid'], 'hardware_spec' => hardware_spec )
35
+ vm_reconfig_hardware('instance_uuid' => options['instance_uuid'], 'hardware_spec' => hardware_spec)
47
36
  end
48
37
  end
49
38
  end
@@ -0,0 +1,54 @@
1
+ module Fog
2
+ module Compute
3
+ class Vsphere
4
+ class Real
5
+ # Clones a VM from a template or existing machine on your vSphere
6
+ # Server.
7
+ #
8
+ # ==== Parameters
9
+ # * options<~Hash>:
10
+ # * 'instance_uuid'<~String> - *REQUIRED* VM to relocate
11
+ # * 'host'<~String> - name of host which will run the VM.
12
+ # * 'pool'<~String> - name of pool which the VM should be
13
+ # attached.
14
+ # * 'disks'<~Array> - disks to relocate. Each disk is a
15
+ # hash with diskId wich is key attribute of volume,
16
+ # and datastore to relocate to.
17
+ def vm_relocate(options = {})
18
+ raise ArgumentError, 'instance_uuid is a required parameter' unless options.key? 'instance_uuid'
19
+
20
+ # Find the VM Object
21
+ search_filter = { :uuid => options['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true }
22
+ vm_mob_ref = connection.searchIndex.FindAllByUuid(search_filter).first
23
+
24
+ unless vm_mob_ref.is_a? RbVmomi::VIM::VirtualMachine
25
+ raise Fog::Vsphere::Errors::NotFound,
26
+ "Could not find VirtualMachine with instance uuid #{options['instance_uuid']}"
27
+ end
28
+ options['host'] = get_raw_host(options['host'], options['cluster'], options['datacenter']) if options['host']
29
+ if options['disks']
30
+ options['disks'] = options['disks'].map do |disk|
31
+ disk['datastore'] = get_raw_datastore(disk['datastore'], nil)
32
+ RbVmomi::VIM::VirtualMachineRelocateSpecDiskLocator(disk)
33
+ end
34
+ end
35
+ spec = RbVmomi::VIM::VirtualMachineRelocateSpec(
36
+ pool: options['pool'],
37
+ host: options['host'],
38
+ disk: options['disks']
39
+ )
40
+ task = vm_mob_ref.RelocateVM_Task(spec: spec, priority: options['priority'])
41
+ task.wait_for_completion
42
+ { 'task_state' => task.info.state }
43
+ end
44
+ end
45
+
46
+ class Mock
47
+ def vm_relocate(options = {})
48
+ raise ArgumentError, 'instance_uuid is a required parameter' unless options.key? 'instance_uuid'
49
+ { 'task_state' => 'success' }
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,29 @@
1
+ module Fog
2
+ module Compute
3
+ class Vsphere
4
+ class Real
5
+ def vm_remove_snapshot(vm_id, snapshot_id, remove_children = false)
6
+ vm = servers.get(vm_id)
7
+ snapshot = vm.snapshots.get(snapshot_id).mo_ref
8
+ task = snapshot.RemoveSnapshot_Task(removeChildren: remove_children)
9
+
10
+ task.wait_for_completion
11
+
12
+ {
13
+ 'task_state' => task.info.state,
14
+ 'was_cancelled' => task.info.cancelled
15
+ }
16
+ end
17
+ end
18
+
19
+ class Mock
20
+ def vm_remove_snapshot(_vm_id, _snapshot_id)
21
+ {
22
+ 'task_state' => 'success',
23
+ 'was_cancelled' => false
24
+ }
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ module Fog
2
+ module Compute
3
+ class Vsphere
4
+ class Real
5
+ def vm_rename(options = {})
6
+ raise ArgumentError, 'name is a required parameter' unless options.key? 'name'
7
+ raise ArgumentError, 'instance_uuid is a required parameter' unless options.key? 'instance_uuid'
8
+ vm_mob_ref = get_vm_ref(options['instance_uuid'])
9
+ task = vm_mob_ref.Rename_Task(newName: options['name'])
10
+ task.wait_for_completion
11
+ { 'task_state' => task.info.state }
12
+ end
13
+ end
14
+
15
+ class Mock
16
+ def vm_rename(options = {})
17
+ raise ArgumentError, 'name is a required parameter' unless options.key? 'name'
18
+ raise ArgumentError, 'instance_uuid is a required parameter' unless options.key? 'instance_uuid'
19
+ { 'task_state' => 'success' }
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ module Fog
2
+ module Compute
3
+ class Vsphere
4
+ class Real
5
+ def vm_revert_snapshot(vm_id, snapshot_id)
6
+ vm = servers.get(vm_id)
7
+ snapshot = vm.snapshots.get(snapshot_id).mo_ref
8
+ task = snapshot.RevertToSnapshot_Task
9
+
10
+ task.wait_for_completion
11
+
12
+ {
13
+ 'task_state' => task.info.state,
14
+ 'was_cancelled' => task.info.cancelled
15
+ }
16
+ end
17
+ end
18
+
19
+ class Mock
20
+ def vm_revert_snapshot(_vm_id, _snapshot_id)
21
+ {
22
+ 'task_state' => 'success',
23
+ 'was_cancelled' => false
24
+ }
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,54 @@
1
+ module Fog
2
+ module Compute
3
+ class Vsphere
4
+ class Real
5
+ def vm_suspend(options = {})
6
+ raise(ArgumentError, 'instance_uuid is a required parameter') unless options.key?('instance_uuid')
7
+ options = { 'force' => false }.merge(options)
8
+
9
+ search_filter = { :uuid => options['instance_uuid'], 'vmSearch' => true, 'instanceUuid' => true }
10
+ vm = connection.searchIndex.FindAllByUuid(search_filter).first
11
+
12
+ if options['force']
13
+ suspend_forcefully(vm)
14
+ else
15
+ suspend_gracefully(vm)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def suspend_forcefully(vm)
22
+ task = vm.SuspendVM_Task
23
+ task.wait_for_completion
24
+ {
25
+ 'task_state' => task.info.result,
26
+ 'suspend_type' => 'suspend'
27
+ }
28
+ end
29
+
30
+ def suspend_gracefully(vm)
31
+ vm.StandbyGuest
32
+ {
33
+ 'task_state' => 'running',
34
+ 'suspend_type' => 'standby_guest'
35
+ }
36
+ end
37
+ end
38
+
39
+ class Mock
40
+ def vm_suspend(options = {})
41
+ raise ArgumentError, 'instance_uuid is a required parameter' unless options.key? 'instance_uuid'
42
+
43
+ vm = get_virtual_machine(options['instance_uuid'])
44
+ vm['power_state'] = 'suspended'
45
+
46
+ {
47
+ 'task_state' => 'running',
48
+ 'suspend_type' => options['force'] ? 'suspend' : 'standby_guest'
49
+ }
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,5 +1,5 @@
1
1
  module Fog
2
2
  module Vsphere
3
- VERSION = '1.7.0'
3
+ VERSION = '1.7.0.1'
4
4
  end
5
5
  end
@@ -4,11 +4,11 @@ class A; class B; class C; end; end; end
4
4
 
5
5
  class TestClassFromString < Minitest::Test
6
6
  def test_empty_string
7
- assert_equal(nil, Fog::Vsphere.class_from_string(''))
7
+ assert_nil(Fog::Vsphere.class_from_string(''))
8
8
  end
9
9
 
10
10
  def test_nil
11
- assert_equal(nil, Fog::Vsphere.class_from_string(nil))
11
+ assert_nil(Fog::Vsphere.class_from_string(nil))
12
12
  end
13
13
 
14
14
  def test_name_as_class
@@ -20,7 +20,7 @@ class TestClassFromString < Minitest::Test
20
20
  end
21
21
 
22
22
  def test_unexpected_input
23
- assert_equal(nil, Fog::Vsphere.class_from_string(8))
23
+ assert_nil(Fog::Vsphere.class_from_string(8))
24
24
  end
25
25
 
26
26
  def test_nested_class_without_default_path
@@ -1,8 +1,7 @@
1
1
  Shindo.tests('Fog::Compute[:vsphere]', ['vsphere']) do
2
-
3
2
  compute = Fog::Compute[:vsphere]
4
3
 
5
- tests("| convert_vm_mob_ref_to_attr_hash") do
4
+ tests('| convert_vm_mob_ref_to_attr_hash') do
6
5
  # Mock the RbVmomi::VIM::ManagedObject class
7
6
  class MockManagedObject
8
7
  attr_reader :parent, :_ref
@@ -11,42 +10,42 @@ Shindo.tests('Fog::Compute[:vsphere]', ['vsphere']) do
11
10
  @parent = @_ref = 'vm-123'
12
11
  end
13
12
 
14
- def collect! *pathSet
13
+ def collect!(*_pathSet)
15
14
  { '_ref' => 'vm-123', 'name' => 'fakevm' }
16
15
  end
17
16
  end
18
17
 
19
18
  fake_vm_mob_ref = MockManagedObject.new
20
19
 
21
- tests("When converting an incomplete vm object") do
22
- test("it should return a Hash") do
23
- compute.send(:convert_vm_mob_ref_to_attr_hash, fake_vm_mob_ref).kind_of? Hash
20
+ tests('When converting an incomplete vm object') do
21
+ test('it should return a Hash') do
22
+ compute.send(:convert_vm_mob_ref_to_attr_hash, fake_vm_mob_ref).is_a? Hash
24
23
  end
25
- tests("The converted Hash should") do
24
+ tests('The converted Hash should') do
26
25
  attr_hash = compute.send(:convert_vm_mob_ref_to_attr_hash, fake_vm_mob_ref)
27
- test("have a name") { attr_hash['name'] == 'fakevm' }
28
- test("have a mo_ref") {attr_hash['mo_ref'] == 'vm-123' }
29
- test("have an id") { attr_hash['id'] == 'vm-123' }
30
- test("not have a instance_uuid") { attr_hash['instance_uuid'].nil? }
26
+ test('have a name') { attr_hash['name'] == 'fakevm' }
27
+ test('have a mo_ref') { attr_hash['mo_ref'] == 'vm-123' }
28
+ test('have an id') { attr_hash['id'] == 'vm-123' }
29
+ test('not have a instance_uuid') { attr_hash['instance_uuid'].nil? }
31
30
  end
32
31
  end
33
32
 
34
- tests("When passed a nil object") do
33
+ tests('When passed a nil object') do
35
34
  attr_hash = compute.send :convert_vm_mob_ref_to_attr_hash, nil
36
- test("it should return a nil object") do
35
+ test('it should return a nil object') do
37
36
  attr_hash.nil?
38
37
  end
39
38
  end
40
39
  end
41
40
 
42
- tests("Compute attributes") do
43
- %w{ vsphere_is_vcenter vsphere_rev vsphere_username vsphere_server }.each do |attr|
41
+ tests('Compute attributes') do
42
+ %w[vsphere_is_vcenter vsphere_rev vsphere_username vsphere_server].each do |attr|
44
43
  test("it should respond to #{attr}") { compute.respond_to? attr }
45
44
  end
46
45
  end
47
46
 
48
- tests("Compute collections") do
49
- %w{ servers }.each do |collection|
47
+ tests('Compute collections') do
48
+ %w[servers].each do |collection|
50
49
  test("it should respond to #{collection}") { compute.respond_to? collection }
51
50
  end
52
51
  end
@@ -2,8 +2,8 @@ Fog.mock! if ENV['FOG_MOCK'] == 'true'
2
2
 
3
3
  if Fog.mock?
4
4
  Fog.credentials = {
5
- :vsphere_server => 'fake_vsphere_server',
6
- :vsphere_username => 'fake_vsphere_username',
7
- :vsphere_password => 'fake_vsphere_password'
5
+ vsphere_server: 'fake_vsphere_server',
6
+ vsphere_username: 'fake_vsphere_username',
7
+ vsphere_password: 'fake_vsphere_password'
8
8
  }.merge(Fog.credentials)
9
9
  end
@@ -1,19 +1,18 @@
1
1
  Shindo.tests('Fog::Compute[:vsphere] | cluster collection', ['vsphere']) do
2
-
3
2
  compute = Fog::Compute[:vsphere]
4
3
 
5
4
  tests('Cluster collection') do
6
5
  clusters = compute.datacenters.first.clusters
7
6
 
8
- test('should not be empty') { not clusters.empty? }
9
- test('should be a kind of Fog::Compute::Vsphere::Clusters') { clusters.kind_of? Fog::Compute::Vsphere::Clusters }
7
+ test('should not be empty') { !clusters.empty? }
8
+ test('should be a kind of Fog::Compute::Vsphere::Clusters') { clusters.is_a? Fog::Compute::Vsphere::Clusters }
10
9
  test('should get a cluster') { clusters.get('Solutionscluster').id == '1d4d9a3f-e4e8-4c40-b7fc-263850068fa4' }
11
10
  end
12
11
 
13
12
  tests('A cluster should') do
14
13
  cluster = compute.datacenters.first.clusters.get('Solutionscluster')
15
14
 
16
- test('have datastores') { cluster.datastores.first.kind_of? Fog::Compute::Vsphere::Datastore }
17
- test('have networks') { cluster.networks.first.kind_of? Fog::Compute::Vsphere::Network }
15
+ test('have datastores') { cluster.datastores.first.is_a? Fog::Compute::Vsphere::Datastore }
16
+ test('have networks') { cluster.networks.first.is_a? Fog::Compute::Vsphere::Network }
18
17
  end
19
18
  end