vmware-vra 2.7.0 → 3.0.1
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 +4 -4
- data/.gitignore +3 -1
- data/CHANGELOG.md +27 -1
- data/README.md +91 -141
- data/Rakefile +1 -12
- data/lib/vra/catalog.rb +39 -8
- data/lib/vra/catalog_base.rb +62 -0
- data/lib/vra/catalog_item.rb +29 -75
- data/lib/vra/catalog_source.rb +116 -0
- data/lib/vra/catalog_type.rb +56 -0
- data/lib/vra/client.rb +72 -53
- data/lib/vra/deployment.rb +155 -0
- data/lib/vra/deployment_request.rb +117 -0
- data/lib/vra/{resources.rb → deployments.rb} +26 -17
- data/lib/vra/exceptions.rb +2 -2
- data/lib/vra/http.rb +20 -7
- data/lib/vra/request.rb +28 -36
- data/lib/vra/request_parameters.rb +12 -10
- data/lib/vra/resource.rb +33 -203
- data/lib/vra/version.rb +2 -2
- data/lib/vra.rb +15 -12
- data/spec/catalog_item_spec.rb +64 -222
- data/spec/catalog_source_spec.rb +178 -0
- data/spec/catalog_spec.rb +112 -72
- data/spec/catalog_type_spec.rb +114 -0
- data/spec/client_spec.rb +287 -228
- data/spec/deployment_request_spec.rb +192 -0
- data/spec/deployment_spec.rb +227 -0
- data/spec/deployments_spec.rb +80 -0
- data/spec/fixtures/resource/sample_catalog_item.json +18 -0
- data/spec/fixtures/resource/sample_catalog_item_2.json +18 -0
- data/spec/fixtures/resource/sample_catalog_source.json +20 -0
- data/spec/fixtures/resource/sample_catalog_type.json +49 -0
- data/spec/fixtures/resource/sample_dep_actions.json +58 -0
- data/spec/fixtures/resource/sample_dep_request.json +19 -0
- data/spec/fixtures/resource/sample_dep_resource.json +112 -0
- data/spec/fixtures/resource/sample_deployment.json +26 -0
- data/spec/fixtures/resource/sample_entitlements.json +25 -0
- data/spec/http_spec.rb +63 -61
- data/spec/request_spec.rb +62 -68
- data/spec/resource_spec.rb +71 -390
- data/spec/spec_helper.rb +10 -4
- data/vmware-vra.gemspec +2 -4
- metadata +42 -32
- data/.travis.yml +0 -14
- data/lib/vra/catalog_request.rb +0 -127
- data/lib/vra/requests.rb +0 -41
- data/spec/catalog_request_spec.rb +0 -265
- data/spec/requests_spec.rb +0 -60
- data/spec/resources_spec.rb +0 -71
data/spec/client_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
#
|
3
3
|
# Author:: Chef Partner Engineering (<partnereng@chef.io>)
|
4
|
-
# Copyright:: Copyright (c)
|
4
|
+
# Copyright:: Copyright (c) 2022 Chef Software, Inc.
|
5
5
|
# License:: Apache License, Version 2.0
|
6
6
|
#
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -17,111 +17,113 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
19
|
|
20
|
-
require
|
20
|
+
require 'spec_helper'
|
21
|
+
require 'pry'
|
22
|
+
# require 'pry-byebug'
|
21
23
|
|
22
24
|
describe Vra::Client do
|
25
|
+
let(:client_params) do
|
26
|
+
{
|
27
|
+
username: 'user@corp.local',
|
28
|
+
password: 'password',
|
29
|
+
tenant: 'tenant',
|
30
|
+
base_url: 'https://vra.corp.local'
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
23
34
|
let(:client) do
|
24
|
-
|
25
|
-
password: "password",
|
26
|
-
tenant: "tenant",
|
27
|
-
base_url: "https://vra.corp.local")
|
35
|
+
described_class.new(client_params)
|
28
36
|
end
|
29
37
|
|
30
38
|
let(:client_without_ssl) do
|
31
|
-
|
32
|
-
password: "password",
|
33
|
-
tenant: "tenant",
|
34
|
-
base_url: "https://vra.corp.local",
|
35
|
-
verify_ssl: false)
|
39
|
+
described_class.new(client_params.merge(verify_ssl: false))
|
36
40
|
end
|
37
41
|
|
38
|
-
describe
|
39
|
-
it
|
40
|
-
client =
|
42
|
+
describe '#initialize' do
|
43
|
+
it 'calls validate_client_options!' do
|
44
|
+
client = described_class.allocate
|
41
45
|
expect(client).to receive(:validate_client_options!)
|
42
|
-
client.send(:initialize,
|
43
|
-
password: "password",
|
44
|
-
tenant: "tenant",
|
45
|
-
base_url: "https://vra.corp.local")
|
46
|
+
client.send(:initialize, client_params)
|
46
47
|
end
|
47
48
|
end
|
48
49
|
|
49
|
-
describe
|
50
|
-
it
|
51
|
-
expect(client.
|
50
|
+
describe '#token_params' do
|
51
|
+
it 'gets the correct password from the PasswordMasker object' do
|
52
|
+
expect(client.token_params[:password]).to eq('password')
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
55
|
-
describe
|
56
|
-
context
|
57
|
-
it
|
58
|
-
client.
|
59
|
-
expect(client.request_headers.key?(
|
56
|
+
describe '#request_headers' do
|
57
|
+
context 'when access token exists' do
|
58
|
+
it 'has an Authorization header' do
|
59
|
+
client.access_token = '12345'
|
60
|
+
expect(client.request_headers.key?('csp-auth-token')).to be true
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
63
|
-
context
|
64
|
-
it
|
65
|
-
expect(client.request_headers.key?(
|
64
|
+
context 'when access token does not exist' do
|
65
|
+
it 'does not have an Authorization header' do
|
66
|
+
expect(client.request_headers.key?('csp-auth-token')).to be false
|
66
67
|
end
|
67
68
|
end
|
68
69
|
end
|
69
70
|
|
70
|
-
describe
|
71
|
-
context
|
72
|
-
it
|
71
|
+
describe '#authorize!' do
|
72
|
+
context 'when a token is not authorized or no token exists' do
|
73
|
+
it 'generates a token successfully' do
|
73
74
|
allow(client).to receive(:authorized?).twice.and_return(false, true)
|
74
|
-
expect(client).to receive(:
|
75
|
+
expect(client).to receive(:generate_access_token)
|
75
76
|
|
76
77
|
client.authorize!
|
77
78
|
end
|
78
79
|
|
79
|
-
it
|
80
|
+
it 'raises an exception if token generation fails' do
|
80
81
|
allow(client).to receive(:authorized?).and_return(false)
|
81
|
-
allow(client).to receive(:
|
82
|
+
allow(client).to receive(:generate_access_token).and_raise(Vra::Exception::Unauthorized)
|
82
83
|
|
83
84
|
expect { client.authorize! }.to raise_error(Vra::Exception::Unauthorized)
|
84
85
|
end
|
85
86
|
|
86
|
-
it
|
87
|
+
it 'raises an exception if a generated token is unauthorized' do
|
87
88
|
allow(client).to receive(:authorized).twice.and_return(false, false)
|
88
|
-
allow(client).to receive(:
|
89
|
+
allow(client).to receive(:generate_access_token)
|
89
90
|
|
90
91
|
expect { client.authorize! }.to raise_error(Vra::Exception::Unauthorized)
|
91
92
|
end
|
92
93
|
end
|
93
94
|
|
94
|
-
context
|
95
|
-
it
|
95
|
+
context 'when a token is authorized' do
|
96
|
+
it 'does not generate a new token' do
|
96
97
|
allow(client).to receive(:authorized?).and_return(true)
|
97
|
-
expect(client).to_not receive(:
|
98
|
+
expect(client).to_not receive(:generate_access_token)
|
98
99
|
|
99
100
|
client.authorize!
|
100
101
|
end
|
101
102
|
end
|
102
103
|
end
|
103
104
|
|
104
|
-
describe
|
105
|
-
context
|
106
|
-
it
|
105
|
+
describe '#authorized?' do
|
106
|
+
context 'when token does not exist' do
|
107
|
+
it 'returns false' do
|
107
108
|
expect(client.authorized?).to be false
|
108
109
|
end
|
109
110
|
end
|
110
111
|
|
111
|
-
context
|
112
|
+
context 'when token exists' do
|
112
113
|
before(:each) do
|
113
|
-
client.
|
114
|
+
client.access_token = '12345'
|
115
|
+
client.refresh_token = '54321'
|
114
116
|
end
|
115
117
|
|
116
|
-
it
|
117
|
-
response = double(
|
118
|
+
it 'returns true if the token validates successfully' do
|
119
|
+
response = double('response', success_no_content?: true, code: 204, success?: true)
|
118
120
|
allow(Vra::Http).to receive(:execute).and_return(response)
|
119
121
|
|
120
122
|
expect(client.authorized?).to be true
|
121
123
|
end
|
122
124
|
|
123
|
-
it
|
124
|
-
response = double(
|
125
|
+
it 'returns false if the token validates unsuccessfully' do
|
126
|
+
response = double('response', success_no_content?: false, code: 401, success?: false)
|
125
127
|
allow(Vra::Http).to receive(:execute).and_return(response)
|
126
128
|
|
127
129
|
expect(client.authorized?).to be false
|
@@ -129,261 +131,291 @@ describe Vra::Client do
|
|
129
131
|
end
|
130
132
|
end
|
131
133
|
|
132
|
-
describe
|
133
|
-
payload
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
134
|
+
describe '#generate_access_token' do
|
135
|
+
let(:payload) do
|
136
|
+
{
|
137
|
+
username: 'user@corp.local',
|
138
|
+
password: 'password',
|
139
|
+
tenant: 'tenant'
|
140
|
+
}.to_json
|
141
|
+
end
|
138
142
|
|
139
|
-
|
140
|
-
|
143
|
+
let(:success_response) do
|
144
|
+
{
|
145
|
+
access_token: '123456',
|
146
|
+
refresh_token: '654321',
|
147
|
+
id: '123456'
|
148
|
+
}.to_json
|
149
|
+
end
|
150
|
+
|
151
|
+
let(:refresh_response_body) { { token: '123456' }.to_json }
|
152
|
+
|
153
|
+
it 'posts to the tokens API endpoint' do
|
154
|
+
response = double('response', code: 200, body: success_response, success_ok?: true)
|
155
|
+
refresh_response = double('response', code: 200, body: refresh_response_body, success_ok?: true)
|
156
|
+
# First request to generate the refresh token
|
141
157
|
expect(Vra::Http).to receive(:execute)
|
142
158
|
.with(method: :post,
|
143
|
-
url: client.full_url(
|
159
|
+
url: client.full_url(described_class::REFRESH_TOKEN_URL),
|
144
160
|
payload: payload,
|
145
161
|
headers: anything,
|
146
162
|
verify_ssl: true)
|
147
163
|
.and_return(response)
|
148
164
|
|
149
|
-
|
165
|
+
# Second request to generate access token
|
166
|
+
expect(Vra::Http).to receive(:execute)
|
167
|
+
.with(method: :post,
|
168
|
+
url: client.full_url(described_class::ACCESS_TOKEN_URL),
|
169
|
+
payload: "{ \"refreshToken\": \"654321\" }",
|
170
|
+
headers: anything,
|
171
|
+
verify_ssl: true)
|
172
|
+
.and_return(refresh_response)
|
173
|
+
|
174
|
+
client.generate_access_token
|
150
175
|
end
|
151
176
|
|
152
|
-
context
|
153
|
-
it
|
154
|
-
response = double(
|
155
|
-
|
177
|
+
context 'when token is generated successfully' do
|
178
|
+
it 'sets the token' do
|
179
|
+
response = double('response', code: 200, body: success_response, success_ok?: true)
|
180
|
+
refresh_response = double('response', code: 200, body: refresh_response_body, success_ok?: true)
|
181
|
+
allow(Vra::Http).to receive(:execute).twice.and_return(response, refresh_response)
|
156
182
|
|
157
|
-
client.
|
183
|
+
client.generate_access_token
|
158
184
|
|
159
|
-
expect(client.
|
185
|
+
expect(client.access_token).to eq '123456'
|
186
|
+
expect(client.refresh_token).to eq '654321'
|
160
187
|
end
|
161
188
|
end
|
162
189
|
|
163
|
-
context
|
164
|
-
it
|
165
|
-
response = double(
|
190
|
+
context 'when token is not generated successfully' do
|
191
|
+
it 'raises an exception' do
|
192
|
+
response = double('response', code: 400, body: 'error string', success_ok?: false)
|
166
193
|
allow(Vra::Http).to receive(:execute).and_return(response)
|
167
194
|
|
168
|
-
expect { client.
|
195
|
+
expect { client.generate_access_token }.to raise_error(Vra::Exception::Unauthorized)
|
169
196
|
end
|
170
197
|
end
|
171
198
|
end
|
172
199
|
|
173
|
-
describe
|
174
|
-
it
|
175
|
-
expect(client.full_url(
|
200
|
+
describe '#full_url' do
|
201
|
+
it 'returns a properly formatted url' do
|
202
|
+
expect(client.full_url('/url_path')).to eq 'https://vra.corp.local/url_path'
|
176
203
|
end
|
177
204
|
end
|
178
205
|
|
179
|
-
describe
|
180
|
-
context
|
181
|
-
it
|
182
|
-
response = double(
|
206
|
+
describe '#http_head' do
|
207
|
+
context 'when skip_auth is nil' do
|
208
|
+
it 'authorizes before proceeding' do
|
209
|
+
response = double('response')
|
183
210
|
allow(Vra::Http).to receive(:execute).and_return(response)
|
184
211
|
expect(client).to receive(:authorize!)
|
185
212
|
|
186
|
-
client.http_head(
|
213
|
+
client.http_head('/test')
|
187
214
|
end
|
188
215
|
end
|
189
216
|
|
190
|
-
context
|
191
|
-
it
|
192
|
-
response = double(
|
217
|
+
context 'when skip_auth is not nil' do
|
218
|
+
it 'does not authorize before proceeding' do
|
219
|
+
response = double('response')
|
193
220
|
allow(Vra::Http).to receive(:execute).and_return(response)
|
194
221
|
expect(client).to_not receive(:authorize!)
|
195
222
|
|
196
|
-
client.http_head(
|
223
|
+
client.http_head('/test', :skip_auth)
|
197
224
|
end
|
198
225
|
end
|
199
226
|
|
200
|
-
it
|
201
|
-
response = double(
|
202
|
-
path =
|
203
|
-
full_url =
|
204
|
-
headers = {
|
227
|
+
it 'calls Vra::Http.execute' do
|
228
|
+
response = double('response')
|
229
|
+
path = '/test'
|
230
|
+
full_url = 'https://vra.corp.local/test'
|
231
|
+
headers = { 'Accept' => 'application/json', 'Content-Type' => 'application/json' }
|
205
232
|
verify_ssl = true
|
206
233
|
|
207
234
|
allow(client).to receive(:authorize!)
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
235
|
+
|
236
|
+
expect(Vra::Http).to receive(:execute)
|
237
|
+
.with(method: :head,
|
238
|
+
url: full_url,
|
239
|
+
headers: headers,
|
240
|
+
verify_ssl: verify_ssl)
|
212
241
|
.and_return(response)
|
213
242
|
|
214
243
|
client.http_head(path)
|
215
244
|
end
|
216
245
|
|
217
|
-
it
|
218
|
-
response = double(
|
219
|
-
path =
|
220
|
-
full_url =
|
221
|
-
headers = {
|
246
|
+
it 'calls Vra::Http.execute with verify_ssl false' do
|
247
|
+
response = double('response')
|
248
|
+
path = '/test'
|
249
|
+
full_url = 'https://vra.corp.local/test'
|
250
|
+
headers = { 'Accept' => 'application/json', 'Content-Type' => 'application/json' }
|
222
251
|
verify_ssl = false
|
223
252
|
|
224
253
|
allow(client_without_ssl).to receive(:authorize!)
|
225
|
-
expect(Vra::Http).to receive(:execute)
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
254
|
+
expect(Vra::Http).to receive(:execute)
|
255
|
+
.with(method: :head,
|
256
|
+
url: full_url,
|
257
|
+
headers: headers,
|
258
|
+
verify_ssl: verify_ssl)
|
259
|
+
.and_return(response)
|
230
260
|
|
231
261
|
client_without_ssl.http_head(path)
|
232
262
|
end
|
233
263
|
|
234
|
-
it
|
264
|
+
it 'raises an HTTPNotFound on a 404 error' do
|
235
265
|
allow(client).to receive(:authorize!)
|
236
266
|
allow(Vra::Http).to receive(:execute)
|
237
|
-
.and_raise(Vra::Http::Error.new(
|
267
|
+
.and_raise(Vra::Http::Error.new('message', 404, 'Not Found'))
|
238
268
|
|
239
|
-
expect { client.http_head(
|
269
|
+
expect { client.http_head('/404') }.to raise_error(Vra::Exception::HTTPNotFound)
|
240
270
|
end
|
241
271
|
end
|
242
272
|
|
243
|
-
describe
|
244
|
-
context
|
245
|
-
it
|
246
|
-
response = double(
|
273
|
+
describe '#http_get' do
|
274
|
+
context 'when skip_auth is nil' do
|
275
|
+
it 'authorizes before proceeding' do
|
276
|
+
response = double('response')
|
247
277
|
allow(Vra::Http).to receive(:execute).and_return(response)
|
248
278
|
expect(client).to receive(:authorize!)
|
249
279
|
|
250
|
-
client.http_get(
|
280
|
+
client.http_get('/test')
|
251
281
|
end
|
252
282
|
end
|
253
283
|
|
254
|
-
context
|
255
|
-
it
|
256
|
-
response = double(
|
284
|
+
context 'when skip_auth is not nil' do
|
285
|
+
it 'does not authorize before proceeding' do
|
286
|
+
response = double('response')
|
257
287
|
allow(Vra::Http).to receive(:execute).and_return(response)
|
258
288
|
expect(client).to_not receive(:authorize!)
|
259
289
|
|
260
|
-
client.http_get(
|
290
|
+
client.http_get('/test', :skip_auth)
|
261
291
|
end
|
262
292
|
end
|
263
293
|
|
264
|
-
it
|
265
|
-
response = double(
|
266
|
-
path =
|
267
|
-
full_url =
|
268
|
-
headers = {
|
294
|
+
it 'calls Vra::Http.execute' do
|
295
|
+
response = double('response')
|
296
|
+
path = '/test'
|
297
|
+
full_url = 'https://vra.corp.local/test'
|
298
|
+
headers = { 'Accept' => 'application/json', 'Content-Type' => 'application/json' }
|
269
299
|
verify_ssl = true
|
270
300
|
|
271
301
|
allow(client).to receive(:authorize!)
|
272
|
-
expect(Vra::Http).to receive(:execute)
|
273
|
-
|
274
|
-
|
275
|
-
|
302
|
+
expect(Vra::Http).to receive(:execute)
|
303
|
+
.with(method: :get,
|
304
|
+
url: full_url,
|
305
|
+
headers: headers,
|
306
|
+
verify_ssl: verify_ssl)
|
276
307
|
.and_return(response)
|
277
308
|
|
278
309
|
client.http_get(path)
|
279
310
|
end
|
280
311
|
|
281
|
-
it
|
312
|
+
it 'raises an HTTPNotFound on a 404 error' do
|
282
313
|
allow(client).to receive(:authorize!)
|
283
314
|
allow(Vra::Http).to receive(:execute)
|
284
|
-
.and_raise(Vra::Http::Error.new(
|
315
|
+
.and_raise(Vra::Http::Error.new('message', 404, 'Not Found'))
|
285
316
|
|
286
|
-
expect { client.http_get(
|
317
|
+
expect { client.http_get('/404') }.to raise_error(Vra::Exception::HTTPNotFound)
|
287
318
|
end
|
288
319
|
end
|
289
320
|
|
290
|
-
describe
|
291
|
-
it
|
321
|
+
describe '#http_get_paginated_array!' do
|
322
|
+
it 'allows a limit override' do
|
292
323
|
client.page_size = 10
|
293
324
|
expect(client).to receive(:get_parsed)
|
294
|
-
.with(
|
295
|
-
.and_return(
|
325
|
+
.with('/test?$top=10&$skip=0')
|
326
|
+
.and_return('content' => [], 'totalPages' => 1)
|
296
327
|
|
297
|
-
client.http_get_paginated_array!(
|
328
|
+
client.http_get_paginated_array!('/test')
|
298
329
|
end
|
299
330
|
|
300
|
-
it
|
331
|
+
it 'only calls get_parsed once when total pages is 0 (no items)' do
|
301
332
|
expect(client).to receive(:get_parsed)
|
302
333
|
.once
|
303
|
-
.with(
|
304
|
-
.and_return(
|
334
|
+
.with('/test?$top=20&$skip=0')
|
335
|
+
.and_return('content' => [], 'totalPages' => 0)
|
305
336
|
|
306
|
-
client.http_get_paginated_array!(
|
337
|
+
client.http_get_paginated_array!('/test')
|
307
338
|
end
|
308
339
|
|
309
|
-
it
|
340
|
+
it 'only calls get_parsed once when total pages is 1' do
|
310
341
|
expect(client).to receive(:get_parsed)
|
311
342
|
.once
|
312
|
-
.with(
|
313
|
-
.and_return(
|
343
|
+
.with('/test?$top=20&$skip=0')
|
344
|
+
.and_return('content' => [], 'totalPages' => 1)
|
314
345
|
|
315
|
-
client.http_get_paginated_array!(
|
346
|
+
client.http_get_paginated_array!('/test')
|
316
347
|
end
|
317
348
|
|
318
|
-
it
|
349
|
+
it 'calls get_parsed 3 times if there are 3 pages of response' do
|
319
350
|
expect(client).to receive(:get_parsed)
|
320
|
-
.with(
|
321
|
-
.and_return(
|
351
|
+
.with('/test?$top=20&$skip=0')
|
352
|
+
.and_return('content' => [], 'totalPages' => 3)
|
322
353
|
expect(client).to receive(:get_parsed)
|
323
|
-
.with(
|
324
|
-
.and_return(
|
354
|
+
.with('/test?$top=20&$skip=20')
|
355
|
+
.and_return('content' => [], 'totalPages' => 3)
|
325
356
|
expect(client).to receive(:get_parsed)
|
326
|
-
.with(
|
327
|
-
.and_return(
|
357
|
+
.with('/test?$top=20&$skip=40')
|
358
|
+
.and_return('content' => [], 'totalPages' => 3)
|
328
359
|
|
329
|
-
client.http_get_paginated_array!(
|
360
|
+
client.http_get_paginated_array!('/test')
|
330
361
|
end
|
331
362
|
|
332
|
-
it
|
363
|
+
it 'raises an exception if duplicate items are returned by the API' do
|
333
364
|
allow(client).to receive(:get_parsed)
|
334
|
-
.with(
|
335
|
-
.and_return(
|
365
|
+
.with('/test?$top=20&$skip=0')
|
366
|
+
.and_return('content' => [1, 2, 3, 1], 'totalPages' => 1)
|
336
367
|
|
337
|
-
expect { client.http_get_paginated_array!(
|
368
|
+
expect { client.http_get_paginated_array!('/test') }.to raise_error(Vra::Exception::DuplicateItemsDetected)
|
338
369
|
end
|
339
370
|
end
|
340
371
|
|
341
|
-
describe
|
342
|
-
context
|
343
|
-
it
|
344
|
-
response = double(
|
372
|
+
describe '#http_post' do
|
373
|
+
context 'when skip_auth is nil' do
|
374
|
+
it 'authorizes before proceeding' do
|
375
|
+
response = double('response')
|
345
376
|
allow(Vra::Http).to receive(:execute).and_return(response)
|
346
377
|
expect(client).to receive(:authorize!)
|
347
378
|
|
348
|
-
client.http_post(
|
379
|
+
client.http_post('/test', 'some payload')
|
349
380
|
end
|
350
381
|
end
|
351
382
|
|
352
|
-
context
|
353
|
-
it
|
354
|
-
response = double(
|
383
|
+
context 'when skip_auth is not nil' do
|
384
|
+
it 'does not authorize before proceeding' do
|
385
|
+
response = double('response')
|
355
386
|
allow(Vra::Http).to receive(:execute).and_return(response)
|
356
387
|
expect(client).to_not receive(:authorize!)
|
357
388
|
|
358
|
-
client.http_post(
|
389
|
+
client.http_post('/test', 'some payload', :skip_auth)
|
359
390
|
end
|
360
391
|
end
|
361
392
|
|
362
|
-
it
|
363
|
-
response = double(
|
364
|
-
path =
|
365
|
-
full_url =
|
366
|
-
headers = {
|
367
|
-
payload =
|
393
|
+
it 'calls Vra::Http.execute' do
|
394
|
+
response = double('response')
|
395
|
+
path = '/test'
|
396
|
+
full_url = 'https://vra.corp.local/test'
|
397
|
+
headers = { 'Accept' => 'application/json', 'Content-Type' => 'application/json' }
|
398
|
+
payload = 'some payload'
|
368
399
|
verify_ssl = true
|
369
400
|
|
370
401
|
allow(client).to receive(:authorize!)
|
371
|
-
expect(Vra::Http).to receive(:execute)
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
402
|
+
expect(Vra::Http).to receive(:execute)
|
403
|
+
.with(method: :post,
|
404
|
+
url: full_url,
|
405
|
+
headers: headers,
|
406
|
+
payload: payload,
|
407
|
+
verify_ssl: verify_ssl)
|
376
408
|
.and_return(response)
|
377
409
|
|
378
410
|
client.http_post(path, payload)
|
379
411
|
end
|
380
412
|
|
381
|
-
context
|
413
|
+
context 'when not verifying ssl' do
|
382
414
|
let(:unverified_client) do
|
383
|
-
Vra::Client.new(username:
|
384
|
-
password:
|
385
|
-
tenant:
|
386
|
-
base_url:
|
415
|
+
Vra::Client.new(username: 'user@corp.local',
|
416
|
+
password: 'password',
|
417
|
+
tenant: 'tenant',
|
418
|
+
base_url: 'https://vra.corp.local',
|
387
419
|
verify_ssl: false)
|
388
420
|
end
|
389
421
|
|
@@ -391,132 +423,159 @@ describe Vra::Client do
|
|
391
423
|
allow(unverified_client).to receive(:authorized?).and_return(true)
|
392
424
|
end
|
393
425
|
|
394
|
-
it
|
426
|
+
it 'configures Net::HTTP with VERIFY_NONE' do
|
395
427
|
allow(Net::HTTP).to receive(:start).and_wrap_original do |_http, *args|
|
396
428
|
expect(args.last).to include(verify_mode: OpenSSL::SSL::VERIFY_NONE)
|
397
|
-
double(
|
429
|
+
double('response', final?: true, success?: true)
|
398
430
|
end
|
399
431
|
|
400
|
-
unverified_client.http_post(
|
432
|
+
unverified_client.http_post('/path', 'payload')
|
401
433
|
|
402
|
-
[
|
403
|
-
unverified_client.http_fetch(method,
|
434
|
+
%i[head get].each do |method|
|
435
|
+
unverified_client.http_fetch(method, '/test', true)
|
404
436
|
end
|
405
437
|
end
|
406
438
|
end
|
407
439
|
|
408
|
-
it
|
440
|
+
it 'calls raise_http_exception upon error' do
|
409
441
|
allow(client).to receive(:authorize!)
|
410
442
|
allow(Vra::Http).to receive(:execute).and_raise(StandardError)
|
411
443
|
expect(client).to receive(:raise_http_exception)
|
412
444
|
|
413
|
-
client.http_post(
|
445
|
+
client.http_post('/404', 'test payload')
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
describe '#http_post!' do
|
450
|
+
it 'returns the response body' do
|
451
|
+
response = double('response', body: 'body text')
|
452
|
+
allow(client).to receive(:http_post).with('/test', 'test payload').and_return(response)
|
453
|
+
|
454
|
+
expect(client.http_post!('/test', 'test payload')).to eq 'body text'
|
414
455
|
end
|
415
456
|
end
|
416
457
|
|
417
|
-
describe
|
418
|
-
it
|
419
|
-
|
420
|
-
|
458
|
+
describe '#http_delete' do
|
459
|
+
it 'should perform the delete method' do
|
460
|
+
allow(client).to receive(:authorized?).and_return(true)
|
461
|
+
expect(Vra::Http).to receive(:execute)
|
421
462
|
|
422
|
-
|
463
|
+
client.http_delete('/test')
|
423
464
|
end
|
424
465
|
end
|
425
466
|
|
426
|
-
describe
|
427
|
-
context
|
467
|
+
describe '#raise_http_exception' do
|
468
|
+
context 'when a 404 is received' do
|
428
469
|
let(:exception) do
|
429
|
-
double(
|
470
|
+
double('RestClient::ResourceNotFound',
|
430
471
|
http_code: 404,
|
431
|
-
message:
|
432
|
-
response:
|
472
|
+
message: 'Not Found',
|
473
|
+
response: '404 Not Found')
|
433
474
|
end
|
434
475
|
|
435
|
-
it
|
436
|
-
expect { client.raise_http_exception(exception,
|
476
|
+
it 'raises a Vra::Exception::HTTPNotFound exception' do
|
477
|
+
expect { client.raise_http_exception(exception, '/test') }.to raise_error(Vra::Exception::HTTPNotFound)
|
437
478
|
end
|
438
479
|
end
|
439
480
|
|
440
|
-
context
|
481
|
+
context 'when an unspecified http error is received' do
|
441
482
|
let(:exception) do
|
442
|
-
double(
|
483
|
+
double('RestClient::BadRequest',
|
443
484
|
http_code: 400,
|
444
|
-
message:
|
445
|
-
response:
|
485
|
+
message: 'Bad Request',
|
486
|
+
response: '400 Bad Request')
|
446
487
|
end
|
447
488
|
|
448
|
-
it
|
449
|
-
expect { client.raise_http_exception(exception,
|
489
|
+
it 'raises a Vra::Exception::HTTPError exception' do
|
490
|
+
expect { client.raise_http_exception(exception, '/test') }.to raise_error(Vra::Exception::HTTPError)
|
450
491
|
end
|
451
492
|
end
|
452
493
|
end
|
453
494
|
|
454
|
-
describe
|
455
|
-
context
|
456
|
-
it
|
495
|
+
describe '#validate_client_options!' do
|
496
|
+
context 'when all required options are supplied' do
|
497
|
+
it 'does not raise an exception' do
|
457
498
|
expect { client.validate_client_options! }.not_to raise_error
|
458
499
|
end
|
459
500
|
end
|
460
501
|
|
461
|
-
context
|
502
|
+
context 'when username is missing' do
|
462
503
|
let(:client) do
|
463
|
-
|
464
|
-
|
465
|
-
|
504
|
+
described_class.new(
|
505
|
+
password: 'password',
|
506
|
+
tenant: 'tenant',
|
507
|
+
base_url: 'https://vra.corp.local'
|
508
|
+
)
|
466
509
|
end
|
467
510
|
|
468
|
-
it
|
511
|
+
it 'raises an exception' do
|
469
512
|
expect { client.validate_client_options! }.to raise_error(ArgumentError)
|
470
513
|
end
|
471
514
|
end
|
472
515
|
|
473
|
-
context
|
516
|
+
context 'when password is missing' do
|
474
517
|
let(:client) do
|
475
|
-
|
476
|
-
|
477
|
-
|
518
|
+
described_class.new(
|
519
|
+
username: 'username',
|
520
|
+
tenant: 'tenant',
|
521
|
+
base_url: 'https://vra.corp.local'
|
522
|
+
)
|
478
523
|
end
|
479
524
|
|
480
|
-
it
|
525
|
+
it 'raises an exception' do
|
481
526
|
expect { client.validate_client_options! }.to raise_error(ArgumentError)
|
482
527
|
end
|
483
528
|
end
|
484
529
|
|
485
|
-
context
|
530
|
+
context 'when tenant is missing' do
|
486
531
|
let(:client) do
|
487
|
-
|
488
|
-
|
489
|
-
|
532
|
+
described_class.new(
|
533
|
+
username: 'username',
|
534
|
+
password: 'password',
|
535
|
+
base_url: 'https://vra.corp.local'
|
536
|
+
)
|
490
537
|
end
|
491
538
|
|
492
|
-
it
|
539
|
+
it 'raises an exception' do
|
493
540
|
expect { client.validate_client_options! }.to raise_error(ArgumentError)
|
494
541
|
end
|
495
542
|
end
|
496
543
|
|
497
|
-
context
|
544
|
+
context 'when base URL is missing' do
|
498
545
|
let(:client) do
|
499
|
-
|
500
|
-
|
501
|
-
|
546
|
+
described_class.new(
|
547
|
+
username: 'username',
|
548
|
+
password: 'password',
|
549
|
+
tenant: 'tenant'
|
550
|
+
)
|
502
551
|
end
|
503
552
|
|
504
|
-
it
|
553
|
+
it 'raises an exception' do
|
505
554
|
expect { client.validate_client_options! }.to raise_error(ArgumentError)
|
506
555
|
end
|
507
556
|
end
|
508
557
|
|
509
|
-
context
|
558
|
+
context 'when base URL is not a valid HTTP URL' do
|
510
559
|
let(:client) do
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
560
|
+
described_class.new(
|
561
|
+
username: 'username',
|
562
|
+
password: 'password',
|
563
|
+
tenant: 'tenant',
|
564
|
+
base_url: 'something-that-is-not-a-HTTP-URI'
|
565
|
+
)
|
515
566
|
end
|
516
567
|
|
517
|
-
it
|
568
|
+
it 'raises an exception' do
|
518
569
|
expect { client.validate_client_options! }.to raise_error(ArgumentError)
|
519
570
|
end
|
571
|
+
|
572
|
+
it 'should raise an exception when the URI::InvalidURIError is raised' do
|
573
|
+
allow(URI).to receive(:parse).and_raise(URI::InvalidURIError)
|
574
|
+
|
575
|
+
expect { client.validate_client_options! }
|
576
|
+
.to raise_error(ArgumentError)
|
577
|
+
.with_message('Base URL something-that-is-not-a-HTTP-URI is not a valid URI.')
|
578
|
+
end
|
520
579
|
end
|
521
580
|
end
|
522
581
|
end
|