vmpooler 2.0.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -60,6 +60,7 @@ module Vmpooler
60
60
  to_set[k] = pool[k]
61
61
  end
62
62
  to_set['alias'] = pool['alias'].join(',') if to_set.key?('alias')
63
+ to_set['domain'] = Parsing.get_domain_for_pool(config, pool['name'])
63
64
  redis.hmset("vmpooler__pool__#{pool['name']}", to_set.to_a.flatten) unless to_set.empty?
64
65
  end
65
66
  previously_configured_pools.each do |pool|
@@ -148,15 +149,15 @@ module Vmpooler
148
149
  end
149
150
  pool_alias = redis.hget("vmpooler__vm__#{vm}", 'pool_alias')
150
151
 
151
- redis.pipelined do
152
- redis.hset("vmpooler__active__#{pool}", vm, Time.now)
153
- redis.hset("vmpooler__vm__#{vm}", 'checkout', Time.now)
152
+ redis.pipelined do |pipeline|
153
+ pipeline.hset("vmpooler__active__#{pool}", vm, Time.now)
154
+ pipeline.hset("vmpooler__vm__#{vm}", 'checkout', Time.now)
154
155
  if ondemandrequest_hash['token:token']
155
- redis.hset("vmpooler__vm__#{vm}", 'token:token', ondemandrequest_hash['token:token'])
156
- redis.hset("vmpooler__vm__#{vm}", 'token:user', ondemandrequest_hash['token:user'])
157
- redis.hset("vmpooler__vm__#{vm}", 'lifetime', $config[:config]['vm_lifetime_auth'].to_i)
156
+ pipeline.hset("vmpooler__vm__#{vm}", 'token:token', ondemandrequest_hash['token:token'])
157
+ pipeline.hset("vmpooler__vm__#{vm}", 'token:user', ondemandrequest_hash['token:user'])
158
+ pipeline.hset("vmpooler__vm__#{vm}", 'lifetime', $config[:config]['vm_lifetime_auth'].to_i)
158
159
  end
159
- redis.sadd("vmpooler__#{request_id}__#{pool_alias}__#{pool}", vm)
160
+ pipeline.sadd("vmpooler__#{request_id}__#{pool_alias}__#{pool}", vm)
160
161
  end
161
162
  move_vm_queue(pool, vm, 'pending', 'running', redis)
162
163
  check_ondemand_request_ready(request_id, redis)
@@ -164,12 +165,12 @@ module Vmpooler
164
165
  redis.smove("vmpooler__pending__#{pool}", "vmpooler__ready__#{pool}", vm)
165
166
  end
166
167
 
167
- redis.pipelined do
168
- redis.hset("vmpooler__boot__#{Date.today}", "#{pool}:#{vm}", finish) # maybe remove as this is never used by vmpooler itself?
169
- redis.hset("vmpooler__vm__#{vm}", 'ready', Time.now)
168
+ redis.pipelined do |pipeline|
169
+ pipeline.hset("vmpooler__boot__#{Date.today}", "#{pool}:#{vm}", finish) # maybe remove as this is never used by vmpooler itself?
170
+ pipeline.hset("vmpooler__vm__#{vm}", 'ready', Time.now)
170
171
 
171
172
  # last boot time is displayed in API, and used by alarming script
172
- redis.hset('vmpooler__lastboot', pool, Time.now)
173
+ pipeline.hset('vmpooler__lastboot', pool, Time.now)
173
174
  end
174
175
 
175
176
  $metrics.timing("time_to_ready_state.#{pool}", finish)
@@ -294,6 +295,12 @@ module Vmpooler
294
295
  move_vm_queue(pool, vm, 'running', 'completed', redis, 'is listed as running, but has no checkouttime data. Removing from running')
295
296
  end
296
297
 
