mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00

Fog::Connection mixed in XML parsing via the `parser` argument which wasn't much use for the majority of APIs using JSON. This adds the deprecation warning and attempts to update providers to the correct version of Connection that they need. Either the cleaner `Fog::Core::Connection` or if reliant on the XML parsing still `Fog::XML::SAXParserConnection` The SAX parser will be moving to `fog/xml` fairly soon.
220 lines
7.2 KiB
Ruby
220 lines
7.2 KiB
Ruby
require 'fog/openstack/core'
|
|
|
|
module Fog
|
|
module Storage
|
|
class OpenStack < Fog::Service
|
|
|
|
requires :openstack_auth_url, :openstack_username,
|
|
:openstack_api_key
|
|
recognizes :persistent, :openstack_service_name,
|
|
:openstack_service_type, :openstack_tenant,
|
|
:openstack_region, :openstack_temp_url_key
|
|
|
|
model_path 'fog/openstack/models/storage'
|
|
model :directory
|
|
collection :directories
|
|
model :file
|
|
collection :files
|
|
|
|
request_path 'fog/openstack/requests/storage'
|
|
request :copy_object
|
|
request :delete_container
|
|
request :delete_object
|
|
request :delete_multiple_objects
|
|
request :delete_static_large_object
|
|
request :get_container
|
|
request :get_containers
|
|
request :get_object
|
|
request :get_object_http_url
|
|
request :get_object_https_url
|
|
request :head_container
|
|
request :head_containers
|
|
request :head_object
|
|
request :put_container
|
|
request :put_object
|
|
request :put_object_manifest
|
|
request :put_dynamic_obj_manifest
|
|
request :put_static_obj_manifest
|
|
request :post_set_meta_temp_url_key
|
|
|
|
class Mock
|
|
|
|
def self.data
|
|
@data ||= Hash.new do |hash, key|
|
|
hash[key] = {}
|
|
end
|
|
end
|
|
|
|
def self.reset
|
|
@data = nil
|
|
end
|
|
|
|
def initialize(options={})
|
|
@openstack_api_key = options[:openstack_api_key]
|
|
@openstack_username = options[:openstack_username]
|
|
@path = '/v1/AUTH_1234'
|
|
end
|
|
|
|
def data
|
|
self.class.data[@openstack_username]
|
|
end
|
|
|
|
def reset_data
|
|
self.class.data.delete(@openstack_username)
|
|
end
|
|
|
|
def change_account(account)
|
|
@original_path ||= @path
|
|
version_string = @original_path.split('/')[1]
|
|
@path = "/#{version_string}/#{account}"
|
|
end
|
|
|
|
def reset_account_name
|
|
@path = @original_path
|
|
end
|
|
|
|
end
|
|
|
|
class Real
|
|
|
|
def initialize(options={})
|
|
@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] || {}
|
|
@openstack_temp_url_key = options[:openstack_temp_url_key]
|
|
authenticate
|
|
@persistent = options[:persistent] || false
|
|
@connection = Fog::Core::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
|
|
end
|
|
|
|
def reload
|
|
@connection.reset
|
|
end
|
|
|
|
# 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
|
|
#
|
|
def change_account(account)
|
|
@original_path ||= @path
|
|
version_string = @path.split('/')[1]
|
|
@path = "/#{version_string}/#{account}"
|
|
end
|
|
|
|
def reset_account_name
|
|
@path = @original_path
|
|
end
|
|
|
|
def request(params, parse_json = true)
|
|
begin
|
|
response = @connection.request(params.merge({
|
|
:headers => {
|
|
'Content-Type' => 'application/json',
|
|
'Accept' => 'application/json',
|
|
'X-Auth-Token' => @auth_token
|
|
}.merge!(params[:headers] || {}),
|
|
:path => "#{@path}/#{params[:path]}",
|
|
}))
|
|
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.get_header('Content-Type') =~ %r{application/json}
|
|
response.body = Fog::JSON.decode(response.body)
|
|
end
|
|
response
|
|
end
|
|
|
|
private
|
|
|
|
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(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
|
|
|
|
end
|
|
end
|
|
end
|
|
end
|