knife-vsphere 1.0.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef/knife/base_vsphere_command.rb +383 -371
  3. data/lib/chef/knife/customization_helper.rb +40 -0
  4. data/lib/chef/knife/vsphere_cluster_list.rb +47 -0
  5. data/lib/chef/knife/vsphere_cpu_ratio.rb +41 -45
  6. data/lib/chef/knife/vsphere_customization_list.rb +24 -29
  7. data/lib/chef/knife/vsphere_datastore_list.rb +68 -72
  8. data/lib/chef/knife/vsphere_datastore_maxfree.rb +48 -49
  9. data/lib/chef/knife/vsphere_datastorecluster_list.rb +66 -71
  10. data/lib/chef/knife/vsphere_datastorecluster_maxfree.rb +75 -84
  11. data/lib/chef/knife/vsphere_folder_list.rb +28 -30
  12. data/lib/chef/knife/vsphere_hosts_list.rb +42 -42
  13. data/lib/chef/knife/vsphere_pool_list.rb +46 -48
  14. data/lib/chef/knife/vsphere_pool_query.rb +58 -58
  15. data/lib/chef/knife/vsphere_template_list.rb +30 -32
  16. data/lib/chef/knife/vsphere_vlan_create.rb +51 -0
  17. data/lib/chef/knife/vsphere_vlan_list.rb +35 -37
  18. data/lib/chef/knife/vsphere_vm_clone.rb +834 -581
  19. data/lib/chef/knife/vsphere_vm_config.rb +48 -46
  20. data/lib/chef/knife/vsphere_vm_delete.rb +70 -66
  21. data/lib/chef/knife/vsphere_vm_execute.rb +62 -66
  22. data/lib/chef/knife/vsphere_vm_list.rb +57 -61
  23. data/lib/chef/knife/vsphere_vm_markastemplate.rb +48 -54
  24. data/lib/chef/knife/vsphere_vm_migrate.rb +73 -0
  25. data/lib/chef/knife/vsphere_vm_move.rb +88 -0
  26. data/lib/chef/knife/vsphere_vm_net.rb +57 -0
  27. data/lib/chef/knife/vsphere_vm_property_get.rb +44 -46
  28. data/lib/chef/knife/vsphere_vm_property_set.rb +83 -84
  29. data/lib/chef/knife/vsphere_vm_query.rb +48 -48
  30. data/lib/chef/knife/vsphere_vm_snapshot.rb +124 -130
  31. data/lib/chef/knife/vsphere_vm_state.rb +122 -127
  32. data/lib/chef/knife/vsphere_vm_toolsconfig.rb +54 -52
  33. data/lib/chef/knife/vsphere_vm_vmdk_add.rb +234 -241
  34. data/lib/chef/knife/vsphere_vm_wait_sysprep.rb +54 -0
  35. data/lib/knife-vsphere/version.rb +3 -4
  36. metadata +43 -15
  37. data/lib/chef/knife/vshpere_vm_migrate.rb +0 -80
  38. data/lib/chef/knife/vshpere_vm_move.rb +0 -92
  39. data/lib/chef/knife/vshpere_vm_net.rb +0 -57
