vmfloaty 0.9.2 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -84,6 +84,26 @@ describe Pooler do
84
84
  expect(vm_req['debian-7-i386']['hostname']).to eq %w[sc0o4xqtodlul5w 4m4dkhqiufnjmxy]
85
85
  expect(vm_req['centos-7-x86_64']['hostname']).to eq 'zb91y9qbrbf6d3q'
86
86
  end
87
+
88
+ context 'with ondemand provisioning' do
89
+ let(:ondemand_response) { '{"ok":true,"request_id":"1234"}' }
90
+ it 'retreives the vm with a token' do
91
+ stub_request(:post, "#{@vmpooler_url}/ondemandvm/debian-7-i386")
92
+ .with(:headers => { 'X-Auth-Token' => 'mytokenfile' })
93
+ .to_return(:status => 200, :body => ondemand_response, :headers => {})
94
+
95
+ stub_request(:get, "#{@vmpooler_url}/ondemandvm/1234")
96
+ .to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {})
97
+
98
+ vm_hash = {}
99
+ vm_hash['debian-7-i386'] = 1
100
+ Pooler.retrieve(false, vm_hash, 'mytokenfile', @vmpooler_url, 'user', {}, true)
101
+ vm_req = Pooler.check_ondemandvm(false, '1234', @vmpooler_url)
102
+ expect(vm_req).to be_an_instance_of Hash
103
+ expect(vm_req['ok']).to equal true
104
+ expect(vm_req['debian-7-i386']['hostname']).to eq 'fq6qlpjlsskycq6'
105
+ end
106
+ end
87
107
  end
88
108
 
89
109
  describe '#modify' do
@@ -5,6 +5,11 @@ require 'json'
5
5
  require 'commander/command'
6
6
  require_relative '../../lib/vmfloaty/utils'
7
7
 
8
+ # allow changing config in service for tests
9
+ class Service
10
+ attr_writer :config
11
+ end
12
+
8
13
  describe Utils do
9
14
  describe '#standardize_hostnames' do
10
15
  before :each do
@@ -77,9 +82,17 @@ describe Utils do
77
82
  expect(Utils.get_service_object).to be Pooler
78
83
  end
79
84
 
85
+ it 'uses abs when told explicitly' do
86
+ expect(Utils.get_service_object('abs')).to be ABS
87
+ end
88
+
80
89
  it 'uses nspooler when told explicitly' do
81
90
  expect(Utils.get_service_object('nspooler')).to be NonstandardPooler
82
91
  end
92
+
93
+ it 'uses vmpooler when told explicitly' do
94
+ expect(Utils.get_service_object('vmpooler')).to be Pooler
95
+ end
83
96
  end
84
97
 
85
98
  describe '#get_service_config' do
@@ -154,97 +167,462 @@ describe Utils do
154
167
  end
155
168
  end
156
169
 
157
- describe '#pretty_print_hosts' do
170
+ describe '#print_fqdn_for_host' do
158
171
  let(:url) { 'http://pooler.example.com' }
159
172
 
160
- it 'prints a vmpooler output with host fqdn, template and duration info' do
161
- hostname = 'mcpy42eqjxli9g2'
162
- response_body = { hostname => {
163
- 'template' => 'ubuntu-1604-x86_64',
164
- 'lifetime' => 12,
165
- 'running' => 9.66,
166
- 'state' => 'running',
167
- 'ip' => '127.0.0.1',
168
- 'domain' => 'delivery.mycompany.net',
169
- } }
170
- output = '- mcpy42eqjxli9g2.delivery.mycompany.net (ubuntu-1604-x86_64, 9.66/12 hours)'
171
-
172
- expect(Utils).to receive(:puts).with(output)
173
-
174
- service = Service.new(MockOptions.new, 'url' => url)
175
- allow(service).to receive(:query)
176
- .with(nil, hostname)
177
- .and_return(response_body)
178
-
179
- Utils.pretty_print_hosts(nil, service, hostname)
173
+ subject { Utils.print_fqdn_for_host(service, hostname, host_data) }
174
+
175
+ describe 'with vmpooler host' do
176
+ let(:service) { Service.new(MockOptions.new, 'url' => url) }
177
+ let(:hostname) { 'mcpy42eqjxli9g2' }
178
+ let(:domain) { 'delivery.mycompany.net' }
179
+ let(:fqdn) { [hostname, domain].join('.') }
180
+
181
+ let(:host_data) do
182
+ {
183
+ 'template' => 'ubuntu-1604-x86_64',
184
+ 'lifetime' => 12,
185
+ 'running' => 9.66,
186
+ 'state' => 'running',
187
+ 'ip' => '127.0.0.1',
188
+ 'domain' => domain,
189
+ }
190
+ end
191
+
192
+ it 'outputs fqdn for host' do
193
+ expect(STDOUT).to receive(:puts).with(fqdn)
194
+
195
+ subject
196
+ end
180
197
  end