298
+ # tag VM if not tagged yet, this ensures the method is only called once
299
+ unless redis.hget("vmpooler__vm__#{vm}", 'user_tagged')
300
+ success = provider.tag_vm_user(pool, vm)
301
+ redis.hset("vmpooler__vm__#{vm}", 'user_tagged', 'true') if success
302
+ end
303
+
297
304
  throw :stop_checking if provider.vm_ready?(pool, vm)
298
305
 
299
306
  throw :stop_checking if provider.get_vm(pool, vm)
@@ -355,35 +362,47 @@ module Vmpooler
355
362
  max_hostname_retries = 3
356
363
  while hostname_retries < max_hostname_retries
357
364
  hostname, hostname_available = generate_and_check_hostname
358
- domain = $config[:config]['domain']
359
- dns_ip, dns_available = check_dns_available(hostname, domain)
365
+ domain = Parsing.get_domain_for_pool(config, pool_name)
366
+ if domain
367
+ fqdn = "#{hostname}.#{domain}"
368
+ else
369
+ fqdn = hostname
370
+ end
371
+
372
+ # skip dns check if the provider is set to skip_dns_check_before_creating_vm
373
+ provider = get_provider_for_pool(pool_name)
374
+ if provider && provider.provider_config['skip_dns_check_before_creating_vm']
375
+ dns_available = true
376
+ else
377
+ dns_ip, dns_available = check_dns_available(fqdn)
378
+ end
379
+
360
380
  break if hostname_available && dns_available
361
381
 
362
382
  hostname_retries += 1
363
383
 
364
384
  if !hostname_available
365
385
  $metrics.increment("errors.duplicatehostname.#{pool_name}")
366
- $logger.log('s', "[!] [#{pool_name}] Generated hostname #{hostname} was not unique (attempt \##{hostname_retries} of #{max_hostname_retries})")
386
+ $logger.log('s', "[!] [#{pool_name}] Generated hostname #{fqdn} was not unique (attempt \##{hostname_retries} of #{max_hostname_retries})")
367
387
  elsif !dns_available
368
388
  $metrics.increment("errors.staledns.#{pool_name}")
369
- $logger.log('s', "[!] [#{pool_name}] Generated hostname #{hostname} already exists in DNS records (#{dns_ip}), stale DNS")
389
+ $logger.log('s', "[!] [#{pool_name}] Generated hostname #{fqdn} already exists in DNS records (#{dns_ip}), stale DNS")
370
390
  end
371
391
  end
372
392
 
373
- raise "Unable to generate a unique hostname after #{hostname_retries} attempts. The last hostname checked was #{hostname}" unless hostname_available && dns_available
393
+ raise "Unable to generate a unique hostname after #{hostname_retries} attempts. The last hostname checked was #{fqdn}" unless hostname_available && dns_available
374
394
 
375
395
  hostname
376
396
  end
377
397
 
378
- def check_dns_available(vm_name, domain = nil)
379
- # Query the DNS for the name we want to create and if it already exists, mark it unavailable
380
- # This protects against stale DNS records
381
- vm_name = "#{vm_name}.#{domain}" if domain
398
+ # Query the DNS for the name we want to create and if it already exists, mark it unavailable
399
+ # This protects against stale DNS records
400
+ def check_dns_available(vm_name)
382
401
  begin
383
402
  dns_ip = Resolv.getaddress(vm_name)
384
403
  rescue Resolv::ResolvError
385
404
  # this is the expected case, swallow the error
386
- # eg "no address for blah-daisy"
405
+ # eg "no address for blah-daisy.example.com"
387
406
  return ['', true]
388
407
  end
389
408
  [dns_ip, false]
@@ -391,6 +410,7 @@ module Vmpooler
391
410
 
392
411
  def _clone_vm(pool_name, provider, request_id = nil, pool_alias = nil)
393
412
  new_vmname = find_unique_hostname(pool_name)
413
+ pool_domain = Parsing.get_domain_for_pool(config, pool_name)
394
414
  mutex = vm_mutex(new_vmname)
