Module: OneviewSDK::Rest

Included in:
Client
Defined in:
lib/oneview-sdk/rest.rb

Overview

Contains all of the methods for making API REST calls

Constant Summary collapse

READ_TIMEOUT =

in seconds, 5 minutes

300
RESPONSE_CODE_OK =
200
RESPONSE_CODE_CREATED =
201
RESPONSE_CODE_ACCEPTED =
202
RESPONSE_CODE_NO_CONTENT =
204
RESPONSE_CODE_BAD_REQUEST =
400
RESPONSE_CODE_UNAUTHORIZED =
401
RESPONSE_CODE_NOT_FOUND =
404

Instance Method Summary collapse

Instance Method Details

#download_file(path, local_drive_path) ⇒ Boolean

Download a file from a specific uri

Parameters:

  • path (String)

    The url path starting with “/”

  • local_drive_path (String)

    Path to save file downloaded

Returns:

  • (Boolean)

    if file was downloaded



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/oneview-sdk/rest.rb', line 176

def download_file(path, local_drive_path)
  uri = URI.parse(Addressable::URI.escape(@url + path))
  http_request = build_http_object(uri)
  req = build_request(:get, uri, {}, @api_version.to_s)

  http_request.start do |http|
    http.request(req) do |res|
      response_handler(res) unless res.code.to_i.between?(200, 204)
      File.open(local_drive_path, 'wb') do |file|
        res.read_body do |segment|
          file.write(segment)
        end
      end
    end
  end
  true
end

#response_handler(response, wait_on_task = true) ⇒ Hash

Handles the response from a rest call.

If an asynchronous task was started, this waits for it to complete.

Parameters:

  • response (HTTPResponse)

    HTTP response

  • wait_on_task (Boolean) (defaults to: true)

    Wait on task (or just return task details)

Returns:

  • (Hash)

    The parsed JSON body

Raises:



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/oneview-sdk/rest.rb', line 208

def response_handler(response, wait_on_task = true)
  case response.code.to_i
  when RESPONSE_CODE_OK # Synchronous read/query
    begin
      return JSON.parse(response.body)
    rescue JSON::ParserError => e
      @logger.warn "Failed to parse JSON response. #{e}"
      return response.body
    end
  when RESPONSE_CODE_CREATED # Synchronous add
    JSON.parse(response.body)
  when RESPONSE_CODE_ACCEPTED # Asynchronous add, update or delete
    return JSON.parse(response.body) unless wait_on_task
    @logger.debug "Waiting for task: response.header['location']"
    uri = response.header['location'] || JSON.parse(response.body)['uri'] # If task uri is not returned in header
    task = wait_for(uri)
    return true unless task['associatedResource'] && task['associatedResource']['resourceUri']
    resource_data = rest_get(task['associatedResource']['resourceUri'])
    JSON.parse(resource_data.body)
  when RESPONSE_CODE_NO_CONTENT # Synchronous delete
    {}
  when RESPONSE_CODE_BAD_REQUEST
    BadRequest.raise! "400 BAD REQUEST #{response.body}", response
  when RESPONSE_CODE_UNAUTHORIZED
    Unauthorized.raise! "401 UNAUTHORIZED #{response.body}", response
  when RESPONSE_CODE_NOT_FOUND
    NotFound.raise! "404 NOT FOUND #{response.body}", response
  else
    RequestError.raise! "#{response.code} #{response.body}", response
  end
end

#rest_api(type, path, options = {}, api_ver = @api_version, redirect_limit = 3) ⇒ NetHTTPResponse

Makes a restful API request to OneView

Parameters:

  • type (Symbol)

    The rest method/type Options: [:get, :post, :delete, :patch, :put]

  • path (String)

    The path for the request. Usually starts with “/rest/”

  • options (Hash) (defaults to: {})

    The options for the request

  • api_ver (Integer) (defaults to: @api_version)

    The api version to use when interracting with this resource

  • redirect_limit (Integer) (defaults to: 3)

    Number of redirects it is allowed to follow

Options Hash (options):

  • :body (String)

    Hash to be converted into json and set as the request body

  • :Content-Type (String) — default: 'application/json'

    Set to nil or :none to have this option removed

  • :X-API-Version (Integer) — default: client.api_version

    API version to use for this request

  • :auth (Integer) — default: client.token

    Authentication token to use for this request

