class Fog::Storage::OpenStack::Real
Public Class Methods
# File lib/fog/openstack/storage.rb, line 76 def initialize(options={}) require 'mime/types' @openstack_api_key = options[:openstack_api_key] @openstack_username = options[:openstack_username] @openstack_auth_url = options[:openstack_auth_url] @openstack_auth_token = options[:openstack_auth_token] @openstack_storage_url = options[:openstack_storage_url] @openstack_must_reauthenticate = false @openstack_service_type = options[:openstack_service_type] || 'object-store' @openstack_service_name = options[:openstack_service_name] @openstack_region = options[:openstack_region] @openstack_tenant = options[:openstack_tenant] @connection_options = options[:connection_options] || {} authenticate @persistent = options[:persistent] || false @connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options) end
Public Instance Methods
Change the current account while re-using the auth token.
This is usefull when you have an admin role and you're able to HEAD other user accounts, set quotas, list files, etc.
For example:
# List current user account details service = Fog::Storage[:openstack] service.request :method => 'HEAD'
Would return something like:
Account: AUTH_1234 Date: Tue, 05 Mar 2013 16:50:52 GMT X-Account-Bytes-Used: 0 (0.00 Bytes) X-Account-Container-Count: 0 X-Account-Object-Count: 0
Now let's change the account
service.change_account('AUTH_3333') service.request :method => 'HEAD'
Would return something like:
Account: AUTH_3333 Date: Tue, 05 Mar 2013 16:51:53 GMT X-Account-Bytes-Used: 23423433 X-Account-Container-Count: 2 X-Account-Object-Count: 10
If we wan't to go back to our original admin account:
service.reset_account_name
# File lib/fog/openstack/storage.rb, line 134 def change_account(account) @original_path ||= @path version_string = @path.split('/')[1] @path = "/#{version_string}/#{account}" end
Copy object
Parameters¶ ↑
-
source_container_name<~String> - Name of source bucket
-
source_object_name<~String> - Name of source object
-
target_container_name<~String> - Name of bucket to create copy in
-
target_object_name<~String> - Name for new copy of object
-
options<~Hash> - Additional headers
# File lib/fog/openstack/requests/storage/copy_object.rb, line 14 def copy_object(source_container_name, source_object_name, target_container_name, target_object_name, options={}) headers = { 'X-Copy-From' => "/#{source_container_name}/#{source_object_name}" }.merge(options) request({ :expects => 201, :headers => headers, :method => 'PUT', :path => "#{Fog::OpenStack.escape(target_container_name)}/#{Fog::OpenStack.escape(target_object_name)}" }) end
Delete an existing object
Parameters¶ ↑
-
container<~String> - Name of container to delete
-
object<~String> - Name of object to delete
# File lib/fog/openstack/requests/storage/delete_object.rb, line 12 def delete_object(container, object) request( :expects => 204, :method => 'DELETE', :path => "#{Fog::OpenStack.escape(container)}/#{Fog::OpenStack.escape(object)}" ) end
Get details for container and total bytes stored
Parameters¶ ↑
-
container<~String> - Name of container to retrieve info for
-
options<~String>:
-
'limit'<~String> - Maximum number of objects to return
-
'marker'<~String> - Only return objects whose name is greater than marker
-
'prefix'<~String> - Limits results to those starting with prefix
-
'path'<~String> - Return objects nested in the pseudo path
-
Returns¶ ↑
-
response<~Excon::Response>:
-
headers<~Hash>:
-
'X-Account-Container-Count'<~String> - Count of containers
-
'X-Account-Bytes-Used'<~String> - Bytes used
-
-
body<~Array>:
-
'bytes'<~Integer> - Number of bytes used by container
-
'count'<~Integer> - Number of items in container
-
'name'<~String> - Name of container
-
item<~Hash>:
-
'bytes'<~String> - Size of object
-
'content_type'<~String> Content-Type of object
-
'hash'<~String> -
Hash
of object (etag?) -
'last_modified'<~String> - Last modified timestamp
-
'name'<~String> - Name of object
-
-
-
# File lib/fog/openstack/requests/storage/get_container.rb, line 31 def get_container(container, options = {}) options = options.reject {|key, value| value.nil?} request( :expects => 200, :method => 'GET', :path => Fog::OpenStack.escape(container), :query => {'format' => 'json'}.merge!(options) ) end
List existing storage containers
Parameters¶ ↑
-
options<~Hash>:
-
'limit'<~Integer> - Upper limit to number of results returned
-
'marker'<~String> - Only return objects with name greater than this value
-
Returns¶ ↑
-
response<~Excon::Response>:
-
body<~Array>:
-
container<~Hash>:
-
'bytes'<~Integer>: - Number of bytes used by container
-
'count'<~Integer>: - Number of items in container
-
'name'<~String>: - Name of container
-
-
-
# File lib/fog/openstack/requests/storage/get_containers.rb, line 20 def get_containers(options = {}) options = options.reject {|key, value| value.nil?} request( :expects => [200, 204], :method => 'GET', :path => '', :query => {'format' => 'json'}.merge!(options) ) end
Get details for object
Parameters¶ ↑
-
container<~String> - Name of container to look in
-
object<~String> - Name of object to look for
# File lib/fog/openstack/requests/storage/get_object.rb, line 12 def get_object(container, object, &block) params = {} if block_given? params[:response_block] = Proc.new end request(params.merge!({ :expects => 200, :method => 'GET', :path => "#{Fog::OpenStack.escape(container)}/#{Fog::OpenStack.escape(object)}" }), false) end
Get an expiring object https url from Cloud Files
Parameters¶ ↑
-
container<~String> - Name of container containing object
-
object<~String> - Name of object to get expiring url for
-
expires<~Time> - An expiry time for this url
Returns¶ ↑
-
response<~Excon::Response>:
-
body<~String> - url for object
-
See Also¶ ↑
docs.rackspace.com/files/api/v1/cf-devguide/content/Create_TempURL-d1a444.html
# File lib/fog/openstack/requests/storage/get_object_https_url.rb, line 20 def get_object_https_url(container, object, expires, options = {}) if @rackspace_temp_url_key.nil? raise ArgumentError, "Storage must my instantiated with the :rackspace_temp_url_key option" end method = 'GET' expires = expires.to_i object_path_escaped = "#{@path}/#{Fog::OpenStack.escape(container)}/#{Fog::OpenStack.escape(object,"/")}" object_path_unescaped = "#{@path}/#{Fog::OpenStack.escape(container)}/#{object}" string_to_sign = "#{method}\n#{expires}\n#{object_path_unescaped}" hmac = Fog::HMAC.new('sha1', @rackspace_temp_url_key) sig = sig_to_hex(hmac.sign(string_to_sign)) "https://#{@host}#{object_path_escaped}?temp_url_sig=#{sig}&temp_url_expires=#{expires}" end
List number of objects and total bytes stored
Parameters¶ ↑
-
container<~String> - Name of container to retrieve info for
Returns¶ ↑
-
response<~Excon::Response>:
-
headers<~Hash>:
-
'X-Container-Object-Count'<~String> - Count of containers
-
'X-Container-Bytes-Used'<~String> - Bytes used
-
-
# File lib/fog/openstack/requests/storage/head_container.rb, line 16 def head_container(container) request( :expects => 204, :method => 'HEAD', :path => Fog::OpenStack.escape(container), :query => {'format' => 'json'} ) end
List number of containers and total bytes stored
Returns¶ ↑
-
response<~Excon::Response>:
-
headers<~Hash>:
-
'X-Account-Container-Count'<~String> - Count of containers
-
'X-Account-Bytes-Used'<~String> - Bytes used
-
-
# File lib/fog/openstack/requests/storage/head_containers.rb, line 13 def head_containers request( :expects => 204, :method => 'HEAD', :path => '', :query => {'format' => 'json'} ) end
Get headers for object
Parameters¶ ↑
-
container<~String> - Name of container to look in
-
object<~String> - Name of object to look for
# File lib/fog/openstack/requests/storage/head_object.rb, line 12 def head_object(container, object) request({ :expects => 200, :method => 'HEAD', :path => "#{Fog::OpenStack.escape(container)}/#{Fog::OpenStack.escape(object)}" }, false) end
Set the account wide Temp URL Key. This is a secret key that's used to generate signed expiring URLs.
Once the key has been set with this request you should create new Storage
objects with the :rackspace_temp_url_key option then use the get_object_https_url
method to generate expiring URLs.
*** CAUTION *** changing this secret key will invalidate any expiring URLS generated with old keys.
Parameters¶ ↑
-
key<~String> - The new Temp URL Key
Returns¶ ↑
-
response<~Excon::Response>
See Also¶ ↑
docs.rackspace.com/files/api/v1/cf-devguide/content/Set_Account_Metadata-d1a4460.html
# File lib/fog/openstack/requests/storage/post_set_meta_temp_url_key.rb, line 25 def post_set_meta_temp_url_key(key) request( :expects => [201, 202, 204], :method => 'POST', :headers => {'X-Account-Meta-Temp-Url-Key' => key} ) end
Create a new container
Parameters¶ ↑
-
name<~String> - Name for container, should be < 256 bytes and must not contain '/'
# File lib/fog/openstack/requests/storage/put_container.rb, line 11 def put_container(name) request( :expects => [201, 202], :method => 'PUT', :path => Fog::OpenStack.escape(name) ) end
Create a new object
Parameters¶ ↑
-
container<~String> - Name for container, should be < 256 bytes and must not contain '/'
-
object<~String> - Name for object
-
data<~String|File> - data to upload
-
options<~Hash> - config headers for object. Defaults to {}.
# File lib/fog/openstack/requests/storage/put_object.rb, line 14 def put_object(container, object, data, options = {}, &block) data = Fog::Storage.parse_data(data) headers = data[:headers].merge!(options) params = block_given? ? { :request_block => block } : { :body => data[:body] } params.merge!( :expects => 201, :idempotent => !params[:request_block], :headers => headers, :method => 'PUT', :path => "#{Fog::OpenStack.escape(container)}/#{Fog::OpenStack.escape(object)}" ) request(params) end
Create a new manifest object
Creates an object with a X-Object-Manifest
header that specifies the common prefix (“<container>/<prefix>”) for all uploaded segments. Retrieving the manifest object streams all segments matching this prefix. Segments must sort in the order they should be concatenated. Note that any future objects stored in the container along with the segments that match the prefix will be included when retrieving the manifest object.
All segments must be stored in the same container, but may be in a different container than the manifest object. The default X-Object-Manifest
header is set to “container
/object
”, but may be overridden in options
to specify the prefix and/or the container where segments were stored. If overridden, names should be CGI escaped (excluding spaces) if needed (see {Fog::Rackspace.escape}).
@param container [String] Name for container where object
will be stored. Should be < 256 bytes and must not contain '/' @param object [String] Name for manifest object. @param options [Hash] Config headers for object
. @option options [String] 'X-Object-Manifest' (“container/object”) “<container>/<prefix>” for segment objects.
@see docs.openstack.org/api/openstack-object-storage/1.0/content/large-object-creation.html
# File lib/fog/openstack/requests/storage/put_object_manifest.rb, line 24 def put_object_manifest(container, object, options = {}) path = "#{Fog::OpenStack.escape(container)}/#{Fog::OpenStack.escape(object)}" headers = {'X-Object-Manifest' => path}.merge(options) request( :expects => 201, :headers => headers, :method => 'PUT', :path => path ) end
# File lib/fog/openstack/storage.rb, line 94 def reload @connection.reset end
# File lib/fog/openstack/storage.rb, line 144 def request(params, parse_json = true, &block) begin response = @connection.request(params.merge({ :headers => { 'Content-Type' => 'application/json', 'X-Auth-Token' => @auth_token }.merge!(params[:headers] || {}), :host => @host, :path => "#{@path}/#{params[:path]}", }), &block) rescue Excon::Errors::Unauthorized => error if error.response.body != 'Bad username or password' # token expiration @openstack_must_reauthenticate = true authenticate retry else # bad credentials raise error end rescue Excon::Errors::HTTPStatusError => error raise case error when Excon::Errors::NotFound Fog::Storage::OpenStack::NotFound.slurp(error) else error end end if !response.body.empty? && parse_json && response.headers['Content-Type'] =~ %r{application/json} response.body = Fog::JSON.decode(response.body) end response end
# File lib/fog/openstack/storage.rb, line 140 def reset_account_name @path = @original_path end
Private Instance Methods
# File lib/fog/openstack/storage.rb, line 178 def authenticate if !@openstack_management_url || @openstack_must_reauthenticate options = { :openstack_api_key => @openstack_api_key, :openstack_username => @openstack_username, :openstack_auth_uri => URI.parse(@openstack_auth_url), :openstack_service_type => @openstack_service_type, :openstack_service_name => @openstack_service_name, :openstack_region => @openstack_region, :openstack_tenant => @openstack_tenant, :openstack_endpoint_type => 'publicURL' } credentials = Fog::OpenStack.authenticate_v2(options, @connection_options) @current_user = credentials[:user] @current_tenant = credentials[:tenant] @openstack_must_reauthenticate = false @auth_token = credentials[:token] @openstack_management_url = credentials[:server_management_url] uri = URI.parse(@openstack_management_url) else @auth_token = @openstack_auth_token uri = URI.parse(@openstack_management_url) end @host = uri.host @path = uri.path @path.sub!(/\/$/, '') @port = uri.port @scheme = uri.scheme true end
# File lib/fog/openstack/requests/storage/get_object_https_url.rb, line 39 def sig_to_hex(str) str.unpack("C*").map { |c| c.to_s(16) }.map { |h| h.size == 1 ? "0#{h}" : h }.join end