vmware-vra 1.5.4 → 1.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dae60d3196f5ec532da18527585691872db37075
4
- data.tar.gz: 17359e6d0041c7872ab974375f0a25f60f1794cb
3
+ metadata.gz: 32967b6a528fdaea4b4c969fcc58ea9f1e84bd1a
4
+ data.tar.gz: 023a8634851534b756d4651373665802fb96c75b
5
5
  SHA512:
6
- metadata.gz: 5f918bbddfde58b24f9c948a5f9c49c3b3648cb6cc96ae19eeb06803491fb2250881c2f02c5a2dd71a954886f6c454b18fd992f46c1b7f8fc8e80a416b5148db
7
- data.tar.gz: a96438c7ff9e64f15cb076bf7a403dbe71a9b0fd57e3c662dfc9ce72a7192bb6f510c292aa510da8607d77cc8f5d4bc6c1ed3292f0dacaa53ac1fce50763d565
6
+ metadata.gz: 4b54eb12f4e39519bb79fba806443064e019a34a917d9b1710186fa55ce99ecd9571e681b638df8bfadcc5d26398f7235e5476522d4984c293b456b39fdde91a
7
+ data.tar.gz: e59668d3a5130eb86d671d57bd5ecc83b1b31fb3c7d4b052faf75ce8fd1da241e51440bc2ccf38bd52519c8d70ab70e235d231849457c055b8b58ea795417af6
@@ -1,5 +1,8 @@
1
1
  # vmware-vra-gem CHANGELOG
2
2
 
