vmfloaty 0.9.1 → 1.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.
@@ -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
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'vmfloaty/ssh'
5
+
6
+ class ServiceStub
7
+ def retrieve(_verbose, os_types, _use_token)
8
+ if os_types.keys[0] == 'abs_host_string'
9
+ return {
10
+ os_types.keys[0] => { 'hostname' => ['abs-hostname.delivery.puppetlabs.net'] },
11
+ 'ok' => true,
12
+ }
13
+ end
14
+
15
+ {
16
+ os_types.keys[0] => { 'hostname' => 'vmpooler-hostname' },
17
+ 'domain' => 'delivery.puppetlabs.net',
18
+ 'ok' => true,
19
+ }
20
+ end
21
+
22
+ def type
23
+ return 'abs' if os_types == 'abs_host_string'
24
+ return 'vmpooler' if os_types == 'vmpooler_host_string'
25
+ end
26
+ end
27
+
28
+ describe Ssh do
29
+ before :each do
30
+ end
31
+
32
+ it 'gets a hostname string for abs' do
33
+ verbose = false
34
+ service = ServiceStub.new
35
+ host_os = 'abs_host_string'
36
+ use_token = false
37
+ cmd = Ssh.command_string(verbose, service, host_os, use_token)
38
+ expect(cmd).to match(/ssh root@abs-hostname.delivery.puppetlabs.net/)
39
+ end
40
+
41
+ it 'gets a hostname string for vmpooler' do
42
+ verbose = false
43
+ service = ServiceStub.new
44
+ host_os = 'vmpooler_host_string'
45
+ use_token = false
46
+ cmd = Ssh.command_string(verbose, service, host_os, use_token)
47
+ expect(cmd).to match(/ssh root@vmpooler-hostname.delivery.puppetlabs.net/)
48
+ end
49
+ end
@@ -77,9 +77,17 @@ describe Utils do
77
77
  expect(Utils.get_service_object).to be Pooler
78
78
  end
79
79
 
80
+ it 'uses abs when told explicitly' do
81
+ expect(Utils.get_service_object('abs')).to be ABS
82
+ end
83
+
80
84
  it 'uses nspooler when told explicitly' do
81
85
  expect(Utils.get_service_object('nspooler')).to be NonstandardPooler
82
86
  end
87
+
88
+ it 'uses vmpooler when told explicitly' do
89
+ expect(Utils.get_service_object('vmpooler')).to be Pooler
90
+ end
83
91
  end
84
92
 
85
93
  describe '#get_service_config' do
@@ -154,97 +162,452 @@ describe Utils do
154
162
  end
155
163
  end
156
164
 
157
- describe '#pretty_print_hosts' do
165
+ describe '#print_fqdn_for_host' do
158
166
  let(:url) { 'http://pooler.example.com' }
159
167
 
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)
168
+ subject { Utils.print_fqdn_for_host(service, hostname, host_data) }
169
+
170
+ describe 'with vmpooler host' do
171
+ let(:service) { Service.new(MockOptions.new, 'url' => url) }
172
+ let(:hostname) { 'mcpy42eqjxli9g2' }
173
+ let(:domain) { 'delivery.mycompany.net' }
174
+ let(:fqdn) { [hostname, domain].join('.') }
175
+
176
+ let(:host_data) do
177
+ {
178
+ 'template' => 'ubuntu-1604-x86_64',
179
+ 'lifetime' => 12,
180
+ 'running' => 9.66,
181
+ 'state' => 'running',
182
+ 'ip' => '127.0.0.1',
183
+ 'domain' => domain,
184
+ }
185
+ end
186
+
187
+ it 'outputs fqdn for host' do
188
+ expect(STDOUT).to receive(:puts).with(fqdn)
189
+
190
+ subject
191
+ end
180
192
  end
