Skip to content

Commit beb3aa3

Browse files
committed
Adding command to get vms from abs
1 parent 9b80b6b commit beb3aa3

10 files changed

+112
-64
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ $ floaty --help
5353
Grabbing a token for authenticated pooler requests:
5454

5555
```
56-
floaty token get --user username --url https://vmpooler.example.net/api/v1
56+
floaty token get --user username --url https://vmpooler.example.net/api/v1 --api (vmpooler|abs)
5757
```
5858

5959
This command will then ask you to log in. If successful, it will return a token that you can save either in a dotfile or use with other cli commands.
@@ -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

+60-12
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,8 +32,6 @@ 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

@@ -42,23 +41,72 @@ def self.list_active(verbose, url, token)
4241
status['reserved_hosts'] || []
4342
end
4443

45-
def self.retrieve(verbose, os_type, token, url)
44+
# Retrieve an OS from ABS.
45+
def self.retrieve(verbose, os_types, token, url, user)
46+
#
47+
# Contents of post must be:j
48+
#
49+
# {
50+
# "resources": {
51+
# "centos-7-i386": 1,
52+
# "ubuntu-1404-x86_64": 2
53+
# },
54+
# "job": {
55+
# "id": "12345",
56+
# "tags": {
57+
# "user": "jenkins",
58+
# "jenkins_build_url": "https://jenkins/job/platform_puppet_intn-van-sys_master"
59+
# }
60+
# }
61+
# }
62+
4663
conn = Http.get_conn(verbose, url)
4764
conn.headers['X-AUTH-TOKEN'] = token if token
4865

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?
66+
saved_job_id = Time.now.to_i
5167

52-
response = conn.post "host/#{os_string}"
68+
reqObj = {
69+
resources: os_types,
70+
job: {
71+
id: Time.now.to_i,
72+
tags: {
73+
user: user,
74+
url_string: "floaty://#{user}/#{Time.now.to_i}"
75+
}
76+
}
77+
}
5378

54-
res_body = JSON.parse(response.body)
79+
# os_string = os_type.map { |os, num| Array(os) * num }.flatten.join('+')
80+
# raise MissingParamError, 'No operating systems provided to obtain.' if os_string.empty?
81+
response = conn.post "api/v2/request", reqObj.to_json
5582

56-
if res_body['ok']
57-
res_body
58-
elsif response.status == 401
83+
i = 0
84+
retries = 10
85+
86+
if response.status == 401
5987
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}"
88+
end
89+
90+
91+
while true
92+
queue_info_response = conn.get "/status/queue/info/#{saved_job_id}"
93+
queue_info = JSON.parse(queue_info_response.body)
94+
95+
response = conn.post "request", reqObj.to_json
96+
i = i.to_i + 1
97+
98+
break if i > retries
99+
100+
if response.body.length > 0
101+
res_body = JSON.parse(response.body)
102+
103+
puts "Returning #{res_body.length} vms: "
104+
puts res_body
105+
break
106+
end
107+
108+
puts "Waiting 10 seconds to check if ABS request has been filled. Queue Position: #{queue_info["queue_place"]}... (x#{i})"
109+
sleep(10)
62110
end
63111
end
64112

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)

spec/vmfloaty/abs/auth_spec.rb

+12-12
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
@@ -15,17 +15,17 @@
1515
end
1616

1717
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' })
18+
stub_request(:post, "#{@abs_url}/token")
19+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'Basic Zmlyc3QubGFzdDpwYXNzd29yZA==', 'Content-Length'=>'0'})
2020
.to_return(:status => 200, :body => @get_token_response, :headers => {})
2121

2222
token = Auth.get_token(false, @abs_url, 'first.last', 'password')
2323
expect(token).to eq @token
2424
end
2525

2626
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' })
27+
stub_request(:post, "#{@abs_url}/token")
28+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'Basic Zmlyc3QubGFzdDpwYXNzd29yZA==', 'Content-Length'=>'0'})
2929
.to_return(:status => 500, :body => '{"ok":false}', :headers => {})
3030

3131
expect { Auth.get_token(false, @abs_url, 'first.last', 'password') }.to raise_error(TokenError)
@@ -39,16 +39,16 @@
3939
end
4040

4141
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 => {})
42+
stub_request(:delete, "#{@abs_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
43+
.with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'Basic Zmlyc3QubGFzdDpwYXNzd29yZA=='})
44+
.to_return(:status => 200, :body => @delete_token_response, :headers => {})
4545

4646
expect(Auth.delete_token(false, @abs_url, 'first.last', 'password', @token)).to eq JSON.parse(@delete_token_response)
4747
end
4848

4949
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' })
50+
stub_request(:delete, "#{@abs_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
51+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3'})
5252
.to_return(:status => 500, :body => '{"ok":false}', :headers => {})
5353

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

6868
it 'checks the status of a token' do
6969
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' })
70+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3'})
7171
.to_return(:status => 200, :body => @token_status_response, :headers => {})
7272

7373
expect(Auth.token_status(false, @abs_url, @token)).to eq JSON.parse(@token_status_response)
7474
end
7575

7676
it 'raises a token error if something goes wrong' do
7777
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' })
78+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3'})
7979
.to_return(:status => 500, :body => '{"ok":false}', :headers => {})
8080

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

spec/vmfloaty/auth_spec.rb

+10-10
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@
1515
end
1616

1717
it 'returns a token from vmpooler' do
18-
stub_request(:post, 'https://first.last:password@vmpooler.example.com/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' })
18+
stub_request(:post, 'https://vmpooler.example.com/token')
19+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0' })
2020
.to_return(:status => 200, :body => @get_token_response, :headers => {})
2121

