vmpooler 1.1.0 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f802530711b24fac0c8b34198895a2b4b5d18f32942bc4fb7b35d5756ead742
4
- data.tar.gz: 31df1542e5d1c2441976780c10c523f95617a8d0ea57457e6c8afd3a488ef983
3
+ metadata.gz: 32b41fec26ba54f25cb6186a6dc1b97904a855f0e5ceeca19978c4c614b5ef55
4
+ data.tar.gz: 1937db66b56b998fe4030ed133eaad5bbabd15646d3786dfa1539a8ee6e35a95
5
5
  SHA512:
6
- metadata.gz: 40705e369c0b5dcc9b5f8a9d1f30258586f6df66528421b054fb772d2a51a5bcbcb3795f23efa1239e9948322b807406cffef2107f741d5c1d713a0f0c125592
7
- data.tar.gz: ef3eb7549072874d71c9ddb0e50913679f47006cdecff869a0db49e7cc8e7af00d4f4455a824e441fb93ef94999b81e411d06418ec5ce08481c9318b670a55aa
6
+ metadata.gz: 747e7156ec196e938a41ffcc7857d01c32d9412b28ce20bea8f52edc6d6579118c7f4d458bdca70d8765b1ce081e44926b0c5560081e6fa27d74110262ce1e2d
7
+ data.tar.gz: e77c0fe360af30347f20ada5cd34879087b4775aff81914ee41c83639d7a9c91951dc8a5cbf0f2028eabd65312d96e94a95bcc81457de3d1c897d121a79282c2
@@ -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
@@ -236,12 +240,25 @@ module Vmpooler
236
240
  result
237
241
  end
238
242
 
243
+ def component_to_test(match, labels_string)
244
+ return if labels_string.nil?
245
+
246
+ labels_string_parts = labels_string.split(',')
247
+ labels_string_parts.each do |part|
248
+ key, value = part.split('=')
249
+ next if value.nil?
250
+ return value if key == match
251
+ end
252
+ 'none'
253
+ end
254
+
239
255
  def update_user_metrics(operation, vmname)
240
256
  backend.multi
241
257
  backend.hget("vmpooler__vm__#{vmname}", 'tag:jenkins_build_url')
242
258
  backend.hget("vmpooler__vm__#{vmname}", 'token:user')
243
259
  backend.hget("vmpooler__vm__#{vmname}", 'template')
244
260
  jenkins_build_url, user, poolname = backend.exec
261
+ poolname = poolname.gsub('.', '_')
245
262
 
246
263
  if user
247
264
  user = user.gsub('.', '_')
@@ -276,6 +293,32 @@ module Vmpooler
276
293
  puts 'd', "[!] [#{poolname}] failed while evaluating usage labels on '#{vmname}' with an error: #{e}"
277
294
  end
278
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
+
279
322
  def update_pool_size(payload)
280
323
  result = { 'ok' => false }
281
324
 
@@ -296,6 +339,33 @@ module Vmpooler
296
339
  result
297
340
  end
298
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
+
299
369
  def update_pool_template(payload)
300
370
  result = { 'ok' => false }
301
371
 
@@ -1362,6 +1432,26 @@ module Vmpooler
1362
1432
  JSON.pretty_generate(result)
1363
1433
  end
1364
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
+
1365
1455
  post "#{api_prefix}/config/poolsize/?" do
1366
1456
  content_type :json
1367
1457
  result = { 'ok' => false }
@@ -1393,6 +1483,26 @@ module Vmpooler
1393
1483
  JSON.pretty_generate(result)
1394
1484
  end
1395
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
+
1396
1506
  post "#{api_prefix}/config/pooltemplate/?" do
1397
1507
  content_type :json
1398
1508
  result = { 'ok' => false }
@@ -478,18 +478,6 @@ module Vmpooler
478
478
  dereference_mutex(vm)
479
479
  end
480
480
 
481
- def component_to_test(match, labels_string)
482
- return if labels_string.nil?
483
-
484
- labels_string_parts = labels_string.split(',')
485
- labels_string_parts.each do |part|
486
- key, value = part.split('=')
487
- next if value.nil?
488
- return value if key == match
489
- end
490
- 'none'
491
- end
492
-
493
481
  def purge_unused_vms_and_folders
494
482
  global_purge = $config[:config]['purge_unconfigured_folders']
495
483
  providers = $config[:providers].keys
@@ -796,6 +784,10 @@ module Vmpooler
796
784
  # - Fires when a pool reset is requested
797
785
  # - Additional options
798
786
  # :poolname
787
+ # :undo_override
788
+ # - Fires when a pool override removal is requested
789
+ # - Additional options
790
+ # :poolname
799
791
  #
800
792
  def sleep_with_wakeup_events(loop_delay, wakeup_period = 5, options = {})
801
793
  exit_by = Time.now + loop_delay
@@ -838,6 +830,11 @@ module Vmpooler
838
830
  break if pending
839
831
  end
840
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
+
841
838
  if options[:pending_vm]
842
839
  pending_vm_count = redis.scard("vmpooler__pending__#{options[:poolname]}")
843
840
  break unless pending_vm_count == 0
@@ -892,7 +889,7 @@ module Vmpooler
892
889
  loop_delay = (loop_delay * loop_delay_decay).to_i
893
890
  loop_delay = loop_delay_max if loop_delay > loop_delay_max
894
891
  end
895
- 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)
896
893
 
897
894
  unless maxloop == 0
898
895
  break if loop_count >= maxloop
@@ -1052,15 +1049,18 @@ module Vmpooler
1052
1049
  return if mutex.locked?
