vmfloaty 0.8.1 → 0.10.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 +5 -5
- data/README.md +96 -55
- data/bin/floaty +2 -1
- data/lib/vmfloaty.rb +60 -53
- data/lib/vmfloaty/abs.rb +318 -0
- data/lib/vmfloaty/auth.rb +14 -22
- data/lib/vmfloaty/conf.rb +3 -2
- data/lib/vmfloaty/errors.rb +6 -4
- data/lib/vmfloaty/http.rb +14 -25
- data/lib/vmfloaty/nonstandard_pooler.rb +15 -31
- data/lib/vmfloaty/pooler.rb +64 -55
- data/lib/vmfloaty/service.rb +25 -17
- data/lib/vmfloaty/ssh.rb +25 -25
- data/lib/vmfloaty/utils.rb +103 -97
- data/lib/vmfloaty/version.rb +3 -1
- data/spec/spec_helper.rb +13 -0
- data/spec/vmfloaty/abs/auth_spec.rb +84 -0
- data/spec/vmfloaty/abs_spec.rb +126 -0
- data/spec/vmfloaty/auth_spec.rb +39 -43
- data/spec/vmfloaty/nonstandard_pooler_spec.rb +132 -146
- data/spec/vmfloaty/pooler_spec.rb +121 -101
- data/spec/vmfloaty/service_spec.rb +17 -17
- data/spec/vmfloaty/ssh_spec.rb +49 -0
- data/spec/vmfloaty/utils_spec.rb +123 -98
- data/spec/vmfloaty/vmfloaty_services_spec.rb +39 -0
- metadata +38 -22
data/lib/vmfloaty/utils.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'vmfloaty/abs'
|
2
4
|
require 'vmfloaty/nonstandard_pooler'
|
5
|
+
require 'vmfloaty/pooler'
|
3
6
|
|
4
7
|
class Utils
|
5
8
|
# TODO: Takes the json response body from an HTTP GET
|
6
9
|
# request and "pretty prints" it
|
7
|
-
def self.
|
10
|
+
def self.standardize_hostnames(response_body)
|
8
11
|
# vmpooler response body example when `floaty get` arguments are `ubuntu-1610-x86_64=2 centos-7-x86_64`:
|
9
12
|
# {
|
10
13
|
# "ok": true,
|
@@ -28,35 +31,35 @@ class Utils
|
|
28
31
|
# }
|
29
32
|
# }
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
# abs pooler response body example when `floaty get` arguments are :
|
35
|
+
# {
|
36
|
+
# "hostname"=>"thin-soutane.delivery.puppetlabs.net",
|
37
|
+
# "type"=>"centos-7.2-tmpfs-x86_64",
|
38
|
+
# "engine"=>"vmpooler"
|
39
|
+
# }
|
34
40
|
|
35
|
-
|
41
|
+
raise ArgumentError, "Bad GET response passed to format_hosts: #{response_body.to_json}" unless response_body.delete('ok')
|
36
42
|
|
37
43
|
# vmpooler reports the domain separately from the hostname
|
38
44
|
domain = response_body.delete('domain')
|
39
45
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
else
|
50
|
-
response_body.each do |os, hosts|
|
51
|
-
if hosts['hostname'].kind_of?(Array)
|
52
|
-
hosts['hostname'].map!{ |host| hostnames << host + " (#{os})" }
|
53
|
-
else
|
54
|
-
hostnames << hosts['hostname'] + " (#{os})"
|
55
|
-
end
|
56
|
-
end
|
46
|
+
result = {}
|
47
|
+
|
48
|
+
STDOUT.puts "response body is #{response_body}"
|
49
|
+
filtered_response_body = response_body.reject { |key, _| key == 'request_id' || key == 'ready' }
|
50
|
+
filtered_response_body.each do |os, value|
|
51
|
+
hostnames = Array(value['hostname'])
|
52
|
+
hostnames.map! { |host| "#{host}.#{domain}" } if domain
|
53
|
+
result[os] = hostnames
|
57
54
|
end
|
58
55
|
|
59
|
-
|
56
|
+
result
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.format_host_output(hosts)
|
60
|
+
hosts.flat_map do |os, names|
|
61
|
+
names.map { |name| "- #{name} (#{os})" }
|
62
|
+
end.join("\n")
|
60
63
|
end
|
61
64
|
|
62
65
|
def self.generate_os_hash(os_args)
|
@@ -70,13 +73,8 @@ class Utils
|
|
70
73
|
# ...]
|
71
74
|
os_types = {}
|
72
75
|
os_args.each do |arg|
|
73
|
-
os_arr = arg.split(
|
74
|
-
|
75
|
-
# assume they didn't specify an = sign if split returns 1 size
|
76
|
-
os_types[os_arr[0]] = 1
|
77
|
-
else
|
78
|
-
os_types[os_arr[0]] = os_arr[1].to_i
|
79
|
-
end
|
76
|
+
os_arr = arg.split('=')
|
77
|
+
os_types[os_arr[0]] = os_arr.size == 1 ? 1 : os_arr[1].to_i
|
80
78
|
end
|
81
79
|
os_types
|
82
80
|
end
|
@@ -89,26 +87,29 @@ class Utils
|
|
89
87
|
host_data = response[hostname]
|
90
88
|
|
91
89
|
case service.type
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
duration = "#{host_data['running']}/#{host_data['lifetime']} hours"
|
98
|
-
metadata = [host_data['template'], duration, *tag_pairs]
|
99
|
-
puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(", ")})"
|
100
|
-
when 'NonstandardPooler'
|
101
|
-
line = "- #{host_data['fqdn']} (#{host_data['os_triple']}"
|
102
|
-
line += ", #{host_data['hours_left_on_reservation']}h remaining"
|
103
|
-
unless host_data['reserved_for_reason'].empty?
|
104
|
-
line += ", reason: #{host_data['reserved_for_reason']}"
|
90
|
+
when 'ABS'
|
91
|
+
# For ABS, 'hostname' variable is the jobID
|
92
|
+
if host_data['state'] == 'allocated' || host_data['state'] == 'filled'
|
93
|
+
host_data['allocated_resources'].each do |vm_name, _i|
|
94
|
+
puts "- [JobID:#{host_data['request']['job']['id']}] #{vm_name['hostname']} (#{vm_name['type']}) <#{host_data['state']}>"
|
105
95
|
end
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
96
|
+
end
|
97
|
+
when 'Pooler'
|
98
|
+
tag_pairs = []
|
99
|
+
tag_pairs = host_data['tags'].map { |key, value| "#{key}: #{value}" } unless host_data['tags'].nil?
|
100
|
+
duration = "#{host_data['running']}/#{host_data['lifetime']} hours"
|
101
|
+
metadata = [host_data['template'], duration, *tag_pairs]
|
102
|
+
puts "- #{hostname}.#{host_data['domain']} (#{metadata.join(', ')})"
|
103
|
+
when 'NonstandardPooler'
|
104
|
+
line = "- #{host_data['fqdn']} (#{host_data['os_triple']}"
|
105
|
+
line += ", #{host_data['hours_left_on_reservation']}h remaining"
|
106
|
+
line += ", reason: #{host_data['reserved_for_reason']}" unless host_data['reserved_for_reason'].empty?
|
107
|
+
line += ')'
|
108
|
+
puts line
|
109
|
+
else
|
110
|
+
raise "Invalid service type #{service.type}"
|
110
111
|
end
|
111
|
-
rescue => e
|
112
|
+
rescue StandardError => e
|
112
113
|
STDERR.puts("Something went wrong while trying to gather information on #{hostname}:")
|
113
114
|
STDERR.puts(e)
|
114
115
|
end
|
@@ -119,45 +120,48 @@ class Utils
|
|
119
120
|
status_response = service.status(verbose)
|
120
121
|
|
121
122
|
case service.type
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
end
|
123
|
+
when 'Pooler'
|
124
|
+
message = status_response['status']['message']
|
125
|
+
pools = status_response['pools']
|
126
|
+
pools.select! { |_, pool| pool['ready'] < pool['max'] } unless verbose
|
127
|
+
|
128
|
+
width = pools.keys.map(&:length).max
|
129
|
+
pools.each do |name, pool|
|
130
|
+
begin
|
131
|
+
max = pool['max']
|
132
|
+
ready = pool['ready']
|
133
|
+
pending = pool['pending']
|
134
|
+
missing = max - ready - pending
|
135
|
+
char = 'o'
|
136
|
+
puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}"
|
137
|
+
rescue StandardError => e
|
138
|
+
puts "#{name.ljust(width)} #{e.red}"
|
139
139
|
end
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
140
|
+
end
|
141
|
+
puts message.colorize(status_response['status']['ok'] ? :default : :red)
|
142
|
+
when 'NonstandardPooler'
|
143
|
+
pools = status_response
|
144
|
+
pools.delete 'ok'
|
145
|
+
pools.select! { |_, pool| pool['available_hosts'] < pool['total_hosts'] } unless verbose
|
146
|
+
|
147
|
+
width = pools.keys.map(&:length).max
|
148
|
+
pools.each do |name, pool|
|
149
|
+
begin
|
150
|
+
max = pool['total_hosts']
|
151
|
+
ready = pool['available_hosts']
|
152
|
+
pending = pool['pending'] || 0 # not available for nspooler
|
153
|
+
missing = max - ready - pending
|
154
|
+
char = 'o'
|
155
|
+
puts "#{name.ljust(width)} #{(char * ready).green}#{(char * pending).yellow}#{(char * missing).red}"
|
156
|
+
rescue StandardError => e
|
157
|
+
puts "#{name.ljust(width)} #{e.red}"
|
158
158
|
end
|
159
|
-
|
160
|
-
|
159
|
+
end
|
160
|
+
when 'ABS'
|
161
|
+
puts 'ABS Not OK'.red unless status_response
|
162
|
+
puts 'ABS is OK'.green if status_response
|
163
|
+
else
|
164
|
+
raise "Invalid service type #{service.type}"
|
161
165
|
end
|
162
166
|
end
|
163
167
|
|
@@ -170,9 +174,12 @@ class Utils
|
|
170
174
|
end
|
171
175
|
|
172
176
|
def self.get_service_object(type = '')
|
173
|
-
nspooler_strings = [
|
177
|
+
nspooler_strings = %w[ns nspooler nonstandard nonstandard_pooler]
|
178
|
+
abs_strings = %w[abs alwaysbescheduling always_be_scheduling]
|
174
179
|
if nspooler_strings.include? type.downcase
|
175
180
|
NonstandardPooler
|
181
|
+
elsif abs_strings.include? type.downcase
|
182
|
+
ABS
|
176
183
|
else
|
177
184
|
Pooler
|
178
185
|
end
|
@@ -181,10 +188,10 @@ class Utils
|
|
181
188
|
def self.get_service_config(config, options)
|
182
189
|
# The top-level url, user, and token values in the config file are treated as defaults
|
183
190
|
service_config = {
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
191
|
+
'url' => config['url'],
|
192
|
+
'user' => config['user'],
|
193
|
+
'token' => config['token'],
|
194
|
+
'type' => config['type'] || 'vmpooler',
|
188
195
|
}
|
189
196
|
|
190
197
|
if config['services']
|
@@ -195,16 +202,15 @@ class Utils
|
|
195
202
|
service_config.merge! values
|
196
203
|
else
|
197
204
|
# If the user provided a service name at the command line, use that service if posible, or fail
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
raise ArgumentError, "Could not find a configured service named '#{options.service}' in ~/.vmfloaty.yml"
|
203
|
-
end
|
205
|
+
raise ArgumentError, "Could not find a configured service named '#{options.service}' in ~/.vmfloaty.yml" unless config['services'][options.service]
|
206
|
+
|
207
|
+
# If the service is configured but some values are missing, use the top-level defaults to fill them in
|
208
|
+
service_config.merge! config['services'][options.service]
|
204
209
|
end
|
205
210
|
end
|
206
211
|
|
207
212
|
# Prioritize an explicitly specified url, user, or token if the user provided one
|
213
|
+
service_config['priority'] = options.priority unless options.priority.nil?
|
208
214
|
service_config['url'] = options.url unless options.url.nil?
|
209
215
|
service_config['token'] = options.token unless options.token.nil?
|
210
216
|
service_config['user'] = options.user unless options.user.nil?
|
data/lib/vmfloaty/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'simplecov'
|
4
|
+
require 'coveralls'
|
5
|
+
|
6
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
|
7
|
+
SimpleCov::Formatter::HTMLFormatter,
|
8
|
+
Coveralls::SimpleCov::Formatter
|
9
|
+
])
|
10
|
+
SimpleCov.start do
|
11
|
+
add_filter %r{^/spec/}
|
12
|
+
end
|
13
|
+
|
1
14
|
require 'vmfloaty'
|
2
15
|
require 'webmock/rspec'
|
3
16
|
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require_relative '../../../lib/vmfloaty/auth'
|
5
|
+
|
6
|
+
describe Pooler do
|
7
|
+
before :each do
|
8
|
+
@abs_url = 'https://abs.example.com/api/v2'
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#get_token' do
|
12
|
+
before :each do
|
13
|
+
@get_token_response = '{"ok": true,"token":"utpg2i2xswor6h8ttjhu3d47z53yy47y"}'
|
14
|
+
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns a token from abs' do
|
18
|
+
stub_request(:post, 'https://first.last:password@abs.example.com/api/v2/token')
|
19
|
+
.to_return(:status => 200, :body => @get_token_response, :headers => {})
|
20
|
+
|
21
|
+
token = Auth.get_token(false, @abs_url, 'first.last', 'password')
|
22
|
+
expect(token).to eq @token
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'raises a token error if something goes wrong' do
|
26
|
+
stub_request(:post, 'https://first.last:password@abs.example.com/api/v2/token')
|
27
|
+
.to_return(:status => 500, :body => '{"ok":false}', :headers => {})
|
28
|
+
|
29
|
+
expect { Auth.get_token(false, @abs_url, 'first.last', 'password') }.to raise_error(TokenError)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#delete_token' do
|
34
|
+
before :each do
|
35
|
+
@delete_token_response = '{"ok":true}'
|
36
|
+
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'deletes the specified token' do
|
40
|
+
stub_request(:delete, 'https://first.last:password@abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
|
41
|
+
.to_return(:status => 200, :body => @delete_token_response, :headers => {})
|
42
|
+
|
43
|
+
expect(Auth.delete_token(false, @abs_url, 'first.last', 'password', @token)).to eq JSON.parse(@delete_token_response)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'raises a token error if something goes wrong' do
|
47
|
+
stub_request(:delete, 'https://first.last:password@abs.example.com/api/v2/token/utpg2i2xswor6h8ttjhu3d47z53yy47y')
|
48
|
+
.to_return(:status => 500, :body => '{"ok":false}', :headers => {})
|
49
|
+
|
50
|
+
expect { Auth.delete_token(false, @abs_url, 'first.last', 'password', @token) }.to raise_error(TokenError)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'raises a token error if no token provided' do
|
54
|
+
expect { Auth.delete_token(false, @abs_url, 'first.last', 'password', nil) }.to raise_error(TokenError)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#token_status' do
|
59
|
+
before :each do
|
60
|
+
@token_status_response = '{"ok":true,"utpg2i2xswor6h8ttjhu3d47z53yy47y":{"created":"2015-04-28 19:17:47 -0700"}}'
|
61
|
+
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'checks the status of a token' do
|
65
|
+
stub_request(:get, "#{@abs_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
|
66
|
+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' })
|
67
|
+
.to_return(:status => 200, :body => @token_status_response, :headers => {})
|
68
|
+
|
69
|
+
expect(Auth.token_status(false, @abs_url, @token)).to eq JSON.parse(@token_status_response)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'raises a token error if something goes wrong' do
|
73
|
+
stub_request(:get, "#{@abs_url}/token/utpg2i2xswor6h8ttjhu3d47z53yy47y")
|
74
|
+
.with(:headers => { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' })
|
75
|
+
.to_return(:status => 500, :body => '{"ok":false}', :headers => {})
|
76
|
+
|
77
|
+
expect { Auth.token_status(false, @abs_url, @token) }.to raise_error(TokenError)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'raises a token error if no token provided' do
|
81
|
+
expect { Auth.token_status(false, @abs_url, nil) }.to raise_error(TokenError)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,126 @@
|
|
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' => {},
|
24
|
+
'ubuntu-7.2-x86_64' => {},
|
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
|
+
end
|
37
|
+
|
38
|
+
it 'won\'t delete a job if not all vms are listed' do
|
39
|
+
hosts = ['host1']
|
40
|
+
allocated_resources = [
|
41
|
+
{
|
42
|
+
'hostname' => 'host1',
|
43
|
+
},
|
44
|
+
{
|
45
|
+
'hostname' => 'host2',
|
46
|
+
},
|
47
|
+
]
|
48
|
+
expect(ABS.all_job_resources_accounted_for(allocated_resources, hosts)).to eq(false)
|
49
|
+
|
50
|
+
hosts = ['host1', 'host2']
|
51
|
+
allocated_resources = [
|
52
|
+
{
|
53
|
+
'hostname' => 'host1',
|
54
|
+
},
|
55
|
+
{
|
56
|
+
'hostname' => 'host2',
|
57
|
+
},
|
58
|
+
]
|
59
|
+
expect(ABS.all_job_resources_accounted_for(allocated_resources, hosts)).to eq(true)
|
60
|
+
end
|
61
|
+
|
62
|
+
before :each do
|
63
|
+
@abs_url = 'https://abs.example.com'
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#test_abs_status_queue_endpoint' do
|
67
|
+
before :each do
|
68
|
+
# rubocop:disable Layout/LineLength
|
69
|
+
@active_requests_response = '
|
70
|
+
[
|
71
|
+
"{ \"state\":\"allocated\",\"last_processed\":\"2019-12-16 23:00:34 +0000\",\"allocated_resources\":[{\"hostname\":\"take-this.delivery.puppetlabs.net\",\"type\":\"win-2012r2-x86_64\",\"engine\":\"vmpooler\"}],\"audit_log\":{\"2019-12-13 16:45:29 +0000\":\"Allocated take-this.delivery.puppetlabs.net for job 1576255517241\"},\"request\":{\"resources\":{\"win-2012r2-x86_64\":1},\"job\":{\"id\":\"1576255517241\",\"tags\":{\"user\":\"test-user\"},\"user\":\"test-user\",\"time-received\":1576255519},\"priority\":1}}",
|
72
|
+
"null",
|
73
|
+
"{\"state\":\"allocated\",\"last_processed\":\"2019-12-16 23:00:34 +0000\",\"allocated_resources\":[{\"hostname\":\"not-this.delivery.puppetlabs.net\",\"type\":\"win-2012r2-x86_64\",\"engine\":\"vmpooler\"}],\"audit_log\":{\"2019-12-13 16:46:14 +0000\":\"Allocated not-this.delivery.puppetlabs.net for job 1576255565159\"},\"request\":{\"resources\":{\"win-2012r2-x86_64\":1},\"job\":{\"id\":\"1576255565159\",\"tags\":{\"user\":\"not-test-user\"},\"user\":\"not-test-user\",\"time-received\":1576255566},\"priority\":1}}"
|
74
|
+
]'
|
75
|
+
# rubocop:enable Layout/LineLength
|
76
|
+
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
|
77
|
+
@test_user = 'test-user'
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'will skip a line with a null value returned from abs' do
|
81
|
+
stub_request(:get, 'https://abs.example.com/status/queue')
|
82
|
+
.to_return(:status => 200, :body => @active_requests_response, :headers => {})
|
83
|
+
|
84
|
+
ret = ABS.get_active_requests(false, @abs_url, @test_user)
|
85
|
+
|
86
|
+
expect(ret[0]).to include(
|
87
|
+
'allocated_resources' => [{
|
88
|
+
'hostname' => 'take-this.delivery.puppetlabs.net',
|
89
|
+
'type' => 'win-2012r2-x86_64',
|
90
|
+
'engine' => 'vmpooler',
|
91
|
+
}],
|
92
|
+
)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#test_abs_delete_jobid' do
|
97
|
+
before :each do
|
98
|
+
# rubocop:disable Layout/LineLength
|
99
|
+
@active_requests_response = '
|
100
|
+
[
|
101
|
+
"{ \"state\":\"allocated\", \"last_processed\":\"2020-01-17 22:29:13 +0000\", \"allocated_resources\":[{\"hostname\":\"craggy-chord.delivery.puppetlabs.net\", \"type\":\"centos-7-x86_64\", \"engine\":\"vmpooler\"}, {\"hostname\":\"visible-revival.delivery.puppetlabs.net\", \"type\":\"centos-7-x86_64\", \"engine\":\"vmpooler\"}], \"audit_log\":{\"2020-01-17 22:28:45 +0000\":\"Allocated craggy-chord.delivery.puppetlabs.net, visible-revival.delivery.puppetlabs.net for job 1579300120799\"}, \"request\":{\"resources\":{\"centos-7-x86_64\":2}, \"job\":{\"id\":\"1579300120799\", \"tags\":{\"user\":\"test-user\"}, \"user\":\"test-user\", \"time-received\":1579300120}, \"priority\":3}}"
|
102
|
+
]'
|
103
|
+
@return_request = { '{"job_id":"1579300120799","hosts":{"hostname":"craggy-chord.delivery.puppetlabs.net","type":"centos-7-x86_64","engine":"vmpooler"},{"hostname":"visible-revival.delivery.puppetlabs.net","type":"centos-7-x86_64","engine":"vmpooler"}}'=>true }
|
104
|
+
# rubocop:enable Layout/LineLength
|
105
|
+
@token = 'utpg2i2xswor6h8ttjhu3d47z53yy47y'
|
106
|
+
@test_user = 'test-user'
|
107
|
+
# Job ID
|
108
|
+
@hosts = ['1579300120799']
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'will delete the whole job' do
|
112
|
+
stub_request(:get, 'https://abs.example.com/status/queue')
|
113
|
+
.to_return(:status => 200, :body => @active_requests_response, :headers => {})
|
114
|
+
stub_request(:post, 'https://abs.example.com/return')
|
115
|
+
.with(:body => @return_request)
|
116
|
+
.to_return(:status => 200, :body => 'OK', :headers => {})
|
117
|
+
|
118
|
+
ret = ABS.delete(false, @abs_url, @hosts, @token, @test_user)
|
119
|
+
|
120
|
+
expect(ret).to include(
|
121
|
+
'craggy-chord.delivery.puppetlabs.net' => { 'ok'=>true }, 'visible-revival.delivery.puppetlabs.net' => { 'ok'=>true },
|
122
|
+
)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|