Returns:

  • (NetHTTPResponse)

    Response object

Raises:

  • (OpenSSL::SSL::SSLError)

    if SSL validation of OneView instance’s certificate failed



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/oneview-sdk/rest.rb', line 36

def rest_api(type, path, options = {}, api_ver = @api_version, redirect_limit = 3)
  @logger.debug "Making :#{type} rest call to #{@url}#{path}"
  raise InvalidRequest, 'Must specify path' unless path
  uri = URI.parse(Addressable::URI.escape(@url + path))
  http = build_http_object(uri)
  request = build_request(type, uri, options.dup, api_ver)
  response = http.request(request)
  @logger.debug "  Response: Code=#{response.code}. Headers=#{response.to_hash}\n  Body=#{response.body}"
  if response.class <= Net::HTTPRedirection && redirect_limit > 0 && response['location']
    @logger.debug "Redirecting to #{response['location']}"
    return rest_api(type, response['location'], options, api_ver, redirect_limit - 1)
  end
  response
rescue OpenSSL::SSL::SSLError => e
  msg = 'SSL verification failed for request. Please either:'
  msg += "\n  1. Install the certificate into your system's cert store"
  msg += ". Using cert store: #{ENV['SSL_CERT_FILE']}" if ENV['SSL_CERT_FILE']
  msg += "\n  2. Run oneview-sdk-ruby cert import #{@url}"
  msg += "\n  3. Set the :ssl_enabled option to false for your client (NOT RECOMMENDED)"
  @logger.error msg
  raise e
end

#rest_delete(path, options = {}, api_ver = @api_version) ⇒ NetHTTPResponse

Makes a restful DELETE request to OneView

Parameters:

  • path (String)

    The path for the request. Usually starts with “/rest/”

  • options (Hash) (defaults to: {})

    The options for the request

  • api_ver (Integer) (defaults to: @api_version)

    The api version to use when interracting with this resource

Options Hash (options):

  • :body (String)

    Hash to be converted into json and set as the request body

  • :Content-Type (String) — default: 'application/json'

    Set to nil or :none to have this option removed

  • :X-API-Version (Integer) — default: client.api_version

    API version to use for this request

  • :auth (Integer) — default: client.token

    Authentication token to use for this request

Returns:

  • (NetHTTPResponse)

    Response object



119
120
121
# File 'lib/oneview-sdk/rest.rb', line 119

def rest_delete(path, options = {}, api_ver = @api_version)
  rest_api(:delete, path, options, api_ver)
end

#rest_get(path, options = {}, api_ver = @api_version) ⇒ NetHTTPResponse

Makes a restful GET request to OneView

Parameters:

  • path (String)

    The path for the request. Usually starts with “/rest/”

  • options (Hash) (defaults to: {})

    The options for the request

  • api_ver (Integer) (defaults to: @api_version)

    The api version to use when interracting with this resource

Options Hash (options):

  • :Content-Type (String) — default: 'application/json'

    Set to nil or :none to have this option removed

  • :X-API-Version (Integer) — default: client.api_version

    API version to use for this request

  • :auth (Integer) — default: client.token

    Authentication token to use for this request

Returns:

  • (NetHTTPResponse)

    Response object



67
68
69
# File 'lib/oneview-sdk/rest.rb', line 67

def rest_get(path, options = {}, api_ver = @api_version)
  rest_api(:get, path, options, api_ver)
end

#rest_patch(path, options = {}, api_ver = @api_version) ⇒ NetHTTPResponse

Makes a restful PATCH request to OneView

Parameters:

  • path (String)

    The path for the request. Usually starts with “/rest/”

  • options (Hash) (defaults to: {})

    The options for the request

  • api_ver (Integer) (defaults to: @api_version)

    The api version to use when interracting with this resource

Options Hash (options):

  • :body (String)

    Hash to be converted into json and set as the request body

  • :Content-Type (String) — default: 'application/json'

    Set to nil or :none to have this option removed

  • :X-API-Version (Integer) — default: client.api_version

    API version to use for this request

  • :auth (Integer) — default: client.token

    Authentication token to use for this request

Returns:

  • (NetHTTPResponse)

    Response object



