vsphere-automation-runtime 0.3.0 → 0.4.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
  SHA256:
3
- metadata.gz: 226f670b612a7a585fe4060cbe04aab7842dade81af508133b98c5e4abe079db
4
- data.tar.gz: 701e30402efc0cb0aee6a5682b82820e2cb91d41450671dfdd8da8c2aa41d0ea
3
+ metadata.gz: 3e3ced8b72983d106a8c17f4cdb4739deb2528a39e9401df2f1f6b77947ec305
4
+ data.tar.gz: ad42fda3b57f5d50096c843bab5bb2a377098cee166d272cdeee5f52c440778e
5
5
  SHA512:
6
- metadata.gz: 63b795bdfd4676d86db78e1ba3ac2ccd12ff80358359dd9bc84285dde03fe294d4dba80e9dba1a506ad8da973757c550bd83ba9a054b1f548bf9ea68983c158c
7
- data.tar.gz: 4a14b1681ba6cd51a7afd5c1a1dcfa1ffecbed03fb1636af5b737905ed7ef4fb1b020ab2ffd14a6979af2bbe117597d3fd7aa530b2872ddb1f8108fb98baf63b
6
+ metadata.gz: fa8fbb24d7d5d79ee0296782742238e3dac960cf8c489f62805c026ef81816f003d5ce3b87d7e5c32b97c4de7b43cd3f8e7c52cd7114b92d42272920c39a6cff
7
+ data.tar.gz: dbd31185017068890cf6c3379a6b747a74be62be85fffec7aa5c593c5a020c717cdc1b12a56c79310427cd5574721e7ff771aeabfc1ce744aed2726fd406ba8f
data/Gemfile.lock CHANGED
@@ -1,32 +1,28 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- vsphere-automation-runtime (0.3.0)
5
- typhoeus (~> 1.3)
4
+ vsphere-automation-runtime (0.4.0)
6
5
 
7
6
  GEM
8
7
  remote: https://rubygems.org/
9
8
  specs:
10
- addressable (2.6.0)
11
- public_suffix (>= 2.0.2, < 4.0)
9
+ addressable (2.7.0)
10
+ public_suffix (>= 2.0.2, < 5.0)
12
11
  ast (2.4.0)
13
12
  coderay (1.1.2)
14
13
  crack (0.4.3)
15
14
  safe_yaml (~> 1.0.0)
16
15
  diff-lcs (1.3)
17
- ethon (0.12.0)
18
- ffi (>= 1.3.0)
19
- ffi (1.11.1)
20
16
  hashdiff (1.0.0)
21
17
  jaro_winkler (1.5.3)
22
18
  method_source (0.9.2)
23
19
  parallel (1.17.0)
24
- parser (2.6.3.0)
20
+ parser (2.6.4.0)
25
21
  ast (~> 2.4.0)
26
22
  pry (0.12.2)
27
23
  coderay (~> 1.1.0)
28
24
  method_source (~> 0.9.0)
29
- public_suffix (3.1.1)
25
+ public_suffix (4.0.1)
30
26
  rainbow (3.0.0)
31
27
  rake (12.3.3)
32
28
  rspec (3.8.0)
@@ -51,11 +47,9 @@ GEM
51
47
  unicode-display_width (>= 1.4.0, < 1.7)
52
48
  ruby-progressbar (1.10.1)
53
49
  safe_yaml (1.0.5)
54
- typhoeus (1.3.1)
55
- ethon (>= 0.9.0)
56
50
  unicode-display_width (1.6.0)
57
51
  vcr (5.0.0)
58
- webmock (3.6.2)
52
+ webmock (3.7.2)
59
53
  addressable (>= 2.3.6)
60
54
  crack (>= 0.3.2)
61
55
  hashdiff (>= 0.4.0, < 2.0.0)
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  The Ruby gem for the vSphere Runtime API
4
4
 
5
5
  - API version: 2.0.0
6
- - Package version: 0.3.0
6
+ - Package version: 0.4.0
7
7
 
8
8
  ## Installation
9
9
 
@@ -1,184 +1,188 @@
1
- =begin
2
- # Copyright (c) 2018-2019 VMware, Inc. All Rights Reserved.
3
- # SPDX-License-Identifier: MIT
1
+ # frozen_string_literal: true
4
2
 
5
- # DO NOT MODIFY. THIS CODE IS GENERATED. CHANGES WILL BE OVERWRITTEN.
6
-
7
- # runtime - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
8
-
9
- =end
10
-
11
- require 'date'
12
3
  require 'json'
13
4
  require 'logger'
14
- require 'tempfile'
15
- require 'typhoeus'
5
+ require 'net/http'
6
+ require 'openssl'
16
7
  require 'uri'
8
+ require 'vsphere-automation-runtime/configuration'
17
9
 
18
10
  module VSphereAutomation
11
+ # The client responsible for communicating with the API.
19
12
  class ApiClient
20
13
  # The Configuration object holding settings to be used in the API client.
21
14
  attr_accessor :config
22
15
 
23
- # Defines the headers to be used in HTTP requests of all API calls by default.
16
+ # Defines the headers to be used in HTTP requests of all API calls by
17
+ # default.
24
18
  #
25
19
  # @return [Hash]
26
- attr_accessor :default_headers
20
+ attr_reader :default_headers
27
21
 
28
- # Initializes the ApiClient
29
- # @option config [Configuration] Configuration for initializing the object, default to Configuration.default
22
+ # Creates a new instance
23
+ #
24
+ # @param config [Configuration] configuration object with values to use
30
25
  def initialize(config = Configuration.default)
31
26
  @config = config
