chef-provisioning-vsphere 0.8.4 → 0.9.0

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