kitchen-vcenter 2.6.0 → 2.7.6

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
  SHA256:
3
- metadata.gz: '09fe38f6c02640a964e4018849dd5051de454bf0a9c92d43e5d26958210a68a3'
4
- data.tar.gz: e84e03176304cb5d8a9720c47e03e38474d959de33f076b25ef9571d670288e7
3
+ metadata.gz: 336491e73efecaf915ea3d66abee8ec788a918b5f4f9a6b89a9a186622f1fbc4
4
+ data.tar.gz: 1c90b4a62e44c40837955a48afde23509c0afccbae563430fc6bfdc3ff7caae0
5
5
  SHA512:
6
- metadata.gz: 9fc5020968df60fc311e0ad4b6ced4e694201641974d8bae3213a97f03dbf951cb5811f81b516e73962de2e0420eac8019f353252969a2702caf48d76b88898a
7
- data.tar.gz: b3ad895ee096db923c9363f2461cad8315ff5cc6130cf2bb00ada31d2a501a46d95d350795e11afe04f5f4f0a1b29ad9f398d293eea00602a76e51974d9a5876
6
+ metadata.gz: bff63dd4a20821ce5ec1f8a2032ceae2962b4d26345810c23ebf44dc5548afc85b642342f617f54d8be79b8075b815f65c20df48070b718897216102cdeab2fc
7
+ data.tar.gz: 8384025e3a26ea8a33122f770aecb961a608f96deab7e349d4501676b1ce8628fc4035b65f0428be363fb31d845c677644729f95382de9d017be03d2e15650f6
@@ -20,5 +20,5 @@
20
20
  # The main kitchen-vcenter module
21
21
  module KitchenVcenter
22
22
  # The version of this version of test-kitchen we assume enterprises want.
23
- VERSION = "2.6.0"
23
+ VERSION = "2.7.6"
24
24
  end
@@ -18,7 +18,8 @@
18
18
  require "kitchen"
19
19
  require "vsphere-automation-cis"
20
20
  require "vsphere-automation-vcenter"
21
- require "support/clone_vm"
21
+ require_relative "../../kitchen-vcenter/version"
22
+ require_relative "../../support/clone_vm"
22
23
  require "securerandom"
23
24
  require "uri"
24
25
 
@@ -50,6 +51,7 @@ module Kitchen
50
51
  default_config :vm_wait_interval, 2.0
51
52
  default_config :vm_rollback, false
52
53
  default_config :customize, nil
54
+ default_config :guest_customization, nil
53
55
  default_config :interface, nil
54
56
  default_config :active_discovery, false
55
57
  default_config :active_discovery_command, nil
@@ -57,6 +59,7 @@ module Kitchen
57
59
  default_config :vm_username, "vagrant"
58
60
  default_config :vm_password, "vagrant"
59
61
  default_config :vm_win_network, "Ethernet0"
62
+ default_config :transform_ip, nil
60
63
 
61
64
  default_config :benchmark, false
62
65
  default_config :benchmark_file, "kitchen-vcenter.csv"
@@ -82,6 +85,8 @@ module Kitchen
82
85
  #
83
86
  # @param [Object] state is the state of the vm
84
87
  def create(state)
88
+ debug format("Starting kitchen-vcenter %s", ::KitchenVcenter::VERSION)
89
+
85
90
  save_and_validate_parameters
86
91
  connect
87
92
 
@@ -112,10 +117,13 @@ module Kitchen
112
117
  end
113
118
 
114
119
  # Check that the datacenter exists
115
- datacenter_exists?(config[:datacenter])
120
+ dc_folder = File.dirname(config[:datacenter])
121
+ dc_folder = nil if dc_folder == "."
122
+ dc_name = File.basename(config[:datacenter])
123
+ datacenter_exists?(dc_folder, dc_name)
116
124
 
117
125
  # Get datacenter and cluster information
118
- datacenter = get_datacenter(config[:datacenter])
126
+ datacenter = get_datacenter(dc_folder, dc_name)
119
127
  cluster_id = get_cluster_id(config[:cluster])
120
128
 
121
129
  # Using the clone class, create a machine for TK
@@ -152,12 +160,14 @@ module Kitchen
152
160
  wait_timeout: config[:vm_wait_timeout],
153
161
  wait_interval: config[:vm_wait_interval],
154
162
  customize: config[:customize],
163
+ guest_customization: config[:guest_customization],
155
164
  active_discovery: config[:active_discovery],
156
165
  active_discovery_command: config[:active_discovery_command],
157
166
  vm_os: config[:vm_os],
158
167
  vm_username: config[:vm_username],
159
168
  vm_password: config[:vm_password],