1053
1050
 
1054
1051
  @redis.with_metrics do |redis|
1055
- poolsize = redis.hget('vmpooler__config__poolsize', pool['name'])
1056
- break if poolsize.nil?
1052
+ pool_size_requested = redis.hget('vmpooler__config__poolsize', pool['name'])
1053
+ break if pool_size_requested.nil?
1057
1054
 
1058
- poolsize = Integer(poolsize)
1059
- 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
1060
1058
 
1061
1059
  mutex.synchronize do
1062
- pool['size'] = poolsize
1060
+ pool['size'] = pool_size_requested
1063
1061
  end
1062
+
1063
+ $logger.log('s', "[*] [#{pool['name']}] size updated from #{pool_size_currently} to #{pool_size_requested}")
1064
1064
  end
1065
1065
  end
1066
1066
 
@@ -1078,6 +1078,38 @@ module Vmpooler
1078
1078
  end
1079
1079
  end
1080
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
+
1081
1113
  def create_inventory(pool, provider, pool_check_response)
1082
1114
  inventory = {}
1083
1115
  begin
@@ -1312,6 +1344,9 @@ module Vmpooler
1312
1344
  # Reset a pool when poolreset is requested from the API
1313
1345
  reset_pool(pool)
1314
1346
 
1347
+ # Undo overrides submitted via the api
1348
+ undo_override(pool, provider)
1349
+
1315
1350
  pool_check_response
1316
1351
  end
1317
1352
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vmpooler
4
- VERSION = '1.1.0'
4
+ VERSION = '1.3.0'
5
5
  end
data/lib/vmpooler.rb CHANGED
@@ -119,6 +119,11 @@ module Vmpooler
119
119
  parsed_config[:auth][:ldap]['port'] = string_to_int(ENV['LDAP_PORT']) if ENV['LDAP_PORT']
120
120
  parsed_config[:auth][:ldap]['base'] = ENV['LDAP_BASE'] if ENV['LDAP_BASE']
121
121
  parsed_config[:auth][:ldap]['user_object'] = ENV['LDAP_USER_OBJECT'] if ENV['LDAP_USER_OBJECT']
122
+ if parsed_config[:auth]['provider'] == 'ldap' && parsed_config[:auth][:ldap].key?('encryption')
123
+ parsed_config[:auth][:ldap]['encryption'] = parsed_config[:auth][:ldap]['encryption']
124
+ elsif parsed_config[:auth]['provider'] == 'ldap'
125
+ parsed_config[:auth][:ldap]['encryption'] = {}
126
+ end
122
127
  end
123
128
 
124
129
  # Create an index of pool aliases
@@ -128,8 +133,17 @@ module Vmpooler
128
133
  parsed_config[:pools] = load_pools_from_redis(redis)
129
134
  end
130
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
+
131
144
  # Create an index of pools by title
132
145
  parsed_config[:pool_index] = pool_index(parsed_config[:pools])
146
+ # rubocop:enable Security/MarshalLoad
133
147
 
134
148
  parsed_config[:pools].each do |pool|
135
149
  parsed_config[:pool_names] << pool['name']
@@ -236,12 +250,12 @@ module Vmpooler
236
250
  if tracing_enabled.eql?('false')
237
251
  puts "Exporting of traces has been disabled so the span processor has been se to a 'NoopSpanExporter'"
238
252
  span_processor = OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
239
- exporter: OpenTelemetry::SDK::Trace::Export::NoopSpanExporter.new
253
+ OpenTelemetry::SDK::Trace::Export::NoopSpanExporter.new
240
254
  )
241
255
  else
242
256
  puts "Exporting of traces will be done over HTTP in binary Thrift format to #{tracing_jaeger_host}"
243
257
  span_processor = OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
244
- exporter: OpenTelemetry::Exporter::Jaeger::CollectorExporter.new(endpoint: tracing_jaeger_host)
258
+ OpenTelemetry::Exporter::Jaeger::CollectorExporter.new(endpoint: tracing_jaeger_host)
245
259
  )
246
260
  end
247
261
 
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.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-08-18 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
@@ -72,84 +72,84 @@ dependencies:
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 0.15.0
75
+ version: 0.17.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 0.15.0
82
+ version: 0.17.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: opentelemetry-instrumentation-concurrent_ruby
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: 0.15.0
89
+ version: 0.17.0
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: 0.15.0
96
+ version: 0.17.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: opentelemetry-instrumentation-redis
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - '='
102
102
  - !ruby/object:Gem::Version
103
- version: 0.15.0
103
+ version: 0.17.0
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - '='
109
109
  - !ruby/object:Gem::Version
110
- version: 0.15.0
110
+ version: 0.17.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: opentelemetry-instrumentation-sinatra
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - '='
116
116
  - !ruby/object:Gem::Version
117
- version: 0.15.0
117
+ version: 0.17.0
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - '='
123
123
  - !ruby/object:Gem::Version
124
- version: 0.15.0
124
+ version: 0.17.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: opentelemetry-resource_detectors
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - '='
130
130
  - !ruby/object:Gem::Version
131
- version: 0.15.0
131
+ version: 0.17.0
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - '='
137
137
  - !ruby/object:Gem::Version
138
- version: 0.15.0
138
+ version: 0.17.0
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: opentelemetry-sdk
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - '='
144
144
  - !ruby/object:Gem::Version
145
- version: 0.15.0
145
+ version: 0.17.0
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - '='
151
151
  - !ruby/object:Gem::Version
152
- version: 0.15.0
152
+ version: 0.17.0
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: pickup
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -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