chef-provisioning-vsphere 0.8.3.dev.2 → 0.8.3

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.
@@ -1,3 +1,3 @@
1
- module ChefProvisioningVsphere
2
- VERSION = '0.8.3.dev.2'
3
- end
1
+ module ChefProvisioningVsphere
2
+ VERSION = '0.8.3'
3
+ end
@@ -1,341 +1,341 @@
1
- require 'rbvmomi'
2
-
3
- module ChefProvisioningVsphere
4
- class VsphereHelper
5
-
6
- if !$guest_op_managers
7
- $guest_op_managers = {}
8
- end
9
-
10
- def initialize(connect_options, datacenter_name)
11
- @connect_options = connect_options
12
- @datacenter_name = datacenter_name
13
- end
14
-
15
- attr_reader :connect_options
16
- attr_reader :datacenter_name
17
-
18
- def vim
19
- if @current_connection.nil? or @current_connection.serviceContent.sessionManager.currentSession.nil?
20
- puts "establishing connection to #{connect_options[:host]}"
21
- @current_connection = RbVmomi::VIM.connect connect_options
22
- str_conn = @current_connection.pretty_inspect # a string in the format of VIM(host ip)
23
-
24
- # we are caching guest operation managers in a global variable...terrible i know
25
- # this object is available from the serviceContent object on API version 5 forward
26
- # Its a singleton and if another connection is made for the same host and user
27
- # that object is not available on any subsequent connection
28
- # I could find no documentation that discusses this
29
- if !$guest_op_managers.has_key?(str_conn)
30
- $guest_op_managers[str_conn] = @current_connection.serviceContent.guestOperationsManager
31
- end
32
- end
33
-
34
- @current_connection
35
- end
36
-
37
- def find_vm(folder, vm_name)
38
- folder = find_folder(folder) unless folder.is_a? RbVmomi::VIM::Folder
39
- folder.find(vm_name, RbVmomi::VIM::VirtualMachine)
40
- end
41
-
42
- def find_vm_by_id(uuid)
43
- vm = vim.searchIndex.FindByUuid(
44
- uuid: uuid,
45
- vmSearch: true,
46
- instanceUuid: true
47
- )
48
- end
49
-
50
- def start_vm(vm, wait_on_port = 22)
51
- state = vm.runtime.powerState
52
- unless state == 'poweredOn'
53
- vm.PowerOnVM_Task.wait_for_completion
54
- end
55
- end
56
-
57
- def stop_vm(vm, timeout = 600)
58
- start = Time.now.utc
59
- begin
60
- vm.ShutdownGuest
61
- until (Time.now.utc - start) > timeout ||
62
- vm.runtime.powerState == 'poweredOff' do
63
- print '.'
64
- sleep 2
65
- end
66
- rescue
67
- vm.PowerOffVM_Task.wait_for_completion
68
- end
69
- end
70
-
71
- #folder could be like: /Level1/Level2/folder_name
72
- def find_folder(folder_name)
73
- base = datacenter.vmFolder
74
- unless folder_name.nil?
75
- folder_name.split('/').reject(&:empty?).each do |item|
76
- base = base.find(item, RbVmomi::VIM::Folder) ||
77
- raise("vSphere Folder not found [#{folder_name}]")
78
- end
79
- end
80
- base
81
- end
82
-
83
- def datacenter
84
- @datacenter ||= vim.serviceInstance.find_datacenter(datacenter_name) ||
85
- raise("vSphere Datacenter not found [#{datacenter_name}]")
86
- end
87
-
88
- def network_adapter_for(operation, network_name, network_label, device_key, backing_info)
89
- connectable = RbVmomi::VIM::VirtualDeviceConnectInfo(
90
- :allowGuestControl => true,
91
- :connected => true,
92
- :startConnected => true)
93
- device = RbVmomi::VIM::VirtualVmxnet3(
94
- :backing => backing_info,
95
- :deviceInfo => RbVmomi::VIM::Description(:label => network_label, :summary => network_name.split('/').last),
96
- :key => device_key,
97
- :connectable => connectable)
98
- RbVmomi::VIM::VirtualDeviceConfigSpec(
99
- :operation => operation,
100
- :device => device)
101
- end
102
-
103
- def find_ethernet_cards_for(vm)
104
- vm.config.hardware.device.select {|d| d.is_a?(RbVmomi::VIM::VirtualEthernetCard)}
105
- end
106
-
107
- def add_extra_nic(action_handler, vm_template, options, vm)
108
- deviceAdditions, changes = network_device_changes(action_handler, vm_template, options)
109
-
110
- if deviceAdditions.count > 0
111
- current_networks = find_ethernet_cards_for(vm).map{|card| network_id_for(card.backing)}
112
- new_devices = deviceAdditions.select { |device| !current_networks.include?(network_id_for(device.device.backing))}
113
-
114
- if new_devices.count > 0
115
- action_handler.report_progress "Adding extra NICs"
116
- task = vm.ReconfigVM_Task(:spec => RbVmomi::VIM.VirtualMachineConfigSpec(:deviceChange => new_devices))
117
- task.wait_for_completion
118
- new_devices
119
- end
120
- end
121
- end
122
-
123
- def network_id_for(backing_info)
124
- if backing_info.is_a?(RbVmomi::VIM::VirtualEthernetCardDistributedVirtualPortBackingInfo)
125
- backing_info.port.portgroupKey
126
- else
127
- backing_info.deviceName
128
- end
129
- end
130
-
131
- def create_delta_disk(vm_template)
132
- disks = vm_template.config.hardware.device.grep(RbVmomi::VIM::VirtualDisk)
133
- disks.select { |disk| disk.backing.parent == nil }.each do |disk|
134
- spec = {
135
- :deviceChange => [
136
- {
137
- :operation => :remove,
138
- :device => disk
139
- },
140
- {
141
- :operation => :add,
142
- :fileOperation => :create,
143
- :device => disk.dup.tap { |new_disk|
144
- new_disk.backing = new_disk.backing.dup
145
- new_disk.backing.fileName = "[#{disk.backing.datastore.name}]"
146
- new_disk.backing.parent = disk.backing
147
- },
148
- }
149
- ]
150
- }
151
- vm_template.ReconfigVM_Task(:spec => spec).wait_for_completion
152
- end
153
- end
154
-
155
- def virtual_disk_for(vm, datastore, size_gb)
156
- idx = vm.disks.count
157
- RbVmomi::VIM::VirtualDeviceConfigSpec(
158
- :operation => :add,
159
- :fileOperation => :create,
160
- :device => RbVmomi::VIM.VirtualDisk(
161
- :key => idx,
162
- :backing => RbVmomi::VIM.VirtualDiskFlatVer2BackingInfo(
163
- :fileName => "[#{datastore}]",
164
- :diskMode => 'persistent',
165
- :thinProvisioned => true
166
- ),
167
- :capacityInKB => size_gb * 1024 * 1024,
168
- :controllerKey => 1000,
169
- :unitNumber => idx
170
- )
171
- )
172
- end
173
-
174
- def network_device_changes(action_handler, vm_template, options)
175
- additions = []
176
- changes = []
177
- networks=options[:network_name]
178
- if networks.kind_of?(String)
179
- networks=[networks]
180
- end
181
-
182
- cards = find_ethernet_cards_for(vm_template)
183
-
184
- key = 4000
185
- networks.each_index do | i |
186
- label = "Ethernet #{i+1}"
187
- backing_info = backing_info_for(action_handler, networks[i])
188
- if card = cards.shift
189
- key = card.key
190
- operation = RbVmomi::VIM::VirtualDeviceConfigSpecOperation('edit')
191
- action_handler.report_progress "changing template nic for #{networks[i]}"
192
- changes.push(
193
- network_adapter_for(operation, networks[i], label, key, backing_info))
194
- else
195
- key = key + 1
196
- operation = RbVmomi::VIM::VirtualDeviceConfigSpecOperation('add')
197
- action_handler.report_progress "will be adding nic for #{networks[i]}"
198
- additions.push(
199
- network_adapter_for(operation, networks[i], label, key, backing_info))
200
- end
201
- end
202
- [additions, changes]
203
- end
204
-
205
- def backing_info_for(action_handler, network_name)
206
- action_handler.report_progress('finding networks...')
207
- network = find_network(network_name)
208
- action_handler.report_progress(
209
- "network: #{network_name} is a #{network.class}")
210
- if network.is_a?(RbVmomi::VIM::DistributedVirtualPortgroup)
211
- port = RbVmomi::VIM::DistributedVirtualSwitchPortConnection(
212
- :switchUuid => network.config.distributedVirtualSwitch.uuid,
213
- :portgroupKey => network.key
214
- )
215
- RbVmomi::VIM::VirtualEthernetCardDistributedVirtualPortBackingInfo(
216
- :port => port)
217
- else
218
- RbVmomi::VIM::VirtualEthernetCardNetworkBackingInfo(
219
- deviceName: network_name.split('/').last)
220
- end
221
- end
222
-
223
- def find_datastore(datastore_name)
224
- datacenter.datastore.find { |f| f.info.name == datastore_name } or raise "no such datastore #{datastore_name}"
225
- end
226
-
227
- def find_entity(name, parent_folder, &block)
228
- parts = name.split('/').reject(&:empty?)
229
- parts.each do |item|
230
- Chef::Log.debug("Identifying entity part: #{item} in folder type: #{parent_folder.class}")
231
- if parent_folder.is_a? RbVmomi::VIM::Folder
232
- Chef::Log.debug('Parent folder is a folder')
233
- parent_folder = parent_folder.childEntity.find { |f| f.name == item }
234
- else
235
- parent_folder = block.call(parent_folder, item)
236
- end
237
- end
238
- parent_folder
239
- end
240
-
241
- def find_host(host_name)
242
- host = find_entity(host_name, datacenter.hostFolder) do |parent, part|
243
- case parent
244
- when RbVmomi::VIM::ClusterComputeResource || RbVmomi::VIM::ComputeResource
245
- parent.host.find { |f| f.name == part }
246
- when RbVmomi::VIM::HostSystem
247
- parent.host.find { |f| f.name == part }
248
- else
249
- nil
250
- end
251
- end
252
-
253
- raise "vSphere Host not found [#{host_name}]" if host.nil?
254
-
255
- if host.is_a?(RbVmomi::VIM::ComputeResource)
256
- host = host.host.first
257
- end
258
- host
259
- end
260
-
261
- def find_pool(pool_name)
262
- Chef::Log.debug("Finding pool: #{pool_name}")
263
- pool = find_entity(pool_name, datacenter.hostFolder) do |parent, part|
264
- case parent
265
- when RbVmomi::VIM::ClusterComputeResource, RbVmomi::VIM::ComputeResource
266
- Chef::Log.debug("finding #{part} in a #{parent.class}: #{parent.name}")
267
- Chef::Log.debug("Parent root pool has #{parent.resourcePool.resourcePool.count} pools")
268
- parent.resourcePool.resourcePool.each { |p| Chef::Log.debug(p.name ) }
269
- parent.resourcePool.resourcePool.find { |f| f.name == part }
270
- when RbVmomi::VIM::ResourcePool
271
- Chef::Log.debug("finding #{part} in a Resource Pool: #{parent.name}")
272
- Chef::Log.debug("Pool has #{parent.resourcePool.count} pools")
273
- parent.resourcePool.each { |p| Chef::Log.debug(p.name ) }
274
- parent.resourcePool.find { |f| f.name == part }
275
- else
276
- Chef::Log.debug("parent of #{part} is unexpected type: #{parent.class}")
277
- nil
278
- end
279
- end
280
-
281
- raise "vSphere ResourcePool not found [#{pool_name}]" if pool.nil?
282
-
283
- if !pool.is_a?(RbVmomi::VIM::ResourcePool) && pool.respond_to?(:resourcePool)
284
- pool = pool.resourcePool
285
- end
286
- pool
287
- end
288
-
289
- def find_network(name)
290
- base = datacenter.networkFolder
291
- entity_array = name.split('/').reject(&:empty?)
292
- entity_array.each do |item|
293
- case base
294
- when RbVmomi::VIM::Folder
295
- base = base.find(item)
296
- when RbVmomi::VIM::VmwareDistributedVirtualSwitch
297
- idx = base.summary.portgroupName.find_index(item)
298
- base = idx.nil? ? nil : base.portgroup[idx]
299
- end
300
- end
301
-
302
- raise "vSphere Network not found [#{name}]" if base.nil?
303
-
304
- base
305
- end
306
-
307
- def find_customization_spec(customization_spec)
308
- csm = vim.serviceContent.customizationSpecManager
309
- csi = csm.GetCustomizationSpec(:name => customization_spec)
310
- spec = csi.spec
311
- raise "Customization Spec not found [#{customization_spec}]" if spec.nil?
312
- spec
313
- end
314
-
315
- def upload_file_to_vm(vm, username, password, local, remote)
316
- auth = RbVmomi::VIM::NamePasswordAuthentication({:username => username, :password => password, :interactiveSession => false})
317
- size = File.size(local)
318
- endpoint = $guest_op_managers[vim.pretty_inspect].fileManager.InitiateFileTransferToGuest(
319
- :vm => vm,
320
- :auth => auth,
321
- :guestFilePath => remote,
322
- :overwrite => true,
323
- :fileAttributes => RbVmomi::VIM::GuestWindowsFileAttributes.new,
324
- :fileSize => size)
325
-
326
- uri = URI.parse(endpoint)
327
- http = Net::HTTP.new(uri.host, uri.port)
328
- http.use_ssl = true
329
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
330
-
331
- req = Net::HTTP::Put.new("#{uri.path}?#{uri.query}")
332
- req.body_stream = File.open(local)
333
- req["Content-Type"] = "application/octet-stream"
334
- req["Content-Length"] = size
335
- res = http.request(req)
336
- unless res.kind_of?(Net::HTTPSuccess)
337
- raise "Error: #{res.inspect} :: #{res.body} :: sending #{local} to #{remote} at #{vm.name} via #{endpoint} with a size of #{size}"
338
- end
339
- end
340
- end
341
- end
1
+ require 'rbvmomi'
2
+
3
+ module ChefProvisioningVsphere
4
+ class VsphereHelper
5
+
6
+ if !$guest_op_managers
7
+ $guest_op_managers = {}
8
+ end
9
+
10
+ def initialize(connect_options, datacenter_name)
11
+ @connect_options = connect_options
12
+ @datacenter_name = datacenter_name
13
+ end
14
+
15
+ attr_reader :connect_options
16
+ attr_reader :datacenter_name
17
+
18
+ def vim
19
+ if @current_connection.nil? or @current_connection.serviceContent.sessionManager.currentSession.nil?
20
+ puts "establishing connection to #{connect_options[:host]}"
21
+ @current_connection = RbVmomi::VIM.connect connect_options
22
+ str_conn = @current_connection.pretty_inspect # a string in the format of VIM(host ip)
23
+
24
+ # we are caching guest operation managers in a global variable...terrible i know
25
+ # this object is available from the serviceContent object on API version 5 forward
26
+ # Its a singleton and if another connection is made for the same host and user
27
+ # that object is not available on any subsequent connection
28
+ # I could find no documentation that discusses this
29
+ if !$guest_op_managers.has_key?(str_conn)
30
+ $guest_op_managers[str_conn] = @current_connection.serviceContent.guestOperationsManager
31
+ end
32
+ end
33
+
34
+ @current_connection
35
+ end
36
+
37
+ def find_vm(folder, vm_name)
38
+ folder = find_folder(folder) unless folder.is_a? RbVmomi::VIM::Folder
39
+ folder.find(vm_name, RbVmomi::VIM::VirtualMachine)
40
+ end
41
+
42
+ def find_vm_by_id(uuid)
43
+ vm = vim.searchIndex.FindByUuid(
44
+ uuid: uuid,
45
+ vmSearch: true,
46
+ instanceUuid: true
47
+ )
48
+ end
49
+
50
+ def start_vm(vm, wait_on_port = 22)
51
+ state = vm.runtime.powerState
52
+ unless state == 'poweredOn'
53
+ vm.PowerOnVM_Task.wait_for_completion
54
+ end
55
+ end
56
+
57
+ def stop_vm(vm, timeout = 600)
58
+ start = Time.now.utc
59
+ begin
60
+ vm.ShutdownGuest
61
+ until (Time.now.utc - start) > timeout ||
62
+ vm.runtime.powerState == 'poweredOff' do
63
+ print '.'
64
+ sleep 2
65
+ end
66
+ rescue
67
+ vm.PowerOffVM_Task.wait_for_completion
68
+ end
69
+ end
70
+
71
+ #folder could be like: /Level1/Level2/folder_name
72
+ def find_folder(folder_name)
73
+ base = datacenter.vmFolder
74
+ unless folder_name.nil?
75
+ folder_name.split('/').reject(&:empty?).each do |item|
76
+ base = base.find(item, RbVmomi::VIM::Folder) ||
77
+ raise("vSphere Folder not found [#{folder_name}]")
78
+ end
79
+ end
80
+ base
81
+ end
82
+
83
+ def datacenter
84
+ @datacenter ||= vim.serviceInstance.find_datacenter(datacenter_name) ||
85
+ raise("vSphere Datacenter not found [#{datacenter_name}]")
86
+ end
87
+
88
+ def network_adapter_for(operation, network_name, network_label, device_key, backing_info)
89
+ connectable = RbVmomi::VIM::VirtualDeviceConnectInfo(
90
+ :allowGuestControl => true,
91
+ :connected => true,
92
+ :startConnected => true)
93
+ device = RbVmomi::VIM::VirtualVmxnet3(
94
+ :backing => backing_info,
95
+ :deviceInfo => RbVmomi::VIM::Description(:label => network_label, :summary => network_name.split('/').last),
96
+ :key => device_key,
97
+ :connectable => connectable)
98
+ RbVmomi::VIM::VirtualDeviceConfigSpec(
99
+ :operation => operation,
100
+ :device => device)
101
+ end
102
+
103
+ def find_ethernet_cards_for(vm)
104
+ vm.config.hardware.device.select {|d| d.is_a?(RbVmomi::VIM::VirtualEthernetCard)}
105
+ end
106
+
107
+ def add_extra_nic(action_handler, vm_template, options, vm)
108
+ deviceAdditions, changes = network_device_changes(action_handler, vm_template, options)
109
+
110
+ if deviceAdditions.count > 0
111
+ current_networks = find_ethernet_cards_for(vm).map{|card| network_id_for(card.backing)}
112
+ new_devices = deviceAdditions.select { |device| !current_networks.include?(network_id_for(device.device.backing))}
113
+
114
+ if new_devices.count > 0
115
+ action_handler.report_progress "Adding extra NICs"
116
+ task = vm.ReconfigVM_Task(:spec => RbVmomi::VIM.VirtualMachineConfigSpec(:deviceChange => new_devices))
117
+ task.wait_for_completion
118
+ new_devices
119
+ end
120
+ end
121
+ end
122
+
123
+ def network_id_for(backing_info)
124
+ if backing_info.is_a?(RbVmomi::VIM::VirtualEthernetCardDistributedVirtualPortBackingInfo)
125
+ backing_info.port.portgroupKey
126
+ else
127
+ backing_info.deviceName
128
+ end
129
+ end
130
+
131
+ def create_delta_disk(vm_template)
132
+ disks = vm_template.config.hardware.device.grep(RbVmomi::VIM::VirtualDisk)
133
+ disks.select { |disk| disk.backing.parent == nil }.each do |disk|
134
+ spec = {
135
+ :deviceChange => [
136
+ {
137
+ :operation => :remove,
138
+ :device => disk
139
+ },
140
+ {
141
+ :operation => :add,
142
+ :fileOperation => :create,
143
+ :device => disk.dup.tap { |new_disk|
144
+ new_disk.backing = new_disk.backing.dup
145
+ new_disk.backing.fileName = "[#{disk.backing.datastore.name}]"
146
+ new_disk.backing.parent = disk.backing
147
+ },
148
+ }
149
+ ]
150
+ }
151
+ vm_template.ReconfigVM_Task(:spec => spec).wait_for_completion
152
+ end
153
+ end
154
+
155
+ def virtual_disk_for(vm, datastore, size_gb)
156
+ idx = vm.disks.count
157
+ RbVmomi::VIM::VirtualDeviceConfigSpec(
158
+ :operation => :add,
159
+ :fileOperation => :create,
160
+ :device => RbVmomi::VIM.VirtualDisk(
161
+ :key => idx,
162
+ :backing => RbVmomi::VIM.VirtualDiskFlatVer2BackingInfo(
163
+ :fileName => "[#{datastore}]",
164
+ :diskMode => 'persistent',
165
+ :thinProvisioned => true
166
+ ),
167
+ :capacityInKB => size_gb * 1024 * 1024,
168
+ :controllerKey => 1000,
169
+ :unitNumber => idx
170
+ )
171
+ )
172
+ end
173
+
174
+ def network_device_changes(action_handler, vm_template, options)
175
+ additions = []
176
+ changes = []
177
+ networks=options[:network_name]
178
+ if networks.kind_of?(String)
179
+ networks=[networks]
180
+ end
181
+
182
+ cards = find_ethernet_cards_for(vm_template)
183
+
184
+ key = 4000
185
+ networks.each_index do | i |
186
+ label = "Ethernet #{i+1}"
187
+ backing_info = backing_info_for(action_handler, networks[i])
188
+ if card = cards.shift
189
+ key = card.key
190
+ operation = RbVmomi::VIM::VirtualDeviceConfigSpecOperation('edit')
191
+ action_handler.report_progress "changing template nic for #{networks[i]}"
192
+ changes.push(
193
+ network_adapter_for(operation, networks[i], label, key, backing_info))
194
+ else
195
+ key = key + 1
196
+ operation = RbVmomi::VIM::VirtualDeviceConfigSpecOperation('add')
197
+ action_handler.report_progress "will be adding nic for #{networks[i]}"
198
+ additions.push(
199
+ network_adapter_for(operation, networks[i], label, key, backing_info))
200
+ end
201
+ end
202
+ [additions, changes]
203
+ end
204
+
205
+ def backing_info_for(action_handler, network_name)
206
+ action_handler.report_progress('finding networks...')
207
+ network = find_network(network_name)
208
+ action_handler.report_progress(
209
+ "network: #{network_name} is a #{network.class}")
210
+ if network.is_a?(RbVmomi::VIM::DistributedVirtualPortgroup)
211
+ port = RbVmomi::VIM::DistributedVirtualSwitchPortConnection(
212
+ :switchUuid => network.config.distributedVirtualSwitch.uuid,
213
+ :portgroupKey => network.key
214
+ )
215
+ RbVmomi::VIM::VirtualEthernetCardDistributedVirtualPortBackingInfo(
216
+ :port => port)
217
+ else
218
+ RbVmomi::VIM::VirtualEthernetCardNetworkBackingInfo(
219
+ deviceName: network_name.split('/').last)
220
+ end
221
+ end
222
+
223
+ def find_datastore(datastore_name)
224
+ datacenter.datastore.find { |f| f.info.name == datastore_name } or raise "no such datastore #{datastore_name}"
225
+ end
226
+
227
+ def find_entity(name, parent_folder, &block)
228
+ parts = name.split('/').reject(&:empty?)
229
+ parts.each do |item|
230
+ Chef::Log.debug("Identifying entity part: #{item} in folder type: #{parent_folder.class}")
231
+ if parent_folder.is_a? RbVmomi::VIM::Folder
232
+ Chef::Log.debug('Parent folder is a folder')
233
+ parent_folder = parent_folder.childEntity.find { |f| f.name == item }
234
+ else
235
+ parent_folder = block.call(parent_folder, item)
236
+ end
237
+ end
238
+ parent_folder
239
+ end
240
+
241
+ def find_host(host_name)
242
+ host = find_entity(host_name, datacenter.hostFolder) do |parent, part|
243
+ case parent
244
+ when RbVmomi::VIM::ClusterComputeResource || RbVmomi::VIM::ComputeResource
245
+ parent.host.find { |f| f.name == part }
246
+ when RbVmomi::VIM::HostSystem
247
+ parent.host.find { |f| f.name == part }
248
+ else
249
+ nil
250
+ end
251
+ end
252
+
253
+ raise "vSphere Host not found [#{host_name}]" if host.nil?
254
+
255
+ if host.is_a?(RbVmomi::VIM::ComputeResource)
256
+ host = host.host.first
257
+ end
258
+ host
259
+ end
260
+
261
+ def find_pool(pool_name)
262
+ Chef::Log.debug("Finding pool: #{pool_name}")
263
+ pool = find_entity(pool_name, datacenter.hostFolder) do |parent, part|
264
+ case parent
265
+ when RbVmomi::VIM::ClusterComputeResource, RbVmomi::VIM::ComputeResource
266
+ Chef::Log.debug("finding #{part} in a #{parent.class}: #{parent.name}")
267
+ Chef::Log.debug("Parent root pool has #{parent.resourcePool.resourcePool.count} pools")
268
+ parent.resourcePool.resourcePool.each { |p| Chef::Log.debug(p.name ) }
269
+ parent.resourcePool.resourcePool.find { |f| f.name == part }
270
+ when RbVmomi::VIM::ResourcePool
271
+ Chef::Log.debug("finding #{part} in a Resource Pool: #{parent.name}")
272
+ Chef::Log.debug("Pool has #{parent.resourcePool.count} pools")
273
+ parent.resourcePool.each { |p| Chef::Log.debug(p.name ) }
274
+ parent.resourcePool.find { |f| f.name == part }
275
+ else
276
+ Chef::Log.debug("parent of #{part} is unexpected type: #{parent.class}")
277
+ nil
278
+ end
279
+ end
280
+
281
+ raise "vSphere ResourcePool not found [#{pool_name}]" if pool.nil?
282
+
283
+ if !pool.is_a?(RbVmomi::VIM::ResourcePool) && pool.respond_to?(:resourcePool)
284
+ pool = pool.resourcePool
285
+ end
286
+ pool
287
+ end
288
+
289
+ def find_network(name)
290
+ base = datacenter.networkFolder
291
+ entity_array = name.split('/').reject(&:empty?)
292
+ entity_array.each do |item|
293
+ case base
294
+ when RbVmomi::VIM::Folder
295
+ base = base.find(item)
296
+ when RbVmomi::VIM::VmwareDistributedVirtualSwitch
297
+ idx = base.summary.portgroupName.find_index(item)
298
+ base = idx.nil? ? nil : base.portgroup[idx]
299
+ end
300
+ end
301
+
302
+ raise "vSphere Network not found [#{name}]" if base.nil?
303
+
304
+ base
305
+ end
306
+
307
+ def find_customization_spec(customization_spec)
308
+ csm = vim.serviceContent.customizationSpecManager
309
+ csi = csm.GetCustomizationSpec(:name => customization_spec)
310
+ spec = csi.spec
311
+ raise "Customization Spec not found [#{customization_spec}]" if spec.nil?
312
+ spec
313
+ end
314
+
315
+ def upload_file_to_vm(vm, username, password, local, remote)
316
+ auth = RbVmomi::VIM::NamePasswordAuthentication({:username => username, :password => password, :interactiveSession => false})
317
+ size = File.size(local)
318
+ endpoint = $guest_op_managers[vim.pretty_inspect].fileManager.InitiateFileTransferToGuest(
319
+ :vm => vm,
320
+ :auth => auth,
321
+ :guestFilePath => remote,
322
+ :overwrite => true,
323
+ :fileAttributes => RbVmomi::VIM::GuestWindowsFileAttributes.new,
324
+ :fileSize => size)
325
+
326
+ uri = URI.parse(endpoint)
327
+ http = Net::HTTP.new(uri.host, uri.port)
328
+ http.use_ssl = true
329
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
330
+
331
+ req = Net::HTTP::Put.new("#{uri.path}?#{uri.query}")
332
+ req.body_stream = File.open(local)
333
+ req["Content-Type"] = "application/octet-stream"
334
+ req["Content-Length"] = size
335
+ res = http.request(req)
336
+ unless res.kind_of?(Net::HTTPSuccess)
337
+ raise "Error: #{res.inspect} :: #{res.body} :: sending #{local} to #{remote} at #{vm.name} via #{endpoint} with a size of #{size}"
338
+ end
339
+ end
340
+ end
341
+ end