knife-vsphere 1.0.1 → 1.2.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 (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