181
198
 
182
- it 'prints a vmpooler output with host fqdn, template, duration info, and tags when supplied' do
183
- hostname = 'aiydvzpg23r415q'
184
- response_body = { hostname => {
185
- 'template' => 'redhat-7-x86_64',
186
- 'lifetime' => 48,
187
- 'running' => 7.67,
188
- 'state' => 'running',
189
- 'tags' => {
190
- 'user' => 'bob',
191
- 'role' => 'agent',
192
- },
193
- 'ip' => '127.0.0.1',
194
- 'domain' => 'delivery.mycompany.net',
195
- } }
196
- output = '- aiydvzpg23r415q.delivery.mycompany.net (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)'
199
+ describe 'with nonstandard pooler host' do
200
+ let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') }
201
+ let(:hostname) { 'sol11-9.delivery.mycompany.net' }
202
+ let(:host_data) do
203
+ {
204
+ 'fqdn' => hostname,
205
+ 'os_triple' => 'solaris-11-sparc',
206
+ 'reserved_by_user' => 'first.last',
207
+ 'reserved_for_reason' => '',
208
+ 'hours_left_on_reservation' => 35.89,
209
+ }
210
+ end
211
+ let(:fqdn) { hostname } # for nspooler these are the same
212
+
213
+ it 'outputs fqdn for host' do
214
+ expect(STDOUT).to receive(:puts).with(fqdn)
215
+
216
+ subject
217
+ end
218
+ end
197
219
 
198
- expect(Utils).to receive(:puts).with(output)
220
+ describe 'with ABS host' do
221
+ let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'abs') }
222
+ let(:hostname) { '1597952189390' }
223
+ let(:fqdn) { 'example-noun.delivery.puppetlabs.net' }
224
+ let(:template) { 'ubuntu-1604-x86_64' }
225
+
226
+ # This seems to be the miminal stub response from ABS for the current output
227
+ let(:host_data) do
228
+ {
229
+ 'state' => 'allocated',
230
+ 'allocated_resources' => [
231
+ {
232
+ 'hostname' => fqdn,
233
+ 'type' => template,
234
+ 'enging' => 'vmpooler',
235
+ },
236
+ ],
237
+ 'request' => {
238
+ 'job' => {
239
+ 'id' => hostname,
240
+ }
241
+ },
242
+ }
243
+ end
199
244
 
200
- service = Service.new(MockOptions.new, 'url' => url)
201
- allow(service).to receive(:query)
202
- .with(nil, hostname)
203
- .and_return(response_body)
245
+ it 'outputs fqdn for host' do
246
+ expect(STDOUT).to receive(:puts).with(fqdn)
204
247
 
205
- Utils.pretty_print_hosts(nil, service, hostname)
248
+ subject
249
+ end
206
250
  end
251
+ end
207
252
 
208
- it 'prints a nonstandard pooler output with host, template, and time remaining' do
209
- hostname = 'sol11-9.delivery.mycompany.net'
210
- response_body = { hostname => {
211
- 'fqdn' => hostname,
212
- 'os_triple' => 'solaris-11-sparc',
213
- 'reserved_by_user' => 'first.last',
214
- 'reserved_for_reason' => '',
215
- 'hours_left_on_reservation' => 35.89,
216
- } }
217
- output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining)'
218
-
219
- expect(Utils).to receive(:puts).with(output)
253
+ describe '#pretty_print_hosts' do
254
+ let(:url) { 'http://pooler.example.com' }
255
+ let(:verbose) { nil }
256
+ let(:print_to_stderr) { false }
220
257
 
221
- service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns')
258
+ before(:each) do
222
259
  allow(service).to receive(:query)
223
- .with(nil, hostname)
260
+ .with(anything, hostname)
224
261
  .and_return(response_body)
262
+ end
225
263
 
