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

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.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