chef-provisioning-vsphere 0.5.7.dev6 → 0.5.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9a2f55b3a6433abfdd06aa270db00b1bed0cb8ab
4
- data.tar.gz: 74c8800daf24128394246648b0e02540ac0485e8
3
+ metadata.gz: e7308c027bc21589567543a1144202d7b8868641
4
+ data.tar.gz: 0f7ce9c37b7ae5662446ca99feb473c61fbbb6ce
5
5
  SHA512:
6
- metadata.gz: 56b566ca067ed38e6d7b639d6a687468b1189be2693bcd608cd85753d98cba8361009f00e145bf2ee2f9dffc8c766898767787f6f1b9177b73271a5dbc3359ce
7
- data.tar.gz: a01d8b591d62cd589569f868e3aa606c1f133f6a099caaab60534628848a56168014d3cd0a95a6722c86d61d8594ca743fe2ff0add2919ca5706ddb99da1cbcf
6
+ metadata.gz: f9c2f84cabb77cd7cc0540e3a4c648129d97360d4430d2c6ff9d1dd31f1afeb3429191aae723e82c8b2c5c033af5a6e54c779aebf4de851df138ce68a6ae02ec
7
+ data.tar.gz: 5fa9251bbca1fe98791fe01d27bdf015118d32f5c1832172d0bdf4af075b5fb6d07ba8a13170773628a540852f32d5026c7b3b1e8e374a3a515ca899a2fc2c1e
@@ -3,7 +3,6 @@ require 'cheffish/merged_config'
3
3
  require 'chef/provisioning/driver'
4
4
  require 'chef/provisioning/machine/windows_machine'
5
5
  require 'chef/provisioning/machine/unix_machine'
6
- require 'chef/provisioning/vsphere_driver/clone_spec_builder'
7
6
  require 'chef/provisioning/vsphere_driver/version'
8
7
  require 'chef/provisioning/vsphere_driver/vsphere_helpers'
9
8
  require 'chef/provisioning/vsphere_driver/vsphere_url'
@@ -12,6 +11,7 @@ module ChefProvisioningVsphere
12
11
  # Provisions machines in vSphere.
13
12
  class VsphereDriver < Chef::Provisioning::Driver
14
13
  include Chef::Mixin::ShellOut
14
+ include ChefProvisioningVsphere::Helpers
15
15
 
16
16
  def self.from_url(driver_url, config)
17
17
  VsphereDriver.new(driver_url, config)
@@ -163,7 +163,7 @@ module ChefProvisioningVsphere
163
163
  end
164
164
 
165
165
  def find_or_create_vm(bootstrap_options, machine_spec, action_handler)