2222
token = Auth.get_token(false, @vmpooler_url, 'first.last', 'password')
2323
expect(token).to eq @token
2424
end
2525

2626
it 'raises a token error if something goes wrong' do
27-
stub_request(:post, 'https://first.last:password@vmpooler.example.com/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' })
27+
stub_request(:post, 'https://vmpooler.example.com/token')
28+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Length' => '0' })
2929
.to_return(:status => 500, :body => '{"ok":false}', :headers => {})
3030

3131
expect { Auth.get_token(false, @vmpooler_url, 'first.last', 'password') }.to raise_error(TokenError)
@@ -39,16 +39,16 @@
3939
end
4040

4141
it 'deletes the specified token' do
42-
stub_request(:delete, 'https://first.last:password@vmpooler.example.com/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' })
42+
stub_request(:delete, 'https://vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
43+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' })
4444
.to_return(:status => 200, :body => @delete_token_response, :headers => {})
4545

4646
expect(Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token)).to eq JSON.parse(@delete_token_response)
4747
end
4848

4949
it 'raises a token error if something goes wrong' do
50-
stub_request(:delete, 'https://first.last:password@vmpooler.example.com/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' })
50+
stub_request(:delete, 'https://vmpooler.example.com/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
51+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' })
5252
.to_return(:status => 500, :body => '{"ok":false}', :headers => {})
5353

5454
expect { Auth.delete_token(false, @vmpooler_url, 'first.last', 'password', @token) }.to raise_error(TokenError)
@@ -67,15 +67,15 @@
6767

6868
it 'checks the status of a token' do
6969
stub_request(:get, "#{@vmpooler_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' })
70+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' })
7171
.to_return(:status => 200, :body => @token_status_response, :headers => {})
7272

7373
expect(Auth.token_status(false, @vmpooler_url, @token)).to eq JSON.parse(@token_status_response)
7474
end
7575

7676
it 'raises a token error if something goes wrong' do
7777
stub_request(:get, "#{@vmpooler_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' })
78+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' })
7979
.to_return(:status => 500, :body => '{"ok":false}', :headers => {})
8080

8181
expect { Auth.token_status(false, @vmpooler_url, @token) }.to raise_error(TokenError)

spec/vmfloaty/nonstandard_pooler_spec.rb

+6-8
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,11 @@
1111
@post_request_headers = {
1212
'Accept' => '*/*',
1313
'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
14-
'User-Agent' => 'Faraday v0.9.2',
1514
'X-Auth-Token' => 'token-value',
1615
}
1716
@get_request_headers = {
1817
'Accept' => '*/*',
1918
'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
20-
'User-Agent' => 'Faraday v0.9.2',
2119
'X-Auth-Token' => 'token-value',
2220
}
2321
@get_request_headers_notoken = @get_request_headers.tap do |headers|
@@ -137,7 +135,7 @@
137135
.to_return(:status => 401, :body => '{"ok":false,"reason": "token: token-value does not exist"}', :headers => {})
138136

139137
vm_hash = { 'solaris-11-sparc' => 1 }
140-
expect { NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url) }.to raise_error(AuthError)
138+
expect { NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, "first.last") }.to raise_error(AuthError)
141139
end
142140

143141
it 'retrieves a single vm with a token' do
@@ -146,7 +144,7 @@
146144
.to_return(:status => 200, :body => @retrieve_response_body_single, :headers => {})
147145

148146
vm_hash = { 'solaris-11-sparc' => 1 }
149-
vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url)
147+
vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, "first.last")
150148
expect(vm_req).to be_an_instance_of Hash
151149
expect(vm_req['ok']).to equal true
152150
expect(vm_req['solaris-11-sparc']['hostname']).to eq 'sol11-4.delivery.puppetlabs.net'
@@ -158,7 +156,7 @@
158156
.to_return(:status => 200, :body => @retrieve_response_body_many, :headers => {})
159157

160158
vm_hash = { 'aix-7.1-power' => 1, 'solaris-10-sparc' => 2 }
161-
vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url)
159+
vm_req = NonstandardPooler.retrieve(false, vm_hash, 'token-value', @nspooler_url, "first.last")
162160
expect(vm_req).to be_an_instance_of Hash
163161
expect(vm_req['ok']).to equal true
164162
expect(vm_req['solaris-10-sparc']['hostname']).to be_an_instance_of Array
@@ -175,18 +173,18 @@
175173
it 'raises an error if the user tries to modify an unsupported attribute' do
176174
stub_request(:put, 'https://nspooler.example.com/host/myfakehost')
177175
.with(:body => { '{}' => true },
178-
:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Faraday v0.9.2', 'X-Auth-Token' => 'token-value' })
176+
:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type' => 'application/x-www-form-urlencoded', 'X-Auth-Token' => 'token-value' })
179177
.to_return(:status => 200, :body => '', :headers => {})
180178
details = { :lifetime => 12 }
181179
expect { NonstandardPooler.modify(false, @nspooler_url, 'myfakehost', 'token-value', details) }
182180
.to raise_error(ModifyError)
183181
end
184182

185183
it 'modifies the reason of a vm' do
186-
modify_request_body = { '{"reserved_for_reason":"testing"}' => true }
184+
modify_request_body = { '{"reserved_for_reason":"testing"}' => nil }
187185
stub_request(:put, "#{@nspooler_url}/host/myfakehost")
188186
.with(:body => modify_request_body,
189-
:headers => @post_request_headers)
187+
:headers => @post_request_headers.merge({'Content-Type'=>'application/x-www-form-urlencoded'}))
190188
.to_return(:status => 200, :body => '{"ok": true}', :headers => {})
191189

192190
modify_hash = { :reason => 'testing' }

0 commit comments

Comments
 (0)