226
- Utils.pretty_print_hosts(nil, service, hostname)
264
+ subject { Utils.pretty_print_hosts(verbose, service, hostname, print_to_stderr) }
265
+
266
+ describe 'with vmpooler service' do
267
+ let(:service) { Service.new(MockOptions.new, 'url' => url) }
268
+
269
+ let(:hostname) { 'mcpy42eqjxli9g2' }
270
+ let(:domain) { 'delivery.mycompany.net' }
271
+ let(:fqdn) { [hostname, domain].join('.') }
272
+
273
+ let(:response_body) do
274
+ {
275
+ hostname => {
276
+ 'template' => 'ubuntu-1604-x86_64',
277
+ 'lifetime' => 12,
278
+ 'running' => 9.66,
279
+ 'state' => 'running',
280
+ 'ip' => '127.0.0.1',
281
+ 'domain' => domain,
282
+ }
283
+ }
284
+ end
285
+
286
+ let(:default_output) { "- #{fqdn} (ubuntu-1604-x86_64, 9.66/12 hours)" }
287
+
288
+ it 'prints output with host fqdn, template and duration info' do
289
+ expect(STDOUT).to receive(:puts).with(default_output)
290
+
291
+ subject
292
+ end
293
+
294
+ context 'when tags are supplied' do
295
+ let(:hostname) { 'aiydvzpg23r415q' }
296
+ let(:response_body) do
297
+ {
298
+ hostname => {
299
+ 'template' => 'redhat-7-x86_64',
300
+ 'lifetime' => 48,
301
+ 'running' => 7.67,
302
+ 'state' => 'running',
303
+ 'tags' => {
304
+ 'user' => 'bob',
305
+ 'role' => 'agent',
306
+ },
307
+ 'ip' => '127.0.0.1',
308
+ 'domain' => domain,
309
+ }
310
+ }
311
+ end
312
+
313
+ it 'prints output with host fqdn, template, duration info, and tags' do
314
+ output = "- #{fqdn} (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)"
315
+
316
+ expect(STDOUT).to receive(:puts).with(output)
317
+
318
+ subject
319
+ end
320
+ end
321
+
322
+ context 'when print_to_stderr option is true' do
323
+ let(:print_to_stderr) { true }
324
+
325
+ it 'outputs to stderr instead of stdout' do
326
+ expect(STDERR).to receive(:puts).with(default_output)
327
+
328
+ subject
329
+ end
330
+ end
227
331
  end
228
332
 
229
- it 'prints a nonstandard pooler output with host, template, time remaining, and reason' do
230
- hostname = 'sol11-9.delivery.mycompany.net'
231
- response_body = { hostname => {
232
- 'fqdn' => hostname,
233
- 'os_triple' => 'solaris-11-sparc',
234
- 'reserved_by_user' => 'first.last',
235
- 'reserved_for_reason' => 'testing',
236
- 'hours_left_on_reservation' => 35.89,
237
- } }
238
- output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining, reason: testing)'
333
+ describe 'with nonstandard pooler service' do
334
+ let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') }
335
+
336
+ let(:hostname) { 'sol11-9.delivery.mycompany.net' }
337
+ let(:response_body) do
338
+ {
339
+ hostname => {
340
+ 'fqdn' => hostname,
341
+ 'os_triple' => 'solaris-11-sparc',
342
+ 'reserved_by_user' => 'first.last',
343
+ 'reserved_for_reason' => '',
344
+ 'hours_left_on_reservation' => 35.89,
345
+ }
346
+ }
347
+ end
348
+
349
+ let(:default_output) { "- #{hostname} (solaris-11-sparc, 35.89h remaining)" }
350
+
351
+ it 'prints output with host, template, and time remaining' do
352
+ expect(STDOUT).to receive(:puts).with(default_output)
353
+
354
+ subject
355
+ end
356
+
357
+ context 'when reason is supplied' do
358
+ let(:response_body) do
359
+ {
360
+ hostname => {
361
+ 'fqdn' => hostname,
362
+ 'os_triple' => 'solaris-11-sparc',
363
+ 'reserved_by_user' => 'first.last',
364
+ 'reserved_for_reason' => 'testing',
365
+ 'hours_left_on_reservation' => 35.89,
366
+ }
367
+ }
368
+ end
369
+
370
+ it 'prints output with host, template, time remaining, and reason' do
371
+ output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining, reason: testing)'
372
+
373
+ expect(STDOUT).to receive(:puts).with(output)
374
+
375
+ subject
376
+ end
377
+ end
378
+
379
+ context 'when print_to_stderr option is true' do
380
+ let(:print_to_stderr) { true }
381
+
382
+ it 'outputs to stderr instead of stdout' do
383
+ expect(STDERR).to receive(:puts).with(default_output)
384
+
385
+ subject
386
+ end
387
+ end
388
+ end
239
389
 
