vmpooler 2.0.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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)