Skip to content

Commit 4bf7ee9

Browse files
committed
Rebasing fixed tests
1 parent de7d0fd commit 4bf7ee9

File tree

10 files changed

+133
-84
lines changed

10 files changed

+133
-84
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ floaty get centos-7-x86_64=2 debian-7-x86_64 windows-10=3 --token mytokenstring
6666

6767
### vmfloaty dotfile
6868

69-
If you do not wish to continuely specify various config options with the cli, you can have a dotfile in your home directory for some defaults. For example:
69+
If you do not wish to continually specify various config options with the cli, you can have a dotfile in your home directory for some defaults. For example:
7070

7171
#### Basic configuration
7272

@@ -135,6 +135,7 @@ services:
135135
url: 'https://abs.example.net/api/v2'
136136
token: 'abs-tokenstring'
137137
type: 'abs' # <-- 'type' is necessary for any non-vmpooler service
138+
138139
```
139140

140141
With this configuration, you could list available OS types from nspooler like this:

lib/vmfloaty.rb

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ def run
8484
c.option '--url STRING', String, 'URL of pooler service'
8585
c.action do |args, options|
8686
verbose = options.verbose || config['verbose']
87+
8788
service = Service.new(options, config)
8889
filter = args[0]
8990

lib/vmfloaty/abs.rb

+68-58
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def self.list(verbose, url, os_filter = nil)
1313
os_list = []
1414

1515
response = conn.get 'status/platforms/vmpooler'
16+
1617
response_body = JSON.parse(response.body)
1718
os_list << "*** VMPOOLER Pools ***"
1819
os_list = os_list + JSON.parse(response_body["vmpooler_platforms"])
@@ -31,89 +32,98 @@ def self.list(verbose, url, os_filter = nil)
3132

3233
os_list.delete 'ok'
3334

34-
puts os_list
35-
3635
os_filter ? os_list.select { |i| i[/#{os_filter}/] } : os_list
3736
end
3837

39-
# List active VMs from ABS
40-
def self.list_active(verbose, url, token)
41-
status = Auth.token_status(verbose, url, token)
42-
status['reserved_hosts'] || []
43-
end
38+
# Retrieve an OS from ABS.
39+
def self.retrieve(verbose, os_types, token, url, user)
40+
#
41+
# Contents of post must be:j
42+
#
43+
# {
44+
# "resources": {
45+
# "centos-7-i386": 1,
46+
# "ubuntu-1404-x86_64": 2
47+
# },
48+
# "job": {
49+
# "id": "12345",
50+
# "tags": {
51+
# "user": "jenkins",
52+
# "jenkins_build_url": "https://jenkins/job/platform_puppet_intn-van-sys_master"
53+
# }
54+
# }
55+
# }
4456

45-
def self.retrieve(verbose, os_type, token, url)
4657
conn = Http.get_conn(verbose, url)
4758
conn.headers['X-AUTH-TOKEN'] = token if token
4859

49-
os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+')
50-
raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty?
51-
52-
response = conn.post "host/#{os_string}"
53-
54-
res_body = JSON.parse(response.body)
60+
saved_job_id = Time.now.to_i
5561

56-
if res_body['ok']
57-
res_body
58-
elsif response.status == 401
59-
raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}"
60-
else
61-
raise "HTTP #{response.status}: Failed to obtain VMs from the pooler at #{url}/host/#{os_string}. #{res_body}"
62-
end
63-
end
62+
reqObj = {
63+
resources: os_types,
64+
job: {
65+
id: saved_job_id,
66+
tags: {
67+
user: user,
68+
url_string: "floaty://#{user}/#{saved_job_id}"
69+
}
70+
}
71+
}
6472

65-
def self.modify(verbose, url, hostname, token, modify_hash)
66-
raise TokenError, 'Token provided was nil; Request cannot be made to modify VM' if token.nil?
73+
# os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+')
74+
# raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty?
75+
puts "Requesting VMs with job_id: #{saved_job_id}. Will retry for up to an hour."
76+
response = conn.post "api/v2/request", reqObj.to_json
6777

68-
modify_hash.each do |key, _value|
69-
raise ModifyError, "Configured service type does not support modification of #{key}" unless %i[reason reserved_for_reason].include? key
70-
end
78+
i = 0
79+
retries = 360
7180

72-
if modify_hash[:reason]
73-
# "reason" is easier to type than "reserved_for_reason", but nspooler needs the latter
74-
modify_hash[:reserved_for_reason] = modify_hash.delete :reason
81+
if response.status == 401
82+
raise AuthError, "HTTP #{response.status}: The token provided could not authenticate to the pooler.\n#{res_body}"
7583
end
7684

77-
conn = Http.get_conn(verbose, url)
78-
conn.headers['X-AUTH-TOKEN'] = token
85+
(1..retries).each do |i|
86+
queue_place, res_body = check_queue(conn, saved_job_id, reqObj)
87+
if res_body
88+
return translated(res_body)
89+
end
7990

80-
response = conn.put do |req|
81-
req.url "host/#{hostname}"
82-
req.body = modify_hash.to_json
91+
puts "Waiting 10 seconds to check if ABS request has been filled. Queue Position: #{queue_place}... (x#{i})"
92+
sleep(10)
8393
end
84-
85-
response.body.empty? ? {} : JSON.parse(response.body)
94+
return nil
8695
end
8796

88-
def self.disk(_verbose, _url, _hostname, _token, _disk)
89-
raise ModifyError, 'Configured service type does not support modification of disk space'
90-
end
91-
92-
def self.snapshot(_verbose, _url, _hostname, _token)
93-
raise ModifyError, 'Configured service type does not support snapshots'
94-
end
97+
#
98+
# We should fix the ABS API to be more like the vmpooler or nspooler api, but for now
99+
#
100+
def self.translated res_body
101+
vmpooler_formatted_body = Hash.new
102+
103+
res_body.each do |host|
104+
if vmpooler_formatted_body[host["type"]] && vmpooler_formatted_body[host["type"]]["hostname"].class == Array
105+
vmpooler_formatted_body[host["type"]]["hostname"] << host["hostname"]
106+
else
107+
vmpooler_formatted_body[host["type"]] = { "hostname" => [host["hostname"]] }
108+
end
109+
end
110+
vmpooler_formatted_body["ok"] = true
95111

96-
def self.revert(_verbose, _url, _hostname, _token, _snapshot_sha)
97-
raise ModifyError, 'Configured service type does not support snapshots'
112+
return vmpooler_formatted_body
98113
end
99114

100-
def self.delete(verbose, url, hosts, token)
101-
raise TokenError, 'Token provided was nil; Request cannot be made to delete VM' if token.nil?
115+
def self.check_queue conn, job_id, reqObj
116+
queue_info_response = conn.get "/status/queue/info/#{job_id}"
117+
queue_info = JSON.parse(queue_info_response.body)
102118

103-
conn = Http.get_conn(verbose, url)
119+
response = conn.post "api/v2/request", reqObj.to_json
104120

105-
conn.headers['X-AUTH-TOKEN'] = token if token
106121

107-
response_body = {}
108-
109-
hosts = hosts.split(',') unless hosts.is_a? Array
110-
hosts.each do |host|
111-
response = conn.delete "host/#{host}"
122+
if response.body.length > 0
112123
res_body = JSON.parse(response.body)
113-
response_body[host] = res_body
124+
return queue_info["queue_place"], res_body
114125
end
115-
116-
response_body
126+
return queue_info["queue_place"], nil
117127
end
118128

119129
def self.status(verbose, url)

lib/vmfloaty/nonstandard_pooler.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def self.list_active(verbose, url, token)
2222
status['reserved_hosts'] || []
2323
end
2424

25-
def self.retrieve(verbose, os_type, token, url)
25+
def self.retrieve(verbose, os_type, token, url, user)
2626
conn = Http.get_conn(verbose, url)
2727
conn.headers['X-AUTH-TOKEN'] = token if token
2828

lib/vmfloaty/service.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def type
3636

3737
def user
3838
unless @config['user']
39-
puts 'Enter your pooler service username:'
39+
puts "Enter your #{@config["url"]} service username:"
4040
@config['user'] = STDIN.gets.chomp
4141
end
4242
@config['user']
@@ -58,7 +58,7 @@ def get_new_token(verbose)
5858

5959
def delete_token(verbose, token_value = @config['token'])
6060
username = user
61-
pass = Commander::UI.password 'Enter your pooler service password:', '*'
61+
pass = Commander::UI.password "Enter your #{@config["url"]} service password:", '*'
6262
Auth.delete_token(verbose, url, username, pass, token_value)
6363
end
6464

@@ -78,7 +78,7 @@ def list_active(verbose)
7878
def retrieve(verbose, os_types, use_token = true)
7979
puts 'Requesting a vm without a token...' unless use_token
8080
token_value = use_token ? token : nil
81-
@service_object.retrieve verbose, os_types, token_value, url
81+
@service_object.retrieve verbose, os_types, token_value, url, user
8282
end
8383

8484
def ssh(verbose, host_os, use_token = true)

lib/vmfloaty/utils.rb

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ def self.standardize_hostnames(response_body)
3131
# }
3232
# }
3333

34+
# abs pooler response body example when `floaty get` arguments are `{"hostname"=>"thin-soutane.delivery.puppetlabs.net", "type"=>"centos-7.2-tmpfs-x86_64", "engine"=>"vmpooler"}`
35+
3436
raise ArgumentError, "Bad GET response passed to format_hosts: #{response_body.to_json}" unless response_body.delete('ok')
3537

3638
# vmpooler reports the domain separately from the hostname

spec/vmfloaty/abs/auth_spec.rb

+9-13
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
describe Pooler do
77
before :each do
8-
@abs_url = 'https://abs.example.com'
8+
@abs_url = 'https://abs.example.com/api/v2'
99
end
1010

1111
describe '#get_token' do
@@ -14,18 +14,16 @@
1414
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
1515
end
1616

17-
it 'returns a token from vmpooler' do
18-
stub_request(:post, 'https://first.last:[email protected]/api/v2/token')
19-
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' })
17+
it 'returns a token from abs' do
18+
stub_request(:post, "https://first.last:[email protected]/api/v2/token")
2019
.to_return(:status => 200, :body => @get_token_response, :headers => {})
2120

2221
token = Auth.get_token(false, @abs_url, 'first.last', 'password')
2322
expect(token).to eq @token
2423
end
2524

2625
it 'raises a token error if something goes wrong' do
27-
stub_request(:post, 'https://first.last:[email protected]/api/v2/token')
28-
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0', 'User-Agent' => 'Faraday v0.9.2' })
26+
stub_request(:post, "https://first.last:[email protected]/api/v2/token")
2927
.to_return(:status => 500, :body => '{"ok":false}', :headers => {})
3028

3129
expect { Auth.get_token(false, @abs_url, 'first.last', 'password') }.to raise_error(TokenError)
@@ -39,16 +37,14 @@
3937
end
4038

4139
it 'deletes the specified token' do
42-
stub_request(:delete, 'https://first.last:[email protected]/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
43-
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' })
44-
.to_return(:status => 200, :body => @delete_token_response, :headers => {})
40+
stub_request(:delete, "https://first.last:[email protected]/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
41+
.to_return(:status => 200, :body => @delete_token_response, :headers => {})
4542

4643
expect(Auth.delete_token(false, @abs_url, 'first.last', 'password', @token)).to eq JSON.parse(@delete_token_response)
4744
end
4845

4946
it 'raises a token error if something goes wrong' do
50-
stub_request(:delete, 'https://first.last:[email protected]/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
51-
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' })
47+
stub_request(:delete, "https://first.last:[email protected]/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
5248
.to_return(:status => 500, :body => '{"ok":false}', :headers => {})
5349

5450
expect { Auth.delete_token(false, @abs_url, 'first.last', 'password', @token) }.to raise_error(TokenError)
@@ -67,15 +63,15 @@
6763

6864
it 'checks the status of a token' do
6965
stub_request(:get, "#{@abs_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
70-
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' })
66+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3'})
7167
.to_return(:status => 200, :body => @token_status_response, :headers => {})
7268

7369
expect(Auth.token_status(false, @abs_url, @token)).to eq JSON.parse(@token_status_response)
7470
end
7571

7672
it 'raises a token error if something goes wrong' do
7773
stub_request(:get, "#{@abs_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
78-
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent' => 'Faraday v0.9.2' })
74+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3'})
7975
.to_return(:status => 500, :body => '{"ok":false}', :headers => {})
8076

8177
expect { Auth.token_status(false, @abs_url, @token) }.to raise_error(TokenError)

spec/vmfloaty/abs_spec.rb

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
require 'vmfloaty/utils'
5+
require 'vmfloaty/errors'
6+
require 'vmfloaty/abs'
7+
8+
describe ABS do
9+
before :each do
10+
end
11+
12+
describe '#format' do
13+
it 'returns an hash formatted like a vmpooler return' do
14+
abs_formatted_response = [
15+
{"hostname" => "aaaaaaaaaaaaaaa.delivery.puppetlabs.net","type" => "centos-7.2-x86_64","engine" => "vmpooler"},
16+
{"hostname" => "aaaaaaaaaaaaaab.delivery.puppetlabs.net","type" => "centos-7.2-x86_64","engine" => "vmpooler"},
17+
{"hostname" => "aaaaaaaaaaaaaac.delivery.puppetlabs.net","type" => "ubuntu-7.2-x86_64","engine" => "vmpooler"}
18+
]
19+
20+
vmpooler_formatted_response = ABS.translated(abs_formatted_response)
21+
22+
vmpooler_formatted_compare = {
23+
"centos-7.2-x86_64" => Hash.new,
24+
"ubuntu-7.2-x86_64" => Hash.new
25+
}
26+
27+
vmpooler_formatted_compare["centos-7.2-x86_64"]["hostname"] = [ "aaaaaaaaaaaaaaa.delivery.puppetlabs.net", "aaaaaaaaaaaaaab.delivery.puppetlabs.net" ]
28+
vmpooler_formatted_compare["ubuntu-7.2-x86_64"]["hostname"] = ["aaaaaaaaaaaaaac.delivery.puppetlabs.net" ]
29+
30+
vmpooler_formatted_compare["ok"] = true
31+
32+
expect(vmpooler_formatted_response).to eq(vmpooler_formatted_compare)
33+
vmpooler_formatted_response.delete('ok')
34+
vmpooler_formatted_compare.delete('ok')
35+
expect(vmpooler_formatted_response).to eq(vmpooler_formatted_compare)
36+
37+
end
38+
end
39+
end

spec/vmfloaty/nonstandard_pooler_spec.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@
125125
.to_return(:status => 401, :body => '{"ok":false,"reason": "token: token-value does not exist"}', :headers => {})
126126

127127
vm_hash = { 'solaris-11-sparc' => 1 }
128-
expect { NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url) }.to raise_error(AuthError)
128+
expect { NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, "first.last") }.to raise_error(AuthError)
129129
end
130130

131131
it 'retrieves a single vm with a token' do
@@ -134,7 +134,7 @@
134134
.to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {})
135135

136136
vm_hash = { 'solaris-11-sparc' => 1 }
137-
vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url)
137+
vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, "first.last")
138138
expect(vm_req).to be_an_instance_of Hash
139139
expect(vm_req['ok']).to equal true
140140
expect(vm_req['solaris-11-sparc']['hostname']).to eq 'sol11-4.delivery.puppetlabs.net'
@@ -146,7 +146,7 @@
146146
.to_return(:status => 200, :body => @retrieve_response_body_many, :headers => {})
147147

148148
vm_hash = { 'aix-7.1-power' => 1, 'solaris-10-sparc' => 2 }
149-
vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url)
149+
vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, "first.last")
150150
expect(vm_req).to be_an_instance_of Hash
151151
expect(vm_req['ok']).to equal true
152152
expect(vm_req['solaris-10-sparc']['hostname']).to be_an_instance_of Array

0 commit comments

Comments
 (0)