32
- @user_agent = "SDK/0.3.0 Ruby/#{RUBY_VERSION} (#{Gem::Platform.local.os}; #{Gem::Platform.local.version}; #{Gem::Platform.local.cpu})"
33
- @default_headers = {
34
- 'Content-Type' => 'application/json',
35
- 'User-Agent' => @user_agent
36
- }
27
+ @http = create_http
28
+ @user_agent = default_user_agent
29
+ @default_headers = { 'Content-Type' => 'application/json',
30
+ 'User-Agent' => @user_agent }
37
31
  end
38
32
 
33
+ # Retrieves an instance of the object in it's default state
34
+ #
35
+ # @return [ApiClient] an instance of the object in it's default state
39
36
  def self.default
40
- @@default ||= ApiClient.new
37
+ DEFAULT
41
38
  end
42
39
 
43
- # Call an API with given options.
40
+ # Build the collection of parameters
41
+ def build_collection_param(params, format)
42
+ params
43
+ end
44
+
45
+ # Make a request to an API endpoint with the given options
44
46
  #
45
- # @return [Array<(Object, Fixnum, Hash)>] an array of 3 elements:
46
- # the data deserialized from response body (could be nil), response status code and response headers.
47
+ # @param http_method [Symbol] the HTTP method to be used
48
+ # @param path [String] the path request will be made to
49
+ # @param opts [Hash] any additional options needed
50
+ # @return [Array<(Object, Fixnum, Hash)>] the deserialized body, status
51
+ # code, and headers.
47
52
  def call_api(http_method, path, opts = {})
48
- request = build_request(http_method, path, opts)
49
- response = request.run
53
+ query_params = opts.fetch(:query_params, {})
54
+ header_params = opts.fetch(:header_params, {})
55
+ form_params = opts.fetch(:form_params, {})
56
+ add_auth(query_params, header_params, opts.fetch(:auth_names, []))
57
+
58
+ uri = build_request_uri(path, query_params)
59
+ request = Net::HTTP.const_get(http_method.capitalize).new(uri)
60
+
61
+ add_form_params(request, form_params)
62
+ add_header_params(request, header_params)
63
+ request.body = opts[:body] if opts[:body]
64
+ request.content_type = request['Content-Type'] if request['Content-Type']
50
65
 
51
66
  if @config.debugging
52
- @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
67
+ @config.logger.debug("Request Body:\n#{request.body}\n")
53
68
  end
54
69
 
55
- unless opts.fetch(:return_type, {}).keys.include?(response.code.to_s) || response.success?
56
- if response.timed_out?
57
- fail ApiError.new('Connection timed out')
58
- elsif response.code == 0
59
- # Errors from libcurl will be made visible here
60
- fail ApiError.new(:code => 0,
61
- :message => response.return_message)
62
- else
63
- fail ApiError.new(:code => response.code,
64
- :response_headers => response.headers,
65
- :response_body => response.body),
66
- response.status_message
67
- end
68
- end
70
+ response = @http.request(request)
71
+ @cookie = cookie_from_response(response)
72
+ api_key_from_response(response)
69
73
 
70
- if opts[:return_type]
71
- data = deserialize(response, opts[:return_type][response.code.to_s])
72
- if path == '/com/vmware/cis/session'
73
- @config.api_key['vmware-api-session-id'] = data.value
74
- end
75
- else
76
- data = nil
77
- end
78
- return data, response.code, response.headers
74
+ return_type = opts.fetch(:return_type, {}).fetch(response.code, nil)
75
+ data = deserialize(response, return_type)
76
+ [data, Integer(response.code), response.each_header.to_h]
77
+ end
78
+
79
+ # Takes an object and returns the object as an HTTP body
80
+ #
81
+ # @param object [Object] object to transform
82
+ # @return [String] object as JSON string
83
+ def object_to_http_body(object)
84
+ return object.map { |o| object_to_http_body(o) } if object.is_a?(Array)
85
+
86
+ return object unless object.respond_to?(:to_hash)
87
+
88
+ object.to_hash.to_json
89
+ end
90
+
91
+ # Select an Accept header to use
92
+ #
93
+ # @param types [Array] a list of suggested types
94
+ # @return [String] the Accept header value
95
+ def select_header_accept(types)
96
+ return DEFAULT_MIME_TYPE unless types.is_a?(Array)
97
+
98
+ types.find { |t| t.include?('json') } || types.join(', ')
79
99
  end
80
100
 
81
- # Builds the HTTP request
101
+ # Select an Content-Type header to use
82
102
  #