@@ -1,54 +1,48 @@
1
- #
2
- # Author:: Ezra Pagel (<ezra@cpan.org>)
3
- # Contributor:: Jesse Campbell (<hikeit@gmail.com>)
4
- # Contributor:: Bethany Erskine (<bethany@paperlesspost.com>)
5
- # Contributor:: Adrian Stanila (https://github.com/sacx)
6
- # License:: Apache License, Version 2.0
7
- #
8
-
9
- require 'chef/knife'
10
- require 'chef/knife/base_vsphere_command'
11
- require 'rbvmomi'
12
-
13
- # Clone an existing template into a new VM, optionally applying a customization specification.
14
- # usage:
15
- # knife vsphere vm markastemplate MyVM --folder /templates
16
- class Chef::Knife::VsphereVmMarkastemplate < Chef::Knife::BaseVsphereCommand
17
-
18
- banner "knife vsphere vm markastemplate VMNAME"
19
-
20
- get_common_options
21
-
22
- option :folder,
23
- :long => "--folder FOLDER",
24
- :description => "The folder which contains the VM"
25
-
26
- def run
27
- $stdout.sync = true
28
-
29
- vmname = @name_args[0]
30
- if vmname.nil?
31
- show_usage
32
- fatal_exit("You must specify a virtual machine name")
33
- end
34
- config[:chef_node_name] = vmname unless config[:chef_node_name]
35
- config[:vmname] = vmname
36
-
37
- if get_config(:bootstrap) && get_config(:distro) && !@@chef_config_dir
38
- fatal_exit("Can't find .chef for bootstrap files. chdir to a location with a .chef directory and try again")
39
- end
40
-
41
- vim = get_vim_connection
42
-
43
- dc = get_datacenter
44
-
45
- src_folder = find_folder(get_config(:folder)) || dc.vmFolder
46
-
47
- vm = find_in_folder(src_folder, RbVmomi::VIM::VirtualMachine, config[:vmname]) or
48
- abort "VM not found"
49
-
50
- puts "Marking VM #{vmname} as template"
51
- vm.MarkAsTemplate()
52
- puts "Finished marking VM #{vmname} as template"
53
- end
54
- end
1
+ #
2
+ # Author:: Ezra Pagel (<ezra@cpan.org>)
3
+ # Contributor:: Jesse Campbell (<hikeit@gmail.com>)
4
+ # Contributor:: Bethany Erskine (<bethany@paperlesspost.com>)
5
+ # Contributor:: Adrian Stanila (https://github.com/sacx)
6
+ # License:: Apache License, Version 2.0
7
+ #
8
+
9
+ require 'chef/knife'
10
+ require 'chef/knife/base_vsphere_command'
11
+ require 'rbvmomi'
12
+
13
+ # Clone an existing template into a new VM, optionally applying a customization specification.
14
+ # usage:
15
+ # knife vsphere vm markastemplate MyVM --folder /templates
16
+ class Chef::Knife::VsphereVmMarkastemplate < Chef::Knife::BaseVsphereCommand
17
+ banner 'knife vsphere vm markastemplate VMNAME'
18
+
19
+ common_options
20
+
21
+ option :folder,
22
+ long: '--folder FOLDER',
23
+ description: 'The folder which contains the VM'
24
+
25
+ def run
26
+ $stdout.sync = true
27
+
28
+ vmname = @name_args[0]
29
+ if vmname.nil?
30
+ show_usage
31
+ fatal_exit('You must specify a virtual machine name')
32
+ end
33
+ config[:chef_node_name] = vmname unless config[:chef_node_name]
34
+ config[:vmname] = vmname
35
+
36
+ vim_connection
37
+
38
+ dc = datacenter
39
+
40
+ src_folder = find_folder(get_config(:folder)) || dc.vmFolder
41
+
42
+ vm = find_in_folder(src_folder, RbVmomi::VIM::VirtualMachine, config[:vmname]) || abort('VM not found')
43
+
44
+ puts "Marking VM #{vmname} as template"
45
+ vm.MarkAsTemplate()
46
+ puts "Finished marking VM #{vmname} as template"
47
+ end
48
+ end
@@ -0,0 +1,73 @@
1
+ #
2
+ # Author:: Raducu Deaconu (<rhadoo_io@yahoo.com>)
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ require 'chef/knife'
6
+ require 'chef/knife/base_vsphere_command'
7
+
8
+ # migrate vm to specified resource pool , datastore and host
9
+ class Chef::Knife::VsphereVmMigrate < Chef::Knife::BaseVsphereCommand
10
+ # migrate --resource-pool --dest-host --dest-datastore
11
+ banner 'knife vsphere vm migrate (options)'
12
+
13
+ common_options
14
+
15
+ option :dest_host,
16
+ long: '--dest-host HOST',
17
+ description: 'Destination host for the VM or template'
18
+
19
+ option :dest_datastore,
20
+ long: '--dest-datastore DATASTORE',
21
+ description: 'The destination datastore'
22
+
23
+ option :priority,
24
+ long: '--priority PRIORITY',
25
+ description: 'migration priority'
26
+
27
+ option :resource_pool,
28
+ long: '--resource-pool POOL',
29
+ description: 'The resource pool into which to put the VM'
30
+
31
+ def traverse_folders_for_pool(folder, poolname)
32
+ children = folder.children.find_all
33
+ children.each do |child|
34
+ if child.class == RbVmomi::VIM::ClusterComputeResource || child.class == RbVmomi::VIM::ComputeResource || child.class == RbVmomi::VIM::ResourcePool
35
+ return child if child.name == poolname
36
+ elsif child.class == RbVmomi::VIM::Folder
37
+ pool = traverse_folders_for_pool(child, poolname)
38
+ return pool if pool
39
+ end
40
+ end
41
+ false
42
+ end
43
+
44
+ def find_host_folder(folder, _type, name)
45
+ folder.host.find { |o| o.name == name }
46
+ end
47
+
48
+ def run
49
+ $stdout.sync = true
50
+ vmname = @name_args[0]
51
+ if vmname.nil?
52
+ show_usage
53
+ fatal_exit('You must specify a virtual machine name')
54
+ end
55
+
56
+ vim_connection
57
+ dc = datacenter
58
+ folder = find_folder(get_config(:folder)) || dc.vmFolder
59
+
60
+ vm = find_in_folder(folder, RbVmomi::VIM::VirtualMachine, vmname) || abort("VM #{vmname} not found")
61
+
62
+ priority = config[:priority]
63
+ dest_host = config[:dest_host]
64
+ ndc = find_datastore(config[:dest_datastore]) || abort('dest-datastore not found')
65
+ npool = find_pool(config[:resource_pool])
66
+ folderd = dc.hostFolder
67
+ pool = traverse_folders_for_pool(folderd, config[:resource_pool]) || abort("Pool #{poolname} not found")
68
+ h = find_host_folder(pool, RbVmomi::VIM::HostSystem, dest_host)
69
+ migrate_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(datastore: ndc, pool: npool, host: h)
70
+ # puts migrate_spec.host.name
71
+ vm.RelocateVM_Task(spec: migrate_spec, priority: priority).wait_for_completion
72
+ end
73
+ end
@@ -0,0 +1,88 @@
1
+ #
2
+ # Author:: Brian Dupras (<bdupras@rallydev.com>)
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ require 'chef/knife'
6
+ require 'chef/knife/base_vsphere_command'
7
+
8
+ # Lists all known virtual machines in the configured datacenter
9
+ class Chef::Knife::VsphereVmMove < Chef::Knife::BaseVsphereCommand
10
+ banner 'knife vsphere vm move'
11
+
12
+ common_options
13
+
14
+ option :dest_name,
15
+ long: '--dest-name NAME',
16
+ short: '-r',
17
+ description: 'Destination name of the VM or template'
18
+
19
+ option :dest_folder,
20
+ long: '--dest-folder FOLDER',
21
+ description: 'The destination folder into which the VM or template should be moved'
22
+
23
+ option :datastore,
24
+ long: '--datastore STORE',
25
+ description: 'The datastore into which to put the cloned VM'
26
+
27
+ option :thin_provision,
28
+ long: '--thin-provision',
29
+ description: 'Indicates whether disk should be thin provisioned.',
30
+ boolean: true
31
+
32
+ option :thick_provision,
33
+ long: '--thick-provision',
34
+ description: 'Indicates whether disk should be thick provisioned.',
35
+ boolean: true
36
+
37
+ # Convert VM
38
+ def convert_vm(vm)
39
+ dc = datacenter
40
+ hosts = find_all_in_folder(dc.hostFolder, RbVmomi::VIM::ComputeResource)
41
+ rp = hosts.first.resourcePool
42
+ rspec = RbVmomi::VIM.VirtualMachineRelocateSpec(pool: rp)
43
+
44
+ if get_config(:thin_provision)
45
+ puts "Thin provsisioning #{vm.name}"
46
+ rspec = RbVmomi::VIM.VirtualMachineRelocateSpec(datastore: find_datastore(get_config(:datastore)), transform: :sparse)
47
+ end
48
+
49
+ if get_config(:thick_provision)
50
+ puts "Thick provsisioning #{vm.name}"
51
+ rspec = RbVmomi::VIM.VirtualMachineRelocateSpec(datastore: find_datastore(get_config(:datastore)), transform: :flat)
52
+ end
53
+
54
+ task = vm.RelocateVM_Task(spec: rspec)
55
+ task.wait_for_completion
56
+ end
57
+
58
+ # Move VM
59
+ def move_vm(vm)
60
+ dest_name = config[:dest_name] || vmname
61
+ dest_folder = config[:dest_folder].nil? ? (vm.parent) : (find_folder(get_config(:dest_folder)))
62
+
63
+ vm.Rename_Task(newName: dest_name).wait_for_completion unless vmname == dest_name
64
+ dest_folder.MoveIntoFolder_Task(list: [vm]).wait_for_completion unless folder == dest_folder
65
+ end
66
+
67
+ def run
68
+ $stdout.sync = true
69
+ vmname = @name_args[0]
70
+ if vmname.nil?
71
+ show_usage
72
+ fatal_exit('You must specify a virtual machine name')
73
+ end
74
+
75
+ vim = vim_connection
76
+ dcname = get_config(:vsphere_dc)
77
+ dc = vim.serviceInstance.find_datacenter(dcname) || abort('datacenter not found')
78
+ folder = find_folder(get_config(:folder)) || dc.vmFolder
79
+
80
+ vm = find_in_folder(folder, RbVmomi::VIM::VirtualMachine, vmname) || abort("VM #{vmname} not found")
81
+
82
+ if get_config(:thin_provision) || get_config(:thick_provision)
83
+ convert_vm(vm)
84
+ else
85
+ move_vm(vm)
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,57 @@
1
+ #
2
+ # Author:: Raducu Deaconu (<rhadoo_io@yahoo.com>)
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ require 'chef/knife'
6
+ require 'chef/knife/base_vsphere_command'
7
+ # Switch VM networking state up/down (on all network interfaces)
8
+ class Chef::Knife::VsphereVmNet < Chef::Knife::BaseVsphereCommand
9
+ banner 'knife vsphere vm net STATE VMNAME'
10
+ common_options
11
+ def run
12
+ $stdout.sync = true
13
+ vmname = @name_args[1]
14
+ if vmname.nil?
15
+ show_usage
16
+ fatal_exit('You must specify a virtual machine name')
17
+ end
18
+
19
+ state = @name_args[0]
20
+ if state.nil?
21
+ show_usage
22
+ fatal_exit('You must specify networking state up/down')
23
+ end
24
+
25
+ if state == 'up'
26
+ if_state = true
27
+ elsif state == 'down'
28
+ if_state = false
29
+ end
30
+ vim_connection
31
+ dc = datacenter
32
+ folder = find_folder(get_config(:folder)) || dc.vmFolder
33
+ vm = find_in_folder(folder, RbVmomi::VIM::VirtualMachine, vmname) ||
34
+ abort("VM #{vmname} not found")
35
+ vm.config.hardware.device.each.grep(RbVmomi::VIM::VirtualEthernetCard) do |a|
36
+ backing = a.backing
37
+ key = a.key
38
+
39
+ puts "#{ui.color('Setting network adapter', :cyan)} :#{a.deviceInfo.label} on vlan :#{a.deviceInfo.summary} :#{state}"
40
+
41
+ conninfo = RbVmomi::VIM.VirtualDeviceConnectInfo(startConnected: true,
42
+ allowGuestControl: true,
43
+ connected: if_state)
44
+
45
+ ndevice = RbVmomi::VIM.VirtualE1000(key: key,
46
+ backing: backing,
47
+ connectable: conninfo)
48
+
49
+ device_spec = RbVmomi::VIM.VirtualDeviceConfigSpec(operation: :edit,
50
+ device: ndevice)
51
+
52
+ vmspec = RbVmomi::VIM.VirtualMachineConfigSpec(deviceChange: [device_spec])
53
+
54
+ vm.ReconfigVM_Task(spec: vmspec).wait_for_completion
55
+ end
56
+ end
57
+ end
@@ -1,46 +1,44 @@
1
- # Author:: Brian Dupras (<bdupras@rallydev.com>)
2
- # License:: Apache License, Version 2.0
3
-
4
- require 'chef/knife'
5
- require 'chef/knife/base_vsphere_command'
6
- require 'rbvmomi'
7
- require 'netaddr'
8
-
9
- class Chef::Knife::VsphereVmPropertyGet < Chef::Knife::BaseVsphereCommand
10
- banner "knife vsphere vm property get VMNAME PROPERTY. Gets a vApp Property on VMNAME."
11
-
12
- get_common_options
13
-
14
- def run
15
- $stdout.sync = true
16
- vmname = @name_args[0]
17
- if vmname.nil?
18
- show_usage
19
- fatal_exit("You must specify a virtual machine name")
20
- end
21
-
22
- property_name = @name_args[1]
23
- if property_name.nil?
24
- show_usage
25
- fatal_exit("You must specify a PROPERTY name (e.g. annotation)")
26
- end
27
- property_name = property_name.to_sym
28
-
29
- vim = get_vim_connection
30
-
31
- dc = get_datacenter
32
- folder = find_folder(get_config(:folder)) || dc.vmFolder
33
-
34
- vm = find_in_folder(folder, RbVmomi::VIM::VirtualMachine, vmname) or
35
- abort "VM #{vmname} not found"
36
-
37
- existing_property = vm.config.vAppConfig.property.find { |p| p.props[:id] == property_name.to_s }
38
-
39
- if existing_property
40
- puts existing_property.props[:value]
41
- else
42
- fatal_exit("PROPERTY [#{property_name.to_s}] not found")
43
- end
44
-
45
- end
46
- end
1
+ # Author:: Brian Dupras (<bdupras@rallydev.com>)
2
+ # License:: Apache License, Version 2.0
3
+
4
+ require 'chef/knife'
5
+ require 'chef/knife/base_vsphere_command'
6
+ require 'rbvmomi'
7
+ require 'netaddr'
8
+
9
+ class Chef::Knife::VsphereVmPropertyGet < Chef::Knife::BaseVsphereCommand
10
+ banner 'knife vsphere vm property get VMNAME PROPERTY. Gets a vApp Property on VMNAME.'
11
+
12
+ common_options
13
+
14
+ def run
15
+ $stdout.sync = true
16
+ vmname = @name_args[0]
17
+ if vmname.nil?
18
+ show_usage
19
+ fatal_exit('You must specify a virtual machine name')
20
+ end
21
+
22
+ property_name = @name_args[1]
23
+ if property_name.nil?
24
+ show_usage
25
+ fatal_exit('You must specify a PROPERTY name (e.g. annotation)')
26
+ end
27
+ property_name = property_name.to_sym
28
+
29
+ vim_connection
30
+
31
+ dc = datacenter
32
+ folder = find_folder(get_config(:folder)) || dc.vmFolder
33
+
34
+ vm = find_in_folder(folder, RbVmomi::VIM::VirtualMachine, vmname) || abort("VM #{vmname} not found")
35
+
36
+ existing_property = vm.config.vAppConfig.property.find { |p| p.props[:id] == property_name.to_s }
37
+
38
+ if existing_property
39
+ puts existing_property.props[:value]
40
+ else
41
+ fatal_exit("PROPERTY [#{property_name}] not found")
42
+ end
43
+ end
44
+ end
@@ -1,84 +1,83 @@
1
- # Author:: Brian Dupras (<bdupras@rallydev.com>)
2
- # License:: Apache License, Version 2.0
3
-
4
- require 'chef/knife'
5
- require 'chef/knife/base_vsphere_command'
6
- require 'rbvmomi'
7
- require 'netaddr'
8
-
9
- class Chef::Knife::VsphereVmPropertySet < Chef::Knife::BaseVsphereCommand
10
- banner "knife vsphere vm property set VMNAME PROPERTY VALUE. Sets a vApp Property on VMNAME."
11
-
12
- get_common_options
13
-
14
- option :ovf_environment_transport,
15
- :long => "--ovf-environment-transport STRING",
16
- :description => "Comma delimited string. Configures the transports to use for properties. Supported values are: iso and com.vmware.guestInfo."
17
-
18
- def run
19
- $stdout.sync = true
20
- vmname = @name_args[0]
21
- if vmname.nil?
22
- show_usage
23
- fatal_exit("You must specify a virtual machine name")
24
- end
25
-
26
- property_name = @name_args[1]
27
- if property_name.nil?
28
- show_usage
29
- fatal_exit("You must specify a PROPERTY name (e.g. annotation)")
30
- end
31
- property_name = property_name.to_sym
32
-
33
- property_value = @name_args[2]
34
- if property_value.nil?
35
- show_usage
36
- fatal_exit("You must specify a PROPERTY value")
37
- end
38
-
39
- vim = get_vim_connection
40
-
41
- dc = get_datacenter
42
- folder = find_folder(get_config(:folder)) || dc.vmFolder
43
-
44
- vm = find_in_folder(folder, RbVmomi::VIM::VirtualMachine, vmname) or
45
- abort "VM #{vmname} not found"
46
-
47
- if vm.config.vAppConfig && vm.config.vAppConfig.property
48
- existing_property = vm.config.vAppConfig.property.find { |p| p.props[:id] == property_name.to_s }
49
- end
50
-
51
- if existing_property
52
- operation = 'edit'
53
- property_key = existing_property.props[:key]
54
- else
55
- operation = 'add'
56
- property_key = property_name.object_id
57
- end
58
-
59
- vm_config_spec = RbVmomi::VIM.VirtualMachineConfigSpec(
60
- :vAppConfig => RbVmomi::VIM.VmConfigSpec(
61
- :property => [
62
- RbVmomi::VIM.VAppPropertySpec(
63
- :operation => operation,
64
- :info => {
65
- :key => property_key,
66
- :id => property_name.to_s,
67
- :type => 'string',
68
- :userConfigurable => true,
69
- :value => property_value
70
- }
71
- )
72
- ]
73
- )
74
- )
75
-
76
- unless config[:ovf_environment_transport].nil?
77
- transport = config[:ovf_environment_transport].split(",")
78
- transport = [""] if transport == [] ## because "".split returns [] and vmware wants [""]
79
- vm_config_spec[:vAppConfig][:ovfEnvironmentTransport] = transport
80
- end
81
-
82
- vm.ReconfigVM_Task( :spec => vm_config_spec ).wait_for_completion
83
- end
84
- end
1
+ # Author:: Brian Dupras (<bdupras@rallydev.com>)
2
+ # License:: Apache License, Version 2.0
3
+
4
+ require 'chef/knife'
5
+ require 'chef/knife/base_vsphere_command'
6
+ require 'rbvmomi'
7
+ require 'netaddr'
8
+
9
+ class Chef::Knife::VsphereVmPropertySet < Chef::Knife::BaseVsphereCommand
10
+ banner 'knife vsphere vm property set VMNAME PROPERTY VALUE. Sets a vApp Property on VMNAME.'
11
+
12
+ common_options
13
+
14
+ option :ovf_environment_transport,
15
+ long: '--ovf-environment-transport STRING',
16
+ description: 'Comma delimited string. Configures the transports to use for properties. Supported values are: iso and com.vmware.guestInfo.'
17
+
18
+ def run
19
+ $stdout.sync = true
20
+ vmname = @name_args[0]
21
+ if vmname.nil?
22
+ show_usage
23
+ fatal_exit('You must specify a virtual machine name')
24
+ end
25
+
26
+ property_name = @name_args[1]
27
+ if property_name.nil?
28
+ show_usage
29
+ fatal_exit('You must specify a PROPERTY name (e.g. annotation)')
30
+ end
31
+ property_name = property_name.to_sym
32
+
33
+ property_value = @name_args[2]
34
+ if property_value.nil?
35
+ show_usage
36
+ fatal_exit('You must specify a PROPERTY value')
37
+ end
38
+
39
+ vim_connection
40
+
41
+ dc = datacenter
42
+ folder = find_folder(get_config(:folder)) || dc.vmFolder
43
+
44
+ vm = find_in_folder(folder, RbVmomi::VIM::VirtualMachine, vmname) || abort("VM #{vmname} not found")
45
+
46
+ if vm.config.vAppConfig && vm.config.vAppConfig.property
47
+ existing_property = vm.config.vAppConfig.property.find { |p| p.props[:id] == property_name.to_s }
48
+ end
49
+
50
+ if existing_property
51
+ operation = 'edit'
52
+ property_key = existing_property.props[:key]
53
+ else
54
+ operation = 'add'
55
+ property_key = property_name.object_id
56
+ end
57
+
58
+ vm_config_spec = RbVmomi::VIM.VirtualMachineConfigSpec(
59
+ vAppConfig: RbVmomi::VIM.VmConfigSpec(
60
+ property: [
61
+ RbVmomi::VIM.VAppPropertySpec(
62
+ operation: operation,
63
+ info: {
64
+ key: property_key,
65
+ id: property_name.to_s,
66
+ type: 'string',
67
+ userConfigurable: true,
68
+ value: property_value
69
+ }
70
+ )
71
+ ]
72
+ )
73
+ )
74
+
75
+ unless config[:ovf_environment_transport].nil?
76
+ transport = config[:ovf_environment_transport].split(',')
77
+ transport = [''] if transport == [] ## because "".split returns [] and vmware wants [""]
78
+ vm_config_spec[:vAppConfig][:ovfEnvironmentTransport] = transport
79
+ end
80
+
81
+ vm.ReconfigVM_Task(spec: vm_config_spec).wait_for_completion
82
+ end
83
+ end