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

Removing Atmos

This commit is contained in:
Paulo Henrique Lopes Ribeiro 2014-12-02 13:15:23 -02:00
parent 9c836706dc
commit 928dad3733
17 changed files with 2 additions and 608 deletions

View file

@ -64,6 +64,7 @@ Gem::Specification.new do |s|
s.add_dependency("fog-terremark")
s.add_dependency("fog-ecloud")
s.add_dependency("fog-storm_on_demand")
s.add_dependency("fog-atmos")
# Disabled until Rackspace isn't broken, see fog-rackspace#10
#s.add_dependency("fog-rackspace")

View file

@ -1 +0,0 @@
require 'fog/atmos/storage'

View file

@ -1,9 +0,0 @@
require 'fog/core'
module Fog
module Atmos
extend Fog::Provider
service(:storage, 'Storage')
end
end

View file

@ -1,44 +0,0 @@
require 'fog/core/collection'
require 'fog/atmos/models/storage/directory'
module Fog
module Storage
class Atmos
class Directories < Fog::Collection
attribute :directory
model Fog::Storage::Atmos::Directory
def all
directory ? ns = directory.key : ns = ''
ns = ns + '/' unless ns =~ /\/$/
data = service.get_namespace(ns).body[:DirectoryList]
data = {:DirectoryEntry => []} if data.kind_of? String
data[:DirectoryEntry] = [data[:DirectoryEntry]] if data[:DirectoryEntry].kind_of? Hash
dirs = data[:DirectoryEntry].select {|de| de[:FileType] == 'directory'}
dirs.each do |d|
d[:Filename] = ns + d[:Filename] if directory
d[:Filename] += '/' unless d[:Filename] =~ /\/$/
end
load(dirs)
end
def get(key, options = {})
return nil if key == '' # Root dir shouldn't be retrieved like this.
key =~ /\/$/ ? ns = key : ns = key + '/'
res = service.get_namespace ns
emc_meta = res.headers['x-emc-meta']
obj_id = emc_meta.scan(/objectid=(\w+),/).flatten[0]
new(:objectid => obj_id, :key => ns)
rescue Fog::Storage::Atmos::NotFound
nil
end
def new(attributes ={})
attributes = {:directory => directory}.merge(attributes) if directory
super(attributes)
end
end
end
end
end

View file

@ -1,48 +0,0 @@
require 'fog/core/model'
module Fog
module Storage
class Atmos
class Directory < Fog::Model
identity :key, :aliases => :Filename
attribute :objectid, :aliases => :ObjectID
def files
@files ||= begin
Fog::Storage::Atmos::Files.new(
:directory => self,
:service => service
)
end
end
def directories
@directories ||= begin
Fog::Storage::Atmos::Directories.new(
:directory => self,
:service => service
)
end
end
def save
self.key = attributes[:directory].key + key if attributes[:directory]
self.key = key + '/' unless key =~ /\/$/
res = service.post_namespace key
reload
end
def destroy(opts={})
if opts[:recursive]
files.each {|f| f.destroy }
directories.each do |d|
d.files.each {|f| f.destroy }
d.destroy(opts)
end
end
service.delete_namespace key
end
end
end
end
end

View file