83
- # @param [String] http_method HTTP method/verb (e.g. POST)
84
- # @param [String] path URL path (e.g. /account/new)
85
- # @option opts [Hash] :header_params Header parameters
86
- # @option opts [Hash] :query_params Query parameters
87
- # @option opts [Hash] :form_params Query parameters
88
- # @option opts [Object] :body HTTP body (JSON/XML)
89
- # @return [Typhoeus::Request] A Typhoeus Request
90
- def build_request(http_method, path, opts = {})
91
- url = build_request_url(path)
92
- http_method = http_method.to_sym.downcase
93
-
94
- header_params = @default_headers.merge(opts[:header_params] || {})
95
- query_params = opts[:query_params] || {}
96
- form_params = opts[:form_params] || {}
97
-
98
- update_params_for_auth! header_params, query_params, opts[:auth_names]
99
-
100
- # set ssl_verifyhosts option based on @config.verify_ssl_host (true/false)
101
- _verify_ssl_host = @config.verify_ssl_host ? 2 : 0
102
-
103
- req_opts = {
104
- :method => http_method,
105
- :headers => header_params,
106
- :params => query_params,
107
- :params_encoding => @config.params_encoding,
108
- :timeout => @config.timeout,
109
- :ssl_verifypeer => @config.verify_ssl,
110
- :ssl_verifyhost => _verify_ssl_host,
111
- :sslcert => @config.cert_file,
112
- :sslkey => @config.key_file,
113
- :verbose => @config.debugging
114
- }
115
-
116
- # set custom cert, if provided
117
- req_opts[:cainfo] = @config.ssl_ca_cert if @config.ssl_ca_cert
118
-
119
- if [:post, :patch, :put, :delete].include?(http_method)
120
- req_body = build_request_body(header_params, form_params, opts[:body])
121
- req_opts.update :body => req_body
122
- if @config.debugging
123
- @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
103
+ # @param types [Array] a list of suggested types
104
+ # @return [String] the Content-Type header value
105
+ def select_header_content_type(types)
106
+ return DEFAULT_MIME_TYPE unless types.is_a?(Array)
107
+
108
+ types.find { |t| t.include?('json') } || types.first
109
+ end
110
+
111
+ private
112
+
113
+ def add_auth(query_params, header_params, auth_names)
114
+ auth_names.map do |name|
115
+ settings = @config.auth_settings.fetch(name, {})
116
+ case settings[:in]
117
+ when 'header'
118
+ header_params[settings[:key]] = settings[:value]
119
+ api_key_from_cookie(header_params, settings) unless settings[:value]
120
+ when 'query'
121
+ query_params[settings[:key]] = settings[:value]
124
122
  end
125
123
  end
124
+ end
126
125
 
127
- request = Typhoeus::Request.new(url, req_opts)
128
- download_file(request) if opts[:return_type] == 'File'
129
- request
126
+ def add_form_params(request, form_params)
127
+ request.set_form_data(form_params) unless form_params.empty?
130
128
  end
131
129
 
132
- # Check if the given MIME is a JSON MIME.
133
- # JSON MIME examples:
134
- # application/json
135
- # application/json; charset=UTF8
136
- # APPLICATION/JSON
137
- # */*
138
- # @param [String] mime MIME
139
- # @return [Boolean] True if the MIME is application/json
140
- def json_mime?(mime)
141
- (mime == '*/*') || !(mime =~ /Application\/.*json(?!p)(;.*)?/i).nil?
130
+ def add_header_params(request, headers)
131
+ header_params = @default_headers.merge(headers, Hash(@cookie))
132
+ header_params.map { |name, value| request[name] = value }
142
133
  end
143
134
 
144
- # Deserialize the response to the given return type.
145
- #
146
- # @param [Response] response HTTP response
147
- # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]"
148
- def deserialize(response, return_type)
149
- body = response.body
135
+ def add_query_params(uri, query_params)
136
+ uri.query = URI.encode_www_form(query_params)
137
+ end
150
138
 
151
- # handle file downloading - return the File instance processed in request callbacks
152
- # note that response body is empty when the file is written in chunks in request on_body callback
153
- return @tempfile if return_type == 'File'
139
+ def build_request_uri(path = '', query_params = {})
140
+ path = "/#{path}".gsub(%r{/+}, '/')
141
+ uri = URI.parse(@config.base_url + path)
142
+ add_query_params(uri, query_params)
143
+ uri
144
+ end
154
145
 
155
- return nil if body.nil? || body.empty?
146
+ def create_http
147
+ uri = build_request_uri
148
+ http = Net::HTTP.new(uri.host, uri.port)
149
+ http.use_ssl = @config.scheme == 'https'
150
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @config.verify_ssl_host
151
+ http
152
+ end
156
153
 
157
- # return response body directly for String return type
158
- return body if return_type == 'String'
154
+ # The default user agent
155
+ #
156
+ # @return [String] the default user agent
157
+ def default_user_agent
158
+ "SDK/#{VSphereAutomation::Runtime::VERSION} "\
159
+ "Ruby/#{RUBY_VERSION} "\
160
+ "(#{Gem::Platform.local.os}; "\
161
+ "#{Gem::Platform.local.version}; "\
162
+ "#{Gem::Platform.local.cpu})"
163
+ end
159
164
 
160
- # ensuring a default content type
161
- content_type = response.headers['Content-Type'] || 'application/json'
165
+ # Deserialize the response to the given return type
166
+ #
167
+ # @param [Response] response the HTTP response
168
+ # @param [String] return_type the type to return
169
+ # @return [Object] the response represented as the return type
170
+ def deserialize(response, return_type)
171
+ body = response.body
162
172
 
163
- fail "Content-Type is not supported: #{content_type}" unless json_mime?(content_type)
173
+ return nil if body.nil? || body.empty? || return_type.nil?
164
174
 
165
175
  begin
166
- data = JSON.parse("[#{body}]", :symbolize_names => true)[0]
176
+ data = JSON.parse("[#{body}]", symbolize_names: true).first
167
177
  rescue JSON::ParserError => e
168
- if %w(String Date DateTime).include?(return_type)
169
- data = body
170
- else
171
- raise e
172
- end
178
+ raise e unless %w[String Date DateTime].include?(return_type)
179
+
180
+ data = body
173
181
  end
174
182
 
175
- convert_to_type data, return_type
183
+ convert_to_type(data, return_type)
176
184
  end
177
185
 
178
- # Convert data to the given return type.
179
- # @param [Object] data Data to be converted
180
- # @param [String] return_type Return type
181
- # @return [Mixed] Data in a particular type
182
186
  def convert_to_type(data, return_type)
183
187
  return nil if data.nil?
184
188
  case return_type
@@ -217,174 +221,33 @@ module VSphereAutomation
217
221
  end
218
222
  end