240
- expect(Utils).to receive(:puts).with(output)
390
+ describe 'with ABS service' do
391
+ let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'abs') }
392
+
393
+ let(:hostname) { '1597952189390' }
394
+ let(:fqdn) { 'example-noun.delivery.mycompany.net' }
395
+ let(:fqdn_hostname) {'example-noun'}
396
+ let(:template) { 'ubuntu-1604-x86_64' }
397
+
398
+ # This seems to be the miminal stub response from ABS for the current output
399
+ let(:response_body) do
400
+ {
401
+ hostname => {
402
+ 'state' => 'allocated',
403
+ 'allocated_resources' => [
404
+ {
405
+ 'hostname' => fqdn,
406
+ 'type' => template,
407
+ 'engine' => 'vmpooler',
408
+ },
409
+ ],
410
+ 'request' => {
411
+ 'job' => {
412
+ 'id' => hostname,
413
+ }
414
+ },
415
+ }
416
+ }
417
+ end
418
+
419
+ # The vmpooler response contains metadata that is printed
420
+ let(:domain) { 'delivery.mycompany.net' }
421
+ let(:response_body_vmpooler) do
422
+ {
423
+ fqdn_hostname => {
424
+ 'template' => template,
425
+ 'lifetime' => 48,
426
+ 'running' => 7.67,
427
+ 'state' => 'running',
428
+ 'tags' => {
429
+ 'user' => 'bob',
430
+ 'role' => 'agent',
431
+ },
432
+ 'ip' => '127.0.0.1',
433
+ 'domain' => domain,
434
+ }
435
+ }
436
+ end
437
+
438
+ before(:each) do
439
+ allow(Utils).to receive(:get_vmpooler_service_config).and_return({
440
+ 'url' => 'http://vmpooler.example.com',
441
+ 'token' => 'krypto-knight'
442
+ })
443
+ allow(service).to receive(:query)
444
+ .with(anything, fqdn_hostname)
445
+ .and_return(response_body_vmpooler)
446
+ end
447
+
448
+ let(:default_output_first_line) { "- [JobID:#{hostname}] <allocated>" }
449
+ let(:default_output_second_line) { " - #{fqdn} (#{template})" }
450
+
451
+ it 'prints output with job id, host, and template' do
452
+ expect(STDOUT).to receive(:puts).with(default_output_first_line)
453
+ expect(STDOUT).to receive(:puts).with(default_output_second_line)
454
+
455
+ subject
456
+ end
457
+
458
+ it 'prints more information when vmpooler_fallback is set output with job id, host, template, lifetime, user and role' do
459
+ fallback = {'vmpooler_fallback' => 'vmpooler'}
460
+ service.config.merge! fallback
461
+ default_output_second_line=" - #{fqdn} (#{template}, 7.67/48 hours, user: bob, role: agent)"
462
+ expect(STDOUT).to receive(:puts).with(default_output_first_line)
463
+ expect(STDOUT).to receive(:puts).with(default_output_second_line)
464
+
465
+ subject
466
+ end
467
+
468
+ context 'when print_to_stderr option is true' do
469
+ let(:print_to_stderr) { true }
470
+
471
+ it 'outputs to stderr instead of stdout' do
472
+ expect(STDERR).to receive(:puts).with(default_output_first_line)
473
+ expect(STDERR).to receive(:puts).with(default_output_second_line)
474
+
475
+ subject
476
+ end
477
+ end
478
+ end
241
479
 