395
415
  mutex.synchronize do
396
416
  @redis.with_metrics do |redis|
@@ -400,6 +420,7 @@ module Vmpooler
400
420
  redis.hset("vmpooler__vm__#{new_vmname}", 'clone', Time.now)
401
421
  redis.hset("vmpooler__vm__#{new_vmname}", 'template', pool_name) # This value is used to represent the pool.
402
422
  redis.hset("vmpooler__vm__#{new_vmname}", 'pool', pool_name)
423
+ redis.hset("vmpooler__vm__#{new_vmname}", 'domain', pool_domain) if pool_domain
403
424
  redis.hset("vmpooler__vm__#{new_vmname}", 'request_id', request_id) if request_id
404
425
  redis.hset("vmpooler__vm__#{new_vmname}", 'pool_alias', pool_alias) if pool_alias
405
426
  redis.exec
@@ -412,9 +433,9 @@ module Vmpooler
412
433
  finish = format('%<time>.2f', time: Time.now - start)
413
434
 
414
435
  @redis.with_metrics do |redis|
415
- redis.pipelined do
416
- redis.hset("vmpooler__clone__#{Date.today}", "#{pool_name}:#{new_vmname}", finish)
417
- redis.hset("vmpooler__vm__#{new_vmname}", 'clone_time', finish)
436
+ redis.pipelined do |pipeline|
437
+ pipeline.hset("vmpooler__clone__#{Date.today}", "#{pool_name}:#{new_vmname}", finish)
438
+ pipeline.hset("vmpooler__vm__#{new_vmname}", 'clone_time', finish)
418
439
  end
419
440
  end
420
441
  $logger.log('s', "[+] [#{pool_name}] '#{new_vmname}' cloned in #{finish} seconds")
@@ -422,10 +443,10 @@ module Vmpooler
422
443
  $metrics.timing("clone.#{pool_name}", finish)
423
444
  rescue StandardError
424
445
  @redis.with_metrics do |redis|
425
- redis.pipelined do
426
- redis.srem("vmpooler__pending__#{pool_name}", new_vmname)
446
+ redis.pipelined do |pipeline|
447
+ pipeline.srem("vmpooler__pending__#{pool_name}", new_vmname)
427
448
  expiration_ttl = $config[:redis]['data_ttl'].to_i * 60 * 60
428
- redis.expire("vmpooler__vm__#{new_vmname}", expiration_ttl)
449
+ pipeline.expire("vmpooler__vm__#{new_vmname}", expiration_ttl)
429
450
  end
430
451
  end
431
452
  raise
@@ -456,12 +477,12 @@ module Vmpooler
456
477
 
457
478
  mutex.synchronize do
458
479
  @redis.with_metrics do |redis|
459
- redis.pipelined do
460
- redis.hdel("vmpooler__active__#{pool}", vm)
461
- redis.hset("vmpooler__vm__#{vm}", 'destroy', Time.now)
480
+ redis.pipelined do |pipeline|
481
+ pipeline.hdel("vmpooler__active__#{pool}", vm)
482
+ pipeline.hset("vmpooler__vm__#{vm}", 'destroy', Time.now)
462
483
 
463
484
  # Auto-expire metadata key
464
- redis.expire("vmpooler__vm__#{vm}", ($config[:redis]['data_ttl'].to_i * 60 * 60))
485
+ pipeline.expire("vmpooler__vm__#{vm}", ($config[:redis]['data_ttl'].to_i * 60 * 60))
465
486
  end
466
487
 
467
488
  start = Time.now
@@ -478,15 +499,15 @@ module Vmpooler
478
499
  dereference_mutex(vm)
479
500
  end
480
501
 
481
- def purge_unused_vms_and_folders
482
- global_purge = $config[:config]['purge_unconfigured_folders']
502
+ def purge_unused_vms_and_resources
503
+ global_purge = $config[:config]['purge_unconfigured_resources']
483
504
  providers = $config[:providers].keys