160
169
  vm_win_network: config[:vm_win_network],
170
+ transform_ip: config[:transform_ip],
161
171
  benchmark: config[:benchmark],
162
172
  benchmark_file: config[:benchmark_file],
163
173
  }
@@ -283,10 +293,13 @@ module Kitchen
283
293
 
284
294
  # Sees in the datacenter exists or not
285
295
  #
296
+ # @param [folder] folder is the name of the folder in which the Datacenter is stored in inventory, possibly nil
286
297
  # @param [name] name is the name of the datacenter
287
- def datacenter_exists?(name)
298
+ def datacenter_exists?(folder, name)
288
299
  dc_api = VSphereAutomation::VCenter::DatacenterApi.new(api_client)
289
- dcs = dc_api.list({ filter_names: name }).value
300
+ opts = { filter_names: name }
301
+ opts[:filter_folders] = get_folder(folder, "DATACENTER") if folder
302
+ dcs = dc_api.list(opts).value
290
303
 
291
304
  raise format("Unable to find data center: %s", name) if dcs.empty?
292
305
  end
@@ -321,9 +334,10 @@ module Kitchen
321
334
  # Gets the folder you want to create the VM
322
335
  #
323
336
  # @param [name] name is the name of the folder
324
- def get_folder(name)
337
+ # @param [type] type is the type of the folder, one of VIRTUAL_MACHINE, DATACENTER, possibly other values
338
+ def get_folder(name, type = "VIRTUAL_MACHINE")
325
339
  folder_api = VSphereAutomation::VCenter::FolderApi.new(api_client)
326
- folders = folder_api.list({ filter_names: name, filter_type: "VIRTUAL_MACHINE" }).value
340
+ folders = folder_api.list({ filter_names: name, filter_type: type }).value
327
341
 
328
342
  raise format("Unable to find folder: %s", name) if folders.empty?
329
343
 
@@ -344,10 +358,13 @@ module Kitchen
344
358
 
345
359
  # Gets the info of the datacenter
346
360
  #
361
+ # @param [folder] folder is the name of the folder in which the Datacenter is stored in inventory, possibly nil
347
362
  # @param [name] name is the name of the Datacenter
348
- def get_datacenter(name)
363
+ def get_datacenter(folder, name)
349
364
  dc_api = VSphereAutomation::VCenter::DatacenterApi.new(api_client)
350
- dcs = dc_api.list({ filter_names: name }).value
365
+ opts = { filter_names: name }
366
+ opts[:filter_folders] = get_folder(folder, "DATACENTER") if folder
367
+ dcs = dc_api.list(opts).value
351
368
 
352
369
  raise format("Unable to find data center: %s", name) if dcs.empty?
353
370
 
@@ -1,6 +1,6 @@
1
1
  require "kitchen"
2
2
  require "rbvmomi"
3
- require "support/guest_operations"
3
+ require_relative "guest_operations"
4
4
 
5
5
  class Support
6
6
  class CloneError < RuntimeError; end
@@ -81,6 +81,17 @@ class Support
81
81
  raise Support::CloneError.new("Timeout waiting for IP address") if ip.nil?
82
82
  raise Support::CloneError.new(format("Error getting accessible IP address, got %s. Check DHCP server and scope exhaustion", ip)) if ip =~ /^169\.254\./
83
83
 
84
+ # Allow IP rewriting (e.g. for 1:1 NAT)
85
+ if options[:transform_ip]
86
+ Kitchen.logger.info format("Received IP: %s", ip)
87
+
88
+ # rubocop:disable Security/Eval
89
+ ip = lambda { eval options[:transform_ip] }.call
90
+ # rubocop:enable Security/Eval
91
+
92
+ Kitchen.logger.info format("Transformed to IP: %s", ip)
93
+ end
94
+
84
95
  @ip = ip
85
96
  end
86
97
 
@@ -210,13 +221,13 @@ class Support
210
221
  case options[:vm_os].downcase.to_sym
211
222
  when :linux
212
223
  # @todo: allow override if no dhclient
