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