166
- vm = vsphere_helper.find_vm(
166
+ vm = find_vm(
167
167
  bootstrap_options[:vm_folder],
168
168
  machine_spec.name
169
169
  )
@@ -231,7 +231,7 @@ module ChefProvisioningVsphere
231
231
  end
232
232
  return if networks.nil? || networks.count < 2
233
233
 
234
- new_nics = vsphere_helper.add_extra_nic(
234
+ new_nics = add_extra_nic(
235
235
  action_handler,
236
236
  vm_template_for(bootstrap_options),
237
237
  bootstrap_options,
@@ -313,7 +313,7 @@ module ChefProvisioningVsphere
313
313
  msg << vm.guest.toolsRunningStatus
314
314
  msg << '. powering up server...'
315
315
  action_handler.report_progress(msg.join)
316
- vsphere_helper.start_vm(vm)
316
+ start_vm(vm)
317
317
  else
318
318
  restart_server(action_handler, machine_spec, machine_options)
319
319
  end
@@ -395,7 +395,7 @@ module ChefProvisioningVsphere
395
395
  vm = vm_for(machine_spec)
396
396
  if vm
397
397
  action_handler.perform_action "Shutdown guest OS and power off VM [#{vm.parent.name}/#{vm.name}]" do
398
- vsphere_helper.stop_vm(vm)
398
+ stop_vm(vm)
399
399
  end
400
400
  end
401
401
  end
@@ -405,7 +405,7 @@ module ChefProvisioningVsphere
405
405
  vm = vm_for(machine_spec)
406
406
  if vm
407
407
  action_handler.perform_action "Power on VM [#{vm.parent.name}/#{vm.name}]" do
408
- vsphere_helper.start_vm(vm, machine_options[:bootstrap_options][:ssh][:port])
408
+ start_vm(vm, machine_options[:bootstrap_options][:ssh][:port])
409
409
  end
410
410
  end
411
411
  vm
@@ -484,53 +484,25 @@ module ChefProvisioningVsphere
484
484
 
485
485
  def vm_for(machine_spec)
486
486
  if machine_spec.location
487
- vsphere_helper.find_vm_by_id(machine_spec.location['server_id'])
487
+ find_vm_by_id(machine_spec.location['server_id'])
488
488
  else
489
489
  nil
490
490
  end
491
491
  end
492
492
 
493
493
  def clone_vm(action_handler, bootstrap_options, machine_name)
494
- vm_template = vm_template_for(bootstrap_options)
495
-
496
- spec_builder = CloneSpecBuilder.new(vsphere_helper, action_handler)
497
- clone_spec = spec_builder.build(vm_template, machine_name, bootstrap_options)
498
- Chef::Log.debug("Clone spec: #{clone_spec.pretty_inspect}")
499
-
500
- vm_folder = vsphere_helper.find_folder(bootstrap_options[:vm_folder])
501
- vm_template.CloneVM_Task(
502
- name: machine_name,
503
- folder: vm_folder,
504
- spec: clone_spec
505
- ).wait_for_completion
506
-
507
- vm = vsphere_helper.find_vm(vm_folder, machine_name)
508
-
509
- if bootstrap_options[:additional_disk_size_gb].to_i > 0
510
- task = vm.ReconfigVM_Task(
511
- spec: RbVmomi::VIM.VirtualMachineConfigSpec(
512
- deviceChange: [
513
- vsphere_helper.virtual_disk_for(vm, bootstrap_options)
514
- ]
515
- )
516
- )
517
- task.wait_for_completion
518
- end
519
-
520
- vm
521
- end
522
-
523
- def vsphere_helper
524
- @vsphere_helper ||= VsphereHelper.new(
525
- connect_options,
526
- config[:machine_options][:bootstrap_options][:datacenter]
494
+ do_vm_clone(
495
+ action_handler,
496
+ vm_template_for(bootstrap_options),
497
+ machine_name,
498
+ bootstrap_options
527
499
  )
528
500
  end
529
501
 
530
502
  def vm_template_for(bootstrap_options)
531
503
  template_folder = bootstrap_options[:template_folder]
532
504
  template_name = bootstrap_options[:template_name]
533
- vsphere_helper.find_vm(template_folder, template_name) ||
505
+ find_vm(template_folder, template_name) ||
534
506
  raise("vSphere VM Template not found [#{template_folder}/#{template_name}]")
535
507
  end
536
508
 
@@ -1,3 +1,3 @@
1
1
  module ChefProvisioningVsphere
2
- VERSION = '0.5.7.dev6'
2
+ VERSION = '0.5.7'
3
3
  end
@@ -1,24 +1,16 @@
1
1
  require 'rbvmomi'
2
2
 
3
3
  module ChefProvisioningVsphere
4
- class VsphereHelper
4
+ module Helpers
5
5
 
6
6
  if !$guest_op_managers
7
7
  $guest_op_managers = {}
8
8
  end
9
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
10
+ def vim(options = connect_options)
19
11
  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
12
+ puts "establishing connection to #{options[:host]}"
13
+ @current_connection = RbVmomi::VIM.connect options
22
14
  str_conn = @current_connection.pretty_inspect # a string in the format of VIM(host ip)
23
15
 
24
16
  # we are caching guest operation managers in a global variable...terrible i know
@@ -39,14 +31,22 @@ module ChefProvisioningVsphere
39
31
  folder.find(vm_name, RbVmomi::VIM::VirtualMachine)
40
32
  end
41
33
 
42
- def find_vm_by_id(uuid)
43
- vm = vim.searchIndex.FindByUuid(
34
+ def find_vm_by_id(uuid, connection = vim)
35
+ vm = connection.searchIndex.FindByUuid(
44
36
  uuid: uuid,
45
37
  vmSearch: true,
46
38
  instanceUuid: true
47
39
  )
48
40
  end
49
41
 
42
+ def vm_started?(vm, wait_on_port = 22)
43
+ return false if vm.nil?
44
+ state = vm.runtime.powerState
45
+ return false unless state == 'poweredOn'
46
+ return false unless port_ready?(vm, wait_on_port)
47
+ return true
48
+ end
49
+
50
50
  def vm_stopped?(vm)
51
51
  return true if vm.nil?
52
52
  state = vm.runtime.powerState
@@ -70,6 +70,31 @@ module ChefProvisioningVsphere
70
70
  end
71
71
  end
72
72
 
73
+ def port_ready?(vm, port)
74
+ vm_ip = vm.guest.ipAddress
75
+ return false if vm_ip.nil?
76
+
77
+ begin
78
+ tcp_socket = TCPSocket.new(vm_ip, port)
79
+ readable = IO.select([tcp_socket], nil, nil, 5)
80
+ if readable
81
+ true
82
+ else
83
+ false
84
+ end
85
+ rescue Errno::ETIMEDOUT
86
+ false
87
+ rescue Errno::EPERM
88
+ false
89
+ rescue Errno::ECONNREFUSED
90
+ false
91
+ rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH
92
+ false
93
+ ensure
94
+ tcp_socket && tcp_socket.close
95
+ end
96
+ end
97
+
73
98
  #folder could be like: /Level1/Level2/folder_name
74
99
  def find_folder(folder_name)
75
100
  base = datacenter.vmFolder
@@ -83,8 +108,9 @@ module ChefProvisioningVsphere
83
108
  end
84
109
 
85
110
  def datacenter
86
- @datacenter ||= vim.serviceInstance.find_datacenter(datacenter_name) ||
87
- raise("vSphere Datacenter not found [#{datacenter_name}]")
111
+ dc_name = config[:machine_options][:bootstrap_options][:datacenter]
112
+ @datacenter ||= vim.serviceInstance.find_datacenter(dc_name) ||
113
+ raise("vSphere Datacenter not found [#{dc_name}]")
88
114
  end
89
115
 
90
116
  def network_adapter_for(operation, network_name, network_label, device_key, backing_info)
@@ -106,6 +132,56 @@ module ChefProvisioningVsphere
106
132
  vm.config.hardware.device.select {|d| d.is_a?(RbVmomi::VIM::VirtualEthernetCard)}
107
133
  end
108
134
 
135
+ def do_vm_clone(action_handler, vm_template, vm_name, options)
136
+ deviceAdditions = []
137
+
138
+ clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(
139
+ location: relocate_spec_for(vm_template, options),
140
+ powerOn: false,
141
+ template: false,
142
+ config: RbVmomi::VIM.VirtualMachineConfigSpec(
143
+ :cpuHotAddEnabled => true,
144
+ :memoryHotAddEnabled => true,
145
+ :cpuHotRemoveEnabled => true,
146
+ :deviceChange => Array.new)
147
+ )
148
+
149
+ clone_spec.customization = customization_options_from(action_handler, vm_template, vm_name, options)
150
+
151
+ unless options[:annotation].to_s.nil?
152
+ clone_spec.config.annotation = options[:annotation]
153
+ end
154
+
155
+ unless options[:num_cpus].to_s.nil?
156
+ clone_spec.config.numCPUs = options[:num_cpus]
157
+ end
158
+
159
+ unless options[:memory_mb].to_s.nil?
160
+ clone_spec.config.memoryMB = options[:memory_mb]
161
+ end
162
+
163
+ unless options[:network_name].nil?
164
+ deviceAdditions, changes = network_device_changes(action_handler, vm_template, options)
165
+ clone_spec.config.deviceChange = changes
166
+ end
167
+
168
+ vm_folder = find_folder(options[:vm_folder])
169
+ vm_template.CloneVM_Task(
170
+ name: vm_name,
171
+ folder: vm_folder,
172
+ spec: clone_spec
173
+ ).wait_for_completion
174
+
175
+ vm = find_vm(vm_folder, vm_name)
176
+
177
+ if options[:additional_disk_size_gb].to_i > 0
178
+ task = vm.ReconfigVM_Task(:spec => RbVmomi::VIM.VirtualMachineConfigSpec(:deviceChange => [virtual_disk_for(vm, options)]))
179
+ task.wait_for_completion
180
+ end
181
+
182
+ vm
183
+ end
184
+
109
185
  def add_extra_nic(action_handler, vm_template, options, vm)
110
186
  deviceAdditions, changes = network_device_changes(action_handler, vm_template, options)
111
187
 
@@ -130,6 +206,28 @@ module ChefProvisioningVsphere
130
206
  end
131
207
  end
132
208
 
209
+ def relocate_spec_for(vm_template, options)
210
+ if options.has_key?(:host)
211
+ host = find_host(options[:host])
212
+ rspec = RbVmomi::VIM.VirtualMachineRelocateSpec(host: host)
213
+ else
214
+ pool = options[:resource_pool] ? find_pool(options[:resource_pool]) : vm_template.resourcePool
215
+ rspec = RbVmomi::VIM.VirtualMachineRelocateSpec(pool: pool)
216
+ raise 'either :host or :resource_pool must be specified when cloning from a VM Template' if pool.nil?
217
+ end
218
+
219
+ if options.has_key?(:use_linked_clone)
220
+ create_delta_disk(vm_template)
221
+ rspec.diskMoveType = :moveChildMostDiskBacking
222
+ end
223
+
224
+ unless options[:datastore].to_s.empty?
225
+ rspec.datastore = find_datastore(options[:datastore])
226
+ end
227
+
228
+ rspec
229
+ end
230
+
133
231
  def create_delta_disk(vm_template)
134
232
  disks = vm_template.config.hardware.device.grep(RbVmomi::VIM::VirtualDisk)
135
233
  disks.select { |disk| disk.backing.parent == nil }.each do |disk|
@@ -228,12 +326,114 @@ module ChefProvisioningVsphere
228
326
  datacenter.datastore.find { |f| f.info.name == datastore_name } or raise "no such datastore #{datastore_name}"
229
327
  end
230
328
 
329
+ def customization_options_from(action_handler, vm_template, vm_name, options)
330
+ if options.has_key?(:customization_spec)
331
+ if(options[:customization_spec].is_a?(Hash))
332
+ cust_options = options[:customization_spec]
333
+ ip_settings = cust_options[:ipsettings]
334
+ cust_domain = cust_options[:domain]
335
+
336
+ raise ArgumentError, 'domain is required' unless cust_domain
337
+ cust_ip_settings = nil
338
+ if ip_settings && ip_settings.key?(:ip)
339
+ unless cust_options[:ipsettings].key?(:subnetMask)
340
+ raise ArgumentError, 'subnetMask is required for static ip'
341
+ end
342
+ cust_ip_settings = RbVmomi::VIM::CustomizationIPSettings.new(ip_settings)
343
+ action_handler.report_progress "customizing #{vm_name} with static IP #{ip_settings[:ip]}"
344
+ cust_ip_settings.ip = RbVmomi::VIM::CustomizationFixedIp(:ipAddress => ip_settings[:ip])
345
+ end
346
+ if cust_ip_settings.nil?
347
+ cust_ip_settings= RbVmomi::VIM::CustomizationIPSettings.new(:ip => RbVmomi::VIM::CustomizationDhcpIpGenerator.new())
348
+ cust_ip_settings.dnsServerList = ip_settings[:dnsServerList]
349
+ action_handler.report_progress "customizing #{vm_name} with dynamic IP and DNS: #{ip_settings[:dnsServerList]}"
350
+ end
351
+
352
+ cust_ip_settings.dnsDomain = cust_domain
353
+ cust_global_ip_settings = RbVmomi::VIM::CustomizationGlobalIPSettings.new
354
+ cust_global_ip_settings.dnsServerList = cust_ip_settings.dnsServerList
355
+ cust_global_ip_settings.dnsSuffixList = [cust_domain]
356
+ cust_hostname = hostname_from(cust_options, vm_name)
357
+ cust_hwclockutc = cust_options[:hw_clock_utc]
358
+ cust_timezone = cust_options[:time_zone]
359
+
360
+ if vm_template.config.guestId.start_with?('win')
361
+ cust_prep = windows_prep_for(action_handler, options, vm_name)
362
+ else
363
+ cust_prep = RbVmomi::VIM::CustomizationLinuxPrep.new(
364
+ :domain => cust_domain,
365
+ :hostName => cust_hostname,
366
+ :hwClockUTC => cust_hwclockutc,
367
+ :timeZone => cust_timezone
368
+ )
369
+ end
370
+ cust_adapter_mapping = [RbVmomi::VIM::CustomizationAdapterMapping.new(:adapter => cust_ip_settings)]
371
+ RbVmomi::VIM::CustomizationSpec.new(
372
+ :identity => cust_prep,
373
+ :globalIPSettings => cust_global_ip_settings,
374
+ :nicSettingMap => cust_adapter_mapping
375
+ )
376
+ else
377
+ find_customization_spec(cust_options)
378
+ end
379
+ end
380
+ end
381
+
382
+ def windows_prep_for(action_handler, options, vm_name)
383
+ cust_options = options[:customization_spec]
384
+ cust_runonce = RbVmomi::VIM::CustomizationGuiRunOnce.new(
385
+ :commandList => [
386
+ 'winrm set winrm/config/client/auth @{Basic="true"}',
387
+ 'winrm set winrm/config/service/auth @{Basic="true"}',
388
+ 'winrm set winrm/config/service @{AllowUnencrypted="true"}',
389
+ 'shutdown -l'])
390
+
391
+ cust_login_password = RbVmomi::VIM::CustomizationPassword(
392
+ :plainText => true,
393
+ :value => options[:ssh][:password])
394
+ if cust_options.has_key?(:domain) and cust_options[:domain] != 'local'
395
+ cust_domain_password = RbVmomi::VIM::CustomizationPassword(
396
+ :plainText => true,
397
+ :value => ENV['domainAdminPassword'] || cust_options[:domainAdminPassword])
398
+ cust_id = RbVmomi::VIM::CustomizationIdentification.new(
399
+ :joinDomain => cust_options[:domain],
400
+ :domainAdmin => cust_options[:domainAdmin],
401
+ :domainAdminPassword => cust_domain_password)
402
+ #puts "my env passwd is: #{ENV['domainAdminPassword']}"
403
+ action_handler.report_progress "joining domain #{cust_options[:domain]} with user: #{cust_options[:domainAdmin]}"
404
+ else
405
+ cust_id = RbVmomi::VIM::CustomizationIdentification.new(
406
+ :joinWorkgroup => 'WORKGROUP')
407
+ end
408
+ cust_gui_unattended = RbVmomi::VIM::CustomizationGuiUnattended.new(
409
+ :autoLogon => true,
410
+ :autoLogonCount => 1,
411
+ :password => cust_login_password,
412
+ :timeZone => cust_options[:win_time_zone])
413
+ cust_userdata = RbVmomi::VIM::CustomizationUserData.new(
414
+ :computerName => hostname_from(cust_options, vm_name),
415
+ :fullName => cust_options[:org_name],
416
+ :orgName => cust_options[:org_name],
417
+ :productId => cust_options[:product_id])
418
+ RbVmomi::VIM::CustomizationSysprep.new(
419
+ :guiRunOnce => cust_runonce,
420
+ :identification => cust_id,
421
+ :guiUnattended => cust_gui_unattended,
422
+ :userData => cust_userdata)
423
+ end
424
+
425
+ def hostname_from(options, vm_name)
426
+ if options.key?(:hostname)
427
+ RbVmomi::VIM::CustomizationFixedName.new(:name => options[:hostname])
428
+ else
429
+ RbVmomi::VIM::CustomizationFixedName.new(:name => vm_name)
430
+ end
431
+ end
432
+
231
433
  def find_entity(name, parent_folder, &block)
232
434
  parts = name.split('/').reject(&:empty?)
233
435
  parts.each do |item|
234
- Chef::Log.debug("Identifying entity part: #{item} in folder type: #{parent_folder.class}")
235
436
  if parent_folder.is_a? RbVmomi::VIM::Folder
236
- Chef::Log.debug('Parent folder is a folder')
237
437
  parent_folder = parent_folder.childEntity.find { |f| f.name == item }
238
438
  else
239
439
  parent_folder = block.call(parent_folder, item)
@@ -256,28 +456,20 @@ module ChefProvisioningVsphere
256
456
 
257
457
  raise "vSphere Host not found [#{host_name}]" if host.nil?
258
458
 
259
- if host.is_a?(RbVmomi::VIM::ComputeResource)
260
- host = host.host.first
459
+ if !host.is_a?(RbVmomi::VIM::HostSystem) && host.respond_to?(:host)
460
+ host = host.host
261
461
  end
262
462
  host
263
463
  end
264
464
 
265
465
  def find_pool(pool_name)
266
- Chef::Log.debug("Finding pool: #{pool_name}")
267
466
  pool = find_entity(pool_name, datacenter.hostFolder) do |parent, part|
268
467
  case parent
269
- when RbVmomi::VIM::ClusterComputeResource, RbVmomi::VIM::ComputeResource
270
- Chef::Log.debug("finding #{part} in a #{parent.class}: #{parent.name}")
271
- Chef::Log.debug("Parent root pool has #{parent.resourcePool.resourcePool.count} pools")
272
- parent.resourcePool.resourcePool.each { |p| Chef::Log.debug(p.name ) }
468
+ when RbVmomi::VIM::ClusterComputeResource || RbVmomi::VIM::ComputeResource
273
469
  parent.resourcePool.resourcePool.find { |f| f.name == part }
274
470
  when RbVmomi::VIM::ResourcePool
275
- Chef::Log.debug("finding #{part} in a Resource Pool: #{parent.name}")
276
- Chef::Log.debug("Pool has #{parent.resourcePool.count} pools")
277
- parent.resourcePool.each { |p| Chef::Log.debug(p.name ) }
278
471
  parent.resourcePool.find { |f| f.name == part }
279
472
  else
280
- Chef::Log.debug("parent of #{part} is unexpected type: #{parent.class}")
281
473
  nil
282
474
  end
283
475
  end
@@ -34,11 +34,12 @@ require 'chef/provisioning/machine_spec'
34
34
  # }
35
35
 
36
36
  describe 'vsphere_driver' do
37
+ include ChefProvisioningVsphere::Helpers
38
+
37
39
  before :all do
38
40
  @vm_name = "cmvd-test-#{SecureRandom.hex}"
39
41
  @metal_config = eval File.read(File.expand_path('../config.rb', __FILE__))
40
42
  Cheffish.honor_local_mode do
41
- Chef::Log.level = :debug
42
43
  chef_server = Cheffish.default_chef_server
43
44
  @machine_spec = Chef::Provisioning.chef_managed_entry_store(chef_server).new_entry(:machine, @vm_name)
44
45
  url = URI::VsphereUrl.from_config(@metal_config[:driver_options]).to_s
@@ -48,11 +49,8 @@ describe 'vsphere_driver' do
48
49
  @metal_config[:machine_options][:convergence_options] = {:chef_server => chef_server}
49
50
  machine = @driver.ready_machine(action_handler, @machine_spec, @metal_config[:machine_options])
50
51
  @server_id = @machine_spec.location['server_id']
51
- @vsphere_helper = ChefProvisioningVsphere::VsphereHelper.new(
52
- @metal_config[:driver_options],
53
- @metal_config[:machine_options][:bootstrap_options][:datacenter]
54
- )
55
- @vm = @vsphere_helper.find_vm_by_id(@server_id)
52
+ @connection = vim(@metal_config[:driver_options])
53
+ @vm = find_vm_by_id(@server_id, @connection)
56
54
  end
57
55
  end
58
56
 
@@ -103,7 +101,7 @@ describe 'vsphere_driver' do
103
101
  end
104
102
  end
105
103
  it 'is in the correct datacenter' do
106
- expect(@vsphere_helper.vim.serviceInstance.find_datacenter(@metal_config[:machine_options][:bootstrap_options][:datacenter]).find_vm("#{@vm.parent.name}/#{@vm_name}")).not_to eq(nil)
104
+ expect(@connection.serviceInstance.find_datacenter(@metal_config[:machine_options][:bootstrap_options][:datacenter]).find_vm("#{@vm.parent.name}/#{@vm_name}")).not_to eq(nil)
107
105
  end
108
106
  it 'has an added disk of the correct size' do
109
107
  disk_count = @vm.disks.count
@@ -148,7 +146,7 @@ describe 'vsphere_driver' do
148
146
  @metal_config[:machine_options]
149
147
  )
150
148
  end
151
- vm = @vsphere_helper.find_vm_by_id(@server_id)
149
+ vm = find_vm_by_id(@server_id, @connection)
152
150
  expect(vm).to eq(nil)
153
151
  end
154
152
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-provisioning-vsphere
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.7.dev6
4
+ version: 0.5.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - CenturyLink Cloud
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-15 00:00:00.000000000 Z
11
+ date: 2015-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rbvmomi
@@ -103,7 +103,6 @@ files:
103
103
  - contribution-notice
104
104
  - lib/chef/provisioning/driver_init/vsphere.rb
105
105
  - lib/chef/provisioning/vsphere_driver.rb
106
- - lib/chef/provisioning/vsphere_driver/clone_spec_builder.rb
107
106
  - lib/chef/provisioning/vsphere_driver/driver.rb
108
107
  - lib/chef/provisioning/vsphere_driver/version.rb
109
108
  - lib/chef/provisioning/vsphere_driver/vsphere_helpers.rb
@@ -113,8 +112,6 @@ files:
113
112
  - spec/integration_tests/vsphere_driver_spec.rb
114
113
  - spec/unit_tests/VsphereDriver_spec.rb
115
114
  - spec/unit_tests/VsphereUrl_spec.rb
116
- - spec/unit_tests/clone_spec_builder_spec.rb
117
- - spec/unit_tests/support/vsphere_helper_stub.rb
118
115
  homepage: https://github.com/tier3/chef-provisioning-vsphere
119
116
  licenses:
120
117
  - MIT
@@ -130,9 +127,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
130
127
  version: '0'
131
128
  required_rubygems_version: !ruby/object:Gem::Requirement
132
129
  requirements:
133
- - - ">"
130
+ - - ">="
134
131
  - !ruby/object:Gem::Version
135
- version: 1.3.1
132
+ version: '0'
136
133
  requirements: []
137
134
  rubyforge_project:
138
135
  rubygems_version: 2.4.4
@@ -144,6 +141,4 @@ test_files:
144
141
  - spec/integration_tests/vsphere_driver_spec.rb
145
142
  - spec/unit_tests/VsphereDriver_spec.rb
146
143
  - spec/unit_tests/VsphereUrl_spec.rb
147
- - spec/unit_tests/clone_spec_builder_spec.rb
148
- - spec/unit_tests/support/vsphere_helper_stub.rb
149
144
  has_rdoc:
@@ -1,200 +0,0 @@
1
- module ChefProvisioningVsphere
2
- class CloneSpecBuilder
3
- def initialize(vsphere_helper, action_handler)
4
- @vsphere_helper = vsphere_helper
5
- @action_handler = action_handler
6
- end
7
-
8
- attr_reader :vsphere_helper
9
- attr_reader :action_handler
10
-
11
- def build(vm_template, vm_name, options)
12
- clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(
13
- location: relocate_spec_for(vm_template, options),
14
- powerOn: false,
15
- template: false,
16
- config: RbVmomi::VIM.VirtualMachineConfigSpec(
17
- :cpuHotAddEnabled => true,
18
- :memoryHotAddEnabled => true,
19
- :cpuHotRemoveEnabled => true,
20
- :deviceChange => Array.new)
21
- )
22
-
23
- unless options[:annotation].to_s.nil?
24
- clone_spec.config.annotation = options[:annotation]
25
- end
26
-
27
- unless options[:num_cpus].to_s.nil?
28
- clone_spec.config.numCPUs = options[:num_cpus]
29
- end
30
-
31
- unless options[:memory_mb].to_s.nil?
32
- clone_spec.config.memoryMB = options[:memory_mb]
33
- end
34
-
35
- unless options[:network_name].nil?
36
- deviceAdditions, changes = vsphere_helper.network_device_changes(
37
- action_handler,
38
- vm_template,
39
- options
40
- )
41
- clone_spec.config.deviceChange = changes
42
- end
43
-
44
- clone_spec.customization = customization_options_from(
45
- vm_template,
46
- vm_name,
47
- options
48
- )
49
-
50
- clone_spec
51
- end
52
-
53
- def relocate_spec_for(vm_template, options)
54
- rspec = RbVmomi::VIM.VirtualMachineRelocateSpec
55
- host = nil
56
-
57
- if options.has_key?(:host)
58
- host = vsphere_helper.find_host(options[:host])
59
- rspec.host = host
60
- end
61
-
62
- if options[:resource_pool]
63
- rspec.pool = vsphere_helper.find_pool(options[:resource_pool])
64
- elsif vm_template.config.template && !host.nil?
65
- rspec.pool = host.parent.resourcePool # assign to the "invisible" pool root
66
- elsif vm_template.config.template
67
- raise 'either :host or :resource_pool must be specified when cloning from a VM Template'
68
- end
69
-
70
-
71
- if options[:use_linked_clone]
72
- if vm_template.config.template
73
- Chef::Log.warn("Using a VM Template, ignoring use_linked_clone.")
74
- else
75
- vsphere_helper.create_delta_disk(vm_template)
76
- rspec.diskMoveType = :moveChildMostDiskBacking
77
- end
78
- end
79
-
80
- unless options[:datastore].to_s.empty?
81
- rspec.datastore = vsphere_helper.find_datastore(options[:datastore])
82
- end
83
-
84
- rspec
85
- end
86
-
87
- def customization_options_from(vm_template, vm_name, options)
88
- if options.has_key?(:customization_spec)
89
- if(options[:customization_spec].is_a?(Hash))
90
- cust_options = options[:customization_spec]
91
- ip_settings = cust_options[:ipsettings]
92
- cust_domain = cust_options[:domain]
93
-
94
- raise ArgumentError, 'domain is required' unless cust_domain
95
- cust_ip_settings = nil
96
- if ip_settings && ip_settings.key?(:ip)
97
- unless cust_options[:ipsettings].key?(:subnetMask)
98
- raise ArgumentError, 'subnetMask is required for static ip'
99
- end
100
- cust_ip_settings = RbVmomi::VIM::CustomizationIPSettings.new(
101
- ip_settings)
102
- action_handler.report_progress "customizing #{vm_name} \
103
- with static IP #{ip_settings[:ip]}"
104
- cust_ip_settings.ip = RbVmomi::VIM::CustomizationFixedIp(
105
- :ipAddress => ip_settings[:ip])
106
- end
107
- if cust_ip_settings.nil?
108
- cust_ip_settings= RbVmomi::VIM::CustomizationIPSettings.new(
109
- :ip => RbVmomi::VIM::CustomizationDhcpIpGenerator.new())
110
- cust_ip_settings.dnsServerList = ip_settings[:dnsServerList]
111
- action_handler.report_progress "customizing #{vm_name} with /
112
- dynamic IP and DNS: #{ip_settings[:dnsServerList]}"
113
- end
114
-
115
- cust_ip_settings.dnsDomain = cust_domain
116
- global_ip_settings = RbVmomi::VIM::CustomizationGlobalIPSettings.new
117
- global_ip_settings.dnsServerList = cust_ip_settings.dnsServerList
118
- global_ip_settings.dnsSuffixList = [cust_domain]
119
- cust_hostname = hostname_from(cust_options, vm_name)
120
- cust_hwclockutc = cust_options[:hw_clock_utc]
121
- cust_timezone = cust_options[:time_zone]
122
-
123
- if vm_template.config.guestId.start_with?('win')
124
- cust_prep = windows_prep_for(options, vm_name)
125
- else
126
- cust_prep = RbVmomi::VIM::CustomizationLinuxPrep.new(
127
- :domain => cust_domain,
128
- :hostName => cust_hostname,
129
- :hwClockUTC => cust_hwclockutc,
130
- :timeZone => cust_timezone
131
- )
132
- end
133
- cust_adapter_mapping = [
134
- RbVmomi::VIM::CustomizationAdapterMapping.new(
135
- :adapter => cust_ip_settings)
136
- ]
137
- RbVmomi::VIM::CustomizationSpec.new(
138
- :identity => cust_prep,
139
- :globalIPSettings => global_ip_settings,
140
- :nicSettingMap => cust_adapter_mapping
141
- )
142
- else
143
- vsphere_helper.find_customization_spec(cust_options)
144
- end
145
- end
146
- end
147
-
148
- def hostname_from(options, vm_name)
149
- if options.key?(:hostname)
150
- RbVmomi::VIM::CustomizationFixedName.new(:name => options[:hostname])
151
- else
152
- RbVmomi::VIM::CustomizationFixedName.new(:name => vm_name)
153
- end
154
- end
155
-
156
- def windows_prep_for(options, vm_name)
157
- cust_options = options[:customization_spec]
158
- cust_runonce = RbVmomi::VIM::CustomizationGuiRunOnce.new(
159
- :commandList => [
160
- 'winrm set winrm/config/client/auth @{Basic="true"}',
161
- 'winrm set winrm/config/service/auth @{Basic="true"}',
162
- 'winrm set winrm/config/service @{AllowUnencrypted="true"}',
163
- 'shutdown -l'])
164
-
165
- cust_login_password = RbVmomi::VIM::CustomizationPassword(
166
- :plainText => true,
167
- :value => options[:ssh][:password])
168
- if cust_options.has_key?(:domain) and cust_options[:domain] != 'local'
169
- cust_domain_password = RbVmomi::VIM::CustomizationPassword(
170
- :plainText => true,
171
- :value => ENV['domainAdminPassword'] || cust_options[:domainAdminPassword])
172
- cust_id = RbVmomi::VIM::CustomizationIdentification.new(
173
- :joinDomain => cust_options[:domain],
174
- :domainAdmin => cust_options[:domainAdmin],
175
- :domainAdminPassword => cust_domain_password)
176
- #puts "my env passwd is: #{ENV['domainAdminPassword']}"
177
- action_handler.report_progress "joining domain #{cust_options[:domain]} /
178
- with user: #{cust_options[:domainAdmin]}"
179
- else
180
- cust_id = RbVmomi::VIM::CustomizationIdentification.new(
181
- :joinWorkgroup => 'WORKGROUP')
182
- end
183
- cust_gui_unattended = RbVmomi::VIM::CustomizationGuiUnattended.new(
184
- :autoLogon => true,
185
- :autoLogonCount => 1,
186
- :password => cust_login_password,
187
- :timeZone => cust_options[:win_time_zone])
188
- cust_userdata = RbVmomi::VIM::CustomizationUserData.new(
189
- :computerName => hostname_from(cust_options, vm_name),
190
- :fullName => cust_options[:org_name],
191
- :orgName => cust_options[:org_name],
192
- :productId => cust_options[:product_id])
193
- RbVmomi::VIM::CustomizationSysprep.new(
194
- :guiRunOnce => cust_runonce,
195
- :identification => cust_id,
196
- :guiUnattended => cust_gui_unattended,
197
- :userData => cust_userdata)
198
- end
199
- end
200
- end
@@ -1,102 +0,0 @@
1
- require 'chef/provisioning/vsphere_driver'
2
-
3
- require_relative 'support/vsphere_helper_stub'
4
-
5
- describe ChefProvisioningVsphere::CloneSpecBuilder do
6
- let(:options) { Hash.new }
7
- let(:vm_template) { double('template') }
8
-
9
- before do
10
- allow(vm_template).to receive_message_chain(:config, :guestId)
11
- allow(vm_template).to receive_message_chain(:config, :template)
12
- .and_return(false)
13
- end
14
-
15
- subject do
16
- builder = ChefProvisioningVsphere::CloneSpecBuilder.new(
17
- ChefProvisioningVsphereStubs::VsphereHelperStub.new,
18
- Chef::Provisioning::ActionHandler.new
19
- )
20
- builder.build(vm_template, 'machine_name', options)
21
- end
22
-
23
- context 'using linked clones' do
24
- before { options[:use_linked_clone] = true }
25
-
26
- it 'sets the disk move type of the relocation spec' do
27
- expect(subject.location.diskMoveType).to be :moveChildMostDiskBacking
28
- end
29
- end
30
-
31
- context 'using linked clone on a template source' do
32
- before do
33
- options[:use_linked_clone] = true
34
- options[:host] = 'host'
35
- allow(vm_template).to receive_message_chain(:config, :template)
36
- .and_return(true)
37
- end
38
-
39
- it 'does not set the disk move type of the relocation spec' do
40
- expect(subject.location.diskMoveType).to be nil
41
- end
42
- end
43
-
44
- context 'not using linked clones' do
45
- before { options[:use_linked_clone] = false }
46
-
47
- it 'does not set the disk move type of the relocation spec' do
48
- expect(subject.location.diskMoveType).to be nil
49
- end
50
- end
51
-
52
- context 'specifying a host' do
53
- before { options[:host] = 'host' }
54
-
55
- it 'sets the host' do
56
- expect(subject.location.host).to_not be nil
57
- end
58
- end
59
-
60
- context 'not specifying a host' do
61
- it 'does not set the host' do
62
- expect(subject.location.host).to be nil
63
- end
64
- end
65
-
66
- context 'specifying a pool' do
67
- before { options[:resource_pool] = 'pool' }
68
-
69
- it 'sets the pool' do
70
- expect(subject.location.pool).to_not be nil
71
- end
72
- end
73
-
74
- context 'not specifying a pool' do
75
- it 'does not set the pool' do
76
- expect(subject.location.pool).to be nil
77
- end
78
- end
79
-
80
- context 'not specifying a pool but specifying a host on a template' do
81
- before do
82
- options[:host] = 'host'
83
- allow(vm_template).to receive_message_chain(:config, :template)
84
- .and_return(true)
85
- end
86
-
87
- it 'sets the pool to the hosts parent root pool' do
88
- expect(subject.location.pool).to be subject.location.host.parent.resourcePool
89
- end
90
- end
91
-
92
- context 'not specifying a pool or host when cloning from a template' do
93
- before do
94
- allow(vm_template).to receive_message_chain(:config, :template)
95
- .and_return(true)
96
- end
97
-
98
- it 'raises an error' do
99
- expect { subject.to raise_error }
100
- end
101
- end
102
- end
@@ -1,52 +0,0 @@
1
- module ChefProvisioningVsphereStubs
2
- class VsphereHelperStub < ChefProvisioningVsphere::VsphereHelper
3
- def initialize
4
- end
5
-
6
- def network_device_changes(action_handler, vm_template, options)
7
- [
8
- [RbVmomi::VIM::VirtualDeviceConfigSpec.new],
9
- [RbVmomi::VIM::VirtualDeviceConfigSpec.new]
10
- ]
11
- end
12
-
13
- def find_host(host_name)
14
- RbVmomi::VIM::HostSystem.new
15
- end
16
-
17
- def find_pool(pool_name)
18
- RbVmomi::VIM::ResourcePool.new(nil, nil)
19
- end
20
-
21
- def find_datastore(datastore_name)
22
- RbVmomi::VIM::Datastore.new
23
- end
24
-
25
- def find_customization_spec(options)
26
- RbVmomi::VIM::CustomizationSpec.new
27
- end
28
-
29
- def create_delta_disk(vm_template)
30
- end
31
- end
32
- end
33
-
34
- module RbVmomi
35
- class VIM::HostSystem
36
- attr_reader :parent
37
-
38
- def parent
39
- @parent ||= RbVmomi::VIM::ComputeResource.new
40
- end
41
- end
42
- end
43
-
44
- module RbVmomi
45
- class VIM::ComputeResource
46
- attr_reader :resourcePool
47
-
48
- def resourcePool
49
- @resourcePool ||= RbVmomi::VIM::ResourcePool.new(nil, nil)
50
- end
51
- end
52
- end