484
505
  providers.each do |provider_key|
485
- provider_purge = $config[:providers][provider_key]['purge_unconfigured_folders'] || global_purge
506
+ provider_purge = $config[:providers][provider_key]['purge_unconfigured_resources'] || global_purge
486
507
  if provider_purge
487
508
  Thread.new do
488
509
  begin
489
- purge_vms_and_folders(provider_key)
510
+ purge_vms_and_resources(provider_key)
490
511
  rescue StandardError => e
491
512
  $logger.log('s', "[!] failed while purging provider #{provider_key} VMs and folders with an error: #{e}")
492
513
  end
@@ -496,33 +517,16 @@ module Vmpooler
496
517
  nil
497
518
  end
498
519
 
499
- # Return a list of pool folders
500
- def pool_folders(provider_name)
501
- folders = {}
502
- $config[:pools].each do |pool|
503
- next unless pool['provider'] == provider_name.to_s
504
-
505
- folder_parts = pool['folder'].split('/')
506
- datacenter = $providers[provider_name.to_s].get_target_datacenter_from_config(pool['name'])
507
- folders[folder_parts.pop] = "#{datacenter}/vm/#{folder_parts.join('/')}"
508
- end
509
- folders
510
- end
511
-
512
- def get_base_folders(folders)
513
- base = []
514
- folders.each do |_key, value|
515
- base << value
516
- end
517
- base.uniq
518
- end
519
-
520
- def purge_vms_and_folders(provider_name)
520
+ def purge_vms_and_resources(provider_name)
521
521
  provider = $providers[provider_name.to_s]
522
- configured_folders = pool_folders(provider_name)
523
- base_folders = get_base_folders(configured_folders)
524
- whitelist = provider.provider_config['folder_whitelist']
525
- provider.purge_unconfigured_folders(base_folders, configured_folders, whitelist)
522
+ # Deprecated, will be removed in version 3
523
+ if provider.provider_config['folder_whitelist']
524
+ $logger.log('d', "[!] [deprecation] rename configuration 'folder_whitelist' to 'resources_allowlist' for provider #{provider_name}")
525
+ allowlist = provider.provider_config['folder_whitelist']
526
+ else
527
+ allowlist = provider.provider_config['resources_allowlist']
528
+ end
529
+ provider.purge_unconfigured_resources(allowlist)
526
530
  end
527
531
 
528
532
  def create_vm_disk(pool_name, vm, disk_size, provider)
@@ -630,8 +634,21 @@ module Vmpooler
630
634
  # @return [Array] - a list of used providers from the config file, defaults to the default providers
631
635
  # ie. ["dummy"]
632
636
  def used_providers
633
- pools = config[:pools] || []
634
- @used_providers ||= (pools.map { |pool| pool[:provider] || pool['provider'] }.compact + default_providers).uniq
637
+ # create an array of provider classes based on the config
638
+ if config[:providers]
639
+ config_provider_names = config[:providers].keys
640
+ config_providers = config_provider_names.map do |config_provider_name|
641
+ if config[:providers][config_provider_name] && config[:providers][config_provider_name]['provider_class']
642
+ config[:providers][config_provider_name]['provider_class'].to_s
643
+ else
644
+ config_provider_name.to_s
645
+ end
646
+ end.compact.uniq
647
+ else
648
+ config_providers = []
649
+ end
650
+ # return the unique array of providers from the config and VMPooler defaults
651
+ @used_providers ||= (config_providers + default_providers).uniq
635
652
  end
636
653
 
637
654
  # @return [Array] - returns a list of providers that should always be loaded
@@ -877,7 +894,7 @@ module Vmpooler
877
894
  loop_count = 1
878
895
  loop_delay = loop_delay_min
879
896
  provider = get_provider_for_pool(pool['name'])
