vmpooler 1.2.0 → 1.3.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: da4a010ab09d34f4fbfa9993526ad18dec205dfbc72f427a250304b2147bdf31
4
- data.tar.gz: 61193bec61a1385754487f107e601c1fc76959ae81fc27a47d4f11a881553e91
3
+ metadata.gz: 32b41fec26ba54f25cb6186a6dc1b97904a855f0e5ceeca19978c4c614b5ef55
4
+ data.tar.gz: 1937db66b56b998fe4030ed133eaad5bbabd15646d3786dfa1539a8ee6e35a95
5
5
  SHA512:
6
- metadata.gz: 13399e493bcaaf5c18541c2125366bb88325936746b715550c6e438d31de77eed9b0f42d9e6140c7529eb0dbd27e4335529f368e6b190c1d047f0cd2710f801e
7
- data.tar.gz: 0f8551abcbb4cfbaf7bbf60d52f6630ce8334fff620ef1e05bad35e53fb7448c69da074494f8df5efa97053ad6b1e3dd2e55c942e97b359156b0ec07b26de912
6
+ metadata.gz: 747e7156ec196e938a41ffcc7857d01c32d9412b28ce20bea8f52edc6d6579118c7f4d458bdca70d8765b1ce081e44926b0c5560081e6fa27d74110262ce1e2d
7
+ data.tar.gz: e77c0fe360af30347f20ada5cd34879087b4775aff81914ee41c83639d7a9c91951dc8a5cbf0f2028eabd65312d96e94a95bcc81457de3d1c897d121a79282c2
@@ -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 }
@@ -784,6 +784,10 @@ module Vmpooler
784
784
  # - Fires when a pool reset is requested
785
785
  # - Additional options
786
786
  # :poolname
787
+ # :undo_override
788
+ # - Fires when a pool override removal is requested
789
+ # - Additional options
790
+ # :poolname
787
791
  #
788
792
  def sleep_with_wakeup_events(loop_delay, wakeup_period = 5, options = {})
789
793
  exit_by = Time.now + loop_delay
@@ -826,6 +830,11 @@ module Vmpooler
826
830
  break if pending
827
831
  end
828
832
 
833
+ if options[:undo_override]
834
+ break if redis.sismember('vmpooler__pool__undo_template_override', options[:poolname])
835
+ break if redis.sismember('vmpooler__pool__undo_size_override', options[:poolname])
836
+ end
837
+
829
838
  if options[:pending_vm]
830
839
  pending_vm_count = redis.scard("vmpooler__pending__#{options[:poolname]}")
831
840
  break unless pending_vm_count == 0
@@ -880,7 +889,7 @@ module Vmpooler
880
889
  loop_delay = (loop_delay * loop_delay_decay).to_i
881
890
  loop_delay = loop_delay_max if loop_delay > loop_delay_max
882
891
  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)
892
+ 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
893
 
885
894
  unless maxloop == 0
886
895
  break if loop_count >= maxloop
@@ -1040,15 +1049,18 @@ module Vmpooler
1040
1049
  return if mutex.locked?
1041
1050
 
1042
1051
  @redis.with_metrics do |redis|
1043
- poolsize = redis.hget('vmpooler__config__poolsize', pool['name'])
1044
- break if poolsize.nil?
1052
+ pool_size_requested = redis.hget('vmpooler__config__poolsize', pool['name'])
1053
+ break if pool_size_requested.nil?
1045
1054
 
1046
- poolsize = Integer(poolsize)
1047
- break if poolsize == pool['size']
1055
+ pool_size_requested = Integer(pool_size_requested)
1056
+ pool_size_currently = pool['size']
1057
+ break if pool_size_requested == pool_size_currently
1048
1058
 
1049
1059
  mutex.synchronize do
1050
- pool['size'] = poolsize
1060
+ pool['size'] = pool_size_requested
1051
1061
  end
1062
+
1063
+ $logger.log('s', "[*] [#{pool['name']}] size updated from #{pool_size_currently} to #{pool_size_requested}")
1052
1064
  end
1053
1065
  end
1054
1066
 
@@ -1066,6 +1078,38 @@ module Vmpooler
1066
1078
  end