242
- service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns')
243
- allow(service).to receive(:query)
244
- .with(nil, hostname)
245
- .and_return(response_body)
480
+ describe 'with ABS service returning vmpooler and nspooler resources' do
481
+ let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'abs') }
482
+
483
+ let(:hostname) { '1597952189390' }
484
+ let(:fqdn) { 'this-noun.delivery.mycompany.net' }
485
+ let(:fqdn_ns) { 'that-noun.delivery.mycompany.net' }
486
+ let(:fqdn_hostname) {'this-noun'}
487
+ let(:fqdn_ns_hostname) {'that-noun'}
488
+ let(:template) { 'ubuntu-1604-x86_64' }
489
+ let(:template_ns) { 'solaris-10-sparc' }
490
+
491
+ # This seems to be the miminal stub response from ABS for the current output
492
+ let(:response_body) do
493
+ {
494
+ hostname => {
495
+ 'state' => 'allocated',
496
+ 'allocated_resources' => [
497
+ {
498
+ 'hostname' => fqdn,
499
+ 'type' => template,
500
+ 'engine' => 'vmpooler',
501
+ },
502
+ {
503
+ 'hostname' => fqdn_ns,
504
+ 'type' => template_ns,
505
+ 'engine' => 'nspooler',
506
+ },
507
+ ],
508
+ 'request' => {
509
+ 'job' => {
510
+ 'id' => hostname,
511
+ }
512
+ },
513
+ }
514
+ }
515
+ end
516
+
517
+ # The vmpooler response contains metadata that is printed
518
+ let(:domain) { 'delivery.mycompany.net' }
519
+ let(:response_body_vmpooler) do
520
+ {
521
+ fqdn_hostname => {
522
+ 'template' => template,
523
+ 'lifetime' => 48,
524
+ 'running' => 7.67,
525
+ 'state' => 'running',
526
+ 'tags' => {
527
+ 'user' => 'bob',
528
+ 'role' => 'agent',
529
+ },
530
+ 'ip' => '127.0.0.1',
531
+ 'domain' => domain,
532
+ }
533
+ }
534
+ end
535
+
536
+ before(:each) do
537
+ allow(Utils).to receive(:get_vmpooler_service_config).and_return({
538
+ 'url' => 'http://vmpooler.example.com',
539
+ 'token' => 'krypto-knight'
540
+ })
541
+ allow(service).to receive(:query)
542
+ .with(anything, fqdn_hostname)
543
+ .and_return(response_body_vmpooler)
544
+ end
545
+
546
+ let(:default_output_first_line) { "- [JobID:#{hostname}] <allocated>" }
547
+ let(:default_output_second_line) { " - #{fqdn} (#{template})" }
548
+ let(:default_output_third_line) { " - #{fqdn_ns} (#{template_ns})" }
549
+
550
+ it 'prints output with job id, host, and template' do
551
+ expect(STDOUT).to receive(:puts).with(default_output_first_line)
552
+ expect(STDOUT).to receive(:puts).with(default_output_second_line)
553
+ expect(STDOUT).to receive(:puts).with(default_output_third_line)
554
+
555
+ subject
556
+ end
557
+
558
+ context 'when print_to_stderr option is true' do
559
+ let(:print_to_stderr) { true }
560
+
561
+ it 'outputs to stderr instead of stdout' do
562
+ expect(STDERR).to receive(:puts).with(default_output_first_line)
563
+ expect(STDERR).to receive(:puts).with(default_output_second_line)
564
+ expect(STDERR).to receive(:puts).with(default_output_third_line)
565
+
566
+ subject
567
+ end
568
+ end
569
+ end
570
+ end
246
571
 
247
- Utils.pretty_print_hosts(nil, service, hostname)
572
+ describe '#get_vmpooler_service_config' do
573
+ let(:Conf) { double }
574
+ it 'returns an error if the vmpooler_fallback is not setup' do
575
+ config = {
576
+ 'user' => 'foo',
577
+ 'services' => {
578
+ 'myabs' => {
579
+ 'url' => 'http://abs.com',
580
+ 'token' => 'krypto-night',
581
+ 'type' => 'abs'
582
+ }
583
+ }
584
+ }
585
+ allow(Conf).to receive(:read_config).and_return(config)
586
+ expect{Utils.get_vmpooler_service_config(config['services']['myabs']['vmpooler_fallback'])}.to raise_error(ArgumentError)
587
+ end
588
+ it 'returns an error if the vmpooler_fallback is setup but cannot be found' do
589
+ config = {
590
+ 'user' => 'foo',
591
+ 'services' => {
592
+ 'myabs' => {
593
+ 'url' => 'http://abs.com',
594
+ 'token' => 'krypto-night',
595
+ 'type' => 'abs',
596
+ 'vmpooler_fallback' => 'myvmpooler'
597
+ }
598
+ }
599
+ }
600
+ allow(Conf).to receive(:read_config).and_return(config)
601
+ expect{Utils.get_vmpooler_service_config(config['services']['myabs']['vmpooler_fallback'])}.to raise_error(ArgumentError, /myvmpooler/)
602
+ end
603
+ it 'returns the vmpooler_fallback config' do
604
+ config = {
605
+ 'user' => 'foo',
606
+ 'services' => {
607
+ 'myabs' => {
608
+ 'url' => 'http://abs.com',
609
+ 'token' => 'krypto-night',
610
+ 'type' => 'abs',
611
+ 'vmpooler_fallback' => 'myvmpooler'
612
+ },
613
+ 'myvmpooler' => {
614
+ 'url' => 'http://vmpooler.com',
615
+ 'token' => 'krypto-knight'
616
+ }
617
+ }
618
+ }
619
+ allow(Conf).to receive(:read_config).and_return(config)
620
+ expect(Utils.get_vmpooler_service_config(config['services']['myabs']['vmpooler_fallback'])).to include({
621
+ 'url' => 'http://vmpooler.com',
622
+ 'token' => 'krypto-knight',
623
+ 'user' => 'foo',
624
+ 'type' => 'vmpooler'
625
+ })
248
626
  end
249
627
  end
250
628
  end