3
+ ## v1.6.0 (2016-05-10)
4
+ * [pr#28](https://github.com/chef-partners/vmware-vra-gem/pull/28) Remove rest-client dependency
5
+
3
6
  ## v1.5.4 (2016-04-27)
4
7
  * [pr#29](https://github.com/chef-partners/vmware-vra-gem/pull/29) Bug fix: handle more gracefully the situations where a resource or catalog item is missing data in the API response
5
8
 
@@ -25,7 +28,7 @@
25
28
  * [pr#11](https://github.com/chef-partners/vmware-vra-gem/pull/11) Ability to set paginated results page size, which is a workaround for issue reported in #10 regarding duplicate items returned in paginated results.
26
29
 
27
30
  ## v1.1.0
28
- * [pr#9](https://github.com/chef-partners/vmware-vra-gem/pull/9) Mask password and bearer token in console/debug/log output.
31
+ * [pr#9](https://github.com/chef-partners/vmware-vra-gem/pull/9) Mask password and bearer token in console/debug/log output.
29
32
  Thanks to [@rubytester](https://github.com/rubytester) for the idea and initial proposal to address in [pr#7](https://github.com/chef-partners/vmware-vra-gem/pull/7)
30
33
 
31
34
  ## v1.0.0
@@ -42,7 +42,7 @@ module Vra
42
42
  end
43
43
 
44
44
  def fetch_catalog_item
45
- @catalog_item_data = FFI_Yajl::Parser.parse(client.http_get!("/catalog-service/api/consumer/catalogItems/#{id}"))
45
+ @catalog_item_data = client.get_parsed("/catalog-service/api/consumer/catalogItems/#{id}")
46
46
  rescue Vra::Exception::HTTPNotFound
47
47
  raise Vra::Exception::NotFound, "catalog ID #{id} does not exist"
48
48
  end
@@ -105,7 +105,7 @@ module Vra
105
105
  raise
106
106
  end
107
107
 
108
- request_id = response.headers[:location].split('/')[-1]
108
+ request_id = response.location.split('/')[-1]
109
109
  Vra::Request.new(client, request_id)
110
110
  end
111
111
  end
@@ -17,8 +17,8 @@
17
17
  #
18
18
 
19
19
  require 'ffi_yajl'
20
- require 'rest-client'
21
20
  require 'passwordmasker'
21
+ require 'vra/http'
22
22
 
23
23
  module Vra
24
24
  # rubocop:disable ClassLength
@@ -93,19 +93,17 @@ module Vra
93
93
  return false if @bearer_token.value.nil?
94
94
 
95
95
  response = http_head("/identity/api/tokens/#{@bearer_token.value}", :skip_auth)
96
- if response.code == 204
97
- true
98
- else
99
- false
100
- end
96
+ response.success_no_content?
101
97
  end
102
98
 
103
99
  def generate_bearer_token
104
100
  @bearer_token.value = nil
105
101
  validate_client_options!
106
102
 
107
- response = http_post('/identity/api/tokens', FFI_Yajl::Encoder.encode(bearer_token_request_body), :skip_auth)
108
- if response.code != 200
103
+ response = http_post('/identity/api/tokens',
104
+ FFI_Yajl::Encoder.encode(bearer_token_request_body),
105
+ :skip_auth)
106
+ unless response.success_ok?
109
107
  raise Vra::Exception::Unauthorized, "Unable to get bearer token: #{response.body}"
110
108
  end
111
109
 
@@ -116,30 +114,25 @@ module Vra
116
114
  "#{@base_url}#{path}"
117
115
  end
118
116
 
119
- def http_head(path, skip_auth=nil)
117
+ def http_fetch(method, path, skip_auth=nil)
120
118
  authorize! unless skip_auth
121
119
 
122
- response = RestClient::Request.execute(method: :head,
123
- url: full_url(path),
124
- headers: request_headers,
125
- verify_ssl: @verify_ssl)
120
+ response = Vra::Http.execute(method: method,
121
+ url: full_url(path),
122
+ headers: request_headers,
123
+ verify_ssl: @verify_ssl)
126
124
  rescue => e
127
125
  raise_http_exception(e, path)
128
126
  else
129
127
  response
130
128
  end
131
129
 
132
- def http_get(path, skip_auth=nil)
133
- authorize! unless skip_auth
130
+ def http_head(path, skip_auth=nil)
131
+ http_fetch(:head, path, skip_auth)
132
+ end
134
133
 
135
- response = RestClient::Request.execute(method: :get,
136
- url: full_url(path),
137
- headers: request_headers,
138
- verify_ssl: @verify_ssl)
139
- rescue => e
140
- raise_http_exception(e, path)
141
- else
142
- response
134
+ def http_get(path, skip_auth=nil)
135
+ http_fetch(:get, path, skip_auth)
143
136
  end
144
137
 
145
138
  def http_get!(path)
@@ -147,13 +140,17 @@ module Vra
147
140
  response.body
148
141
  end
149
142
 
143
+ def get_parsed(path)
144
+ FFI_Yajl::Parser.parse(http_get!(path))
145
+ end
146
+
150
147
  def http_get_paginated_array!(path)
151
148
  items = []
152
149
  page = 1
153
150
  base_path = path + "?limit=#{page_size}"
154
151
 
155
152
  loop do
156
- response = FFI_Yajl::Parser.parse(http_get!("#{base_path}&page=#{page}"))
153
+ response = get_parsed("#{base_path}&page=#{page}")
157
154
  items += response['content']
158
155
 
159
156
  break if page >= response['metadata']['totalPages']
@@ -172,11 +169,11 @@ module Vra
172
169
  def http_post(path, payload, skip_auth=nil)
173
170
  authorize! unless skip_auth
174
171
 
175
- response = RestClient::Request.execute(method: :post,
176
- url: full_url(path),
177
- headers: request_headers,
178
- payload: payload,
179
- verify_ssl: @verify_ssl)
172
+ response = Vra::Http.execute(method: :post,
173
+ url: full_url(path),
174
+ headers: request_headers,
175
+ payload: payload,
176
+ verify_ssl: @verify_ssl)
180
177
  rescue => e
181
178
  raise_http_exception(e, path)
182
179
  else
@@ -0,0 +1,142 @@
1
+ require 'net/http'
2
+
3
+ module Vra
4
+ module Http
5
+ def self.execute(params)
6
+ request = Request.new(params)
7
+ response = request.call
8
+ response = response.forward(request).call until response.final?
9
+ fail error(response) unless response.success?
10
+ response
11
+ end
12
+
13
+ def self.error(response)
14
+ Error.from_response(response)
15
+ end
16
+
17
+ class Request
18
+ attr_reader :params
19
+
20
+ def initialize(params)
21
+ @params = params
22
+ end
23
+
24
+ def redirectable?
25
+ [:get, :head].include?(params[:method])
26
+ end
27
+
28
+ def redirect_to(location)
29
+ new(url: location)
30
+ end
31
+
32
+ def see_other(location)
33
+ redirect_to(location).new(method: :get)
34
+ end
35
+
36
+ def call
37
+ uri = URI(params[:url]) || fail(':url required')
38
+
39
+ Net::HTTP.start(uri.host, uri.port,
40
+ use_ssl: uri.scheme == 'https') do |http|
41
+ request = http_request(params[:method], uri)
42
+ request.initialize_http_header(params[:headers] || {})
43
+ request.body = params[:payload] || ''
44
+
45
+ Response.new(http.request(request))
46
+ end
47
+ end
48
+
49
+ def http_request(method, uri)
50
+ type = {
51
+ get: Net::HTTP::Get,
52
+ head: Net::HTTP::Head,
53
+ post: Net::HTTP::Post
54
+ }.fetch(method, nil)
55
+
56
+ fail "Unknown HTTP method #{method}!" unless type
57
+
58
+ type.new(uri)
59
+ end
60
+
61
+ protected
62
+
63
+ def new(new_params)
64
+ self.class.new(params.dup.merge(new_params))
65
+ end
66
+ end
67
+
68
+ class Response
69
+ # For hiding the details of the HTTP response class
70
+ # so it can be swapped out easily
71
+ def initialize(response)
72
+ @response = response
73
+ end
74
+
75
+ def forward(request)
76
+ if redirect?
77
+ fail Http.error(self) unless request.redirectable?
78
+ request.redirect_to(location)
79
+ elsif see_other?
80
+ request.see_other(location)
81
+ else
82
+ request
83
+ end
84
+ end
85
+
86
+ def location
87
+ @response['location']
88
+ end
89
+
90
+ def body
91
+ @response.body
92
+ end
93
+
94
+ def code
95
+ @response.code.to_i
96
+ end
97
+
98
+ def message
99
+ @response.message
100
+ end
101
+
102
+ def success_ok?
103
+ code == 200
104
+ end
105
+
106
+ def success_no_content?
107
+ code == 204
108
+ end
109
+
110
+ def success?
111
+ (200..207).cover?(code)
112
+ end
113
+
114
+ def redirect?
115
+ [301, 302, 307].include?(code)
116
+ end
117
+
118
+ def see_other?
119
+ code == 303
120
+ end
121
+
122
+ def final?
123
+ !(redirect? || see_other?)
124
+ end
125
+ end
126
+
127
+ class Error < StandardError
128
+ def self.from_response(http_response)
129
+ new(http_response.message, http_response.code, http_response.body)
130
+ end
131
+
132
+ attr_reader :http_code
133
+ attr_reader :response
134
+
135
+ def initialize(message, http_code, response)
136
+ super(message)
137
+ @http_code = http_code
138
+ @response = response
139
+ end
140
+ end
141
+ end
142
+ end
@@ -32,7 +32,7 @@ module Vra
32
32
  end
33
33
 
34
34
  def refresh
35
- @request_data = FFI_Yajl::Parser.parse(client.http_get!("/catalog-service/api/consumer/requests/#{@id}"))
35
+ @request_data = client.get_parsed("/catalog-service/api/consumer/requests/#{@id}")
36
36
  rescue Vra::Exception::HTTPNotFound
37
37
  raise Vra::Exception::NotFound, "request ID #{@id} is not found"
38
38
  end
@@ -45,7 +45,7 @@ module Vra
45
45
  end
46
46
 
47
47
  def fetch_resource_data
48
- @resource_data = FFI_Yajl::Parser.parse(client.http_get!("/catalog-service/api/consumer/resources/#{@id}"))
48
+ @resource_data = client.get_parsed("/catalog-service/api/consumer/resources/#{@id}")
49
49
  rescue Vra::Exception::HTTPNotFound
50
50
  raise Vra::Exception::NotFound, "resource ID #{@id} does not exist"
51
51
  end
@@ -239,7 +239,7 @@ module Vra
239
239
  def submit_action_request(action_id)
240
240
  payload = action_request_payload(action_id).to_json
241
241
  response = client.http_post('/catalog-service/api/consumer/requests', payload)
242
- request_id = response.headers[:location].split('/')[-1]
242
+ request_id = response.location.split('/')[-1]
243
243
  Vra::Request.new(client, request_id)
244
244
  end
245
245
  end
@@ -17,5 +17,5 @@
17
17
  #
18
18
 
19
19
  module Vra
20
- VERSION = '1.5.4'.freeze
20
+ VERSION = '1.6.0'.freeze
21
21
  end
@@ -106,7 +106,7 @@ describe Vra::CatalogRequest do
106
106
  describe '#submit' do
107
107
  before do
108
108
  allow(request).to receive(:request_payload).and_return({})
109
- response = double('response', code: 200, headers: { location: '/requests/request-12345' })
109
+ response = double('response', location: '/requests/request-12345')
110
110
  allow(client).to receive(:http_post).with('/catalog-service/api/consumer/requests', '{}').and_return(response)
111
111
  end
112
112
 
@@ -104,20 +104,16 @@ describe Vra::Client do
104
104
  client.bearer_token = '12345'
105
105
  end
106
106
 
107
- url = '/identity/api/tokens/12345'
108
-
109
107
  it 'returns true if the token validates successfully' do
110
- response = double('response')
111
- allow(response).to receive(:code).and_return(204)
112
- allow(client).to receive(:http_head).with(url, :skip_auth).and_return(response)
108
+ response = double('response', success_no_content?: true, code: 204)
109
+ allow(Vra::Http).to receive(:execute).and_return(response)
113
110
 
114
111
  expect(client.authorized?).to be true
115
112
  end
116
113
 
117
114
  it 'returns false if the token validates unsuccessfully' do
118
- response = double('response')
119
- allow(response).to receive(:code).and_return(500)
120
- allow(client).to receive(:http_head).with(url, :skip_auth).and_return(response)
115
+ response = double('response', success_no_content?: false, code: 500)
116
+ allow(Vra::Http).to receive(:execute).and_return(response)
121
117
 
122
118
  expect(client.authorized?).to be false
123
119
  end
@@ -132,24 +128,22 @@ describe Vra::Client do
132
128
  }.to_json
133
129
 
134
130
  it 'posts to the tokens API endpoint' do
135
- response = double('response')
136
- allow(response).to receive(:code).and_return(200)
137
- allow(response).to receive(:body).and_return('{"id":"12345"}')
138
- expect(client).to receive(:http_post).with('/identity/api/tokens',
139
- payload,
140
- :skip_auth).and_return(response)
131
+ response = double('response', code: 200, body: '{"id":"12345"}', success_ok?: true)
132
+ expect(Vra::Http).to receive(:execute)
133
+ .with(method: :post,
134
+ url: client.full_url('/identity/api/tokens'),
135
+ payload: payload,
136
+ headers: anything,
137
+ verify_ssl: true)
138
+ .and_return(response)
141
139
 
142
140
  client.generate_bearer_token
143
141
  end
144
142
 
145
143
  context 'when token is generated successfully' do
146
144
  it 'sets the token' do
147
- response = double('response')
148
- allow(response).to receive(:code).and_return(200)
149
- allow(response).to receive(:body).and_return('{"id":"12345"}')
150
- allow(client).to receive(:http_post).with('/identity/api/tokens',
151
- payload,
152
- :skip_auth).and_return(response)
145
+ response = double('response', code: 200, body: '{"id":"12345"}', success_ok?: true)
146
+ allow(Vra::Http).to receive(:execute).and_return(response)
153
147
 
154
148
  client.generate_bearer_token
155
149
 
@@ -159,13 +153,8 @@ describe Vra::Client do
159
153
 
160
154
  context 'when token is not generated successfully' do
161
155
  it 'raises an exception' do
162
- response = double('response')
163
- allow(response).to receive(:code).and_return(500)
164
- allow(response).to receive(:body).and_return('error string')
165
- allow(client).to receive(:http_post).with('/identity/api/tokens',
166
- payload,
167
- :skip_auth)
168
- .and_return(response)
156
+ response = double('response', code: 500, body: 'error string', success_ok?: false)
157
+ allow(Vra::Http).to receive(:execute).and_return(response)
169
158
 
170
159
  expect { client.generate_bearer_token }.to raise_error(Vra::Exception::Unauthorized)
171
160
  end
@@ -182,7 +171,7 @@ describe Vra::Client do
182
171
  context 'when skip_auth is nil' do
183
172
  it 'authorizes before proceeding' do
184
173
  response = double('response')
185
- allow(RestClient::Request).to receive(:execute).and_return(response)
174
+ allow(Vra::Http).to receive(:execute).and_return(response)
186
175
  expect(client).to receive(:authorize!)
187
176
 
188
177
  client.http_head('/test')
@@ -192,14 +181,14 @@ describe Vra::Client do
192
181
  context 'when skip_auth is not nil' do
193
182
  it 'does not authorize before proceeding' do
194
183
  response = double('response')
195
- allow(RestClient::Request).to receive(:execute).and_return(response)
184
+ allow(Vra::Http).to receive(:execute).and_return(response)
196
185
  expect(client).to_not receive(:authorize!)
197
186
 
198
187
  client.http_head('/test', :skip_auth)
199
188
  end
200
189
  end
201
190
 
202
- it 'calls RestClient::Request#execute' do
191
+ it 'calls Vra::Http.execute' do
203
192
  response = double('response')
204
193
  path = '/test'
205
194
  full_url = 'https://vra.corp.local/test'
@@ -207,21 +196,21 @@ describe Vra::Client do
207
196
  verify_ssl = true
208
197
 
209
198
  allow(client).to receive(:authorize!)
210
- expect(RestClient::Request).to receive(:execute).with(method: :head,
211
- url: full_url,
212
- headers: headers,
213
- verify_ssl: verify_ssl)
199
+ expect(Vra::Http).to receive(:execute).with(method: :head,
200
+ url: full_url,
201
+ headers: headers,
202
+ verify_ssl: verify_ssl)
214
203
  .and_return(response)
215
204
 
216
205
  client.http_head(path)
217
206
  end
218
207
 
219
- it 'calls raise_http_exception upon a RestClient error' do
208
+ it 'raises an HTTPNotFound on a 404 error' do
220
209
  allow(client).to receive(:authorize!)
221
- allow(RestClient::Request).to receive(:execute).and_raise(RestClient::ResourceNotFound)
222
- expect(client).to receive(:raise_http_exception)
210
+ allow(Vra::Http).to receive(:execute)
211
+ .and_raise(Vra::Http::Error.new('message', 404, 'Not Found'))
223
212
 
224
- client.http_head('/404')
213
+ expect { client.http_head('/404') }.to raise_error(Vra::Exception::HTTPNotFound)
225
214
  end
226
215
  end
227
216
 
@@ -229,7 +218,7 @@ describe Vra::Client do
229
218
  context 'when skip_auth is nil' do
230
219
  it 'authorizes before proceeding' do
231
220
  response = double('response')
232
- allow(RestClient::Request).to receive(:execute).and_return(response)
221
+ allow(Vra::Http).to receive(:execute).and_return(response)
233
222
  expect(client).to receive(:authorize!)
234
223
 
235
224
  client.http_get('/test')
@@ -239,14 +228,14 @@ describe Vra::Client do
239
228
  context 'when skip_auth is not nil' do
240
229
  it 'does not authorize before proceeding' do
241
230
  response = double('response')
242
- allow(RestClient::Request).to receive(:execute).and_return(response)
231
+ allow(Vra::Http).to receive(:execute).and_return(response)
243
232
  expect(client).to_not receive(:authorize!)
244
233
 
245
234
  client.http_get('/test', :skip_auth)
246
235
  end
247
236
  end
248
237
 
249
- it 'calls RestClient::Request#execute' do
238
+ it 'calls Vra::Http.execute' do
250
239
  response = double('response')
251
240
  path = '/test'
252
241
  full_url = 'https://vra.corp.local/test'
@@ -254,79 +243,70 @@ describe Vra::Client do
254
243
  verify_ssl = true
255
244
 
256
245
  allow(client).to receive(:authorize!)
257
- expect(RestClient::Request).to receive(:execute).with(method: :get,
258
- url: full_url,
259
- headers: headers,
260
- verify_ssl: verify_ssl)
246
+ expect(Vra::Http).to receive(:execute).with(method: :get,
247
+ url: full_url,
248
+ headers: headers,
249
+ verify_ssl: verify_ssl)
261
250
  .and_return(response)
262
251
 
263
252
  client.http_get(path)
264
253
  end
265
254
 
266
- it 'calls raise_http_exception upon a RestClient error' do
255
+ it 'raises an HTTPNotFound on a 404 error' do
267
256
  allow(client).to receive(:authorize!)
268
- allow(RestClient::Request).to receive(:execute).and_raise(RestClient::ResourceNotFound)
269
- expect(client).to receive(:raise_http_exception)
270
-
271
- client.http_get('/404')
272
- end
273
- end
274
-
275
- describe '#http_get!' do
276
- it 'returns the response body' do
277
- response = double('response', body: 'body text')
278
- allow(client).to receive(:http_get).with('/test').and_return(response)
257
+ allow(Vra::Http).to receive(:execute)
258
+ .and_raise(Vra::Http::Error.new('message', 404, 'Not Found'))
279
259
 
280
- expect(client.http_get!('/test')).to eq 'body text'
260
+ expect { client.http_get('/404') }.to raise_error(Vra::Exception::HTTPNotFound)
281
261
  end
282
262
  end
283
263
 
284
264
  describe '#http_get_paginated_array!' do
285
265
  it 'allows a limit override' do
286
266
  client.page_size = 10
287
- expect(client).to receive(:http_get!)
267
+ expect(client).to receive(:get_parsed)
288
268
  .with('/test?limit=10&page=1')
289
- .and_return({ 'content' => [], 'metadata' => { 'totalPages' => 1 } }.to_json)
269
+ .and_return('content' => [], 'metadata' => { 'totalPages' => 1 })
290
270
 
291
271
  client.http_get_paginated_array!('/test')
292
272
  end
293
273
 
294
- it 'only calls http_get! once when total pages is 0 (no items)' do
295
- expect(client).to receive(:http_get!)
274
+ it 'only calls get_parsed once when total pages is 0 (no items)' do
275
+ expect(client).to receive(:get_parsed)
296
276
  .once
297
277
  .with('/test?limit=20&page=1')
298
- .and_return({ 'content' => [], 'metadata' => { 'totalPages' => 0 } }.to_json)
278
+ .and_return('content' => [], 'metadata' => { 'totalPages' => 0 })
299
279
 
300
280
  client.http_get_paginated_array!('/test')
301
281
  end
302
282
 
303
- it 'only calls http_get! once when total pages is 1' do
304
- expect(client).to receive(:http_get!)
283
+ it 'only calls get_parsed once when total pages is 1' do
284
+ expect(client).to receive(:get_parsed)
305
285
  .once
306
286
  .with('/test?limit=20&page=1')
307
- .and_return({ 'content' => [], 'metadata' => { 'totalPages' => 1 } }.to_json)
287
+ .and_return('content' => [], 'metadata' => { 'totalPages' => 1 })
308
288
 
309
289
  client.http_get_paginated_array!('/test')
310
290
  end
311
291
 
312
- it 'calls http_get! 3 times if there are 3 pages of response' do
313
- expect(client).to receive(:http_get!)
292
+ it 'calls get_parsed 3 times if there are 3 pages of response' do
293
+ expect(client).to receive(:get_parsed)
314
294
  .with('/test?limit=20&page=1')
315
- .and_return({ 'content' => [], 'metadata' => { 'totalPages' => 3 } }.to_json)
316
- expect(client).to receive(:http_get!)
295
+ .and_return('content' => [], 'metadata' => { 'totalPages' => 3 })
296
+ expect(client).to receive(:get_parsed)
317
297
  .with('/test?limit=20&page=2')
318
- .and_return({ 'content' => [], 'metadata' => { 'totalPages' => 3 } }.to_json)
319
- expect(client).to receive(:http_get!)
298
+ .and_return('content' => [], 'metadata' => { 'totalPages' => 3 })
299
+ expect(client).to receive(:get_parsed)
320
300
  .with('/test?limit=20&page=3')
321
- .and_return({ 'content' => [], 'metadata' => { 'totalPages' => 3 } }.to_json)
301
+ .and_return('content' => [], 'metadata' => { 'totalPages' => 3 })
322
302
 
323
303
  client.http_get_paginated_array!('/test')
324
304
  end
325
305
 
326
306
  it 'raises an exception if duplicate items are returned by the API' do
327
- allow(client).to receive(:http_get!)
307
+ allow(client).to receive(:get_parsed)
328
308
  .with('/test?limit=20&page=1')
329
- .and_return({ 'content' => [ 1, 2, 3, 1 ], 'metadata' => { 'totalPages' => 1 } }.to_json)
309
+ .and_return('content' => [ 1, 2, 3, 1 ], 'metadata' => { 'totalPages' => 1 })
330
310
 
331
311
  expect { client.http_get_paginated_array!('/test') }.to raise_error(Vra::Exception::DuplicateItemsDetected)
332
312
  end
@@ -336,7 +316,7 @@ describe Vra::Client do
336
316
  context 'when skip_auth is nil' do
337
317
  it 'authorizes before proceeding' do
338
318
  response = double('response')
339
- allow(RestClient::Request).to receive(:execute).and_return(response)
319
+ allow(Vra::Http).to receive(:execute).and_return(response)
340
320
  expect(client).to receive(:authorize!)
341
321
 
342
322
  client.http_post('/test', 'some payload')
@@ -346,14 +326,14 @@ describe Vra::Client do
346
326
  context 'when skip_auth is not nil' do
347
327
  it 'does not authorize before proceeding' do
348
328
  response = double('response')
349
- allow(RestClient::Request).to receive(:execute).and_return(response)
329
+ allow(Vra::Http).to receive(:execute).and_return(response)
350
330
  expect(client).to_not receive(:authorize!)
351
331
 
352
332
  client.http_post('/test', 'some payload', :skip_auth)
353
333
  end
354
334
  end
355
335
 
356
- it 'calls RestClient::Request#execute' do
336
+ it 'calls Vra::Http.execute' do
357
337
  response = double('response')
358
338
  path = '/test'
359
339
  full_url = 'https://vra.corp.local/test'
@@ -362,19 +342,19 @@ describe Vra::Client do
362
342
  verify_ssl = true
363
343
 
364
344
  allow(client).to receive(:authorize!)
365
- expect(RestClient::Request).to receive(:execute).with(method: :post,
366
- url: full_url,
367
- headers: headers,
368
- payload: payload,
369
- verify_ssl: verify_ssl)
345
+ expect(Vra::Http).to receive(:execute).with(method: :post,
346
+ url: full_url,
347
+ headers: headers,
348
+ payload: payload,
349
+ verify_ssl: verify_ssl)
370
350
  .and_return(response)
371
351
 
372
352
  client.http_post(path, payload)
373
353
  end
374
354
 
375
- it 'calls raise_http_exception upon a RestClient error' do
355
+ it 'calls raise_http_exception upon error' do
376
356
  allow(client).to receive(:authorize!)
377
- allow(RestClient::Request).to receive(:execute).and_raise(RestClient::ResourceNotFound)
357
+ allow(Vra::Http).to receive(:execute).and_raise(StandardError)
378
358
  expect(client).to receive(:raise_http_exception)
379
359
 
380
360
  client.http_post('/404', 'test payload')
@@ -0,0 +1,146 @@
1
+ require 'spec_helper'
2
+ require 'webmock'
3
+
4
+ describe Vra::Http do
5
+ def expecting_request(method, url, with=nil)
6
+ stub = stub_request(method, url)
7
+ stub.with(with) if with
8
+ yield if block_given?
9
+ expect(stub).to have_been_requested
10
+ end
11
+
12
+ def execute(method, params)
13
+ Vra::Http.execute(params.merge(method: method))
14
+ end
15
+
16
+ def get(params)
17
+ execute :get, params
18
+ end
19
+
20
+ def post(params)
21
+ execute :post, params
22
+ end
23
+
24
+ def head(params)
25
+ execute :head, params
26
+ end
27
+
28
+ describe '#execute' do
29
+ it 'makes a HEAD request' do
30
+ headers = { 'X-Made-Up-Header' => 'Foo AND bar? Are you sure?' }
31
+
32
+ expecting_request(:head, 'http://test.local', headers: headers) do
33
+ head url: 'http://test.local', headers: headers
34
+ end
35
+ end
36
+
37
+ it 'makes a GET request' do
38
+ headers = { 'X-Made-Up-Header' => 'Foo AND bar? Are you sure?' }
39
+
40
+ expecting_request(:get, 'http://test.local', headers: headers) do
41
+ get url: 'http://test.local', headers: headers
42
+ end
43
+ end
44
+
45
+ it 'makes a POST request' do
46
+ headers = { 'X-Made-Up-Header' => 'Foo AND bar? Are you sure?' }
47
+ payload = 'withabodylikethis'
48
+
49
+ expecting_request(:post, 'http://test.local', headers: headers, body: payload) do
50
+ post url: 'http://test.local', headers: headers, payload: payload
51
+ end
52
+ end
53
+
54
+ it 'preserves Location' do
55
+ stub_request(:head, 'http://test.local')
56
+ .to_return(headers: { 'Location' => 'http://test-location.local' })
57
+
58
+ response = head(url: 'http://test.local')
59
+
60
+ expect(response.location).to eq 'http://test-location.local'
61
+ end
62
+
63
+ it 'preserves status code' do
64
+ stub_request(:head, 'http://test.local')
65
+ .to_return(status: [204, 'No content'])
66
+
67
+ response = head(url: 'http://test.local')
68
+
69
+ expect(response.code).to eq 204
70
+ end
71
+
72
+ context 'when successful' do
73
+ it 'returns a successful response given a status 200' do
74
+ stub_request(:head, 'http://test.local')
75
+ .to_return(status: [200, 'Whatevs'])
76
+
77
+ response = head(url: 'http://test.local')
78
+
79
+ expect(response.success_ok?).to be_truthy
80
+ end
81
+
82
+ it 'returns a successful response given a status 204' do
83
+ stub_request(:head, 'http://test.local')
84
+ .to_return(status: [204, 'Whatevs'])
85
+
86
+ response = head(url: 'http://test.local')
87
+
88
+ expect(response.success_no_content?).to be_truthy
89
+ end
90
+ end
91
+
92
+ context 'when unsuccessful' do
93
+ (400..418).each do |status|
94
+ it 'raises an exception given a status #{status}' do
95
+ stub_request(:get, 'http://test.local')
96
+ .to_return(status: [status, 'Whatevs'],
97
+ body: 'Error body')
98
+
99
+ expect { get(url: 'http://test.local') }.to raise_error do |error|
100
+ expect(error).to be_a(StandardError)
101
+ expect(error.http_code).to eq status
102
+ expect(error.response).to eq 'Error body'
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ context 'when redirected' do
109
+ [301, 302, 307].each do |status|
110
+ [:get, :head].each do |method|
111
+ it "follows #{status} redirected #{method.to_s.upcase} requests" do
112
+ stub_request(method, 'http://test.local')
113
+ .to_return(status: [status, 'redirect'],
114
+ headers: { 'Location' => 'http://test.local/redirect' })
115
+ expecting_request(method, 'http://test.local/redirect') do
116
+ execute(method, url: 'http://test.local')
117
+ end
118
+ end
119
+ end
120
+
121
+ it "does not follow #{status} redirected POST requests" do
122
+ stub_request(:post, 'http://test.local')
123
+ .to_return(status: [status, 'redirect'],
124
+ headers: { 'Location' => 'http://test.local/redirect' })
125
+
126
+ expect { post(url: 'http://test.local') }.to raise_error do |error|
127
+ expect(error).to be_a(StandardError)
128
+ expect(error.http_code).to eq status
129
+ end
130
+ end
131
+ end
132
+
133
+ [:head, :post].each do |method|
134
+ it "converts #{method.to_s.upcase} to GET on 303 redirect" do
135
+ stub_request(method, 'http://test.local')
136
+ .to_return(status: [303, 'See Other'],
137
+ headers: { 'Location' => 'http://test.local/redirect' })
138
+
139
+ expecting_request(:get, 'http://test.local/redirect') do
140
+ execute method, url: 'http://test.local'
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -71,9 +71,9 @@ describe Vra::Request do
71
71
 
72
72
  describe '#refresh' do
73
73
  it 'calls the request API endpoint' do
74
- expect(client).to receive(:http_get!)
74
+ expect(client).to receive(:get_parsed)
75
75
  .with("/catalog-service/api/consumer/requests/#{request_id}")
76
- .and_return(in_progress_payload.to_json)
76
+ .and_return(in_progress_payload)
77
77
 
78
78
  request.refresh
79
79
  end
@@ -92,10 +92,10 @@ describe Vra::Resource do
92
92
  end
93
93
 
94
94
  describe '#fetch_resource_data' do
95
- it 'calls http_get! against the resources API endpoint' do
96
- expect(client).to receive(:http_get!)
95
+ it 'calls get_parsed against the resources API endpoint' do
96
+ expect(client).to receive(:get_parsed)
97
97
  .with("/catalog-service/api/consumer/resources/#{resource_id}")
98
- .and_return('')
98
+ .and_return({})
99
99
 
100
100
  Vra::Resource.new(client, id: resource_id)
101
101
  end
@@ -356,7 +356,7 @@ describe Vra::Resource do
356
356
  describe '#submit_action_request' do
357
357
  before do
358
358
  allow(resource).to receive(:action_request_payload).and_return({})
359
- response = double('response', code: 200, headers: { location: '/requests/request-12345' })
359
+ response = double('response', location: '/requests/request-12345')
360
360
  allow(client).to receive(:http_post).with('/catalog-service/api/consumer/requests', '{}').and_return(response)
361
361
  end
362
362
 
@@ -18,7 +18,6 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'rest-client', '~> 1.8'
22
21
  spec.add_dependency 'ffi-yajl', '~> 2.2'
23
22
  spec.add_dependency 'passwordmasker', '~> 1.2'
24
23
 
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vmware-vra
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.4
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Leff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-27 00:00:00.000000000 Z
11
+ date: 2016-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: rest-client
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.8'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.8'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: ffi-yajl
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -157,6 +143,7 @@ files:
157
143
  - lib/vra/catalog_request.rb
158
144
  - lib/vra/client.rb
159
145
  - lib/vra/exceptions.rb
146
+ - lib/vra/http.rb
160
147
  - lib/vra/request.rb
161
148
  - lib/vra/request_parameters.rb
162
149
  - lib/vra/requests.rb
@@ -170,6 +157,7 @@ files:
170
157
  - spec/fixtures/resource/non_vm_resource.json
171
158
  - spec/fixtures/resource/vm_resource.json
172
159
  - spec/fixtures/resource/vm_resource_no_operations.json
160
+ - spec/http_spec.rb
173
161
  - spec/request_spec.rb
174
162
  - spec/requests_spec.rb
175
163
  - spec/resource_spec.rb
@@ -196,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
184
  version: '0'
197
185
  requirements: []
198
186
  rubyforge_project:
199
- rubygems_version: 2.4.8
187
+ rubygems_version: 2.2.2
200
188
  signing_key:
201
189
  specification_version: 4
202
190
  summary: Client gem for interacting with VMware vRealize Automation.
@@ -208,6 +196,7 @@ test_files:
208
196
  - spec/fixtures/resource/non_vm_resource.json
209
197
  - spec/fixtures/resource/vm_resource.json
210
198
  - spec/fixtures/resource/vm_resource_no_operations.json
199
+ - spec/http_spec.rb
211
200
  - spec/request_spec.rb
212
201
  - spec/requests_spec.rb
213
202
  - spec/resource_spec.rb