181
193
 
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)'
194
+ describe 'with nonstandard pooler host' do
195
+ let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') }
196
+ let(:hostname) { 'sol11-9.delivery.mycompany.net' }
197
+ let(:host_data) do
198
+ {
199
+ 'fqdn' => hostname,
200
+ 'os_triple' => 'solaris-11-sparc',
201
+ 'reserved_by_user' => 'first.last',
202
+ 'reserved_for_reason' => '',
203
+ 'hours_left_on_reservation' => 35.89,
204
+ }
205
+ end
206
+ let(:fqdn) { hostname } # for nspooler these are the same
207
+
208
+ it 'outputs fqdn for host' do
209
+ expect(STDOUT).to receive(:puts).with(fqdn)
210
+
211
+ subject
212
+ end
213
+ end
197
214
 
198
- expect(Utils).to receive(:puts).with(output)
215
+ describe 'with ABS host' do
216
+ let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'abs') }
217
+ let(:hostname) { '1597952189390' }
218
+ let(:fqdn) { 'example-noun.delivery.puppetlabs.net' }
219
+ let(:template) { 'ubuntu-1604-x86_64' }
220
+
221
+ # This seems to be the miminal stub response from ABS for the current output
222
+ let(:host_data) do
223
+ {
224
+ 'state' => 'allocated',
225
+ 'allocated_resources' => [
226
+ {
227
+ 'hostname' => fqdn,
228
+ 'type' => template,
229
+ 'enging' => 'vmpooler',
230
+ },
231
+ ],
232
+ 'request' => {
233
+ 'job' => {
234
+ 'id' => hostname,
235
+ }
236
+ },
237
+ }
238
+ end
199
239
 
200
- service = Service.new(MockOptions.new, 'url' => url)
201
- allow(service).to receive(:query)
202
- .with(nil, hostname)
203
- .and_return(response_body)
240
+ it 'outputs fqdn for host' do
241
+ expect(STDOUT).to receive(:puts).with(fqdn)
204
242
 
205
- Utils.pretty_print_hosts(nil, service, hostname)
243
+ subject
244
+ end
206
245
  end
246
+ end
207
247
 
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)
248
+ describe '#pretty_print_hosts' do
249
+ let(:url) { 'http://pooler.example.com' }
250
+ let(:verbose) { nil }
251
+ let(:print_to_stderr) { false }
220
252
 
221
- service = Service.new(MockOptions.new, 'url' => url, 'type' => 'ns')
253
+ before(:each) do
222
254
  allow(service).to receive(:query)
223
- .with(nil, hostname)
255
+ .with(anything, hostname)
224
256
  .and_return(response_body)
257
+ end
225
258
 
226
- Utils.pretty_print_hosts(nil, service, hostname)
259
+ subject { Utils.pretty_print_hosts(verbose, service, hostname, print_to_stderr) }
260
+
261
+ describe 'with vmpooler service' do
262
+ let(:service) { Service.new(MockOptions.new, 'url' => url) }
263
+
264
+ let(:hostname) { 'mcpy42eqjxli9g2' }
265
+ let(:domain) { 'delivery.mycompany.net' }
266
+ let(:fqdn) { [hostname, domain].join('.') }
267
+
268
+ let(:response_body) do
269
+ {
270
+ hostname => {
271
+ 'template' => 'ubuntu-1604-x86_64',
272
+ 'lifetime' => 12,
273
+ 'running' => 9.66,
274
+ 'state' => 'running',
275
+ 'ip' => '127.0.0.1',
276
+ 'domain' => domain,
277
+ }
278
+ }
279
+ end
280
+
281
+ let(:default_output) { "- #{fqdn} (ubuntu-1604-x86_64, 9.66/12 hours)" }
282
+
283
+ it 'prints output with host fqdn, template and duration info' do
284
+ expect(STDOUT).to receive(:puts).with(default_output)
285
+
286
+ subject
287
+ end
288
+
289
+ context 'when tags are supplied' do
290
+ let(:hostname) { 'aiydvzpg23r415q' }
291
+ let(:response_body) do
292
+ {
293
+ hostname => {
294
+ 'template' => 'redhat-7-x86_64',
295
+ 'lifetime' => 48,
296
+ 'running' => 7.67,
297
+ 'state' => 'running',
298
+ 'tags' => {
299
+ 'user' => 'bob',
300
+ 'role' => 'agent',
301
+ },
302
+ 'ip' => '127.0.0.1',
303
+ 'domain' => domain,
304
+ }
305
+ }
306
+ end
307
+
308
+ it 'prints output with host fqdn, template, duration info, and tags' do
309
+ output = "- #{fqdn} (redhat-7-x86_64, 7.67/48 hours, user: bob, role: agent)"
310
+
311
+ expect(STDOUT).to receive(:puts).with(output)
312
+
313
+ subject
314
+ end
315
+ end
316
+
317
+ context 'when print_to_stderr option is true' do
318
+ let(:print_to_stderr) { true }
319
+
320
+ it 'outputs to stderr instead of stdout' do
321
+ expect(STDERR).to receive(:puts).with(default_output)
322
+
323
+ subject
324
+ end
325
+ end
227
326
  end