219
223
 
220
- # Save response body into a file in (the defined) temporary folder, using the filename
221
- # from the "Content-Disposition" header if provided, otherwise a random filename.
222
- # The response body is written to the file in chunks in order to handle files which
223
- # size is larger than maximum Ruby String or even larger than the maximum memory a Ruby
224
- # process can use.
225
- #
226
- # @see Configuration#temp_folder_path
227
- def download_file(request)
228
- tempfile = nil
229
- encoding = nil
230
- request.on_headers do |response|
231
- content_disposition = response.headers['Content-Disposition']
232
- if content_disposition && content_disposition =~ /filename=/i
233
- filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
234
- prefix = sanitize_filename(filename)
235
- else
236
- prefix = 'download-'
237
- end
238
- prefix = prefix + '-' unless prefix.end_with?('-')
239
- encoding = response.body.encoding
240
- tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
241
- @tempfile = tempfile
242
- end
243
- request.on_body do |chunk|
244
- chunk.force_encoding(encoding)
245
- tempfile.write(chunk)
246
- end
247
- request.on_complete do |response|
248
- tempfile.close
249
- @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\
250
- "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\
251
- "will be deleted automatically with GC. It's also recommended to delete the temp file "\
252
- "explicitly with `tempfile.delete`"
253
- end
254
- end
255
-
256
- # Sanitize filename by removing path.
257
- # e.g. ../../sun.gif becomes sun.gif
258
- #
259
- # @param [String] filename the filename to be sanitized
260
- # @return [String] the sanitized filename
261
- def sanitize_filename(filename)
262
- filename.gsub(/.*[\/\\]/, '')
263
- end
264
-
265
- def build_request_url(path)
266
- # Add leading and trailing slashes to path
267
- path = "/#{path}".gsub(/\/+/, '/')
268
- URI.encode(@config.base_url + path)
269
- end
270
-
271
- # Builds the HTTP request body
272
- #
273
- # @param [Hash] header_params Header parameters
274
- # @param [Hash] form_params Query parameters
275
- # @param [Object] body HTTP body (JSON/XML)
276
- # @return [String] HTTP body data in the form of string
277
- def build_request_body(header_params, form_params, body)
278
- # http form
279
- if header_params['Content-Type'] == 'application/x-www-form-urlencoded' ||
280
- header_params['Content-Type'] == 'multipart/form-data'
281
- data = {}
282
- form_params.each do |key, value|
283
- case value
284
- when ::File, ::Array, nil
285
- # let typhoeus handle File, Array and nil parameters
286
- data[key] = value
287
- else
288
- data[key] = value.to_s
289
- end
290
- end
291
- elsif body
292
- data = body.is_a?(String) ? body : body.to_json
293
- else
294
- data = nil
295
- end
296
- data
297
- end
298
-
299
- # Update hearder and query params based on authentication settings.
224
+ # Create the Cookie header from a response
300
225
  #
301
- # @param [Hash] header_params Header parameters
302
- # @param [Hash] query_params Query parameters
303
- # @param [String] auth_names Authentication scheme name
304
- def update_params_for_auth!(header_params, query_params, auth_names)
305
- Array(auth_names).each do |auth_name|
306
- auth_setting = @config.auth_settings[auth_name]
307
- next unless auth_setting
308
- case auth_setting[:in]
309
- when 'header' then header_params[auth_setting[:key]] = auth_setting[:value]
310
- when 'query' then query_params[auth_setting[:key]] = auth_setting[:value]
311
- else fail ArgumentError, 'Authentication token must be in `query` of `header`'
312
- end
313
- end
226
+ # @param response [Net::HTTPResponse] the response
227
+ # @return [Hash, nil] the Cookie header
228
+ def cookie_from_response(response)
229
+ { 'Cookie' => response['set-cookie'] } if response['set-cookie']
314
230
  end
315
231
 
316
- # Sets user agent in HTTP header
317
- #
318
- # @param [String] user_agent User agent (e.g. openapi-generator/ruby/1.0.0)
319
- def user_agent=(user_agent)
320
- @user_agent = user_agent
321
- @default_headers['User-Agent'] = @user_agent
232
+ def api_key_from_response(response)
233
+ key = @config.auth_settings['api_key'][:key]
234
+ @config.api_key[key] = response[key] if response[key]
322
235
  end
323
236
 
324
- # Return Accept header based on an array of accepts provided.
325
- # @param [Array] accepts array for Accept
326
- # @return [String] the Accept header (e.g. application/json)
327
- def select_header_accept(accepts)
328
- return nil if accepts.nil? || accepts.empty?
329
- # use JSON when present, otherwise use all of the provided
330
- json_accept = accepts.find { |s| json_mime?(s) }
331
- json_accept || accepts.join(',')
332
- end
237
+ def api_key_from_cookie(headers, auth)
238
+ return if @cookie.nil?
333
239
 