213
- return [
224
+ [
214
225
  "/sbin/modprobe -r vmxnet3",
215
226
  "/sbin/modprobe vmxnet3",
216
227
  "/sbin/dhclient",
217
228
  ]
218
229
  when :windows
219
- return [
230
+ [
220
231
  "netsh interface set Interface #{options[:vm_win_network]} disable",
221
232
  "netsh interface set Interface #{options[:vm_win_network]} enable",
222
233
  "ipconfig /renew",
@@ -251,6 +262,8 @@ class Support
251
262
  # "wmic nicconfig get IPAddress",
252
263
  # "netsh interface ip show ipaddress #{options[:vm_win_network]}"
253
264
  end
265
+ else
266
+ options[:active_discovery_command]
254
267
  end
255
268
  end
256
269
 
@@ -395,15 +408,109 @@ class Support
395
408
  options[:clone_type] == :full
396
409
  end
397
410
 
411
+ def root_folder
412
+ @root_folder ||= vim.serviceInstance.content.rootFolder
413
+ end
414
+
415
+ #
416
+ # @return [String]
417
+ #
418
+ def datacenter
419
+ options[:datacenter]
420
+ end
421
+
422
+ #
423
+ # @return [RbVmomi::VIM::Datacenter]
424
+ #
425
+ def find_datacenter
426
+ vim.serviceInstance.find_datacenter(datacenter)
427
+ rescue RbVmomi::Fault
428
+ root_folder.childEntity.grep(RbVmomi::VIM::Datacenter).find { |x| x.name == datacenter }
429
+ end
430
+
431
+ def ip?(string)
432
+ IPAddr.new(string)
433
+ true
434
+ rescue IPAddr::InvalidAddressError
435
+ false
436
+ end
437
+
438
+ def customization_spec
439
+ unless options[:guest_customization]
440
+ return false
441
+ end
442
+
443
+ unless ip?(options[:guest_customization][:ip_address])
444
+ raise Support::CloneError.new("Guest customization error: ip_address is required to be formatted as an IPv4 address")
445
+ end
446
+
447
+ unless ip?(options[:guest_customization][:subnet_mask])
448
+ raise Support::CloneError.new("Guest customization error: subnet_mask is required to be formatted as an IPv4 address")
449
+ end
450
+
451
+ options[:guest_customization][:gateway].each do |v|
452
+ unless ip?(v)
453
+ raise Support::CloneError.new("Guest customization error: gateway is required to be formatted as an IPv4 address")
454
+ end
455
+ end
456
+
457
+ options[:guest_customization][:dns_server_list].each do |v|
458
+ unless ip?(v)
459
+ raise Support::CloneError.new("Guest customization error: dns_server_list is required to be formatted as an IPv4 address")
460
+ end
461
+ end
462
+
463
+ unless %i{dns_domain timezone dns_server_list dns_suffix_list ip_address gateway subnet_mask}.all? { |k| options[:guest_customization].key? k }
464
+ raise Support::CloneError.new("Guest customization error: currently all options are required to support guest customization")
465
+ end
466
+
467
+ if !options[:guest_customization][:dns_server_list].is_a?(Array)
468
+ raise Support::CloneError.new("Guest customization error: dns_server_list must be an array")
469
+ elsif !options[:guest_customization][:dns_suffix_list].is_a?(Array)
470
+ raise Support::CloneError.new("Guest customization error: dns_suffix_list must be an array")
471
+ elsif !options[:guest_customization][:gateway].is_a?(Array)
472
+ raise Support::CloneError.new("Guest customization error: gateway must be an array")
473
+ end
474
+
475
+ spec = RbVmomi::VIM::CustomizationSpec.new(
476
+ identity: RbVmomi::VIM::CustomizationLinuxPrep.new(
477
+ domain: options[:guest_customization][:dns_domain],
478
+ hostName: RbVmomi::VIM::CustomizationFixedName.new(
479
+ name: name
480
+ ),
481
+ hwClockUTC: true,
482
+ timeZone: options[:guest_customization][:timezone]
483
+ ),
484
+ globalIPSettings: RbVmomi::VIM::CustomizationGlobalIPSettings.new(
485
+ dnsServerList: options[:guest_customization][:dns_server_list],
486
+ dnsSuffixList: options[:guest_customization][:dns_suffix_list]
487
+ ),
488
+ nicSettingMap: [RbVmomi::VIM::CustomizationAdapterMapping.new(
489
+ adapter: RbVmomi::VIM::CustomizationIPSettings.new(
490
+ ip: RbVmomi::VIM::CustomizationFixedIp(
491
+ ipAddress: options[:guest_customization][:ip_address]
492
+ ),
493
+ gateway: options[:guest_customization][:gateway],
494
+ subnetMask: options[:guest_customization][:subnet_mask],
495
+ dnsDomain: options[:guest_customization][:dns_domain]
496
+ )
497
+ )]
498
+ )
499
+
500
+ spec
501
+ end
502
+
398
503
  def clone
399
504
  benchmark_start if benchmark?
400
505
 
401
506
  # set the datacenter name
402
- dc = vim.serviceInstance.find_datacenter(options[:datacenter])
507
+ dc = find_datacenter
508
+
509
+ # get guest customization spec
510
+ guest_customization = customization_spec
403
511
 
404
512
  # reference template using full inventory path
405
- root_folder = vim.serviceInstance.content.rootFolder
406
- inventory_path = format("/%s/vm/%s", options[:datacenter], options[:template])
513
+ inventory_path = format("/%s/vm/%s", datacenter, options[:template])
407
514
  src_vm = root_folder.findByInventoryPath(inventory_path)
408
515
  raise Support::CloneError.new(format("Unable to find template: %s", options[:template])) if src_vm.nil?
409
516
 
@@ -432,10 +539,11 @@ class Support
432
539
  # Change network, if wanted
433
540
  unless options[:network_name].nil?
434
541
  networks = dc.network.select { |n| n.name == options[:network_name] }
435
- raise Support::CloneError.new(format("Could not find network named %s", option[:network_name])) if networks.empty?
542
+ raise Support::CloneError.new(format("Could not find network named %s", options[:network_name])) if networks.empty?
436
543
 
437
544
  Kitchen.logger.warn format("Found %d networks named %s, picking first one", networks.count, options[:network_name]) if networks.count > 1
438
545
  network_obj = networks.first
546
+ network_device = network_device(src_vm)
439
547
 
440
548
  if network_obj.is_a? RbVmomi::VIM::DistributedVirtualPortgroup
441
549
  Kitchen.logger.info format("Assigning network %s...", network_obj.pretty_path)
@@ -443,7 +551,6 @@ class Support
443
551
  vds_obj = network_obj.config.distributedVirtualSwitch
444
552
  Kitchen.logger.info format("Using vDS '%s' for network connectivity...", vds_obj.name)
445
553
 
446
- network_device = network_device(src_vm)
447
554
  network_device.backing = RbVmomi::VIM.VirtualEthernetCardDistributedVirtualPortBackingInfo(
448
555
  port: RbVmomi::VIM.DistributedVirtualSwitchPortConnection(
449
556
  portgroupKey: network_obj.key,
@@ -520,9 +627,15 @@ class Support
520
627
  benchmark_checkpoint("initialized") if benchmark?
521
628
  task = src_vm.InstantClone_Task(spec: clone_spec)
522
629
  else
523
- clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(location: relocate_spec,
524
- powerOn: options[:poweron] && options[:customize].nil?,
525
- template: false)
630
+ clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(
631
+ location: relocate_spec,
632
+ powerOn: options[:poweron] && options[:customize].nil?,
633
+ template: false
634
+ )
635
+
636
+ if guest_customization
637
+ clone_spec.customization = guest_customization
638
+ end
526
639
 
527
640
  benchmark_checkpoint("initialized") if benchmark?
528
641
  task = src_vm.CloneVM_Task(spec: clone_spec, folder: dest_folder, name: name)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-vcenter
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.0
4
+ version: 2.7.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chef Software
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-05 00:00:00.000000000 Z
11
+ date: 2020-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rbvmomi
@@ -30,20 +30,6 @@ dependencies:
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '3.0'
33
- - !ruby/object:Gem::Dependency
34
- name: savon
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: '2.11'
40
- type: :runtime
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: '2.11'
47
33
  - !ruby/object:Gem::Dependency
48
34
  name: test-kitchen
49
35
  requirement: !ruby/object:Gem::Requirement
@@ -78,34 +64,6 @@ dependencies:
78
64
  - - "~>"
79
65
  - !ruby/object:Gem::Version
80
66
  version: '0.4'
81
- - !ruby/object:Gem::Dependency
82
- name: bundler
83
- requirement: !ruby/object:Gem::Requirement
84
- requirements:
85
- - - ">="
86
- - !ruby/object:Gem::Version
87
- version: '0'
88
- type: :development
89
- prerelease: false
90
- version_requirements: !ruby/object:Gem::Requirement
91
- requirements:
92
- - - ">="
93
- - !ruby/object:Gem::Version
94
- version: '0'
95
- - !ruby/object:Gem::Dependency
96
- name: rake
97
- requirement: !ruby/object:Gem::Requirement
98
- requirements:
99
- - - ">="
100
- - !ruby/object:Gem::Version
101
- version: '0'
102
- type: :development
103
- prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
- requirements:
106
- - - ">="
107
- - !ruby/object:Gem::Version
108
- version: '0'
109
67
  description: Test Kitchen driver for VMware vCenter using SDK
110
68
  email:
111
69
  - oss@chef.io
@@ -130,7 +88,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
130
88
  requirements:
131
89
  - - ">="
132
90
  - !ruby/object:Gem::Version
133
- version: '2.3'
91
+ version: '2.4'
134
92
  required_rubygems_version: !ruby/object:Gem::Requirement
135
93
  requirements:
136
94
  - - ">="