You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltacloud.apache.org by ma...@apache.org on 2013/04/23 15:11:14 UTC
[2/4] git commit: First release of storage for Arubacloud driver
First release of storage for Arubacloud driver
Project: http://git-wip-us.apache.org/repos/asf/deltacloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltacloud/commit/8ba93a37
Tree: http://git-wip-us.apache.org/repos/asf/deltacloud/tree/8ba93a37
Diff: http://git-wip-us.apache.org/repos/asf/deltacloud/diff/8ba93a37
Branch: refs/heads/master
Commit: 8ba93a3709b13808b4cc01543cbc010169f53ca7
Parents: e97b180
Author: Luciano Castro <lu...@staff.aruba.it>
Authored: Fri Apr 19 10:57:46 2013 +0200
Committer: marios <ma...@redhat.com>
Committed: Tue Apr 23 16:08:43 2013 +0300
----------------------------------------------------------------------
server/config/drivers/arubacloud.yaml | 6 +-
.../drivers/arubacloud/arubacloud_driver.rb | 200 ++++++++++++++-
2 files changed, 203 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/8ba93a37/server/config/drivers/arubacloud.yaml
----------------------------------------------------------------------
diff --git a/server/config/drivers/arubacloud.yaml b/server/config/drivers/arubacloud.yaml
index 04f85eb..4e345f5 100644
--- a/server/config/drivers/arubacloud.yaml
+++ b/server/config/drivers/arubacloud.yaml
@@ -6,4 +6,8 @@
dc2: https://api.dc2.computing.cloud.it/WsEndUser/v2.4/WsEndUser.svc?wsdl
dc3: https://api.dc3.computing.cloud.it/WsEndUser/v2.4/WsEndUser.svc?wsdl
dc4: https://api.dc4.computing.cloud.it/WsEndUser/v2.4/WsEndUser.svc?wsdl
- :name: Arubacloud
+ storage:
+ dc1: https://r1-it.storage.cloud.it
+ dc3: https://r1-cz.storage.forpsicloud.cz
+ dc4: https://r1-fr.storage.arubacloud.fr
+ :name: Arubacloud
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/deltacloud/blob/8ba93a37/server/lib/deltacloud/drivers/arubacloud/arubacloud_driver.rb
----------------------------------------------------------------------
diff --git a/server/lib/deltacloud/drivers/arubacloud/arubacloud_driver.rb b/server/lib/deltacloud/drivers/arubacloud/arubacloud_driver.rb
index b945fea..c5ac624 100644
--- a/server/lib/deltacloud/drivers/arubacloud/arubacloud_driver.rb
+++ b/server/lib/deltacloud/drivers/arubacloud/arubacloud_driver.rb
@@ -16,6 +16,10 @@
#
require "savon"
+require 'base64'
+require 'openssl'
+require "rest_client"
+require "xmlsimple"
HTTPI.log = false
@@ -31,6 +35,8 @@ class ArubacloudDriver < Deltacloud::BaseDriver
feature :instances, :authentication_password
feature :instances, :user_name
+ feature :buckets, :bucket_location
+
define_instance_states do
start.to( :pending ) .automatically
pending.to( :running ) .automatically
@@ -62,6 +68,196 @@ class ArubacloudDriver < Deltacloud::BaseDriver
architecture ['x86_64', 'i386']
end
+ def generate_headers(method, credentials, bucket=nil, blob=nil, user_headers={})
+ headers = {
+ 'x-amz-date' => Time.new.getgm.strftime("%a, %d %b %Y %H:%M:%S %Z"),
+ 'Content-Md5'=>'',
+ 'Date'=>'',
+ 'Content-Type'=> ''
+ }
+
+ headers = headers.merge(user_headers)
+
+ signature = ["#{method}\n"]
+ headers.sort_by{|k, v| k}.each do |name, value|
+ lk = name.downcase
+ if lk.start_with? 'x-amz-'
+ signature << "#{name}:#{value}\n"
+ elsif lk == 'content-type' or lk == 'content-md5' or lk == 'date'
+ signature << "#{value}\n"
+ end
+ end
+
+ signature << "/"
+ if bucket
+ signature << "#{bucket}/"
+ end
+
+ if blob
+ signature << blob
+ end
+
+ signed = Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new("sha1"),
+ credentials.password, signature.join("")))
+
+ headers['Authorization'] = "AWS #{credentials.user}:#{signed}"
+
+ headers.delete_if { |k, v| v.is_a? String and v.empty? }
+
+ headers
+ end
+
+ def storage_request(credentials, request=:buckets, params={})
+ dc = params['realm_id'] ? "dc#{params['realm_id']}" : DEFAULT_REGION
+ host_base = Deltacloud::Drivers::driver_config[:arubacloud][:entrypoints]["storage"][dc]
+
+ begin
+ case request
+ when :bucket_info
+ headers = generate_headers("GET", credentials, params['bucket_name'])
+ response = RestClient.get "#{host_base}/#{params['bucket_name']}/", headers
+ when :bucket_create
+ headers = generate_headers("PUT", credentials, params['bucket_name'])
+ headers['Content-Length'] = 0
+ response = RestClient.put host_base.sub("//", "//#{params['bucket_name']}."), nil, headers
+ when :bucket_delete
+ headers = generate_headers("DELETE", credentials, params['bucket_name'])
+ response = RestClient.delete "#{host_base}/#{params['bucket_name']}/", headers
+ when :buckets
+ headers = generate_headers("GET", credentials)
+ response = RestClient.get host_base, headers
+ when :blob_info
+ headers = generate_headers("HEAD", credentials, params['bucket_name'], params['blob_name'])
+ host = host_base.sub("//", "//#{params['bucket_name']}.") + "/#{params['blob_name']}"
+ response = RestClient.head host, headers
+ when :blob_create
+ base_headers = {'Content-Type'=> params['content_type'],
+ 'x-amz-acl' => 'private',
+ 'Content-Length' => File.size(params['tmp'])}
+ params.each do |k,v|
+ if k.start_with? "x-amz-meta-"
+ base_headers[k] = v
+ end
+ end
+
+ headers = generate_headers("PUT", credentials, params['bucket_name'], params['blob_name'], base_headers)
+ host = host_base.sub("//", "//#{params['bucket_name']}.") + "/#{params['blob_name']}"
+
+ response = RestClient.put host, File.read(params['tmp']) , headers
+ when :blob_data
+ headers = generate_headers("GET", credentials, params['bucket_name'], params['blob_name'])
+ host = host_base.sub("//", "//#{params['bucket_name']}.") + "/#{params['blob_name']}"
+ response = RestClient.get host, headers
+ when :blob_delete
+ headers = generate_headers("DELETE", credentials, params['bucket_name'], params['blob_name'])
+ host = host_base.sub("//", "//#{params['bucket_name']}.") + "/#{params['blob_name']}"
+ response = RestClient.delete host, headers
+ else
+ raise("Unknown request: " + request.to_s)
+ end
+
+ rescue RestClient::UnprocessableEntity, RestClient::BadRequest => e
+ raise("FAILED: #{e.response}")
+ rescue RestClient::Unauthorized
+ raise("Authentication failure")
+ rescue RestClient::Forbidden
+ raise("Remote Error: Forbidden")
+ rescue RestClient::Conflict
+ raise("Remote Error: Conflict")
+ end
+
+ response
+
+ end
+
+ def buckets(credentials, opts={})
+ buckets = []
+
+ unless (opts[:id].nil?)
+ blob_list = []
+ response = storage_request(credentials, :bucket_info, {'bucket_name'=>opts[:id]})
+ data = XmlSimple.xml_in(response.body)
+ if data['Contents']
+ data['Contents'].each do |blob|
+ blob_list << blob["Key"][0]
+ end
+ end
+ buckets << Bucket.new({:id => opts[:id], :name => opts[:id],
+ :size => blob_list.length,
+ :blob_list => blob_list})
+ else
+ response = storage_request(credentials, :buckets)
+ data = XmlSimple.xml_in(response.body)
+ data['Buckets'].each do |bucket|
+ if not bucket["Bucket"]
+ next
+ end
+ bucket['Bucket'].each do |item|
+ buckets << Bucket.new({:name => item["Name"][0], :id => item["Name"][0]})
+ end
+ end
+ end
+
+ filter_on(buckets, :id, opts)
+ end
+
+ def create_bucket(credentials, name, opts={})
+ response = storage_request(credentials, :bucket_create, {'bucket_name'=>name})
+ Bucket.new({:id => name, :name => name, :size => 0, :blob_list => []})
+ end
+
+ def delete_bucket(credentials, name, opts={})
+ storage_request(credentials, :bucket_delete, {'bucket_name'=>name})
+ end
+
+ def blobs(credentials, opts={})
+ blobs = []
+ #safely do
+ if(opts[:id])
+ response = storage_request(credentials, :blob_info, {'bucket_name'=>opts['bucket'], "blob_name"=>opts[:id]})
+ h = response.headers
+ blobs << Blob.new(
+ :id => opts[:id],
+ :bucket => opts['bucket'],
+ :content_length => response.headers[:content_length],
+ :content_type => response.headers[:content_type],
+ :last_modified => response.headers[:last_modified],
+ :user_metadata => []
+ )
+ end
+ #end
+ blobs = filter_on(blobs, :id, opts)
+ blobs
+
+ end
+
+ def create_blob(credentials, bucket_id, blob_id, data=nil, opts={})
+ params = {'bucket_name'=>bucket_id, 'blob_name'=>blob_id,
+ 'tmp'=>data[:tempfile], 'content_type'=>data[:type]}
+ opts_meta = opts.select{|k,v| k.match(/^x-amz-meta-/i)}
+
+ response = storage_request(credentials, :blob_create, params.merge(opts_meta))
+
+ Blob.new({ :id => blob_id,
+ :bucket => bucket_id,
+ :content_length => ((data && data[:tempfile]) ? data[:tempfile].length : nil),
+ :content_type => ((data && data[:type]) ? data[:type] : nil),
+ :last_modified => '',
+ :user_metadata => opts_meta
+ })
+
+ end
+
+ def delete_blob(credentials, bucket_id, blob_id, opts={})
+ response = storage_request(credentials, :blob_delete, {'bucket_name'=>bucket_id, "blob_name"=>blob_id})
+ end
+
+ def blob_data(credentials, bucket_id, blob_id, opts={})
+ response = storage_request(credentials, :blob_data, {'bucket_name'=>bucket_id, "blob_name"=>blob_id})
+ # Aruba doesn't provides methods for stream data
+ yield response
+ end
+
def realms(credentials, opts=nil)
client = new_client(credentials)
safely do
@@ -125,7 +321,7 @@ class ArubacloudDriver < Deltacloud::BaseDriver
end
def create_instance(credentials, image_id, opts={})
- client = new_client(credentials, opts[:realm_id])
+ client = new_client(credentials, opts[:realm_id], true)
safely do
@@ -139,7 +335,7 @@ class ArubacloudDriver < Deltacloud::BaseDriver
if not opts[:name] or opts[:name] == ''
o = [('a'..'z')].map{|i| i.to_a}.flatten
- name = "Delta14-" + (0...8).map{ o[rand(o.length)] }.join
+ name = "deltacloud-" + (0...12).map{ o[rand(o.length)] }.join
else
name = opts[:name]
end