@ -1,108 +0,0 @@
require 'fog/core/model'
module Fog
module Storage
class Atmos
class File < Fog::Model
identity :key, :aliases => :Filename
attribute :content_length, :aliases => ['bytes', 'Content-Length'], :type => :integer
attribute :content_type, :aliases => ['content_type', 'Content-Type']
attribute :objectid, :aliases => :ObjectID
attribute :created_at, :aliases => :ctime
def body
attributes[:body] ||= if objectid
collection.get(identity).body
else
''
end
end
def body=(new_body)
attributes[:body] = new_body
end
def directory
@directory
end
def copy(target_directory_key, target_file_key, options={})
target_directory = service.directories.new(:key => target_directory_key)
target_directory.files.create(
:key => target_file_key,
:body => body
)
end
def destroy
requires :directory, :key
service.delete_namespace([directory.key, key].join('/'))
true
end
def meta_data
requires :directory, :key
service.get_namespace([directory.key, key].join('/') + "?metadata/system")
end
def file_size
data = meta_data
meta_data.headers["x-emc-meta"].match(/size=\d+/).to_s.gsub(/size=/,"")
end
def public=(new_public)
# NOOP - we don't need to flag files as public, getting the public URL for a file handles it.
end
# By default, expire in 5 years
def public_url(expires = (Time.now + 5 * 365 * 24 * 60 * 60))
file = directory.files.head(key)
self.objectid = if file && file.to_s.strip != "" then file.attributes['x-emc-meta'].scan(/objectid=(\w+),/).flatten[0] else nil end
if self.objectid && self.objectid.to_s.strip != ""
klass = service.ssl? ? URI::HTTPS : URI::HTTP
uri = klass.build(:host => service.host, :port => service.port.to_i, :path => "/rest/objects/#{self.objectid}" )
sb = "GET\n"
sb += uri.path.downcase + "\n"
sb += service.uid + "\n"
sb += String(expires.to_i())
signature = service.sign( sb )
uri.query = "uid=#{CGI::escape(service.uid)}&expires=#{expires.to_i()}&signature=#{CGI::escape(signature)}"
uri.to_s
else
nil
end
end
def save(options = {})
requires :body, :directory, :key
directory.kind_of?(Directory) ? ns = directory.key : ns = directory
ns += key
options[:headers] ||= {}
options[:headers]['Content-Type'] = content_type if content_type
options[:body] = body
begin
data = service.post_namespace(ns, options)
self.objectid = data.headers['location'].split('/')[-1]
rescue => error
if error.message =~ /The resource you are trying to create already exists./
data = service.put_namespace(ns, options)
else
raise error
end
end
# merge_attributes(data.headers)
true
end
private
def directory=(new_directory)
@directory = new_directory
end
end
end
end
end

View file

@ -1,74 +0,0 @@
require 'fog/core/collection'
require 'fog/atmos/models/storage/file'
module Fog
module Storage
class Atmos
class Files < Fog::Collection
attribute :directory
attribute :limit
attribute :marker
attribute :path
attribute :prefix
model Fog::Storage::Atmos::File
def all(options = {})
requires :directory
directory ? ns = directory.key : ns = ''
ns = ns + '/' unless ns =~ /\/$/
data = service.get_namespace(ns).body[:DirectoryList]
data = {:DirectoryEntry => []} if data.kind_of? String
data[:DirectoryEntry] = [data[:DirectoryEntry]] if data[:DirectoryEntry].kind_of? Hash
files = data[:DirectoryEntry].select {|de| de[:FileType] == 'regular'}
files.each do |s|
data = service.head_namespace(directory.key + s[:Filename], :parse => false)
headers = Hash[data.headers["x-emc-meta"].split(", ").map{|s|s.split("=")}]
s[:content_length] = data.headers["Content-Length"]
s[:content_type] = data.headers["Content-Type"]
s[:created_at] = headers["ctime"]
s[:directory] = directory
end
# TODO - Load additional file meta?
load(files)
end
def get(key, &block)
requires :directory
data = service.get_namespace(directory.key + key, :parse => false, &block)
file_data = data.headers.merge({
:body => data.body,
:key => key
})
new(file_data)
rescue Fog::Storage::Atmos::NotFound
nil
end
def get_url(key)
requires :directory
if self.directory.public_url
"#{self.directory.public_url}/#{key}"
end
end
def head(key, options = {})
requires :directory
data = service.head_namespace(directory.key + key, :parse => false)
file_data = data.headers.merge({
:body => data.body,
:key => key
})
new(file_data)
rescue Fog::Storage::Atmos::NotFound
nil
end
def new(attributes = {})
requires :directory
super({ :directory => directory }.merge!(attributes))
end
end
end
end
end

View file

@ -1,17 +0,0 @@
module Fog
module Storage
class Atmos
class Real
def delete_namespace(namespace = '', options = {})
options = options.reject {|key, value| value.nil?}
request({
:expects => 204,
:method => 'DELETE',
:path => "namespace/" + namespace,
:query => options
}.merge(options))
end
end
end
end
end