228
327
 
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)'
328
+ describe 'with nonstandard pooler service' do
329
+ let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'ns') }
330
+
331
+ let(:hostname) { 'sol11-9.delivery.mycompany.net' }
332
+ let(:response_body) do
333
+ {
334
+ hostname => {
335
+ 'fqdn' => hostname,
336
+ 'os_triple' => 'solaris-11-sparc',
337
+ 'reserved_by_user' => 'first.last',
338
+ 'reserved_for_reason' => '',
339
+ 'hours_left_on_reservation' => 35.89,
340
+ }
341
+ }
342
+ end
343
+
344
+ let(:default_output) { "- #{hostname} (solaris-11-sparc, 35.89h remaining)" }
345
+
346
+ it 'prints output with host, template, and time remaining' do
347
+ expect(STDOUT).to receive(:puts).with(default_output)
348
+
349
+ subject
350
+ end
351
+
352
+ context 'when reason is supplied' do
353
+ let(:response_body) do
354
+ {
355
+ hostname => {
356
+ 'fqdn' => hostname,
357
+ 'os_triple' => 'solaris-11-sparc',
358
+ 'reserved_by_user' => 'first.last',
359
+ 'reserved_for_reason' => 'testing',
360
+ 'hours_left_on_reservation' => 35.89,
361
+ }
362
+ }
363
+ end
364
+
365
+ it 'prints output with host, template, time remaining, and reason' do
366
+ output = '- sol11-9.delivery.mycompany.net (solaris-11-sparc, 35.89h remaining, reason: testing)'
367
+
368
+ expect(STDOUT).to receive(:puts).with(output)
369
+
370
+ subject
371
+ end
372
+ end
373
+
374
+ context 'when print_to_stderr option is true' do
375
+ let(:print_to_stderr) { true }
376
+
377
+ it 'outputs to stderr instead of stdout' do
378
+ expect(STDERR).to receive(:puts).with(default_output)
379
+
380
+ subject
381
+ end
382
+ end
383
+ end
239
384
 
