chef-provisioning-vsphere 0.10.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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