View file

@ -1,23 +0,0 @@
module Fog
module Storage
class Atmos
class Real
def get_namespace(namespace = '', options = {}, &block)
options = options.reject {|key, value| value.nil?}
if block_given?
options[:response_block] = Proc.new
end
request({
:expects => 200,
:method => 'GET',
:path => "namespace/" + URI.escape(namespace),
:query => {},
:parse => true
}.merge(options))
end
end
end
end
end

View file

@ -1,18 +0,0 @@
module Fog
module Storage
class Atmos
class Real
def head_namespace(namespace = '', options = {})
options = options.reject {|key, value| value.nil?}
request({
:expects => 200,
:method => 'HEAD',
:path => "namespace/" + URI.escape(namespace),
:query => {},
:parse => true
}.merge(options))
end
end
end
end
end

View file

@ -1,18 +0,0 @@
module Fog
module Storage
class Atmos
class Real
def post_namespace(namespace = '', options = {})
options = options.reject {|key, value| value.nil?}
request({
:expects => 201,
:method => 'POST',
:path => "namespace/" + namespace,
:query => {},
:parse => true
}.merge(options))
end
end
end
end
end

View file

@ -1,18 +0,0 @@
module Fog
module Storage
class Atmos
class Real
def put_namespace(namespace = '', options = {})
options = options.reject {|key, value| value.nil?}
request({
:expects => 200,
:method => 'PUT',
:path => "namespace/" + namespace,
:query => {},
:parse => true
}.merge(options))
end
end
end
end
end

View file

@ -1,184 +0,0 @@
require 'fog/atmos/core'
module Fog
module Storage
class Atmos < Fog::Service
requires :atmos_storage_endpoint,
:atmos_storage_secret,
:atmos_storage_token
recognizes :persistent
model_path 'fog/atmos/models/storage'
model :directory
collection :directories
model :file
collection :files
request_path 'fog/atmos/requests/storage'
# request :delete_container
request :get_namespace
request :head_namespace
request :post_namespace
request :put_namespace
request :delete_namespace
module Utils
ENDPOINT_REGEX = /(https*):\/\/([a-zA-Z0-9\.\-]+)(:[0-9]+)?(\/.*)?/
def ssl?
protocol = @endpoint.match(ENDPOINT_REGEX)[1]
raise ArgumentError, 'Invalid endpoint URL' if protocol.nil?
return true if protocol == 'https'
return false if protocol == 'http'
raise ArgumentError, "Unknown protocol #{protocol}"
end
def port
port = @endpoint.match(ENDPOINT_REGEX)[3]
return ssl? ? 443 : 80 if port.nil?
port.split(':')[1].to_i
end
def host
@endpoint.match(ENDPOINT_REGEX)[2]
end
def api_path
@endpoint.match(ENDPOINT_REGEX)[4]
end
def setup_credentials(options)
@storage_token = options[:atmos_storage_token]
@storage_secret = options[:atmos_storage_secret]
@storage_secret_decoded = Base64.decode64(@storage_secret)
@endpoint = options[:atmos_storage_endpoint]
@prefix = self.ssl? ? 'https' : 'http'
@storage_host = self.host
@storage_port = self.port
@api_path = self.api_path
end
end
class Mock
include Utils
def initialize(options={})
setup_credentials(options)
end
def request(options)
raise "Atmos Storage mocks not implemented"
end
end
class Real
include Utils
def initialize(options={})
setup_credentials(options)
@connection_options = options[:connection_options] || {}
@hmac = Fog::HMAC.new('sha1', @storage_secret_decoded)
@persistent = options.fetch(:persistent, false)
@connection = Fog::XML::Connection.new("#{@prefix}://#{@storage_host}:#{@storage_port}",
@persistent, @connection_options)
end
def uid
@storage_token#.split('/')[-1]
end
def sign(string)
value = @hmac.sign(string)
Base64.encode64( value ).chomp()
end
def reload
@connection.reset
end
def request(params, &block)
req_path = params[:path]
# Force set host and port
params.merge!({
:host => @storage_host,
:path => "#{@api_path}/rest/#{params[:path]}",
})
# Set default method and headers
params = {:method => 'GET', :headers => {}}.merge params
params[:headers]["Content-Type"] ||= "application/octet-stream"
# Add request date
params[:headers]["date"] = Time.now().httpdate()
params[:headers]["x-emc-uid"] = @storage_token
# Build signature string
signstring = ""
signstring += params[:method]
signstring += "\n"
signstring += params[:headers]["Content-Type"]
signstring += "\n"
if( params[:headers]["range"] )
signstring += params[:headers]["range"]
end
signstring += "\n"
signstring += params[:headers]["date"]
signstring += "\n"
signstring += "/rest/" + URI.unescape( req_path ).downcase
query_str = params[:query].map{|k,v| "#{k}=#{v}"}.join('&')
signstring += '?' + query_str unless query_str.empty?
signstring += "\n"
customheaders = {}
params[:headers].each { |key,value|
case key
when 'x-emc-date', 'x-emc-signature'
#skip
when /^x-emc-/
customheaders[ key.downcase ] = value
end
}
header_arr = customheaders.sort()
header_arr.each { |key,value|
# Values are lowercase and whitespace-normalized
signstring += key + ":" + value.strip.chomp.squeeze( " " ) + "\n"
}
digest = @hmac.sign(signstring.chomp())
signature = Base64.encode64( digest ).chomp()
params[:headers]["x-emc-signature"] = signature
params.delete(:host) #invalid excon request parameter
parse = params.delete(:parse)
begin
response = @connection.request(params, &block)
rescue Excon::Errors::HTTPStatusError => error
raise case error
when Excon::Errors::NotFound
Fog::Storage::Atmos::NotFound.slurp(error)
else
error
end
end
unless response.body.empty?
if parse
document = Fog::ToHashDocument.new
parser = Nokogiri::XML::SAX::PushParser.new(document)
parser << response.body
parser.finish
response.body = document.body
end
end
response
end
end
end
end
end

