vmpooler 2.4.0 → 3.0.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.
- checksums.yaml +4 -4
- data/lib/vmpooler/api/helpers.rb +10 -13
- data/lib/vmpooler/api/v3.rb +1761 -0
- data/lib/vmpooler/api.rb +2 -4
- data/lib/vmpooler/dns/base.rb +81 -0
- data/lib/vmpooler/dns.rb +91 -0
- data/lib/vmpooler/pool_manager.rb +99 -21
- data/lib/vmpooler/providers/base.rb +8 -0
- data/lib/vmpooler/public/lib/dashboard.js +3 -3
- data/lib/vmpooler/util/parsing.rb +0 -20
- data/lib/vmpooler/version.rb +1 -1
- data/lib/vmpooler.rb +5 -2
- metadata +6 -6
- data/lib/vmpooler/api/reroute.rb +0 -89
- data/lib/vmpooler/api/v1.rb +0 -1757
- data/lib/vmpooler/api/v2.rb +0 -505
data/lib/vmpooler/api.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Vmpooler
|
4
4
|
class API < Sinatra::Base
|
5
5
|
# Load API components
|
6
|
-
%w[helpers dashboard
|
6
|
+
%w[helpers dashboard v3 request_logger healthcheck].each do |lib|
|
7
7
|
require "vmpooler/api/#{lib}"
|
8
8
|
end
|
9
9
|
# Load dashboard components
|
@@ -52,9 +52,7 @@ module Vmpooler
|
|
52
52
|
|
53
53
|
use Vmpooler::Dashboard
|
54
54
|
use Vmpooler::API::Dashboard
|
55
|
-
use Vmpooler::API::
|
56
|
-
use Vmpooler::API::V1
|
57
|
-
use Vmpooler::API::V2
|
55
|
+
use Vmpooler::API::V3
|
58
56
|
end
|
59
57
|
|
60
58
|
# Get thee started O WebServer
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Vmpooler
|
4
|
+
class PoolManager
|
5
|
+
class Dns
|
6
|
+
class Base
|
7
|
+
# These defs must be overidden in child classes
|
8
|
+
|
9
|
+
# Helper Methods
|
10
|
+
# Global Logger object
|
11
|
+
attr_reader :logger
|
12
|
+
# Global Metrics object
|
13
|
+
attr_reader :metrics
|
14
|
+
# Provider options passed in during initialization
|
15
|
+
attr_reader :dns_options
|
16
|
+
|
17
|
+
def initialize(config, logger, metrics, redis_connection_pool, name, options)
|
18
|
+
@config = config
|
19
|
+
@logger = logger
|
20
|
+
@metrics = metrics
|
21
|
+
@redis = redis_connection_pool
|
22
|
+
@dns_plugin_name = name
|
23
|
+
|
24
|
+
@dns_options = options
|
25
|
+
|
26
|
+
logger.log('s', "[!] Creating dns plugin '#{name}'")
|
27
|
+
end
|
28
|
+
|
29
|
+
def pool_config(pool_name)
|
30
|
+
# Get the configuration of a specific pool
|
31
|
+
@config[:pools].each do |pool|
|
32
|
+
return pool if pool['name'] == pool_name
|
33
|
+
end
|
34
|
+
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns this dns plugin's configuration
|
39
|
+
#
|
40
|
+
# @returns [Hashtable] This dns plugins's configuration from the config file. Returns nil if the dns plugin config does not exist
|
41
|
+
def dns_config
|
42
|
+
@config[:dns_configs].each do |dns|
|
43
|
+
# Convert the symbol from the config into a string for comparison
|
44
|
+
return (dns[1].nil? ? {} : dns[1]) if dns[0].to_s == @dns_plugin_name
|
45
|
+
end
|
46
|
+
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def global_config
|
51
|
+
# This entire VM Pooler config
|
52
|
+
@config
|
53
|
+
end
|
54
|
+
|
55
|
+
def name
|
56
|
+
@dns_plugin_name
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_ip(vm_name)
|
60
|
+
@redis.with_metrics do |redis|
|
61
|
+
redis.hget("vmpooler__vm__#{vm_name}", 'ip')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# returns
|
66
|
+
# Array[String] : Array of pool names this provider services
|
67
|
+
def provided_pools
|
68
|
+
@config[:pools].select { |pool| pool['dns_config'] == name }.map { |pool| pool['name'] }
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_or_replace_record(hostname)
|
72
|
+
raise("#{self.class.name} does not implement create_or_replace_record #{hostname}")
|
73
|
+
end
|
74
|
+
|
75
|
+
def delete_record(hostname)
|
76
|
+
raise("#{self.class.name} does not implement delete_record for #{hostname}")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/vmpooler/dns.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
module Vmpooler
|
6
|
+
class Dns
|
7
|
+
# Load one or more VMPooler DNS plugin gems by name
|
8
|
+
#
|
9
|
+
# @param names [Array<String>] The list of gem names to load
|
10
|
+
def self.load_by_name(names)
|
11
|
+
names = Array(names)
|
12
|
+
instance = new
|
13
|
+
names.map { |name| instance.load_from_gems(name) }.flatten
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the plugin class for the specified dns config by name
|
17
|
+
#
|
18
|
+
# @param config [Object] The entire VMPooler config object
|
19
|
+
# @param name [Symbol] The name of the dns config key to get the dns class
|
20
|
+
# @return [String] The plugin class for the specifid dns config
|
21
|
+
def self.get_dns_plugin_class_by_name(config, name)
|
22
|
+
dns_configs = config[:dns_configs].keys
|
23
|
+
plugin_class = ''
|
24
|
+
|
25
|
+
dns_configs.map do |dns_config_name|
|
26
|
+
plugin_class = config[:dns_configs][dns_config_name]['dns_class'] if dns_config_name.to_s == name
|
27
|
+
end
|
28
|
+
|
29
|
+
plugin_class
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the domain for the specified pool
|
33
|
+
#
|
34
|
+
# @param config [String] - the full config structure
|
35
|
+
# @param pool_name [String] - the name of the pool
|
36
|
+
# @return [String] - domain name for pool, which is set via reference to the dns_configs block
|
37
|
+
def self.get_domain_for_pool(config, pool_name)
|
38
|
+
pool = config[:pools].find { |p| p['name'] == pool_name }
|
39
|
+
pool_dns_config = pool['dns_plugin']
|
40
|
+
dns_configs = config[:dns_configs].keys
|
41
|
+
dns_configs.map do |dns_config_name|
|
42
|
+
return config[:dns_configs][dns_config_name]['domain'] if dns_config_name.to_s == pool_dns_config
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the plugin domain for the specified dns config by name
|
47
|
+
#
|
48
|
+
# @param config [Object] The entire VMPooler config object
|
49
|
+
# @param name [Symbol] The name of the dns config key to get the dns domain
|
50
|
+
# @return [String] The domain for the specifid dns config
|
51
|
+
def self.get_dns_plugin_domain_by_name(config, name)
|
52
|
+
dns_configs = config[:dns_configs].keys
|
53
|
+
dns_configs.map do |dns_config_name|
|
54
|
+
return config[:dns_configs][dns_config_name]['domain'] if dns_config_name.to_s == name
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns a list of DNS plugin classes specified in the vmpooler configuration
|
59
|
+
#
|
60
|
+
# @param config [Object] The entire VMPooler config object
|
61
|
+
# @return nil || [Array<String>] A list of DNS plugin classes
|
62
|
+
def self.get_dns_plugin_config_classes(config)
|
63
|
+
return nil unless config[:dns_configs]
|
64
|
+
|
65
|
+
dns_configs = config[:dns_configs].keys
|
66
|
+
dns_plugins = dns_configs.map do |dns_config_name|
|
67
|
+
if config[:dns_configs][dns_config_name] && config[:dns_configs][dns_config_name]['dns_class']
|
68
|
+
config[:dns_configs][dns_config_name]['dns_class'].to_s
|
69
|
+
else
|
70
|
+
dns_config_name.to_s
|
71
|
+
end
|
72
|
+
end.compact.uniq
|
73
|
+
|
74
|
+
# dynamic-dns is not actually a class, it's just used as a value to denote
|
75
|
+
# that dynamic dns is used so no loading or record management is needed
|
76
|
+
dns_plugins.delete('dynamic-dns')
|
77
|
+
|
78
|
+
dns_plugins
|
79
|
+
end
|
80
|
+
|
81
|
+
# Load a single DNS plugin gem by name
|
82
|
+
#
|
83
|
+
# @param name [String] The name of the DNS plugin gem to load
|
84
|
+
# @return [String] The full require path to the specified gem
|
85
|
+
def load_from_gems(name = nil)
|
86
|
+
require_path = "vmpooler/dns/#{name.gsub('-', '/')}"
|
87
|
+
require require_path
|
88
|
+
require_path
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'vmpooler/dns'
|
3
4
|
require 'vmpooler/providers'
|
4
5
|
require 'vmpooler/util/parsing'
|
5
6
|
require 'spicy-proton'
|
@@ -26,6 +27,9 @@ module Vmpooler
|
|
26
27
|
# VM Provider objects
|
27
28
|
$providers = Concurrent::Hash.new
|
28
29
|
|
30
|
+
# VM DNS objects
|
31
|
+
$dns_plugins = Concurrent::Hash.new
|
32
|
+
|
29
33
|
# Our thread-tracker object
|
30
34
|
$threads = Concurrent::Hash.new
|
31
35
|
|
@@ -39,6 +43,9 @@ module Vmpooler
|
|
39
43
|
|
40
44
|
# load specified providers from config file
|
41
45
|
load_used_providers
|
46
|
+
|
47
|
+
# load specified dns plugins from config file
|
48
|
+
load_used_dns_plugins
|
42
49
|
end
|
43
50
|
|
44
51
|
def config
|
@@ -60,7 +67,7 @@ module Vmpooler
|
|
60
67
|
to_set[k] = pool[k]
|
61
68
|
end
|
62
69
|
to_set['alias'] = pool['alias'].join(',') if to_set.key?('alias')
|
63
|
-
to_set['domain'] =
|
70
|
+
to_set['domain'] = Vmpooler::Dns.get_domain_for_pool(config, pool['name'])
|
64
71
|
redis.hmset("vmpooler__pool__#{pool['name']}", to_set.to_a.flatten) unless to_set.empty?
|
65
72
|
end
|
66
73
|
previously_configured_pools.each do |pool|
|
@@ -106,6 +113,11 @@ module Vmpooler
|
|
106
113
|
|
107
114
|
def remove_nonexistent_vm(vm, pool, redis)
|
108
115
|
redis.srem("vmpooler__pending__#{pool}", vm)
|
116
|
+
dns_plugin = get_dns_plugin_class_for_pool(pool)
|
117
|
+
dns_plugin_class_name = get_dns_plugin_class_name_for_pool(pool)
|
118
|
+
domain = get_dns_plugin_domain_for_pool(pool)
|
119
|
+
fqdn = "#{vm}.#{domain}"
|
120
|
+
dns_plugin.delete_record(fqdn) unless dns_plugin_class_name == 'dynamic-dns'
|
109
121
|
$logger.log('d', "[!] [#{pool}] '#{vm}' no longer exists. Removing from pending.")
|
110
122
|
end
|
111
123
|
|
@@ -323,10 +335,10 @@ module Vmpooler
|
|
323
335
|
end
|
324
336
|
|
325
337
|
# Clone a VM
|
326
|
-
def clone_vm(pool_name, provider, request_id = nil, pool_alias = nil)
|
338
|
+
def clone_vm(pool_name, provider, dns_plugin, request_id = nil, pool_alias = nil)
|
327
339
|
Thread.new do
|
328
340
|
begin
|
329
|
-
_clone_vm(pool_name, provider, request_id, pool_alias)
|
341
|
+
_clone_vm(pool_name, provider, dns_plugin, request_id, pool_alias)
|
330
342
|
rescue StandardError => e
|
331
343
|
if request_id
|
332
344
|
$logger.log('s', "[!] [#{pool_name}] failed while cloning VM for request #{request_id} with an error: #{e}")
|
@@ -368,12 +380,8 @@ module Vmpooler
|
|
368
380
|
max_hostname_retries = 3
|
369
381
|
while hostname_retries < max_hostname_retries
|
370
382
|
hostname, hostname_available = generate_and_check_hostname
|
371
|
-
domain =
|
372
|
-
|
373
|
-
fqdn = "#{hostname}.#{domain}"
|
374
|
-
else
|
375
|
-
fqdn = hostname
|
376
|
-
end
|
383
|
+
domain = Vmpooler::Dns.get_domain_for_pool(config, pool_name)
|
384
|
+
fqdn = "#{hostname}.#{domain}"
|
377
385
|
|
378
386
|
# skip dns check if the provider is set to skip_dns_check_before_creating_vm
|
379
387
|
provider = get_provider_for_pool(pool_name)
|
@@ -414,9 +422,9 @@ module Vmpooler
|
|
414
422
|
[dns_ip, false]
|
415
423
|
end
|
416
424
|
|
417
|
-
def _clone_vm(pool_name, provider, request_id = nil, pool_alias = nil)
|
425
|
+
def _clone_vm(pool_name, provider, dns_plugin, request_id = nil, pool_alias = nil)
|
418
426
|
new_vmname = find_unique_hostname(pool_name)
|
419
|
-
pool_domain =
|
427
|
+
pool_domain = Vmpooler::Dns.get_domain_for_pool(config, pool_name)
|
420
428
|
mutex = vm_mutex(new_vmname)
|
421
429
|
mutex.synchronize do
|
422
430
|
@redis.with_metrics do |redis|
|
@@ -426,7 +434,7 @@ module Vmpooler
|
|
426
434
|
redis.hset("vmpooler__vm__#{new_vmname}", 'clone', Time.now)
|
427
435
|
redis.hset("vmpooler__vm__#{new_vmname}", 'template', pool_name) # This value is used to represent the pool.
|
428
436
|
redis.hset("vmpooler__vm__#{new_vmname}", 'pool', pool_name)
|
429
|
-
redis.hset("vmpooler__vm__#{new_vmname}", 'domain', pool_domain)
|
437
|
+
redis.hset("vmpooler__vm__#{new_vmname}", 'domain', pool_domain)
|
430
438
|
redis.hset("vmpooler__vm__#{new_vmname}", 'request_id', request_id) if request_id
|
431
439
|
redis.hset("vmpooler__vm__#{new_vmname}", 'pool_alias', pool_alias) if pool_alias
|
432
440
|
redis.exec
|
@@ -437,16 +445,25 @@ module Vmpooler
|
|
437
445
|
start = Time.now
|
438
446
|
provider.create_vm(pool_name, new_vmname)
|
439
447
|
finish = format('%<time>.2f', time: Time.now - start)
|
448
|
+
$logger.log('s', "[+] [#{pool_name}] '#{new_vmname}' cloned in #{finish} seconds")
|
449
|
+
$metrics.timing("clone.#{pool_name}", finish)
|
450
|
+
|
451
|
+
$logger.log('d', "[ ] [#{pool_name}] Obtaining IP for '#{new_vmname}'")
|
452
|
+
ip_start = Time.now
|
453
|
+
ip = provider.get_vm_ip_address(new_vmname, pool_name)
|
454
|
+
ip_finish = format('%<time>.2f', time: Time.now - ip_start)
|
455
|
+
$logger.log('s', "[+] [#{pool_name}] Obtained IP for '#{new_vmname}' in #{ip_finish} seconds")
|
440
456
|
|
441
457
|
@redis.with_metrics do |redis|
|
442
458
|
redis.pipelined do |pipeline|
|
443
459
|
pipeline.hset("vmpooler__clone__#{Date.today}", "#{pool_name}:#{new_vmname}", finish)
|
444
460
|
pipeline.hset("vmpooler__vm__#{new_vmname}", 'clone_time', finish)
|
461
|
+
pipeline.hset("vmpooler__vm__#{new_vmname}", 'ip', ip)
|
445
462
|
end
|
446
463
|
end
|
447
|
-
$logger.log('s', "[+] [#{pool_name}] '#{new_vmname}' cloned in #{finish} seconds")
|
448
464
|
|
449
|
-
|
465
|
+
dns_plugin_class_name = get_dns_plugin_class_name_for_pool(pool_name)
|
466
|
+
dns_plugin.create_or_replace_record(new_vmname) unless dns_plugin_class_name == 'dynamic-dns'
|
450
467
|
rescue StandardError
|
451
468
|
@redis.with_metrics do |redis|
|
452
469
|
redis.pipelined do |pipeline|
|
@@ -466,10 +483,10 @@ module Vmpooler
|
|
466
483
|
end
|
467
484
|
|
468
485
|
# Destroy a VM
|
469
|
-
def destroy_vm(vm, pool, provider)
|
486
|
+
def destroy_vm(vm, pool, provider, dns_plugin)
|
470
487
|
Thread.new do
|
471
488
|
begin
|
472
|
-
_destroy_vm(vm, pool, provider)
|
489
|
+
_destroy_vm(vm, pool, provider, dns_plugin)
|
473
490
|
rescue StandardError => e
|
474
491
|
$logger.log('d', "[!] [#{pool}] '#{vm}' failed while destroying the VM with an error: #{e}")
|
475
492
|
raise
|
@@ -477,7 +494,7 @@ module Vmpooler
|
|
477
494
|
end
|
478
495
|
end
|
479
496
|
|
480
|
-
def _destroy_vm(vm, pool, provider)
|
497
|
+
def _destroy_vm(vm, pool, provider, dns_plugin)
|
481
498
|
mutex = vm_mutex(vm)
|
482
499
|
return if mutex.locked?
|
483
500
|
|
@@ -494,6 +511,11 @@ module Vmpooler
|
|
494
511
|
start = Time.now
|
495
512
|
|
496
513
|
provider.destroy_vm(pool, vm)
|
514
|
+
domain = get_dns_plugin_domain_for_pool(pool)
|
515
|
+
fqdn = "#{vm}.#{domain}"
|
516
|
+
|
517
|
+
dns_plugin_class_name = get_dns_plugin_class_name_for_pool(pool)
|
518
|
+
dns_plugin.delete_record(fqdn) unless dns_plugin_class_name == 'dynamic-dns'
|
497
519
|
|
498
520
|
redis.srem("vmpooler__completed__#{pool}", vm)
|
499
521
|
|
@@ -632,6 +654,12 @@ module Vmpooler
|
|
632
654
|
result
|
633
655
|
end
|
634
656
|
|
657
|
+
# load only dns plugins used in config file
|
658
|
+
def load_used_dns_plugins
|
659
|
+
dns_plugins = Vmpooler::Dns.get_dns_plugin_config_classes(config)
|
660
|
+
Vmpooler::Dns.load_by_name(dns_plugins)
|
661
|
+
end
|
662
|
+
|
635
663
|
# load only providers used in config file
|
636
664
|
def load_used_providers
|
637
665
|
Vmpooler::Providers.load_by_name(used_providers)
|
@@ -679,6 +707,31 @@ module Vmpooler
|
|
679
707
|
$providers[provider_name]
|
680
708
|
end
|
681
709
|
|
710
|
+
def get_dns_plugin_class_name_for_pool(pool_name)
|
711
|
+
pool = $config[:pools].find { |p| p['name'] == pool_name }
|
712
|
+
return nil unless pool
|
713
|
+
|
714
|
+
plugin_name = pool.fetch('dns_plugin')
|
715
|
+
Vmpooler::Dns.get_dns_plugin_class_by_name(config, plugin_name)
|
716
|
+
end
|
717
|
+
|
718
|
+
def get_dns_plugin_class_for_pool(pool_name)
|
719
|
+
pool = $config[:pools].find { |p| p['name'] == pool_name }
|
720
|
+
return nil unless pool
|
721
|
+
|
722
|
+
plugin_name = pool.fetch('dns_plugin')
|
723
|
+
plugin_class = Vmpooler::Dns.get_dns_plugin_class_by_name(config, plugin_name)
|
724
|
+
$dns_plugins[plugin_class]
|
725
|
+
end
|
726
|
+
|
727
|
+
def get_dns_plugin_domain_for_pool(pool_name)
|
728
|
+
pool = $config[:pools].find { |p| p['name'] == pool_name }
|
729
|
+
return nil unless pool
|
730
|
+
|
731
|
+
plugin_name = pool.fetch('dns_plugin')
|
732
|
+
Vmpooler::Dns.get_dns_plugin_domain_by_name(config, plugin_name)
|
733
|
+
end
|
734
|
+
|
682
735
|
def check_disk_queue(maxloop = 0, loop_delay = 5)
|
683
736
|
$logger.log('d', '[*] [disk_manager] starting worker thread')
|
684
737
|
|
@@ -1223,7 +1276,8 @@ module Vmpooler
|
|
1223
1276
|
if inventory[vm]
|
1224
1277
|
begin
|
1225
1278
|
pool_check_response[:destroyed_vms] += 1
|
1226
|
-
|
1279
|
+
dns_plugin = get_dns_plugin_class_for_pool(pool_name)
|
1280
|
+
destroy_vm(vm, pool_name, provider, dns_plugin)
|
1227
1281
|
rescue StandardError => e
|
1228
1282
|
redis.pipelined do |pipeline|
|
1229
1283
|
pipeline.srem("vmpooler__completed__#{pool_name}", vm)
|
@@ -1290,6 +1344,8 @@ module Vmpooler
|
|
1290
1344
|
$metrics.gauge("ready.#{pool_name}", ready)
|
1291
1345
|
$metrics.gauge("running.#{pool_name}", running)
|
1292
1346
|
|
1347
|
+
dns_plugin = get_dns_plugin_class_for_pool(pool_name)
|
1348
|
+
|
1293
1349
|
unless pool_size == 0
|
1294
1350
|
if redis.get("vmpooler__empty__#{pool_name}")
|
1295
1351
|
redis.del("vmpooler__empty__#{pool_name}") unless ready == 0
|
@@ -1304,7 +1360,7 @@ module Vmpooler
|
|
1304
1360
|
begin
|
1305
1361
|
redis.incr('vmpooler__tasks__clone')
|
1306
1362
|
pool_check_response[:cloned_vms] += 1
|
1307
|
-
clone_vm(pool_name, provider)
|
1363
|
+
clone_vm(pool_name, provider, dns_plugin)
|
1308
1364
|
rescue StandardError => e
|
1309
1365
|
$logger.log('s', "[!] [#{pool_name}] clone failed during check_pool with an error: #{e}")
|
1310
1366
|
redis.decr('vmpooler__tasks__clone')
|
@@ -1390,6 +1446,16 @@ module Vmpooler
|
|
1390
1446
|
raise("Provider '#{provider_class}' is unknown for pool with provider name '#{provider_name}'") if provider_klass.nil?
|
1391
1447
|
end
|
1392
1448
|
|
1449
|
+
def create_dns_object(config, logger, metrics, redis_connection_pool, dns_class, dns_name, options)
|
1450
|
+
dns_klass = Vmpooler::PoolManager::Dns
|
1451
|
+
dns_klass.constants.each do |classname|
|
1452
|
+
next unless classname.to_s.casecmp(dns_class) == 0
|
1453
|
+
|
1454
|
+
return dns_klass.const_get(classname).new(config, logger, metrics, redis_connection_pool, dns_name, options)
|
1455
|
+
end
|
1456
|
+
raise("DNS '#{dns_class}' is unknown for pool with dns name '#{dns_name}'") if dns_klass.nil?
|
1457
|
+
end
|
1458
|
+
|
1393
1459
|
def check_ondemand_requests(maxloop = 0,
|
1394
1460
|
loop_delay_min = CHECK_LOOP_DELAY_MIN_DEFAULT,
|
1395
1461
|
loop_delay_max = CHECK_LOOP_DELAY_MAX_DEFAULT,
|
@@ -1473,20 +1539,21 @@ module Vmpooler
|
|
1473
1539
|
pool_alias, pool, count, request_id = request.split(':')
|
1474
1540
|
count = count.to_i
|
1475
1541
|
provider = get_provider_for_pool(pool)
|
1542
|
+
dns_plugin = get_dns_plugin_class_for_pool(pool)
|
1476
1543
|
slots = ondemand_clone_limit - clone_count
|
1477
1544
|
break if slots == 0
|
1478
1545
|
|
1479
1546
|
if slots >= count
|
1480
1547
|
count.times do
|
1481
1548
|
redis.incr('vmpooler__tasks__ondemandclone')
|
1482
|
-
clone_vm(pool, provider, request_id, pool_alias)
|
1549
|
+
clone_vm(pool, provider, dns_plugin, request_id, pool_alias)
|
1483
1550
|
end
|
1484
1551
|
redis.zrem(queue_key, request)
|
1485
1552
|
else
|
1486
1553
|
remaining_count = count - slots
|
1487
1554
|
slots.times do
|
1488
1555
|
redis.incr('vmpooler__tasks__ondemandclone')
|
1489
|
-
clone_vm(pool, provider, request_id, pool_alias)
|
1556
|
+
clone_vm(pool, provider, dns_plugin, request_id, pool_alias)
|
1490
1557
|
end
|
1491
1558
|
redis.pipelined do |pipeline|
|
1492
1559
|
pipeline.zrem(queue_key, request)
|
@@ -1601,6 +1668,7 @@ module Vmpooler
|
|
1601
1668
|
# Create the providers
|
1602
1669
|
$config[:pools].each do |pool|
|
1603
1670
|
provider_name = pool['provider']
|
1671
|
+
dns_plugin_name = pool['dns_plugin']
|
1604
1672
|
# The provider_class parameter can be defined in the provider's data eg
|
1605
1673
|
# :providers:
|
1606
1674
|
# :vsphere:
|
@@ -1621,12 +1689,22 @@ module Vmpooler
|
|
1621
1689
|
else
|
1622
1690
|
provider_class = $config[:providers][provider_name.to_sym]['provider_class']
|
1623
1691
|
end
|
1692
|
+
|
1624
1693
|
begin
|
1625
1694
|
$providers[provider_name] = create_provider_object($config, $logger, $metrics, @redis, provider_class, provider_name, {}) if $providers[provider_name].nil?
|
1626
1695
|
rescue StandardError => e
|
1627
1696
|
$logger.log('s', "Error while creating provider for pool #{pool['name']}: #{e}")
|
1628
1697
|
raise
|
1629
1698
|
end
|
1699
|
+
|
1700
|
+
dns_plugin_class = $config[:dns_configs][dns_plugin_name.to_sym]['dns_class']
|
1701
|
+
|
1702
|
+
begin
|
1703
|
+
$dns_plugins[dns_plugin_class] = create_dns_object($config, $logger, $metrics, @redis, dns_plugin_class, dns_plugin_name, {}) if $dns_plugins[dns_plugin_class].nil?
|
1704
|
+
rescue StandardError => e
|
1705
|
+
$logger.log('s', "Error while creating dns plugin for pool #{pool['name']}: #{e}")
|
1706
|
+
raise
|
1707
|
+
end
|
1630
1708
|
end
|
1631
1709
|
|
1632
1710
|
purge_unused_vms_and_resources
|
@@ -58,6 +58,10 @@ module Vmpooler
|
|
58
58
|
nil
|
59
59
|
end
|
60
60
|
|
61
|
+
def dns_config(dns_config_name)
|
62
|
+
Vmpooler::Dns.get_dns_plugin_domain_by_name(@config, dns_config_name)
|
63
|
+
end
|
64
|
+
|
61
65
|
# returns
|
62
66
|
# [Hashtable] : The entire VMPooler configuration
|
63
67
|
def global_config
|
@@ -257,6 +261,10 @@ module Vmpooler
|
|
257
261
|
raise("#{self.class.name} does not implement purge_unconfigured_resources")
|
258
262
|
end
|
259
263
|
|
264
|
+
def get_vm_ip_address(vm_name, pool_name)
|
265
|
+
raise("#{self.class.name} does not implement get_vm_ip_address for vm #{vm_name} in pool #{pool_name}")
|
266
|
+
end
|
267
|
+
|
260
268
|
# DEPRECATED if a provider does not implement the new method, it will hit this base class method
|
261
269
|
# and return a deprecation message
|
262
270
|
def purge_unconfigured_folders(_deprecated, _deprecated2, allowlist)
|
@@ -29,10 +29,10 @@ Date.prototype.yyyymmdd = function() {
|
|
29
29
|
|
30
30
|
var data_url = {
|
31
31
|
'capacity': '/dashboard/stats/vmpooler/pool',
|
32
|
-
'pools' : '/api/
|
32
|
+
'pools' : '/api/v3/vm',
|
33
33
|
'running' : '/dashboard/stats/vmpooler/running',
|
34
|
-
'status' : '/api/
|
35
|
-
'summary' : '/api/
|
34
|
+
'status' : '/api/v3/status',
|
35
|
+
'summary' : '/api/v3/summary'
|
36
36
|
};
|
37
37
|
|
38
38
|
|
@@ -12,25 +12,5 @@ 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
|
35
15
|
end
|
36
16
|
end
|
data/lib/vmpooler/version.rb
CHANGED
data/lib/vmpooler.rb
CHANGED
@@ -34,7 +34,7 @@ module Vmpooler
|
|
34
34
|
config_string = ENV['VMPOOLER_CONFIG']
|
35
35
|
# Parse the YAML config into a Hash
|
36
36
|
# Allow the Symbol class
|
37
|
-
parsed_config = YAML.safe_load(config_string, [Symbol])
|
37
|
+
parsed_config = YAML.safe_load(config_string, permitted_classes: [Symbol])
|
38
38
|
else
|
39
39
|
# Take the name of the config file either from an ENV variable or from the filepath argument
|
40
40
|
config_file = ENV['VMPOOLER_CONFIG_FILE'] || filepath
|
@@ -76,7 +76,10 @@ module Vmpooler
|
|
76
76
|
parsed_config[:config]['prefix'] = ENV['PREFIX'] || parsed_config[:config]['prefix'] || ''
|
77
77
|
parsed_config[:config]['logfile'] = ENV['LOGFILE'] if ENV['LOGFILE']
|
78
78
|
parsed_config[:config]['site_name'] = ENV['SITE_NAME'] if ENV['SITE_NAME']
|
79
|
-
parsed_config[:config]['domain']
|
79
|
+
if !parsed_config[:config]['domain'].nil? || !ENV['DOMAIN'].nil?
|
80
|
+
puts '[!] [error] The "domain" config setting has been removed in v3. Please see the docs for migrating the domain config to use a dns plugin at https://github.com/puppetlabs/vmpooler/blob/main/README.md#migrating-to-v3'
|
81
|
+
exit 1
|
82
|
+
end
|
80
83
|
parsed_config[:config]['clone_target'] = ENV['CLONE_TARGET'] if ENV['CLONE_TARGET']
|
81
84
|
parsed_config[:config]['timeout'] = string_to_int(ENV['TIMEOUT']) if ENV['TIMEOUT']
|
82
85
|
parsed_config[:config]['vm_lifetime_auth'] = string_to_int(ENV['VM_LIFETIME_AUTH']) if ENV['VM_LIFETIME_AUTH']
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vmpooler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -449,10 +449,10 @@ files:
|
|
449
449
|
- lib/vmpooler/api/healthcheck.rb
|
450
450
|
- lib/vmpooler/api/helpers.rb
|
451
451
|
- lib/vmpooler/api/request_logger.rb
|
452
|
-
- lib/vmpooler/api/
|
453
|
-
- lib/vmpooler/api/v1.rb
|
454
|
-
- lib/vmpooler/api/v2.rb
|
452
|
+
- lib/vmpooler/api/v3.rb
|
455
453
|
- lib/vmpooler/dashboard.rb
|
454
|
+
- lib/vmpooler/dns.rb
|
455
|
+
- lib/vmpooler/dns/base.rb
|
456
456
|
- lib/vmpooler/generic_connection_pool.rb
|
457
457
|
- lib/vmpooler/logger.rb
|
458
458
|
- lib/vmpooler/metrics.rb
|
@@ -500,7 +500,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
500
500
|
- !ruby/object:Gem::Version
|
501
501
|
version: '0'
|
502
502
|
requirements: []
|
503
|
-
rubygems_version: 3.
|
503
|
+
rubygems_version: 3.3.25
|
504
504
|
signing_key:
|
505
505
|
specification_version: 4
|
506
506
|
summary: vmpooler provides configurable pools of instantly-available (running) virtual
|