880
- raise("Could not find provider '#{pool['provider']}") if provider.nil?
897
+ raise("Could not find provider '#{pool['provider']}'") if provider.nil?
881
898
 
882
899
  sync_pool_template(pool)
883
900
  loop do
@@ -1202,19 +1219,19 @@ module Vmpooler
1202
1219
  pool_check_response[:destroyed_vms] += 1
1203
1220
  destroy_vm(vm, pool_name, provider)
1204
1221
  rescue StandardError => e
1205
- redis.pipelined do
1206
- redis.srem("vmpooler__completed__#{pool_name}", vm)
1207
- redis.hdel("vmpooler__active__#{pool_name}", vm)
1208
- redis.del("vmpooler__vm__#{vm}")
1222
+ redis.pipelined do |pipeline|
1223
+ pipeline.srem("vmpooler__completed__#{pool_name}", vm)
1224
+ pipeline.hdel("vmpooler__active__#{pool_name}", vm)
1225
+ pipeline.del("vmpooler__vm__#{vm}")
1209
1226
  end
1210
1227
  $logger.log('d', "[!] [#{pool_name}] _check_pool failed with an error while evaluating completed VMs: #{e}")
1211
1228
  end
1212
1229
  else
1213
1230
  $logger.log('s', "[!] [#{pool_name}] '#{vm}' not found in inventory, removed from 'completed' queue")
1214
- redis.pipelined do
1215
- redis.srem("vmpooler__completed__#{pool_name}", vm)
1216
- redis.hdel("vmpooler__active__#{pool_name}", vm)
1217
- redis.del("vmpooler__vm__#{vm}")
1231
+ redis.pipelined do |pipeline|
1232
+ pipeline.srem("vmpooler__completed__#{pool_name}", vm)
1233
+ pipeline.hdel("vmpooler__active__#{pool_name}", vm)
1234
+ pipeline.del("vmpooler__vm__#{vm}")
1218
1235
  end
1219
1236
  end
1220
1237
  end
@@ -1364,7 +1381,7 @@ module Vmpooler
1364
1381
 
1365
1382
  return provider_klass.const_get(classname).new(config, logger, metrics, redis_connection_pool, provider_name, options)
1366
1383
  end
1367
- raise("Provider '#{provider_class}' is unknown for pool with provider name '#{provider_name}'") if provider.nil?
1384
+ raise("Provider '#{provider_class}' is unknown for pool with provider name '#{provider_name}'") if provider_klass.nil?
1368
1385
  end
1369
1386
 