240
- expect(Utils).to receive(:puts).with(output)
385
+ describe 'with ABS service' do
386
+ let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'abs') }
387
+
388
+ let(:hostname) { '1597952189390' }
389
+ let(:fqdn) { 'example-noun.delivery.mycompany.net' }
390
+ let(:fqdn_hostname) {'example-noun'}
391
+ let(:template) { 'ubuntu-1604-x86_64' }
392
+
393
+ # This seems to be the miminal stub response from ABS for the current output
394
+ let(:response_body) do
395
+ {
396
+ hostname => {
397
+ 'state' => 'allocated',
398
+ 'allocated_resources' => [
399
+ {
400
+ 'hostname' => fqdn,
401
+ 'type' => template,
402
+ 'engine' => 'vmpooler',
403
+ },
404
+ ],
405
+ 'request' => {
406
+ 'job' => {
407
+ 'id' => hostname,
408
+ }
409
+ },
410
+ }
411
+ }
412
+ end
413
+
414
+ # The vmpooler response contains metadata that is printed
415
+ let(:domain) { 'delivery.mycompany.net' }
416
+ let(:response_body_vmpooler) do
417
+ {
418
+ fqdn_hostname => {
419
+ 'template' => template,
420
+ 'lifetime' => 48,
421
+ 'running' => 7.67,
422
+ 'state' => 'running',
423
+ 'tags' => {
424
+ 'user' => 'bob',
425
+ 'role' => 'agent',
426
+ },
427
+ 'ip' => '127.0.0.1',
428
+ 'domain' => domain,
429
+ }
430
+ }
431
+ end
432
+
433
+ before(:each) do
434
+ allow(Utils).to receive(:get_vmpooler_service_config).and_return({
435
+ 'url' => 'http://vmpooler.example.com',
436
+ 'token' => 'krypto-knight'
437
+ })
438
+ allow(service).to receive(:query)
439
+ .with(anything, fqdn_hostname)
440
+ .and_return(response_body_vmpooler)
441
+ end
442
+
443
+ let(:default_output_first_line) { "- [JobID:#{hostname}] <allocated>" }
444
+ let(:default_output_second_line) { " - #{fqdn} (#{template}, 7.67/48 hours, user: bob, role: agent)" }
445
+
446
+ it 'prints output with job id, host, and template' do
447
+ expect(STDOUT).to receive(:puts).with(default_output_first_line)
448
+ expect(STDOUT).to receive(:puts).with(default_output_second_line)
449
+
450
+ subject
451
+ end
452
+
453
+ context 'when print_to_stderr option is true' do
454
+ let(:print_to_stderr) { true }
455
+
456
+ it 'outputs to stderr instead of stdout' do
457
+ expect(STDERR).to receive(:puts).with(default_output_first_line)
458
+ expect(STDERR).to receive(:puts).with(default_output_second_line)
459
+
460
+ subject
461
+ end
462
+ end
463
+ end
241
464
 
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)
465
+ describe 'with ABS service returning vmpooler and nspooler resources' do
466
+ let(:service) { Service.new(MockOptions.new, 'url' => url, 'type' => 'abs') }
467
+
468
+ let(:hostname) { '1597952189390' }
469
+ let(:fqdn) { 'this-noun.delivery.mycompany.net' }
470
+ let(:fqdn_ns) { 'that-noun.delivery.mycompany.net' }
471
+ let(:fqdn_hostname) {'this-noun'}
472
+ let(:fqdn_ns_hostname) {'that-noun'}
473
+ let(:template) { 'ubuntu-1604-x86_64' }
474
+ let(:template_ns) { 'solaris-10-sparc' }
475
+
476
+ # This seems to be the miminal stub response from ABS for the current output
477
+ let(:response_body) do
478
+ {
479
+ hostname => {
480
+ 'state' => 'allocated',
481
+ 'allocated_resources' => [
482
+ {
483
+ 'hostname' => fqdn,
484
+ 'type' => template,
485
+ 'engine' => 'vmpooler',
486
+ },
487
+ {
488
+ 'hostname' => fqdn_ns,
489
+ 'type' => template_ns,
490
+ 'engine' => 'nspooler',
491
+ },
492
+ ],
493
+ 'request' => {
494
+ 'job' => {
495
+ 'id' => hostname,
496
+ }
497
+ },
498
+ }
499
+ }
500
+ end
501
+
502
+ # The vmpooler response contains metadata that is printed
503
+ let(:domain) { 'delivery.mycompany.net' }
504
+ let(:response_body_vmpooler) do
505
+ {
506
+ fqdn_hostname => {
507
+ 'template' => template,
508
+ 'lifetime' => 48,
509
+ 'running' => 7.67,
510
+ 'state' => 'running',
511
+ 'tags' => {
512
+ 'user' => 'bob',
513
+ 'role' => 'agent',
514
+ },
515
+ 'ip' => '127.0.0.1',
516
+ 'domain' => domain,
517
+ }
518
+ }
519
+ end
520
+
521
+ before(:each) do
522
+ allow(Utils).to receive(:get_vmpooler_service_config).and_return({
523
+ 'url' => 'http://vmpooler.example.com',
524
+ 'token' => 'krypto-knight'
525
+ })
526
+ allow(service).to receive(:query)
527
+ .with(anything, fqdn_hostname)
528
+ .and_return(response_body_vmpooler)
529
+ end
530
+
531
+ let(:default_output_first_line) { "- [JobID:#{hostname}] <allocated>" }
532
+ let(:default_output_second_line) { " - #{fqdn} (#{template}, 7.67/48 hours, user: bob, role: agent)" }
533
+ let(:default_output_third_line) { " - #{fqdn_ns} (#{template_ns})" }
534
+
535
+ it 'prints output with job id, host, and template' do
536
+ expect(STDOUT).to receive(:puts).with(default_output_first_line)
537
+ expect(STDOUT).to receive(:puts).with(default_output_second_line)
538
+ expect(STDOUT).to receive(:puts).with(default_output_third_line)
539
+
540
+ subject
541
+ end
542
+
543
+ context 'when print_to_stderr option is true' do
544
+ let(:print_to_stderr) { true }
545
+
546
+ it 'outputs to stderr instead of stdout' do
547
+ expect(STDERR).to receive(:puts).with(default_output_first_line)
548
+ expect(STDERR).to receive(:puts).with(default_output_second_line)
549
+ expect(STDERR).to receive(:puts).with(default_output_third_line)
550
+
551
+ subject
552
+ end
553
+ end
554
+ end
555
+ end
246
556
 
