Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: 1ed3b91f4e
Fetching contributors…

Cannot retrieve contributors at this time

162 lines (143 sloc) 5.205 kB
# Copyright (c) 2009-2012 VMware, Inc.
require "base64"
require "fog"
require "multi_json"
require "uri"
require "httpclient"
module Bosh
module Blobstore
class SwiftBlobstoreClient < BaseClient
# Blobstore client for Swift
# @param [Hash] options Swift BlobStore options
# @option options [Symbol] container_name
# @option options [Symbol] swift_provider
def initialize(options)
super(options)
@http_client = HTTPClient.new
end
def container
return @container if @container
validate_options(@options)
swift_provider = @options[:swift_provider]
swift_options = {:provider => swift_provider}
swift_options.merge!(@options[swift_provider.to_sym])
swift = Fog::Storage.new(swift_options)
container_name = @options[:container_name]
@container = swift.directories.get(container_name)
if @container.nil?
raise NotFound, "Swift container '#{container_name}' not found"
end
@container
end
protected
def create_file(object_id, file)
object_id ||= generate_object_id
object = container.files.create(:key => object_id,
:body => file,
:public => true)
encode_object_id(object_id, object.public_url)
rescue Exception => e
raise BlobstoreError, "Failed to create object: #{e.message}"
end
def get_file(object_id, file)
object_info = decode_object_id(object_id)
if object_info["purl"]
response = @http_client.get(object_info["purl"]) do |block|
file.write(block)
end
if response.status != 200
raise BlobstoreError, "Could not fetch object, %s/%s" %
[response.status, response.content]
end
else
object = container.files.get(object_info["oid"]) do |block|
file.write(block)
end
if object.nil?
raise NotFound, "Swift object '#{object_id}' not found"
end
end
rescue Exception => e
raise BlobstoreError,
"Failed to find object '#{object_id}': #{e.message}"
end
def delete_object(object_id)
object_info = decode_object_id(object_id)
object = container.files.get(object_info["oid"])
if object.nil?
raise NotFound, "Swift object '#{object_id}' not found"
else
object.destroy
end
rescue Exception => e
raise BlobstoreError,
"Failed to delete object '#{object_id}': #{e.message}"
end
private
def generate_object_id
SecureRandom.uuid
end
def encode_object_id(object_id, public_url = nil)
json = MultiJson.encode({:oid => object_id, :purl => public_url})
URI::escape(Base64.encode64(json))
end
def decode_object_id(object_id)
begin
object_info = MultiJson.decode(Base64.decode64(URI::unescape(object_id)))
rescue MultiJson::DecodeError => e
raise BlobstoreError, "Failed to parse object_id: #{e.message}"
end
if !object_info.kind_of?(Hash) || object_info["oid"].nil?
raise BlobstoreError, "Invalid object_id: #{object_info.inspect}"
end
object_info
end
def validate_options(options)
unless options.is_a?(Hash)
raise "Invalid options format, Hash expected, #{options.class} given"
end
unless options.has_key?(:container_name)
raise "Swift container name is missing"
end
unless options.has_key?(:swift_provider)
raise "Swift provider is missing"
end
case options[:swift_provider]
when "hp"
unless options.has_key?(:hp)
raise "HP options are missing"
end
unless options[:hp].is_a?(Hash)
raise "Invalid HP options, Hash expected,
#{options[:hp].class} given"
end
unless options[:hp].has_key?(:hp_account_id)
raise "HP account ID is missing"
end
unless options[:hp].has_key?(:hp_secret_key)
raise "HP secret key is missing"
end
unless options[:hp].has_key?(:hp_tenant_id)
raise "HP tenant ID is missing"
end
when "rackspace"
unless options.has_key?(:rackspace)
raise "Rackspace options are missing"
end
unless options[:rackspace].is_a?(Hash)
raise "Invalid Rackspace options, Hash expected,
#{options[:rackspace].class} given"
end
unless options[:rackspace].has_key?(:rackspace_username)
raise "Rackspace username is missing"
end
unless options[:rackspace].has_key?(:rackspace_api_key)
raise "Rackspace API key is missing"
end
else
raise "Swift provider #{options[:swift_provider]} not supported"
end
end
end
end
end
Jump to Line
Something went wrong with that request. Please try again.