334
- # Return Content-Type header based on an array of content types provided.
335
- # @param [Array] content_types array for Content-Type
336
- # @return [String] the Content-Type header (e.g. application/json)
337
- def select_header_content_type(content_types)
338
- # use application/json by default
339
- return 'application/json' if content_types.nil? || content_types.empty?
340
- # use JSON when present, otherwise use the first one
341
- json_content_type = content_types.find { |s| json_mime?(s) }
342
- json_content_type || content_types.first
240
+ regex = /(?<key>#{auth[:key]})=(?<value>\w+)/
241
+ matches = Hash(@cookie)['Cookie'].match(regex)
242
+ headers[matches[:key]] = matches[:value] if matches
343
243
  end
344
244
 
345
- # Convert object (array, hash, object, etc) to JSON string.
346
- # @param [Object] model object to be converted into JSON string
347
- # @return [String] JSON string representation of the object
348
- def object_to_http_body(model)
349
- return model if model.nil? || model.is_a?(String)
350
- local_body = nil
351
- if model.is_a?(Array)
352
- local_body = model.map { |m| object_to_hash(m) }
353
- else
354
- local_body = object_to_hash(model)
355
- end
356
- local_body.to_json
357
- end
245
+ # An instance of the object in it's default state
246
+ DEFAULT = new
358
247
 
359
- # Convert object(non-array) to hash.
360
- # @param [Object] obj object to be converted into JSON string
361
- # @return [String] JSON string representation of the object
362
- def object_to_hash(obj)
363
- if obj.respond_to?(:to_hash)
364
- obj.to_hash
365
- else
366
- obj
367
- end
368
- end
248
+ # The default MIME type for Content-Type and Accept headers
249
+ DEFAULT_MIME_TYPE = 'application/json'
369
250
 
370
- # Build parameter value according to the given collection format.
371
- # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi
372
- def build_collection_param(param, collection_format)
373
- case collection_format
374
- when :csv
375
- param.join(',')
376
- when :ssv
377
- param.join(' ')
378
- when :tsv
379
- param.join("\t")
380
- when :pipes
381
- param.join('|')
382
- when :multi
383
- # return the array directly as typhoeus will handle it as expected
384
- param
385
- else
386
- fail "unknown collection format: #{collection_format.inspect}"
387
- end
388
- end
251
+ private_constant :DEFAULT, :DEFAULT_MIME_TYPE
389
252
  end
390
253
  end
@@ -8,6 +8,6 @@
8
8
 
9
9
  module VSphereAutomation
10
10
  module Runtime
11
- VERSION = '0.3.0'
11
+ VERSION = '0.4.0'
12
12
  end
13
13
  end
@@ -1,222 +1,236 @@
1
- # Copyright (c) 2018-2019 VMware, Inc. All Rights Reserved.
2
- # SPDX-License-Identifier: MIT
3
-
4
- # DO NOT MODIFY. THIS CODE IS GENERATED. CHANGES WILL BE OVERWRITTEN.
5
-
6
- # runtime - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
7
-
8
-
9
1
  require 'spec_helper'
10
2
 
11
3
  describe VSphereAutomation::ApiClient do
12
- context 'initialization' do
13
- context 'URL stuff' do
14
- context 'host' do
15
- it 'removes http from host' do
16
- VSphereAutomation.configure { |c| c.host = 'http://example.com' }
17
- expect(VSphereAutomation::Configuration.default.host).to eq('example.com')
18
- end
4
+ describe '.default' do
5
+ it 'returns the same instance every time' do
6
+ first_instance = VSphereAutomation::ApiClient.default
7
+ second_instance = VSphereAutomation::ApiClient.default
8
+ third_instance = VSphereAutomation::ApiClient.default
9
+ expect(first_instance).to be(second_instance)
10
+ expect(first_instance).to be(third_instance)
11
+ end
12
+ end
19
13
 
20
- it 'removes https from host' do
21
- VSphereAutomation.configure { |c| c.host = 'https://wookiee.com' }
22
- expect(VSphereAutomation::ApiClient.default.config.host).to eq('wookiee.com')
23
- end
14
+ describe '#build_collection_param' do
15
+ context 'when called with format :multi' do
16
+ it 'returns the collection' do
17
+ params = { foo: 'bar', baz: 'quux' }
18
+ expect(subject.build_collection_param(params, :multi)).to eq(params)
19
+ end
20
+ end
21
+ end
24
22
 
25
- it 'removes trailing path from host' do
26
- VSphereAutomation.configure { |c| c.host = 'hobo.com/v4' }
27
- expect(VSphereAutomation::Configuration.default.host).to eq('hobo.com')
28
- end
23
+ describe '#call_api' do
24
+ let(:host) { 'example.com' }
25
+ let(:config) do
26
+ VSphereAutomation::Configuration.new.tap do |c|
27
+ c.scheme = 'https'
28
+ c.host = host
29
29
  end
30
+ end
31
+ let(:url) { 'https://example.com/rest/test' }
32
+ subject { VSphereAutomation::ApiClient.new(config) }
30
33
 
31
- context 'base_path' do
32
- it "prepends a slash to base_path" do
33
- VSphereAutomation.configure { |c| c.base_path = 'v4/dog' }
34
- expect(VSphereAutomation::Configuration.default.base_path).to eq('/v4/dog')
35
- end
34
+ it 'adds headers to request' do
35
+ headers = { 'foo' => 'bar' }
36
+ stub_request(:get, url).with(headers: headers)
36
37
 
37
- it "doesn't prepend a slash if one is already there" do
38
- VSphereAutomation.configure { |c| c.base_path = '/v4/dog' }
39
- expect(VSphereAutomation::Configuration.default.base_path).to eq('/v4/dog')
40
- end
38
+ subject.call_api(:GET, '/test', header_params: headers)
41
39
 
42
- it "ends up as a blank string if nil" do
43
- VSphereAutomation.configure { |c| c.base_path = nil }
44
- expect(VSphereAutomation::Configuration.default.base_path).to eq('')
45
- end
46
- end
40
+ expect(a_request(:get, url).with(headers: headers)).to have_been_made
47
41
  end
48
- end
49
42
 
50
- describe 'params_encoding in #build_request' do
51
- let(:config) { VSphereAutomation::Configuration.new }
52
- let(:api_client) { VSphereAutomation::ApiClient.new(config) }
43
+ it 'adds query parameters to request' do
44
+ query_params = { 'foo' => 'bar' }
45
+ stub_request(:get, url).with(query: query_params)
53
46
 
54
- it 'defaults to nil' do
55
- expect(VSphereAutomation::Configuration.default.params_encoding).to eq(nil)
56
- expect(config.params_encoding).to eq(nil)
47
+ subject.call_api(:GET, '/test', query_params: query_params)
57
48
 
58
- request = api_client.build_request(:get, '/test')
59
- expect(request.options[:params_encoding]).to eq(nil)
49
+ expect(a_request(:get, url).with(query: query_params)).to have_been_made
60
50
  end
61
51
 
62
- it 'can be customized' do
63
- config.params_encoding = :multi
64
- request = api_client.build_request(:get, '/test')
65
- expect(request.options[:params_encoding]).to eq(:multi)
52
+ it 'adds form parameters to the request body' do
53
+ form_params = { 'foo' => 'bar' }
54
+ body = form_params.to_a.map { |e| e.join('=') }.join('&')
55
+ stub_request(:get, url).with(body: body)
56
+
57
+ subject.call_api(:GET, '/test', form_params: form_params)
58
+
59
+ expect(a_request(:get, url).with(body: body)).to have_been_made
66
60
  end
67
- end
68
61
 
69
- describe 'timeout in #build_request' do
70
- let(:config) { VSphereAutomation::Configuration.new }
71
- let(:api_client) { VSphereAutomation::ApiClient.new(config) }
62
+ it 'uses basic auth information from configuration' do
63
+ auth_name = 'basic_auth'
64
+ auth_header = { config.auth_settings[auth_name][:key] =>
65
+ config.auth_settings[auth_name][:value] }
66
+ stub_request(:get, url).with(headers: auth_header)
72
67
 
73
- it 'defaults to 0' do
74
- expect(VSphereAutomation::Configuration.default.timeout).to eq(0)
75
- expect(config.timeout).to eq(0)
68
+ subject.call_api(:GET, '/test', auth_names: [auth_name])
76
69
 
77
- request = api_client.build_request(:get, '/test')
78
- expect(request.options[:timeout]).to eq(0)
70
+ expect(a_request(:get, url)
71
+ .with(headers: auth_header)).to have_been_made
79
72
  end
80
73
 
81
- it 'can be customized' do
82
- config.timeout = 100
83
- request = api_client.build_request(:get, '/test')
84
- expect(request.options[:timeout]).to eq(100)
85
- end
86
- end
74
+ it 'use API key information from configuration' do
75
+ auth_name = 'api_key'
76
+ config.api_key[config.auth_settings[auth_name][:key]] = 'foo'
77
+ auth_header = { config.auth_settings[auth_name][:key] =>
78
+ config.auth_settings[auth_name][:value] }
79
+ stub_request(:get, url).with(headers: auth_header)
87
80
 
88
- describe '#deserialize' do
89
- it "handles Array<Integer>" do
90
- api_client = VSphereAutomation::ApiClient.new
91
- headers = { 'Content-Type' => 'application/json' }
92
- response = double('response', headers: headers, body: '[12, 34]')
93
- data = api_client.deserialize(response, 'Array<Integer>')
94
- expect(data).to be_instance_of(Array)
95
- expect(data).to eq([12, 34])
96
- end
97
-
98
- it 'handles Array<Array<Integer>>' do
99
- api_client = VSphereAutomation::ApiClient.new
100
- headers = { 'Content-Type' => 'application/json' }
101
- response = double('response', headers: headers, body: '[[12, 34], [56]]')
102
- data = api_client.deserialize(response, 'Array<Array<Integer>>')
103
- expect(data).to be_instance_of(Array)
104
- expect(data).to eq([[12, 34], [56]])
105
- end
106
-
107
- it 'handles Hash<String, String>' do
108
- api_client = VSphereAutomation::ApiClient.new
109
- headers = { 'Content-Type' => 'application/json' }
110
- response = double('response', headers: headers, body: '{"message": "Hello"}')
111
- data = api_client.deserialize(response, 'Hash<String, String>')
112
- expect(data).to be_instance_of(Hash)
113
- expect(data).to eq(:message => 'Hello')
114
- end
115
- end
81
+ subject.call_api(:GET, '/test', auth_names: [auth_name])
116
82
 
117
- describe "#object_to_hash" do
118
- it 'ignores nils and includes empty arrays' do
119
- # uncomment below to test object_to_hash for model
120
- # api_client = VSphereAutomation::ApiClient.new
121
- # _model = VSphereAutomation::ModelName.new
122
- # update the model attribute below
123
- # _model.id = 1
124
- # update the expected value (hash) below
125
- # expected = {id: 1, name: '', tags: []}
126
- # expect(api_client.object_to_hash(_model)).to eq(expected)
83
+ expect(a_request(:get, url)
84
+ .with(headers: auth_header)).to have_been_made
127
85
  end
128
- end
129
86
 
130
- describe '#build_collection_param' do
131
- let(:param) { ['aa', 'bb', 'cc'] }
132
- let(:api_client) { VSphereAutomation::ApiClient.new }
87
+ it 'updates api_key from responses with set-cookie header' do
88
+ key = config.auth_settings['api_key'][:key]
89
+ value = 'foo'
90
+ cookie = "#{key}=#{value};Path=/rest;Secure;HttpOnly"
91
+ set_cookie_header = { 'set-cookie' => cookie }
92
+ auth_header = { key => value }
93
+ stub_request(:get, url + '1').to_return(headers: set_cookie_header)
94
+ stub_request(:get, url + '2').with(headers: auth_header)
95
+
96
+ subject.call_api(:GET, '/test1')
97
+ subject.call_api(:GET, '/test2', auth_names: ['api_key'])
133
98
 
134
- it 'works for csv' do
135
- expect(api_client.build_collection_param(param, :csv)).to eq('aa,bb,cc')
99
+ expect(a_request(:get, url + '1')).to have_been_made
100
+ expect(a_request(:get, url + '2')
101
+ .with(headers: auth_header)).to have_been_made
136
102
  end
137
103
 
138
- it 'works for ssv' do
139
- expect(api_client.build_collection_param(param, :ssv)).to eq('aa bb cc')
104
+ it 'updates api_key from responses with api_key header' do
105
+ key = config.auth_settings['api_key'][:key]
106
+ value = 'foo'
107
+ auth_header = { key => value }
108
+
109
+ stub_request(:get, url + '1').to_return(headers: auth_header)
110
+ stub_request(:get, url + '2').with(headers: auth_header)
111
+
112
+ subject.call_api(:GET, '/test1')
113
+ subject.call_api(:GET, '/test2', auth_names: ['api_key'])
114
+
115
+ expect(a_request(:get, url + '1')).to have_been_made
116
+ expect(a_request(:get, url + '2')
117
+ .with(headers: auth_header)).to have_been_made
140
118
  end
141
119
 
142
- it 'works for tsv' do
143
- expect(api_client.build_collection_param(param, :tsv)).to eq("aa\tbb\tcc")
120
+ it 'adds the body to requests when available' do
121
+ body = { foo: 'bar' }.to_json
122
+ stub_request(:post, url).with(body: body)
123
+
124
+ subject.call_api(:POST, '/test', body: body)
125
+
126
+ expect(a_request(:post, url).with(body: body)).to have_been_made
144
127
  end
145
128
 
146
- it 'works for pipes' do
147
- expect(api_client.build_collection_param(param, :pipes)).to eq('aa|bb|cc')
129
+ it 'sets the Content-Type on requests when available' do
130
+ content_type = { 'Content-Type' => 'application/json' }
131
+ body = { foo: 'bar' }.to_json
132
+
133
+ stub_request(:post, url).with(body: body, headers: content_type)
134
+
135
+ subject.call_api(:POST, '/test', body: body, header_params: content_type)
136
+
137
+ expect(a_request(:post, url)
138
+ .with(body: body, headers: content_type)).to have_been_made
148
139
  end
140
+ end
149
141
 
150
- it 'works for multi' do
151
- expect(api_client.build_collection_param(param, :multi)).to eq(['aa', 'bb', 'cc'])
142
+ describe '#object_to_http_body' do
143
+ context 'when given nil' do
144
+ it 'returns the object as is' do
145
+ expect(subject.object_to_http_body(nil)).to be_nil
146
+ end
152
147
  end
153
148
 
154
- it 'fails for invalid collection format' do
155
- expect(proc { api_client.build_collection_param(param, :INVALID) }).to raise_error(RuntimeError, 'unknown collection format: :INVALID')
149
+ context 'when given a string' do
150
+ it 'returns the object as is' do
151
+ expect(subject.object_to_http_body('asdf')).to eq('asdf')
152
+ end
156
153
  end
157
- end
158
154
 
159
- describe '#json_mime?' do
160
- let(:api_client) { VSphereAutomation::ApiClient.new }
155
+ context 'when given an object that responds to `to_hash`' do
156
+ it 'returns that object as JSON' do
157
+ obj = OpenStruct.new(foo: 'bar', baz: 'quux')
158
+ obj.to_hash = obj.to_h
159
+ json = obj.to_hash.to_json
161
160
 
162
- it 'works' do
163
- expect(api_client.json_mime?(nil)).to eq false
164
- expect(api_client.json_mime?('')).to eq false
161
+ expect(subject.object_to_http_body(obj)).to eq(json)
162
+ end
163
+ end
165
164
 
166
- expect(api_client.json_mime?('application/json')).to eq true
167
- expect(api_client.json_mime?('application/json; charset=UTF8')).to eq true
168
- expect(api_client.json_mime?('APPLICATION/JSON')).to eq true
165
+ context 'when given an array' do
166
+ it 'returns a JSON array of objects' do
167
+ obj = OpenStruct.new(foo: 'bar', baz: 'quux')
168
+ obj.to_hash = obj.to_h
169
+ json = obj.to_hash.to_json
169
170
 
170
- expect(api_client.json_mime?('application/xml')).to eq false
171
- expect(api_client.json_mime?('text/plain')).to eq false
172
- expect(api_client.json_mime?('application/jsonp')).to eq false
171
+ expect(subject.object_to_http_body([obj])).to eq([json])
172
+ end
173
173
  end
174
174
  end
175
175
 
176
176
  describe '#select_header_accept' do
177
- let(:api_client) { VSphereAutomation::ApiClient.new }
177
+ context 'when given anything other than an array' do
178
+ it 'returns application/json as a default' do
179
+ expect(subject.select_header_accept(nil)).to eq('application/json')
180
+ expect(subject.select_header_accept('')).to eq('application/json')
181
+ expect(subject.select_header_accept(1)).to eq('application/json')
182
+ end
183
+ end
184
+
185
+ context 'when given a list of types' do
186
+ context 'that includes a JSON type' do
187
+ it 'returns the first type containing JSON' do
188
+ xml = 'application/xml'
189
+ json = 'application/json'
178
190
 
179
- it 'works' do
180
- expect(api_client.select_header_accept(nil)).to be_nil
181
- expect(api_client.select_header_accept([])).to be_nil
191
+ expect(subject.select_header_accept([xml, json])).to eq(json)
192
+ end
193
+ end
182
194
 
183
- expect(api_client.select_header_accept(['application/json'])).to eq('application/json')
184
- expect(api_client.select_header_accept(['application/xml', 'application/json; charset=UTF8'])).to eq('application/json; charset=UTF8')
185
- expect(api_client.select_header_accept(['APPLICATION/JSON', 'text/html'])).to eq('APPLICATION/JSON')
195
+ context 'that does not include a JSON type' do
196
+ it 'returns the all of the types' do
197
+ xml = 'application/xml'
198
+ html = 'text/html'
199
+ result = [xml, html].join(', ')
186
200
 
187
- expect(api_client.select_header_accept(['application/xml'])).to eq('application/xml')
188
- expect(api_client.select_header_accept(['text/html', 'application/xml'])).to eq('text/html,application/xml')
201
+ expect(subject.select_header_accept([xml, html])).to eq(result)
202
+ end
203
+ end
189
204
  end
190
205
  end
191
206
 
192
207
  describe '#select_header_content_type' do
193
- let(:api_client) { VSphereAutomation::ApiClient.new }
208
+ context 'when given anything other than an array' do
209
+ it 'returns application/json as a default' do
210
+ expect(subject.select_header_content_type(nil)).to eq('application/json')
211
+ expect(subject.select_header_content_type('')).to eq('application/json')
212
+ expect(subject.select_header_content_type(1)).to eq('application/json')
213
+ end
214
+ end
194
215
 
195
- it 'works' do
196
- expect(api_client.select_header_content_type(nil)).to eq('application/json')
197
- expect(api_client.select_header_content_type([])).to eq('application/json')
216
+ context 'when given a list of types' do
217
+ context 'that includes a JSON type' do
218
+ it 'returns the first type containing JSON' do
219
+ xml = 'application/xml'
220
+ json = 'application/json'
198
221
 
199
- expect(api_client.select_header_content_type(['application/json'])).to eq('application/json')
200
- expect(api_client.select_header_content_type(['application/xml', 'application/json; charset=UTF8'])).to eq('application/json; charset=UTF8')
201
- expect(api_client.select_header_content_type(['APPLICATION/JSON', 'text/html'])).to eq('APPLICATION/JSON')
202
- expect(api_client.select_header_content_type(['application/xml'])).to eq('application/xml')
203
- expect(api_client.select_header_content_type(['text/plain', 'application/xml'])).to eq('text/plain')
204
- end
205
- end
222
+ expect(subject.select_header_content_type([xml, json])).to eq(json)
223
+ end
224
+ end
206
225
 
207
- describe '#sanitize_filename' do
208
- let(:api_client) { VSphereAutomation::ApiClient.new }
209
-
210
- it 'works' do
211
- expect(api_client.sanitize_filename('sun')).to eq('sun')
212
- expect(api_client.sanitize_filename('sun.gif')).to eq('sun.gif')
213
- expect(api_client.sanitize_filename('../sun.gif')).to eq('sun.gif')
214
- expect(api_client.sanitize_filename('/var/tmp/sun.gif')).to eq('sun.gif')
215
- expect(api_client.sanitize_filename('./sun.gif')).to eq('sun.gif')
216
- expect(api_client.sanitize_filename('..\sun.gif')).to eq('sun.gif')
217
- expect(api_client.sanitize_filename('\var\tmp\sun.gif')).to eq('sun.gif')
218
- expect(api_client.sanitize_filename('c:\var\tmp\sun.gif')).to eq('sun.gif')
219
- expect(api_client.sanitize_filename('.\sun.gif')).to eq('sun.gif')
226
+ context 'that does not include a JSON type' do
227
+ it 'returns the first type' do
228
+ xml = 'application/xml'
229
+ html = 'text/html'
230
+
231
+ expect(subject.select_header_content_type([xml, html])).to eq(xml)
232
+ end
233
+ end
220
234
  end
221
235
  end
222
236
  end
data/spec/spec_helper.rb CHANGED
@@ -8,6 +8,9 @@
8
8
 
9
9
  # load the gem
10
10
  require 'vsphere-automation-runtime'
11
+ require 'webmock/rspec'
12
+
13
+ WebMock.disable_net_connect!(allow_localhost: true)
11
14
 
12
15
  # The following was generated by the `rspec --init` command. Conventionally, all
13
16
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
@@ -23,8 +23,6 @@ Gem::Specification.new do |s|
23
23
  s.license = 'MIT'
24
24
  s.required_ruby_version = ">= 2.3"
25
25
 
26
- s.add_runtime_dependency 'typhoeus', '~> 1.3'
27
-
28
26
  s.add_development_dependency 'bundler', '~> 2.0'
29
27
  s.add_development_dependency 'pry', '~> 0.12.2'
30
28
  s.add_development_dependency 'rake', '~> 12.3'
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vsphere-automation-runtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - J.R. Garcia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-22 00:00:00.000000000 Z
11
+ date: 2019-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: typhoeus
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.3'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.3'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: bundler
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -139,8 +125,8 @@ files:
139
125
  - lib/vsphere-automation-runtime/api_error.rb
140
126
  - lib/vsphere-automation-runtime/configuration.rb
141
127
  - lib/vsphere-automation-runtime/version.rb
142
- - pkg/vsphere-automation-runtime-0.2.1.gem
143
- - pkg/vsphere-automation-runtime-0.2.2.gem
128
+ - pkg/vsphere-automation-runtime-0.3.0.gem
129
+ - pkg/vsphere-automation-runtime-0.4.0.gem
144
130
  - spec/api_client_spec.rb
145
131
  - spec/configuration_spec.rb
146
132
  - spec/spec_helper.rb