vmpooler 1.1.2 → 2.1.0

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: 0e7864a4052aa108e7946af16f5388c43d2f755b55a45cd04e5c1aa808209fe7
4
- data.tar.gz: b11cc686a8f1ea02551ee874b67f98d70b621848865fdde8acdb6bb1b43e716e
3
+ metadata.gz: dc5733b50c5c48ba22925f993a81573840cc9621c1707d453e3b6febc71db5eb
4
+ data.tar.gz: 65ff19db989378ac0ba7d1f1c0f0f2a241a5455cb22a212c2c9b813b40854b6e
5
5
  SHA512:
6
- metadata.gz: 6e20f396405f1eaad295555312603977242b5803466ef0049de517efae3d0098edda2d51bf85e1168e9b5c188364b8fdab8c9e8b5197bd5e2970109d148f838c
7
- data.tar.gz: 54c61501623bee35381b7e4241d98b00ad0cee8f8904d5ba20edabd6bc942a69c6cfcc11e8bbc8e23429da661ccb0f027e13e83452ad98327c48a210075b3ce8
6
+ metadata.gz: 5abd2edab02d247335f5b67c37004a4a6407798ad0739dde17c55db11e7651dd1d1328d11542972f9b7d9d6b15fffec99c9fb4ee02fb678f5af4e7ed41239a35
7
+ data.tar.gz: 52ceac894cac6e96f9c73b4a6048dd19ef700a271fc5da1977110020c412b6a376b498da430162f953555b626618009c2e932e260314754141e9f10bbd372a0f
@@ -56,14 +56,11 @@ module Vmpooler
56
56
  return false
57
57
  end
58
58
 