1067
1079
  end
1068
1080
 
1081
+ def undo_override(pool, provider)
1082
+ poolname = pool['name']
1083
+ mutex = pool_mutex(poolname)
1084
+ return if mutex.locked?
1085
+
1086
+ @redis.with_metrics do |redis|
1087
+ break unless redis.sismember('vmpooler__pool__undo_template_override', poolname)
1088
+
1089
+ redis.srem('vmpooler__pool__undo_template_override', poolname)
1090
+ template_now = pool['template']
1091
+ template_original = $config[:pools_at_startup][$config[:pool_index][poolname]]['template']
1092
+
1093
+ mutex.synchronize do
1094
+ update_pool_template(pool, provider, template_original, template_now, redis)
1095
+ end
1096
+ end
1097
+
1098
+ @redis.with_metrics do |redis|
1099
+ break unless redis.sismember('vmpooler__pool__undo_size_override', poolname)
1100
+
1101
+ redis.srem('vmpooler__pool__undo_size_override', poolname)
1102
+ pool_size_now = pool['size']
1103
+ pool_size_original = $config[:pools_at_startup][$config[:pool_index][poolname]]['size']
1104
+
1105
+ mutex.synchronize do
1106
+ pool['size'] = pool_size_original
1107
+ end
1108
+
1109
+ $logger.log('s', "[*] [#{poolname}] size updated from #{pool_size_now} to #{pool_size_original}")
1110
+ end
1111
+ end
1112
+
1069
1113
  def create_inventory(pool, provider, pool_check_response)
1070
1114
  inventory = {}
1071
1115
  begin
@@ -1300,6 +1344,9 @@ module Vmpooler
1300
1344
  # Reset a pool when poolreset is requested from the API
1301
1345
  reset_pool(pool)
1302
1346
 
1347
+ # Undo overrides submitted via the api
1348
+ undo_override(pool, provider)
1349
+
1303
1350
  pool_check_response
1304
1351
  end
1305
1352
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vmpooler
4
- VERSION = '1.2.0'
4
+ VERSION = '1.3.0'
5
5
  end
data/lib/vmpooler.rb CHANGED
@@ -133,8 +133,17 @@ module Vmpooler
133
133
  parsed_config[:pools] = load_pools_from_redis(redis)
134
134
  end
135
135
 
136
+ # Marshal.dump is paired with Marshal.load to create a copy that has its own memory space
137
+ # so that each can be edited independently
138
+ # rubocop:disable Security/MarshalLoad
139
+
140
+ # retain a copy of the pools that were observed at startup
141
+ serialized_pools = Marshal.dump(parsed_config[:pools])
142
+ parsed_config[:pools_at_startup] = Marshal.load(serialized_pools)
143
+
136
144
  # Create an index of pools by title
137
145
  parsed_config[:pool_index] = pool_index(parsed_config[:pools])
146
+ # rubocop:enable Security/MarshalLoad
138
147
 
139
148
  parsed_config[:pools].each do |pool|
140
149
  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.2.0
4
+ version: 1.3.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-09-15 00:00:00.000000000 Z
11
+ date: 2021-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -400,6 +400,26 @@ dependencies:
400
400
  - - ">="
401
401
  - !ruby/object:Gem::Version
402
402
  version: 0.11.2
403
+ - !ruby/object:Gem::Dependency
404
+ name: thor
405
+ requirement: !ruby/object:Gem::Requirement
406
+ requirements:
407
+ - - "~>"
408
+ - !ruby/object:Gem::Version
409
+ version: '1.0'
410
+ - - ">="
411
+ - !ruby/object:Gem::Version
412
+ version: 1.0.1
413
+ type: :development
414
+ prerelease: false
415
+ version_requirements: !ruby/object:Gem::Requirement
416
+ requirements:
417
+ - - "~>"
418
+ - !ruby/object:Gem::Version
419
+ version: '1.0'
420
+ - - ">="
421
+ - !ruby/object:Gem::Version
422
+ version: 1.0.1
403
423
  - !ruby/object:Gem::Dependency
404
424
  name: yarjuf
405
425
  requirement: !ruby/object:Gem::Requirement