1370
1387
  def check_ondemand_requests(maxloop = 0,
@@ -1430,12 +1447,12 @@ module Vmpooler
1430
1447
  score = redis.zscore('vmpooler__provisioning__request', request_id)
1431
1448
  requested = requested.split(',')
1432
1449
 
1433
- redis.pipelined do
1450
+ redis.pipelined do |pipeline|
1434
1451
  requested.each do |request|
1435
- redis.zadd('vmpooler__odcreate__task', Time.now.to_i, "#{request}:#{request_id}")
1452
+ pipeline.zadd('vmpooler__odcreate__task', Time.now.to_i, "#{request}:#{request_id}")
1436
1453
  end
1437
- redis.zrem('vmpooler__provisioning__request', request_id)
1438
- redis.zadd('vmpooler__provisioning__processing', score, request_id)
1454
+ pipeline.zrem('vmpooler__provisioning__request', request_id)
1455
+ pipeline.zadd('vmpooler__provisioning__processing', score, request_id)
1439
1456
  end
1440
1457
  end
1441
1458
 
@@ -1465,9 +1482,9 @@ module Vmpooler
1465
1482
  redis.incr('vmpooler__tasks__ondemandclone')
1466
1483
  clone_vm(pool, provider, request_id, pool_alias)
1467
1484
  end
1468
- redis.pipelined do
1469
- redis.zrem(queue_key, request)
1470
- redis.zadd(queue_key, score, "#{pool_alias}:#{pool}:#{remaining_count}:#{request_id}")
1485
+ redis.pipelined do |pipeline|
1486
+ pipeline.zrem(queue_key, request)
1487
+ pipeline.zadd(queue_key, score, "#{pool_alias}:#{pool}:#{remaining_count}:#{request_id}")
1471
1488
  end
1472
1489
  end
1473
1490
  end
@@ -1518,10 +1535,10 @@ module Vmpooler
1518
1535
 
1519
1536
  $logger.log('s', "Ondemand request for '#{request_id}' failed to provision all instances within the configured ttl '#{ondemand_request_ttl}'")
1520
1537
  expiration_ttl = $config[:redis]['data_ttl'].to_i * 60 * 60
1521
- redis.pipelined do
1522
- redis.zrem('vmpooler__provisioning__processing', request_id)
1523
- redis.hset("vmpooler__odrequest__#{request_id}", 'status', 'failed')
1524
- redis.expire("vmpooler__odrequest__#{request_id}", expiration_ttl)
1538
+ redis.pipelined do |pipeline|
1539
+ pipeline.zrem('vmpooler__provisioning__processing', request_id)
1540
+ pipeline.hset("vmpooler__odrequest__#{request_id}", 'status', 'failed')
1541
+ pipeline.expire("vmpooler__odrequest__#{request_id}", expiration_ttl)
1525
1542
  end
1526
1543
  remove_vms_for_failed_request(request_id, expiration_ttl, redis)
1527
1544
  true
@@ -1531,11 +1548,11 @@ module Vmpooler
1531
1548
  request_hash = redis.hgetall("vmpooler__odrequest__#{request_id}")
1532
1549
  Parsing.get_platform_pool_count(request_hash['requested']) do |platform_alias, pool, _count|
1533
1550
  pools_filled = redis.smembers("vmpooler__#{request_id}__#{platform_alias}__#{pool}")
1534
- redis.pipelined do
1551
+ redis.pipelined do |pipeline|
1535
1552
  pools_filled&.each do |vm|
1536
- move_vm_queue(pool, vm, 'running', 'completed', redis, "moved to completed queue. '#{request_id}' could not be filled in time")
1553
+ move_vm_queue(pool, vm, 'running', 'completed', pipeline, "moved to completed queue. '#{request_id}' could not be filled in time")
1537
1554
  end
1538
- redis.expire("vmpooler__#{request_id}__#{platform_alias}__#{pool}", expiration_ttl)
1555
+ pipeline.expire("vmpooler__#{request_id}__#{platform_alias}__#{pool}", expiration_ttl)
1539
1556
  end
1540
1557
  end
1541
1558
  end
@@ -1606,7 +1623,7 @@ module Vmpooler
1606
1623
  end
1607
1624
  end
1608
1625
 
1609
- purge_unused_vms_and_folders
1626
+ purge_unused_vms_and_resources
1610
1627
 
1611
1628
  loop_count = 1
1612
1629
  loop do
@@ -212,6 +212,22 @@ module Vmpooler
212
212
  raise("#{self.class.name} does not implement vm_ready?")
213
213
  end
214
214
 
215
+ # tag_vm_user This method is called once we know who is using the VM (it is running). This method enables seeing
216
+ # who is using what in the provider pools.
217
+ # This method should be implemented in the providers, if it is not implemented, this base method will be called
218
+ # and should be a noop. The implementation should check if the vm has a user (as per redis) and add a new tag
219
+ # with the information.
220
+ # inputs
221
+ # [String] pool_name : Name of the pool
222
+ # [String] vm_name : Name of the VM to check if ready
223
+ # returns
224
+ # [Boolean] : true if successful, false if an error occurred and it should retry
225
+ def tag_vm_user(_pool_name, _vm_name)
226
+ # noop by design. If the provider does not implement this method, this base method is called (because inherited)
227
+ # and should basically do nothing.
228
+ true
229
+ end
230
+
215
231
  # inputs
216
232
  # [String] pool_name : Name of the pool
217
233
  # [String] vm_name : Name of the VM to check if it exists
@@ -226,7 +242,7 @@ module Vmpooler
226
242
  # returns
227
243
  # nil when successful. Raises error when encountered
228
244
  def create_template_delta_disks(_pool)
229
- raise("#{self.class.name} does not implement create_template_delta_disks")
245
+ puts("#{self.class.name} does not implement create_template_delta_disks")
230
246
  end
231
247
 
232
248
  # inputs
@@ -237,8 +253,15 @@ module Vmpooler
237
253
  raise("#{self.class.name} does not implement get_target_datacenter_from_config")
238
254
  end
239
255
 
240
- def purge_unconfigured_folders(_base_folders, _configured_folders, _whitelist)
241
- raise("#{self.class.name} does not implement purge_unconfigured_folders")
256
+ def purge_unconfigured_resources(_allowlist)
257
+ raise("#{self.class.name} does not implement purge_unconfigured_resources")
258
+ end
259
+
260
+ # DEPRECATED if a provider does not implement the new method, it will hit this base class method
261
+ # and return a deprecation message
262
+ def purge_unconfigured_folders(_deprecated, _deprecated2, allowlist)
263
+ logger.log('s', '[!] purge_unconfigured_folders was renamed to purge_unconfigured_resources, please update your provider implementation')
264
+ purge_unconfigured_resources(allowlist)
242
265
  end
243
266
  end
244
267
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # utility class shared between apps
3
+ # utility class shared between apps api and pool_manager
4
4
  module Vmpooler
5
5
  class Parsing
6
6
  def self.get_platform_pool_count(requested, &_block)
@@ -12,5 +12,25 @@ module Vmpooler
12
12
  yield platform_alias, pool, count
13
13
  end
14
14
  end
15
+
16
+ # @param config [String] - the full config structure
17
+ # @param pool_name [String] - the name of the pool
18
+ # @return [String] - domain name for pool, if set in the provider for the pool or in the config block
19
+ def self.get_domain_for_pool(config, pool_name)
20
+ pool = config[:pools].find { |p| p['name'] == pool_name }
21
+ return nil unless pool
22
+
23
+ provider_name = pool.fetch('provider', 'vsphere') # see vmpooler.yaml.example where it states defaulting to vsphere
24
+
25
+ if config[:providers] && config[:providers][provider_name.to_sym] && config[:providers][provider_name.to_sym]['domain']
26
+ domain = config[:providers][provider_name.to_sym]['domain']
27
+ elsif config[:config] && config[:config]['domain']
28
+ domain = config[:config]['domain']
29
+ else
30
+ domain = nil
31
+ end
32
+
33
+ domain
34
+ end
15
35
  end
16
36
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vmpooler
4
- VERSION = '2.0.0'
4
+ VERSION = '2.3.0'
5
5
  end
data/lib/vmpooler.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  module Vmpooler
4
4
  require 'concurrent'
5
5
  require 'date'
6
+ require 'deep_merge'
6
7
  require 'json'
7
8
  require 'net/ldap'
8
9
  require 'open-uri'
@@ -16,6 +17,7 @@ module Vmpooler
16
17
 
17
18
  # Dependencies for tracing
18
19
  require 'opentelemetry-instrumentation-concurrent_ruby'
20
+ require 'opentelemetry-instrumentation-http_client'
19
21
  require 'opentelemetry-instrumentation-redis'
20
22
  require 'opentelemetry-instrumentation-sinatra'
21
23
  require 'opentelemetry-sdk'
@@ -31,7 +33,7 @@ module Vmpooler
31
33
  if ENV['VMPOOLER_CONFIG']
32
34
  config_string = ENV['VMPOOLER_CONFIG']
33
35
  # Parse the YAML config into a Hash
34
- # Whitelist the Symbol class
36
+ # Allow the Symbol class
35
37
  parsed_config = YAML.safe_load(config_string, [Symbol])
36
38
  else
37
39
  # Take the name of the config file either from an ENV variable or from the filepath argument
@@ -41,8 +43,9 @@ module Vmpooler
41
43
  if parsed_config[:config]['extra_config']
42
44
  extra_configs = parsed_config[:config]['extra_config'].split(',')
43
45
  extra_configs.each do |config|
46
+ puts "loading extra_config file #{config}"
44
47
  extra_config = YAML.load_file(config)
45
- parsed_config.merge!(extra_config)
48
+ parsed_config.deep_merge(extra_config)
46
49
  end
47
50
  end
48
51
  end
@@ -81,10 +84,13 @@ module Vmpooler
81
84
  parsed_config[:config]['retry_factor'] = string_to_int(ENV['RETRY_FACTOR']) if ENV['RETRY_FACTOR']
82
85
  parsed_config[:config]['create_folders'] = true?(ENV['CREATE_FOLDERS']) if ENV['CREATE_FOLDERS']
83
86
  parsed_config[:config]['experimental_features'] = ENV['EXPERIMENTAL_FEATURES'] if ENV['EXPERIMENTAL_FEATURES']
84
- parsed_config[:config]['purge_unconfigured_folders'] = ENV['PURGE_UNCONFIGURED_FOLDERS'] if ENV['PURGE_UNCONFIGURED_FOLDERS']
85
87
  parsed_config[:config]['usage_stats'] = ENV['USAGE_STATS'] if ENV['USAGE_STATS']
86
88
  parsed_config[:config]['request_logger'] = ENV['REQUEST_LOGGER'] if ENV['REQUEST_LOGGER']
87
89
  parsed_config[:config]['create_template_delta_disks'] = ENV['CREATE_TEMPLATE_DELTA_DISKS'] if ENV['CREATE_TEMPLATE_DELTA_DISKS']
90
+ parsed_config[:config]['purge_unconfigured_resources'] = ENV['PURGE_UNCONFIGURED_RESOURCES'] if ENV['PURGE_UNCONFIGURED_RESOURCES']
91
+ parsed_config[:config]['purge_unconfigured_resources'] = ENV['PURGE_UNCONFIGURED_FOLDERS'] if ENV['PURGE_UNCONFIGURED_FOLDERS']
92
+ # ENV PURGE_UNCONFIGURED_FOLDERS deprecated, will be removed in version 3
93
+ puts '[!] [deprecation] rename ENV var \'PURGE_UNCONFIGURED_FOLDERS\' to \'PURGE_UNCONFIGURED_RESOURCES\'' if ENV['PURGE_UNCONFIGURED_FOLDERS']
88
94
  set_linked_clone(parsed_config)
89
95
 
90
96
  parsed_config[:redis] = parsed_config[:redis] || {}
@@ -128,6 +134,7 @@ module Vmpooler
128
134
  # Create an index of pool aliases
129
135
  parsed_config[:pool_names] = Set.new
130
136
  unless parsed_config[:pools]
137
+ puts 'loading pools configuration from redis, since the config[:pools] is empty'
131
138
  redis = new_redis(parsed_config[:redis]['server'], parsed_config[:redis]['port'], parsed_config[:redis]['password'])
132
139
  parsed_config[:pools] = load_pools_from_redis(redis)
133
140
  end
@@ -261,6 +268,7 @@ module Vmpooler
261
268
  OpenTelemetry::SDK.configure do |c|
262
269
  c.use 'OpenTelemetry::Instrumentation::Sinatra'
263
270
  c.use 'OpenTelemetry::Instrumentation::ConcurrentRuby'
271
+ c.use 'OpenTelemetry::Instrumentation::HttpClient'
264
272
  c.use 'OpenTelemetry::Instrumentation::Redis'
265
273
 
266
274
  c.add_span_processor(span_processor)