View file

@ -12,7 +12,7 @@ module Fog
requires :ninefold_storage_token, :ninefold_storage_secret
recognizes :persistent
model_path 'fog/atmos/models/storage'
model_path 'fog/storage/atmos/models'
model :directory
collection :directories
model :file

View file

@ -1,19 +0,0 @@
Shindo.tests("Storage[:atmos] | nested directories", ['atmos']) do
unless Fog.mocking?
@directory = Fog::Storage[:atmos].directories.create(:key => 'updatefiletests')
end
atmos = Fog::Storage[:atmos]
tests("update a file").succeeds do
pending if Fog.mocking?
file = @directory.files.create(:key => 'lorem.txt', :body => lorem_file)
file.body = "xxxxxx"
file.save
end
unless Fog.mocking?
@directory.destroy(:recursive => true)
end
end

View file

@ -1,23 +0,0 @@
Shindo.tests("Storage[:atmos] | nested directories", ['atmos']) do
atmos = Fog::Storage[:atmos]
tests("create a directory with a / character").succeeds do
pending if Fog.mocking?
atmos.directories.create(:key => 'sub/path')
end
tests("List of top directory returns sub dir").returns(1) do
pending if Fog.mocking?
atmos.directories.get('sub').directories.count
end
tests("create a directory in a sub dir").returns('sub/path/newdir/') do
pending if Fog.mocking?
atmos.directories.get('sub/path').directories.create(:key => 'newdir').identity
end
tests("Recursively destroy parent dir").succeeds do
pending if Fog.mocking?
atmos.directories.get('sub').destroy(:recursive => true)
end
end

View file

@ -13,9 +13,6 @@ if Fog.mock?
:aws_secret_access_key => 'aws_secret_access_key',
:ia_access_key_id => 'aws_access_key_id',
:ia_secret_access_key => 'aws_secret_access_key',
:atmos_storage_token => 'atmos_token',
:atmos_storage_secret => 'atmos_secret',
:atmos_storage_endpoint => 'http://atmos.is.cool:1000/test1.0',
:bluebox_api_key => 'bluebox_api_key',
:bluebox_customer_id => 'bluebox_customer_id',
:brightbox_client_id => 'brightbox_client_id',