106
107
108
# File 'lib/oneview-sdk/rest.rb', line 106

def rest_patch(path, options = {}, api_ver = @api_version)
  rest_api(:patch, path, options, api_ver)
end

#rest_post(path, options = {}, api_ver = @api_version) ⇒ NetHTTPResponse

Makes a restful POST request to OneView

Parameters:

  • path (String)

    The path for the request. Usually starts with “/rest/”

  • options (Hash) (defaults to: {})

    The options for the request

  • api_ver (Integer) (defaults to: @api_version)

    The api version to use when interracting with this resource

Options Hash (options):

  • :body (String)

    Hash to be converted into json and set as the request body

  • :Content-Type (String) — default: 'application/json'

    Set to nil or :none to have this option removed

  • :X-API-Version (Integer) — default: client.api_version

    API version to use for this request

  • :auth (Integer) — default: client.token

    Authentication token to use for this request

Returns:

  • (NetHTTPResponse)

    Response object



80
81
82
# File 'lib/oneview-sdk/rest.rb', line 80

def rest_post(path, options = {}, api_ver = @api_version)
  rest_api(:post, path, options, api_ver)
end

#rest_put(path, options = {}, api_ver = @api_version) ⇒ NetHTTPResponse

Makes a restful PUT request to OneView

Parameters:

  • path (String)

    The path for the request. Usually starts with “/rest/”

  • options (Hash) (defaults to: {})

    The options for the request

  • api_ver (Integer) (defaults to: @api_version)

    The api version to use when interracting with this resource

Options Hash (options):

  • :body (String)

    Hash to be converted into json and set as the request body

  • :Content-Type (String) — default: 'application/json'

    Set to nil or :none to have this option removed

  • :X-API-Version (Integer) — default: client.api_version

    API version to use for this request

  • :auth (Integer) — default: client.token

    Authentication token to use for this request

Returns:

  • (NetHTTPResponse)

    Response object



93
94
95
# File 'lib/oneview-sdk/rest.rb', line 93

def rest_put(path, options = {}, api_ver = @api_version)
  rest_api(:put, path, options, api_ver)
end

#upload_file(file_path, path, options = {}, timeout = READ_TIMEOUT) ⇒ Hash

Uploads a file to a specific uri

Parameters:

  • file_path (String)
  • path (String)

    The url path starting with “/”

  • options (Hash) (defaults to: {})

    The options for the request. Default is {}.

  • timeout (Integer) (defaults to: READ_TIMEOUT)

    The number of seconds to wait for completing the request. Default is 300.

Options Hash (options):

  • :body (String)

    Hash to be converted into json and set as the request body

  • :header (String)

    Hash to be converted into json and set as the request header

  • :file_name (String)

    String that defines the new file name

Returns:

  • (Hash)

    The parsed JSON body of response

Raises:



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/oneview-sdk/rest.rb', line 132

def upload_file(file_path, path, options = {}, timeout = READ_TIMEOUT)
  raise NotFound, "ERROR: File '#{file_path}' not found!" unless File.file?(file_path)
  options = Hash[options.map { |k, v| [k.to_s, v] }]
  body_params = options['body'] || {}
  headers_params = options['header'] || {}
  headers = {
    'Content-Type' => 'multipart/form-data',
    'X-Api-Version' => @api_version.to_s,
    'auth' => @token
  }
  headers.merge!(headers_params)

  File.open(file_path) do |file|
    name_to_show = options['file_name'] || File.basename(file_path)
    body_params['file'] = UploadIO.new(file, 'application/octet-stream', name_to_show)

    uri = URI.parse(Addressable::URI.escape(@url + path))
    http_request = build_http_object(uri)
    http_request.read_timeout = timeout

    req = Net::HTTP::Post::Multipart.new(
      uri.path,
      body_params,
      headers
    )

    http_request.start do |http|
      begin
        response = http.request(req)
        return response_handler(response)
      rescue Net::ReadTimeout
        raise "The connection was closed because the timeout of #{timeout} seconds has expired."\
          'You can specify the timeout in seconds by passing the timeout on the method call.'\
          'Interrupted file uploads may result in corrupted file remaining in the appliance.'\
          'HPE recommends checking the appliance for corrupted file and removing it.'
      end
    end
  end
end