247
- Utils.pretty_print_hosts(nil, service, hostname)
557
+ describe '#get_vmpooler_service_config' do
558
+ let(:Conf) { double }
559
+ it 'returns an error if the vmpooler_fallback is not setup' do
560
+ config = {
561
+ 'user' => 'foo',
562
+ 'services' => {
563
+ 'myabs' => {
564
+ 'url' => 'http://abs.com',
565
+ 'token' => 'krypto-night',
566
+ 'type' => 'abs'
567
+ }
568
+ }
569
+ }
570
+ allow(Conf).to receive(:read_config).and_return(config)
571
+ expect{Utils.get_vmpooler_service_config(config['services']['myabs']['vmpooler_fallback'])}.to raise_error(ArgumentError)
572
+ end
573
+ it 'returns an error if the vmpooler_fallback is setup but cannot be found' do
574
+ config = {
575
+ 'user' => 'foo',
576
+ 'services' => {
577
+ 'myabs' => {
578
+ 'url' => 'http://abs.com',
579
+ 'token' => 'krypto-night',
580
+ 'type' => 'abs',
581
+ 'vmpooler_fallback' => 'myvmpooler'
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, /myvmpooler/)
587
+ end
588
+ it 'returns the vmpooler_fallback config' 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
+ 'myvmpooler' => {
599
+ 'url' => 'http://vmpooler.com',
600
+ 'token' => 'krypto-knight'
601
+ }
602
+ }
603
+ }
604
+ allow(Conf).to receive(:read_config).and_return(config)
605
+ expect(Utils.get_vmpooler_service_config(config['services']['myabs']['vmpooler_fallback'])).to include({
606
+ 'url' => 'http://vmpooler.com',
607
+ 'token' => 'krypto-knight',
608
+ 'user' => 'foo',
609
+ 'type' => 'vmpooler'
610
+ })
248
611
  end
249
612
  end
250
613
  end