Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
ricardogpsf committed Mar 2, 2017
1 parent 2f393c0 commit 0a95269
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 240 deletions.
Expand Up @@ -50,7 +50,7 @@ def self.create_from_file(client, file_path, artifact_name, timeout = OneviewSDK
file_name = File.basename(file_path)
end

params = { 'name' => file_name }
params = { 'body' => { 'name' => file_name } }
body = client.upload_file(file_path, BASE_URI, params, timeout)
ArtifactBundle.new(client, body)
end
Expand Down
67 changes: 6 additions & 61 deletions lib/oneview-sdk/image-streamer/resource/api300/golden_image.rb
Expand Up @@ -10,15 +10,13 @@
# language governing permissions and limitations under the License.

require_relative 'resource'
require 'net/http/post/multipart'

module OneviewSDK
module ImageStreamer
module API300
# Golden Image resource implementation for Image Streamer
class GoldenImage < Resource
BASE_URI = '/rest/golden-images'.freeze
READ_TIMEOUT = 300 # in seconds (5 minutes)
ACCEPTED_FORMATS = %w(.zip .ZIP).freeze # Supported upload extensions

# Create a resource object, associate it with a client, and set its properties.
Expand All @@ -44,36 +42,10 @@ def download_details_archive(file_path)
# Downloads the content of the selected golden image to the specified file path.
# @param [String] file_path
# @param [Integer] timeout The number of seconds to wait for the request to complete
# @return [True] When was saved successfully
def download(file_path, timeout = READ_TIMEOUT)
# @return [True] When it was saved successfully
def download(file_path)
ensure_client && ensure_uri
uri = URI.parse(URI.escape("#{client.url}#{BASE_URI}/download/#{@data['uri'].split('/').last}"))
req = Net::HTTP::Get.new(uri.request_uri)

options = {}
options['Content-Type'] = 'application/json'
options['X-Api-Version'] = @client.api_version.to_s
options['auth'] = @client.token
options.each do |key, val|
req[key] = val
end

http_request = Net::HTTP.new(uri.host, uri.port)
http_request.use_ssl = true
http_request.verify_mode = OpenSSL::SSL::VERIFY_NONE
http_request.read_timeout = timeout

http_request.start do |http|
http.request(req) do |res|
client.response_handler(res) unless res.code.to_i.between?(200, 204)
File.open(file_path, 'wb') do |file|
res.read_body do |segment|
file.write(segment)
end
end
end
end
true
client.download_file("#{BASE_URI}/download/#{@data['uri'].split('/').last}", file_path)
end

# Upload a golden image from the specified local file path.
Expand All @@ -85,40 +57,13 @@ def download(file_path, timeout = READ_TIMEOUT)
# @option data_options [String] :description The description of the Golden Image (required)
# @param [Integer] timeout The number of seconds to wait for the request to complete
# @return [OneviewSDK::ImageStreamer::API300::GoldenImage] if the upload was successful, return a GoldenImage object
def self.add(client, file_path, data_options, timeout = READ_TIMEOUT)
def self.add(client, file_path, data_options, timeout = OneviewSDK::Rest::READ_TIMEOUT)
data_options = Hash[data_options.map { |k, v| [k.to_s, v] }] # Convert symbols hash keys to string
raise NotFound, "ERROR: File '#{file_path}' not found!" unless File.file?(file_path)
raise InvalidFormat, 'ERROR: File with extension not supported!' unless ACCEPTED_FORMATS.include? File.extname(file_path)
raise IncompleteResource, 'Please set the name of the golden image!' unless data_options['name']
raise IncompleteResource, 'Please set the description of the golden image!' unless data_options['description']
options = {}
options['Content-Type'] = 'multipart/form-data'
options['X-Api-Version'] = client.api_version.to_s
options['auth'] = client.token
options['file'] = File.basename(file_path)
url = URI.parse(URI.escape("#{client.url}#{BASE_URI}"))

File.open(file_path) do |file|
req = Net::HTTP::Post::Multipart.new(
url.path,
{ 'file' => UploadIO.new(file, 'application/octet-stream', File.basename(file_path)) }.merge(data_options),
options
)

http_request = Net::HTTP.new(url.host, url.port)
http_request.use_ssl = true if url.scheme == 'https'
if client.ssl_enabled
http_request.cert_store = client.cert_store if client.cert_store
else http_request.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
http_request.read_timeout = timeout

http_request.start do |http|
response = http.request(req)
data = client.response_handler(response)
return OneviewSDK::ImageStreamer::API300::GoldenImage.new(client, data)
end
end
data = client.upload_file(file_path, BASE_URI, { 'body' => data_options }, timeout)
GoldenImage.new(client, data)
end

# Sets the OS volume
Expand Down
40 changes: 3 additions & 37 deletions lib/oneview-sdk/resource/api200/firmware_bundle.rb
Expand Up @@ -9,54 +9,20 @@
# CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.

require 'net/http/post/multipart'

module OneviewSDK
module API200
# Firmware bundle resource implementation
class FirmwareBundle
BASE_URI = '/rest/firmware-bundles'.freeze
READ_TIMEOUT = 300 # in seconds, 5 minutes

# Uploads a firmware bundle file
# @param [OneviewSDK::Client] client The client object for the OneView appliance
# @param [String] file_path
# @param [Integer] timeout The number of seconds to wait for completing the request
# @return [OneviewSDK::FirmwareDriver] if the upload was successful, return a FirmwareDriver object
def self.add(client, file_path, timeout = READ_TIMEOUT)
raise NotFound, "ERROR: File '#{file_path}' not found!" unless File.file?(file_path)
options = {}
options['Content-Type'] = 'multipart/form-data'
options['X-Api-Version'] = client.api_version.to_s
options['auth'] = client.token
options['uploadfilename'] = File.basename(file_path)
url = URI.parse(URI.escape("#{client.url}#{BASE_URI}"))

File.open(file_path) do |file|
req = Net::HTTP::Post::Multipart.new(
url.path,
{ 'file' => UploadIO.new(file, 'application/octet-stream', File.basename(file_path)) },
options
)

http_request = Net::HTTP.new(url.host, url.port)
http_request.use_ssl = true
http_request.verify_mode = OpenSSL::SSL::VERIFY_NONE
http_request.read_timeout = timeout

http_request.start do |http|
begin
response = http.request(req)
data = client.response_handler(response)
return OneviewSDK::FirmwareDriver.new(client, data)
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 firmware uploads may result in corrupted firmware remaining in the appliance.'\
'HPE recommends checking the appliance for corrupted firmware and removing it.'
end
end
end
def self.add(client, file_path, timeout = OneviewSDK::Rest::READ_TIMEOUT)
result = client.upload_file(file_path, BASE_URI, {}, timeout)
OneviewSDK::FirmwareDriver.new(client, result)
end
end
end
Expand Down
26 changes: 18 additions & 8 deletions lib/oneview-sdk/rest.rb
Expand Up @@ -118,20 +118,23 @@ def rest_delete(path, options = {}, api_ver = @api_version)
# Uploads a file to a specific uri
# @param [String] file_path
# @param [String] path The url path starting with "/"
# @param [Hash] body_params The params to append to body of http request. Default is {}.
# @option body_params [String] 'name' The name to show (when resource accepts a name)
# @param [Hash] options The options for the request. Default is {}.
# @option options [String] :body Hash to be converted into json and set as the request body
# @param [Integer] timeout The number of seconds to wait for completing the request. Default is 300.
# @return [Hash] The parsed JSON body of response
def upload_file(file_path, path, body_params = {}, timeout = READ_TIMEOUT)
def upload_file(file_path, path, options = {}, timeout = READ_TIMEOUT)
raise NotFound, "ERROR: File '#{file_path}' not found!" unless File.file?(file_path)
options = {
options = options.dup
body_params = options.delete('body') || options.delete(:body) || {}
headers = {
'Content-Type' => 'multipart/form-data',
'X-Api-Version' => @api_version.to_s,
'auth' => @token
}
headers.merge!(options)

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

uri = URI.parse(URI.escape(@url + path))
Expand All @@ -141,12 +144,19 @@ def upload_file(file_path, path, body_params = {}, timeout = READ_TIMEOUT)
req = Net::HTTP::Post::Multipart.new(
uri.path,
body_params,
options
headers
)

http_request.start do |http|
response = http.request(req)
return response_handler(response)
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 firmware uploads may result in corrupted firmware remaining in the appliance.'\
'HPE recommends checking the appliance for corrupted firmware and removing it.'
end
end
end
end
Expand Down
Expand Up @@ -107,7 +107,10 @@

describe '::create_backup_from_file!' do
it 'should create a backup from local file and extract it' do
expect { klass.create_backup_from_file!($client_i3s_300, deployment_group, @backup_bundle_file_path, 'BundleBackup') }.not_to raise_error
item = nil
expect { item = klass.create_backup_from_file!($client_i3s_300, deployment_group, @backup_bundle_file_path, 'BundleBackup') }.not_to raise_error
expect(item).to be
expect(item['name']).to eq('BundleBackup')
end
end

Expand Down
26 changes: 6 additions & 20 deletions spec/unit/image-streamer/api300/golden_image_spec.rb
Expand Up @@ -62,10 +62,6 @@
end

describe '#add' do
it 'raises an exception when file does not exist' do
expect { klass.add(@client_i3s_300, 'file.zip', {}) }.to raise_error(OneviewSDK::NotFound, //)
end

it 'raises an exception when name of the golden image is not informed with hash keys symbols' do
allow(File).to receive(:file?).and_return(true)
options = { description: 'anything' }
Expand Down Expand Up @@ -97,28 +93,18 @@

it 'should use default http read_timeout when new value is not passed as parameter' do
options = { name: 'image1', description: 'anything' }
allow(File).to receive(:file?).and_return(true)
allow(File).to receive(:open).with('file.zip').and_yield('FAKE FILE CONTENT')
allow(UploadIO).to receive(:new).and_return('FAKE FILE CONTENT')
http_fake = spy('http')
allow(Net::HTTP).to receive(:new).and_return(http_fake)
allow_any_instance_of(OneviewSDK::ImageStreamer::Client).to receive(:response_handler)
.and_return(FakeResponse.new)
expected_options = { 'name' => 'image1', 'description' => 'anything' }
expect(@client_i3s_300).to receive(:upload_file).with('file.zip', '/rest/golden-images', expected_options, OneviewSDK::Rest::READ_TIMEOUT)
.and_return({})
klass.add(@client_i3s_300, 'file.zip', options)
expect(http_fake).to have_received(:read_timeout=).with(klass::READ_TIMEOUT)
end

it 'should use value of http read_timeout passed as parameter' do
options = { name: 'image1', description: 'anything' }
allow(File).to receive(:file?).and_return(true)
allow(File).to receive(:open).with('file.zip').and_yield('FAKE FILE CONTENT')
allow(UploadIO).to receive(:new).and_return('FAKE FILE CONTENT')
http_fake = spy('http')
allow(Net::HTTP).to receive(:new).and_return(http_fake)
allow_any_instance_of(OneviewSDK::ImageStreamer::Client).to receive(:response_handler)
.and_return(FakeResponse.new)
expect_options = { 'name' => 'image1', 'description' => 'anything' }
expect(@client_i3s_300).to receive(:upload_file).with('file.zip', '/rest/golden-images', expect_options, 600)
.and_return({})
klass.add(@client_i3s_300, 'file.zip', options, 600)
expect(http_fake).to have_received(:read_timeout=).with(600)
end

it 'upload of the golden image file' do
Expand Down
43 changes: 5 additions & 38 deletions spec/unit/resource/api200/firmware_bundle_spec.rb
Expand Up @@ -5,47 +5,14 @@
include_context 'shared context'

describe '#add' do
it 'fails if the file does not exist' do
expect { described_class.add(@client, 'file.fake') }.to raise_error(OneviewSDK::NotFound, //)
end

it 'returns a FirmwareDriver resource' do
allow_any_instance_of(Net::HTTP).to receive(:request).and_return(FakeResponse.new({}, 200))
allow_any_instance_of(Net::HTTP).to receive(:connect).and_return(true)
allow(@client).to receive(:response_handler).and_return(uri: '/rest/firmware-drivers/f1')
allow(File).to receive(:file?).and_return(true)
allow(File).to receive(:open).with('file.tar').and_yield('FAKE FILE CONTENT')
allow(UploadIO).to receive(:new).and_return('FAKE FILE CONTENT')
expect(OneviewSDK::FirmwareBundle.add(@client, 'file.tar').class).to eq(OneviewSDK::FirmwareDriver)
end

it 'should use default http read_timeout when new value is not passed as parameter' do
allow(File).to receive(:file?).and_return(true)
allow(File).to receive(:open).with('file.tar').and_yield('FAKE FILE CONTENT')
allow(UploadIO).to receive(:new).and_return('FAKE FILE CONTENT')
http_fake = spy('http')
allow(Net::HTTP).to receive(:new).and_return(http_fake)
OneviewSDK::FirmwareBundle.add(@client, 'file.tar')
expect(http_fake).to have_received(:read_timeout=).with(OneviewSDK::FirmwareBundle::READ_TIMEOUT)
end

it 'should use value of http read_timeout passed as parameter' do
allow(File).to receive(:file?).and_return(true)
allow(File).to receive(:open).with('file.tar').and_yield('FAKE FILE CONTENT')
allow(UploadIO).to receive(:new).and_return('FAKE FILE CONTENT')
http_fake = spy('http')
allow(Net::HTTP).to receive(:new).and_return(http_fake)
OneviewSDK::FirmwareBundle.add(@client, 'file.tar', 600)
expect(http_fake).to have_received(:read_timeout=).with(600)
expect(@client_300).to receive(:upload_file).with('file.tar', '/rest/firmware-bundles', {}, OneviewSDK::Rest::READ_TIMEOUT).and_return({})
expect(described_class.add(@client_300, 'file.tar').class).to eq(OneviewSDK::FirmwareDriver)
end

it 'raises an exception when timeout expire' do
allow_any_instance_of(Net::HTTP).to receive(:request).and_raise(Net::ReadTimeout)
allow_any_instance_of(Net::HTTP).to receive(:connect).and_return(true)
allow(File).to receive(:file?).and_return(true)
allow(File).to receive(:open).with('file.tar').and_yield('FAKE FILE CONTENT')
allow(UploadIO).to receive(:new).and_return('FAKE FILE CONTENT')
expect { OneviewSDK::FirmwareBundle.add(@client, 'file.tar') }.to raise_error(/The connection was closed/)
it 'should call client.upload_file correctly' do
expect(@client_300).to receive(:upload_file).with('file.tar', '/rest/firmware-bundles', {}, 100).and_return({})
expect(described_class.add(@client_300, 'file.tar', 100).class).to eq(OneviewSDK::FirmwareDriver)
end
end
end
41 changes: 4 additions & 37 deletions spec/unit/resource/api300/c7000/firmware_bundle_spec.rb
Expand Up @@ -9,47 +9,14 @@
end

describe '#add' do
it 'fails if the file does not exist' do
expect { described_class.add(@client_300, 'file.fake') }.to raise_error(OneviewSDK::NotFound, //)
end

it 'returns a FirmwareDriver resource' do
allow_any_instance_of(Net::HTTP).to receive(:request).and_return(FakeResponse.new({}, 200))
allow_any_instance_of(Net::HTTP).to receive(:connect).and_return(true)
allow(@client_300).to receive(:response_handler).and_return(uri: '/rest/firmware-drivers/f1')
allow(File).to receive(:file?).and_return(true)
allow(File).to receive(:open).with('file.tar').and_yield('FAKE FILE CONTENT')
allow(UploadIO).to receive(:new).and_return('FAKE FILE CONTENT')
expect(@client_300).to receive(:upload_file).with('file.tar', '/rest/firmware-bundles', {}, OneviewSDK::Rest::READ_TIMEOUT).and_return({})
expect(described_class.add(@client_300, 'file.tar').class).to eq(OneviewSDK::FirmwareDriver)
end

it 'should use default http read_timeout when new value is not passed as parameter' do
allow(File).to receive(:file?).and_return(true)
allow(File).to receive(:open).with('file.tar').and_yield('FAKE FILE CONTENT')
allow(UploadIO).to receive(:new).and_return('FAKE FILE CONTENT')
http_fake = spy('http')
allow(Net::HTTP).to receive(:new).and_return(http_fake)
described_class.add(@client, 'file.tar')
expect(http_fake).to have_received(:read_timeout=).with(described_class::READ_TIMEOUT)
end

it 'should use value of http read_timeout passed as parameter' do
allow(File).to receive(:file?).and_return(true)
allow(File).to receive(:open).with('file.tar').and_yield('FAKE FILE CONTENT')
allow(UploadIO).to receive(:new).and_return('FAKE FILE CONTENT')
http_fake = spy('http')
allow(Net::HTTP).to receive(:new).and_return(http_fake)
described_class.add(@client, 'file.tar', 600)
expect(http_fake).to have_received(:read_timeout=).with(600)
end

it 'raises an exception when timeout expire' do
allow_any_instance_of(Net::HTTP).to receive(:request).and_raise(Net::ReadTimeout)
allow_any_instance_of(Net::HTTP).to receive(:connect).and_return(true)
allow(File).to receive(:file?).and_return(true)
allow(File).to receive(:open).with('file.tar').and_yield('FAKE FILE CONTENT')
allow(UploadIO).to receive(:new).and_return('FAKE FILE CONTENT')
expect { described_class.add(@client, 'file.tar') }.to raise_error(/The connection was closed/)
it 'should call client.upload_file correctly' do
expect(@client_300).to receive(:upload_file).with('file.tar', '/rest/firmware-bundles', {}, 100).and_return({})
expect(described_class.add(@client_300, 'file.tar', 100).class).to eq(OneviewSDK::FirmwareDriver)
end
end
end

0 comments on commit 0a95269

Please sign in to comment.