59
- def authenticate_ldap(port, host, user_object, base, username_str, password_str)
59
+ def authenticate_ldap(port, host, encryption_hash, user_object, base, username_str, password_str)
60
60
  ldap = Net::LDAP.new(
61
61
  :host => host,
62
62
  :port => port,
63
- :encryption => {
64
- :method => :start_tls,
65
- :tls_options => { :ssl_version => 'TLSv1' }
66
- },
63
+ :encryption => encryption_hash,
67
64
  :base => base,
68
65
  :auth => {
69
66
  :method => :simple,
@@ -86,6 +83,10 @@ module Vmpooler
86
83
  ldap_port = auth[:ldap]['port'] || 389
87
84
  ldap_user_obj = auth[:ldap]['user_object']
88
85
  ldap_host = auth[:ldap]['host']
86
+ ldap_encryption_hash = auth[:ldap]['encryption'] || {
87
+ :method => :start_tls,
88
+ :tls_options => { :ssl_version => 'TLSv1' }
89
+ }
89
90
 
90
91
  unless ldap_base.is_a? Array
91
92
  ldap_base = ldap_base.split
@@ -100,6 +101,7 @@ module Vmpooler
100
101
  result = authenticate_ldap(
101
102
  ldap_port,
102
103
  ldap_host,
104
+ ldap_encryption_hash,
103
105
  search_user_obj,
104
106
  search_base,
105
107
  username_str,
@@ -28,6 +28,10 @@ module Vmpooler
28
28
  Vmpooler::API.settings.config[:pools]
29
29
  end
30
30
 
31
+ def pools_at_startup
32
+ Vmpooler::API.settings.config[:pools_at_startup]
33
+ end
34
+
31
35
  def pool_exists?(template)
32
36
  Vmpooler::API.settings.config[:pool_names].include?(template)
33
37
  end
@@ -289,6 +293,32 @@ module Vmpooler
289
293
  puts 'd', "[!] [#{poolname}] failed while evaluating usage labels on '#{vmname}' with an error: #{e}"
290
294
  end
291
295
 
296
+ def reset_pool_size(poolname)
297
+ result = { 'ok' => false }
298
+
299
+ pool_index = pool_index(pools)
300
+
301
+ pools_updated = 0
302
+ sync_pool_sizes
303
+
304
+ pool_size_now = pools[pool_index[poolname]]['size'].to_i
305
+ pool_size_original = pools_at_startup[pool_index[poolname]]['size'].to_i
306
+ result['pool_size_before_reset'] = pool_size_now
307
+ result['pool_size_before_overrides'] = pool_size_original
308
+
309
+ unless pool_size_now == pool_size_original
310
+ pools[pool_index[poolname]]['size'] = pool_size_original
311
+ backend.hdel('vmpooler__config__poolsize', poolname)
312
+ backend.sadd('vmpooler__pool__undo_size_override', poolname)
313
+ pools_updated += 1
314
+ status 201
315
+ end
316
+
317
+ status 200 unless pools_updated > 0
318
+ result['ok'] = true
319
+ result
320
+ end
321
+
292
322
  def update_pool_size(payload)
293
323
  result = { 'ok' => false }
294
324
 
@@ -309,6 +339,33 @@ module Vmpooler
309
339
  result
310
340
  end
311
341
 
342
+ def reset_pool_template(poolname)
343
+ result = { 'ok' => false }
344
+
345
+ pool_index_live = pool_index(pools)
346
+ pool_index_original = pool_index(pools_at_startup)
347
+
348
+ pools_updated = 0
349
+ sync_pool_templates
350
+
351
+ template_now = pools[pool_index_live[poolname]]['template']
352
+ template_original = pools_at_startup[pool_index_original[poolname]]['template']
353
+ result['template_before_reset'] = template_now
354
+ result['template_before_overrides'] = template_original
355
+
356
+ unless template_now == template_original
357
+ pools[pool_index_live[poolname]]['template'] = template_original
358
+ backend.hdel('vmpooler__config__template', poolname)
359
+ backend.sadd('vmpooler__pool__undo_template_override', poolname)
360
+ pools_updated += 1
361
+ status 201
362
+ end
363
+
364
+ status 200 unless pools_updated > 0
365
+ result['ok'] = true
366
+ result
367
+ end
368
+
312
369
  def update_pool_template(payload)
313
370
  result = { 'ok' => false }
314
371
 
@@ -1375,6 +1432,26 @@ module Vmpooler
1375
1432
  JSON.pretty_generate(result)
1376
1433
  end
1377
1434
 
1435
+ delete "#{api_prefix}/config/poolsize/:pool/?" do
1436
+ content_type :json
1437
+ result = { 'ok' => false }
1438
+
1439
+ if config['experimental_features']
1440
+ need_token! if Vmpooler::API.settings.config[:auth]
1441
+
1442
+ if pool_exists?(params[:pool])
1443
+ result = reset_pool_size(params[:pool])
1444
+ else
1445
+ metrics.increment('config.invalid.unknown')
1446
+ status 404
1447
+ end
1448
+ else
1449
+ status 405
1450
+ end
1451
+
1452
+ JSON.pretty_generate(result)
1453
+ end
1454
+
1378
1455
  post "#{api_prefix}/config/poolsize/?" do
1379
1456
  content_type :json
1380
1457
  result = { 'ok' => false }
@@ -1406,6 +1483,26 @@ module Vmpooler
1406
1483
  JSON.pretty_generate(result)
1407
1484
  end
1408
1485
 
1486
+ delete "#{api_prefix}/config/pooltemplate/:pool/?" do
1487
+ content_type :json
1488
+ result = { 'ok' => false }
1489
+
1490
+ if config['experimental_features']
1491
+ need_token! if Vmpooler::API.settings.config[:auth]
1492
+
1493
+ if pool_exists?(params[:pool])
1494
+ result = reset_pool_template(params[:pool])
1495
+ else
1496
+ metrics.increment('config.invalid.unknown')
1497
+ status 404
1498
+ end
1499
+ else
1500
+ status 405
1501
+ end
1502
+
1503
+ JSON.pretty_generate(result)
1504
+ end
1505
+
1409
1506
  post "#{api_prefix}/config/pooltemplate/?" do
1410
1507
  content_type :json
1411
1508
  result = { 'ok' => false }
@@ -294,6 +294,12 @@ module Vmpooler
294
294
  move_vm_queue(pool, vm, 'running', 'completed', redis, 'is listed as running, but has no checkouttime data. Removing from running')
295
295
  end
296
296
 
297
+ # tag VM if not tagged yet, this ensures the method is only called once
298
+ unless redis.hget("vmpooler__vm__#{vm}", 'user_tagged')
299
+ success = provider.tag_vm_user(pool, vm)
300
+ redis.hset("vmpooler__vm__#{vm}", 'user_tagged', 'true') if success
301
+ end
302
+
297
303
  throw :stop_checking if provider.vm_ready?(pool, vm)
298
304
 
299
305
  throw :stop_checking if provider.get_vm(pool, vm)
@@ -478,15 +484,15 @@ module Vmpooler
478
484
  dereference_mutex(vm)
479
485
  end
480
486
 
481
- def purge_unused_vms_and_folders
482
- global_purge = $config[:config]['purge_unconfigured_folders']
487
+ def purge_unused_vms_and_resources
488
+ global_purge = $config[:config]['purge_unconfigured_resources']
483
489
  providers = $config[:providers].keys
484
490
  providers.each do |provider_key|
485
- provider_purge = $config[:providers][provider_key]['purge_unconfigured_folders'] || global_purge
491
+ provider_purge = $config[:providers][provider_key]['purge_unconfigured_resources'] || global_purge
486
492
  if provider_purge
487
493
  Thread.new do
488
494
  begin
489
- purge_vms_and_folders(provider_key)
495
+ purge_vms_and_resources(provider_key)
490
496
  rescue StandardError => e
491
497
  $logger.log('s', "[!] failed while purging provider #{provider_key} VMs and folders with an error: #{e}")
492
498
  end
@@ -496,33 +502,16 @@ module Vmpooler
496
502
  nil
497
503
  end
498
504
 
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)
505
+ def purge_vms_and_resources(provider_name)
521
506
  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)
507
+ # Deprecated, will be removed in version 3
508
+ if provider.provider_config['folder_whitelist']
509
+ $logger.log('d', "[!] [deprecation] rename configuration 'folder_whitelist' to 'resources_allowlist' for provider #{provider_name}")
510
+ allowlist = provider.provider_config['folder_whitelist']
511
+ else
512
+ allowlist = provider.provider_config['resources_allowlist']
513
+ end
514
+ provider.purge_unconfigured_resources(allowlist)
526
515
  end
527
516
 
528
517
  def create_vm_disk(pool_name, vm, disk_size, provider)
@@ -628,17 +617,30 @@ module Vmpooler
628
617
  end
629
618
 
630
619
  # @return [Array] - a list of used providers from the config file, defaults to the default providers
631
- # ie. ["vsphere", "dummy"]
620
+ # ie. ["dummy"]
632
621
  def used_providers
633
- pools = config[:pools] || []
634
- @used_providers ||= (pools.map { |pool| pool[:provider] || pool['provider'] }.compact + default_providers).uniq
622
+ # create an array of provider classes based on the config
623
+ if config[:providers]
624
+ config_provider_names = config[:providers].keys
625
+ config_providers = config_provider_names.map do |config_provider_name|
626
+ if config[:providers][config_provider_name] && config[:providers][config_provider_name]['provider_class']
627
+ config[:providers][config_provider_name]['provider_class'].to_s
628
+ else
629
+ config_provider_name.to_s
630
+ end
631
+ end.compact.uniq
632
+ else
633
+ config_providers = []
634
+ end
635
+ # return the unique array of providers from the config and VMPooler defaults
636
+ @used_providers ||= (config_providers + default_providers).uniq
635
637
  end
636
638
 
637
639
  # @return [Array] - returns a list of providers that should always be loaded
638
640
  # note: vsphere is the default if user does not specify although this should not be
639
641
  # if vsphere is to no longer be loaded by default please remove
640
642
  def default_providers
641
- @default_providers ||= %w[vsphere dummy]
643
+ @default_providers ||= %w[dummy]
642
644
  end
643
645
 
644
646
  def get_pool_name_for_vm(vm_name, redis)
@@ -784,6 +786,10 @@ module Vmpooler
784
786
  # - Fires when a pool reset is requested
785
787
  # - Additional options
786
788
  # :poolname
789
+ # :undo_override
790
+ # - Fires when a pool override removal is requested
791
+ # - Additional options
792
+ # :poolname
787
793
  #
788
794
  def sleep_with_wakeup_events(loop_delay, wakeup_period = 5, options = {})
789
795
  exit_by = Time.now + loop_delay
@@ -826,6 +832,11 @@ module Vmpooler
826
832
  break if pending
827
833
  end
828
834
 
835
+ if options[:undo_override]
836
+ break if redis.sismember('vmpooler__pool__undo_template_override', options[:poolname])
837
+ break if redis.sismember('vmpooler__pool__undo_size_override', options[:poolname])
838
+ end
839
+
829
840
  if options[:pending_vm]
830
841
  pending_vm_count = redis.scard("vmpooler__pending__#{options[:poolname]}")
831
842
  break unless pending_vm_count == 0
@@ -880,7 +891,7 @@ module Vmpooler
880
891
  loop_delay = (loop_delay * loop_delay_decay).to_i
881
892
  loop_delay = loop_delay_max if loop_delay > loop_delay_max
882
893
  end
883
- sleep_with_wakeup_events(loop_delay, loop_delay_min, pool_size_change: true, poolname: pool['name'], pool_template_change: true, clone_target_change: true, pending_vm: true, pool_reset: true)
894
+ sleep_with_wakeup_events(loop_delay, loop_delay_min, pool_size_change: true, poolname: pool['name'], pool_template_change: true, clone_target_change: true, pending_vm: true, pool_reset: true, undo_override: true)
884
895
 
885
896
  unless maxloop == 0
886
897
  break if loop_count >= maxloop
@@ -1040,15 +1051,18 @@ module Vmpooler
1040
1051
  return if mutex.locked?
1041
1052
 
1042
1053
  @redis.with_metrics do |redis|
1043
- poolsize = redis.hget('vmpooler__config__poolsize', pool['name'])
1044
- break if poolsize.nil?
1054
+ pool_size_requested = redis.hget('vmpooler__config__poolsize', pool['name'])
1055
+ break if pool_size_requested.nil?
1045
1056
 
1046
- poolsize = Integer(poolsize)
1047
- break if poolsize == pool['size']
1057
+ pool_size_requested = Integer(pool_size_requested)
1058
+ pool_size_currently = pool['size']
1059
+ break if pool_size_requested == pool_size_currently
1048
1060
 
1049
1061
  mutex.synchronize do
1050
- pool['size'] = poolsize
1062
+ pool['size'] = pool_size_requested
1051
1063
  end
1064
+
1065
+ $logger.log('s', "[*] [#{pool['name']}] size updated from #{pool_size_currently} to #{pool_size_requested}")
1052
1066
  end
1053
1067
  end
1054
1068
 
@@ -1066,6 +1080,38 @@ module Vmpooler
1066
1080
  end
1067
1081
  end
1068
1082
 
1083
+ def undo_override(pool, provider)
1084
+ poolname = pool['name']
1085
+ mutex = pool_mutex(poolname)
1086
+ return if mutex.locked?
1087
+
1088
+ @redis.with_metrics do |redis|
1089
+ break unless redis.sismember('vmpooler__pool__undo_template_override', poolname)
1090
+
1091
+ redis.srem('vmpooler__pool__undo_template_override', poolname)
1092
+ template_now = pool['template']
1093
+ template_original = $config[:pools_at_startup][$config[:pool_index][poolname]]['template']
1094
+
1095
+ mutex.synchronize do
1096
+ update_pool_template(pool, provider, template_original, template_now, redis)
1097
+ end
1098
+ end
1099
+
1100
+ @redis.with_metrics do |redis|
1101
+ break unless redis.sismember('vmpooler__pool__undo_size_override', poolname)
1102
+
1103
+ redis.srem('vmpooler__pool__undo_size_override', poolname)
1104
+ pool_size_now = pool['size']
1105
+ pool_size_original = $config[:pools_at_startup][$config[:pool_index][poolname]]['size']
1106
+
1107
+ mutex.synchronize do
1108
+ pool['size'] = pool_size_original
1109
+ end
1110
+
1111
+ $logger.log('s', "[*] [#{poolname}] size updated from #{pool_size_now} to #{pool_size_original}")
1112
+ end
1113
+ end
1114
+
1069
1115
  def create_inventory(pool, provider, pool_check_response)
1070
1116
  inventory = {}
1071
1117
  begin
@@ -1300,6 +1346,9 @@ module Vmpooler
1300
1346
  # Reset a pool when poolreset is requested from the API
1301
1347
  reset_pool(pool)
1302
1348
 
1349
+ # Undo overrides submitted via the api
1350
+ undo_override(pool, provider)
1351
+
1303
1352
  pool_check_response
1304
1353
  end
1305
1354
 
@@ -1514,8 +1563,8 @@ module Vmpooler
1514
1563
  # Set default provider for all pools that do not have one defined
1515
1564
  $config[:pools].each do |pool|
1516
1565
  if pool['provider'].nil?
1517
- $logger.log('d', "[!] Setting provider for pool '#{pool['name']}' to 'vsphere' as default")
1518
- pool['provider'] = 'vsphere'
1566
+ $logger.log('d', "[!] Setting provider for pool '#{pool['name']}' to 'dummy' as default")
1567
+ pool['provider'] = 'dummy'
1519
1568
  end
1520
1569
  end
1521
1570
 
@@ -1559,7 +1608,7 @@ module Vmpooler
1559
1608
  end
1560
1609
  end
1561
1610
 
1562
- purge_unused_vms_and_folders
1611
+ purge_unused_vms_and_resources
1563
1612
 
1564
1613
  loop_count = 1
1565
1614
  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
@@ -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
Binary file
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vmpooler
4
- VERSION = '1.1.2'
4
+ VERSION = '2.1.0'
5
5
  end
data/lib/vmpooler.rb CHANGED
@@ -7,7 +7,6 @@ module Vmpooler
7
7
  require 'net/ldap'
8
8
  require 'open-uri'
9
9
  require 'pickup'
10
- require 'rbvmomi'
11
10
  require 'redis'
12
11
  require 'set'
13
12
  require 'sinatra/base'
@@ -32,7 +31,7 @@ module Vmpooler
32
31
  if ENV['VMPOOLER_CONFIG']
33
32
  config_string = ENV['VMPOOLER_CONFIG']
34
33
  # Parse the YAML config into a Hash
35
- # Whitelist the Symbol class
34
+ # Allow the Symbol class
36
35
  parsed_config = YAML.safe_load(config_string, [Symbol])
37
36
  else
38
37
  # Take the name of the config file either from an ENV variable or from the filepath argument
@@ -82,10 +81,13 @@ module Vmpooler
82
81
  parsed_config[:config]['retry_factor'] = string_to_int(ENV['RETRY_FACTOR']) if ENV['RETRY_FACTOR']
83
82
  parsed_config[:config]['create_folders'] = true?(ENV['CREATE_FOLDERS']) if ENV['CREATE_FOLDERS']
84
83
  parsed_config[:config]['experimental_features'] = ENV['EXPERIMENTAL_FEATURES'] if ENV['EXPERIMENTAL_FEATURES']
85
- parsed_config[:config]['purge_unconfigured_folders'] = ENV['PURGE_UNCONFIGURED_FOLDERS'] if ENV['PURGE_UNCONFIGURED_FOLDERS']
86
84
  parsed_config[:config]['usage_stats'] = ENV['USAGE_STATS'] if ENV['USAGE_STATS']
87
85
  parsed_config[:config]['request_logger'] = ENV['REQUEST_LOGGER'] if ENV['REQUEST_LOGGER']
88
86
  parsed_config[:config]['create_template_delta_disks'] = ENV['CREATE_TEMPLATE_DELTA_DISKS'] if ENV['CREATE_TEMPLATE_DELTA_DISKS']
87
+ parsed_config[:config]['purge_unconfigured_resources'] = ENV['PURGE_UNCONFIGURED_RESOURCES'] if ENV['PURGE_UNCONFIGURED_RESOURCES']
88
+ parsed_config[:config]['purge_unconfigured_resources'] = ENV['PURGE_UNCONFIGURED_FOLDERS'] if ENV['PURGE_UNCONFIGURED_FOLDERS']
89
+ # ENV PURGE_UNCONFIGURED_FOLDERS deprecated, will be removed in version 3
90
+ puts '[!] [deprecation] rename ENV var \'PURGE_UNCONFIGURED_FOLDERS\' to \'PURGE_UNCONFIGURED_RESOURCES\'' if ENV['PURGE_UNCONFIGURED_FOLDERS']
89
91
  set_linked_clone(parsed_config)
90
92
 
91
93
  parsed_config[:redis] = parsed_config[:redis] || {}
@@ -119,6 +121,11 @@ module Vmpooler
119
121
  parsed_config[:auth][:ldap]['port'] = string_to_int(ENV['LDAP_PORT']) if ENV['LDAP_PORT']
120
122
  parsed_config[:auth][:ldap]['base'] = ENV['LDAP_BASE'] if ENV['LDAP_BASE']
121
123
  parsed_config[:auth][:ldap]['user_object'] = ENV['LDAP_USER_OBJECT'] if ENV['LDAP_USER_OBJECT']
124
+ if parsed_config[:auth]['provider'] == 'ldap' && parsed_config[:auth][:ldap].key?('encryption')
125
+ parsed_config[:auth][:ldap]['encryption'] = parsed_config[:auth][:ldap]['encryption']
126
+ elsif parsed_config[:auth]['provider'] == 'ldap'
127
+ parsed_config[:auth][:ldap]['encryption'] = {}
128
+ end
122
129
  end
123
130
 
124
131
  # Create an index of pool aliases
@@ -128,8 +135,17 @@ module Vmpooler
128
135
  parsed_config[:pools] = load_pools_from_redis(redis)
129
136
  end
130
137
 
138
+ # Marshal.dump is paired with Marshal.load to create a copy that has its own memory space
139
+ # so that each can be edited independently
140
+ # rubocop:disable Security/MarshalLoad
141
+
142
+ # retain a copy of the pools that were observed at startup
143
+ serialized_pools = Marshal.dump(parsed_config[:pools])
144
+ parsed_config[:pools_at_startup] = Marshal.load(serialized_pools)
145
+
131
146
  # Create an index of pools by title
132
147
  parsed_config[:pool_index] = pool_index(parsed_config[:pools])
148
+ # rubocop:enable Security/MarshalLoad
133
149
 
134
150
  parsed_config[:pools].each do |pool|
135
151
  parsed_config[:pool_names] << pool['name']
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: 1.1.2
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-25 00:00:00.000000000 Z
11
+ date: 2021-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -226,26 +226,6 @@ dependencies:
226
226
  - - "~>"
227
227
  - !ruby/object:Gem::Version
228
228
  version: '13.0'
229
- - !ruby/object:Gem::Dependency
230
- name: rbvmomi
231
- requirement: !ruby/object:Gem::Requirement
232
- requirements:
233
- - - ">="
234
- - !ruby/object:Gem::Version
235
- version: '2.1'
236
- - - "<"
237
- - !ruby/object:Gem::Version
238
- version: '4.0'
239
- type: :runtime
240
- prerelease: false
241
- version_requirements: !ruby/object:Gem::Requirement
242
- requirements:
243
- - - ">="
244
- - !ruby/object:Gem::Version
245
- version: '2.1'
246
- - - "<"
247
- - !ruby/object:Gem::Version
248
- version: '4.0'
249
229
  - !ruby/object:Gem::Dependency
250
230
  name: redis
251
231
  requirement: !ruby/object:Gem::Requirement
@@ -400,6 +380,26 @@ dependencies:
400
380
  - - ">="
401
381
  - !ruby/object:Gem::Version
402
382
  version: 0.11.2
383
+ - !ruby/object:Gem::Dependency
384
+ name: thor
385
+ requirement: !ruby/object:Gem::Requirement
386
+ requirements:
387
+ - - "~>"
388
+ - !ruby/object:Gem::Version
389
+ version: '1.0'
390
+ - - ">="
391
+ - !ruby/object:Gem::Version
392
+ version: 1.0.1
393
+ type: :development
394
+ prerelease: false
395
+ version_requirements: !ruby/object:Gem::Requirement
396
+ requirements:
397
+ - - "~>"
398
+ - !ruby/object:Gem::Version
399
+ version: '1.0'
400
+ - - ">="
401
+ - !ruby/object:Gem::Version
402
+ version: 1.0.1
403
403
  - !ruby/object:Gem::Dependency
404
404
  name: yarjuf
405
405
  requirement: !ruby/object:Gem::Requirement
@@ -444,10 +444,10 @@ files:
444
444
  - lib/vmpooler/providers.rb
445
445
  - lib/vmpooler/providers/base.rb
446
446
  - lib/vmpooler/providers/dummy.rb
447
- - lib/vmpooler/providers/vsphere.rb
448
447
  - lib/vmpooler/public/bootstrap.min.css
449
448
  - lib/vmpooler/public/img/bg.png
450
449
  - lib/vmpooler/public/img/logo.gif
450
+ - lib/vmpooler/public/img/logo.png
451
451
  - lib/vmpooler/public/img/spinner.svg
452
452
  - lib/vmpooler/public/img/subtle_dots.png
453
453
  - lib/vmpooler/public/img/textured_paper.png
@@ -479,7 +479,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
479
479
  - !ruby/object:Gem::Version
480
480
  version: '0'
481
481
  requirements: []
482
- rubygems_version: 3.0.8
482
+ rubyforge_project:
483
+ rubygems_version: 2.7.6.2
483
484
  signing_key:
484
485
  specification_version: 4
485
486
  summary: vmpooler provides configurable pools of instantly-available (running) virtual