2010-06-12 14:13:49 -04:00
|
|
|
module Fog
|
2011-07-27 10:30:49 -04:00
|
|
|
|
|
|
|
def self.services
|
|
|
|
@services ||= {}
|
|
|
|
end
|
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
class Service
|
2010-09-02 16:39:01 -04:00
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
class Error < Fog::Errors::Error; end
|
|
|
|
class NotFound < Fog::Errors::NotFound; end
|
2010-06-12 16:21:32 -04:00
|
|
|
|
2012-06-08 19:36:08 -04:00
|
|
|
module NoLeakInspector
|
|
|
|
def inspect
|
|
|
|
"#<#{self.class}:#{self.object_id} #{(self.instance_variables - service.secrets).map {|iv| [iv, self.instance_variable_get(iv).inspect].join('=')}.join(' ')}>"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
module Collections
|
|
|
|
|
|
|
|
def collections
|
|
|
|
service.collections
|
|
|
|
end
|
|
|
|
|
2011-02-09 19:22:32 -05:00
|
|
|
def mocked_requests
|
|
|
|
service.mocked_requests
|
|
|
|
end
|
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
def requests
|
|
|
|
service.requests
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
class << self
|
|
|
|
|
|
|
|
def inherited(child)
|
|
|
|
child.class_eval <<-EOS, __FILE__, __LINE__
|
2011-05-27 13:46:09 -04:00
|
|
|
class Error < Fog::Service::Error; end
|
|
|
|
class NotFound < Fog::Service::NotFound; end
|
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
module Collections
|
|
|
|
include Fog::Service::Collections
|
|
|
|
|
|
|
|
def service
|
|
|
|
#{child}
|
2010-06-12 14:13:49 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
def self.service
|
|
|
|
#{child}
|
2010-06-12 14:13:49 -04:00
|
|
|
end
|
2010-09-03 04:11:45 -04:00
|
|
|
EOS
|
|
|
|
end
|
2010-06-17 19:58:09 -04:00
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
def new(options={})
|
2012-04-20 07:51:40 -04:00
|
|
|
options = Fog.symbolize_credentials(options)
|
2012-06-18 04:44:51 -04:00
|
|
|
options = fetch_credentials(options).merge(options)
|
2010-12-16 18:31:24 -05:00
|
|
|
validate_options(options)
|
2011-09-06 14:38:03 -04:00
|
|
|
coerce_options(options)
|
2010-09-14 13:40:02 -04:00
|
|
|
setup_requirements
|
|
|
|
|
|
|
|
if Fog.mocking?
|
|
|
|
service::Mock.send(:include, service::Collections)
|
|
|
|
service::Mock.new(options)
|
|
|
|
else
|
|
|
|
service::Real.send(:include, service::Collections)
|
2012-06-08 19:36:08 -04:00
|
|
|
service::Real.send(:include, service::NoLeakInspector)
|
2010-09-14 13:40:02 -04:00
|
|
|
service::Real.new(options)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-06-18 04:44:51 -04:00
|
|
|
def fetch_credentials(options)
|
|
|
|
# attempt to load credentials from config file
|
|
|
|
begin
|
2013-04-22 18:16:32 -04:00
|
|
|
Fog.credentials.reject {|key, value| !(recognized | requirements).include?(key)}
|
2012-06-18 04:44:51 -04:00
|
|
|
rescue LoadError
|
|
|
|
# if there are no configured credentials, do nothing
|
|
|
|
{}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-09-14 13:40:02 -04:00
|
|
|
def setup_requirements
|
|
|
|
if superclass.respond_to?(:setup_requirements)
|
|
|
|
superclass.setup_requirements
|
|
|
|
end
|
|
|
|
|
2010-10-12 19:22:12 -04:00
|
|
|
@required ||= false
|
2010-09-03 04:11:45 -04:00
|
|
|
unless @required
|
|
|
|
for collection in collections
|
|
|
|
require [@model_path, collection].join('/')
|
|
|
|
constant = collection.to_s.split('_').map {|characters| characters[0...1].upcase << characters[1..-1]}.join('')
|
|
|
|
service::Collections.module_eval <<-EOS, __FILE__, __LINE__
|
2010-09-14 13:40:02 -04:00
|
|
|
def #{collection}(attributes = {})
|
2012-12-19 17:28:04 -05:00
|
|
|
#{service}::#{constant}.new({:service => self}.merge(attributes))
|
2010-09-03 04:11:45 -04:00
|
|
|
end
|
|
|
|
EOS
|
2010-09-02 19:01:19 -04:00
|
|
|
end
|
2010-09-03 04:11:45 -04:00
|
|
|
for model in models
|
|
|
|
require [@model_path, model].join('/')
|
|
|
|
end
|
|
|
|
for request in requests
|
|
|
|
require [@request_path, request].join('/')
|
2011-02-09 19:22:32 -05:00
|
|
|
if service::Mock.method_defined?(request)
|
|
|
|
mocked_requests << request
|
|
|
|
else
|
|
|
|
service::Mock.module_eval <<-EOS, __FILE__, __LINE__
|
|
|
|
def #{request}(*args)
|
|
|
|
Fog::Mock.not_implemented
|
|
|
|
end
|
|
|
|
EOS
|
|
|
|
end
|
2010-09-02 19:01:19 -04:00
|
|
|
end
|
2010-09-03 04:11:45 -04:00
|
|
|
@required = true
|
|
|
|
end
|
|
|
|
end
|
2010-09-02 19:01:19 -04:00
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
def model_path(new_path)
|
|
|
|
@model_path = new_path
|
|
|
|
end
|
2010-06-12 14:13:49 -04:00
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
def collection(new_collection)
|
|
|
|
collections << new_collection
|
|
|
|
end
|
2010-06-12 14:13:49 -04:00
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
def collections
|
|
|
|
@collections ||= []
|
|
|
|
end
|
2010-09-02 19:01:19 -04:00
|
|
|
|
2011-09-06 14:38:03 -04:00
|
|
|
def coerce_options(options)
|
|
|
|
options.each do |key, value|
|
|
|
|
value_string = value.to_s.downcase
|
2011-09-06 14:41:01 -04:00
|
|
|
if value.nil?
|
|
|
|
options.delete(key)
|
|
|
|
elsif value == value_string.to_i.to_s
|
2011-09-06 14:38:03 -04:00
|
|
|
options[key] = value.to_i
|
|
|
|
else
|
|
|
|
options[key] = case value_string
|
|
|
|
when 'false'
|
|
|
|
false
|
|
|
|
when 'true'
|
|
|
|
true
|
|
|
|
else
|
|
|
|
value
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-02-09 19:22:32 -05:00
|
|
|
def mocked_requests
|
|
|
|
@mocked_requests ||= []
|
|
|
|
end
|
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
def model(new_model)
|
|
|
|
models << new_model
|
|
|
|
end
|
2010-09-02 19:01:19 -04:00
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
def models
|
|
|
|
@models ||= []
|
|
|
|
end
|
2010-06-12 14:13:49 -04:00
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
def request_path(new_path)
|
|
|
|
@request_path = new_path
|
|
|
|
end
|
2010-06-12 14:13:49 -04:00
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
def request(new_request)
|
|
|
|
requests << new_request
|
|
|
|
end
|
2010-06-12 14:13:49 -04:00
|
|
|
|
2010-09-03 04:11:45 -04:00
|
|
|
def requests
|
|
|
|
@requests ||= []
|
|
|
|
end
|
2010-06-12 14:13:49 -04:00
|
|
|
|
2012-06-08 19:36:08 -04:00
|
|
|
def secrets(*args)
|
|
|
|
if args.empty?
|
|
|
|
@secrets ||= []
|
|
|
|
else
|
|
|
|
args.inject(secrets) do |secrets, secret|
|
|
|
|
secrets << "@#{secret}".to_sym
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-12-16 18:31:24 -05:00
|
|
|
def requires(*args)
|
|
|
|
requirements.concat(args)
|
|
|
|
end
|
|
|
|
|
|
|
|
def requirements
|
|
|
|
@requirements ||= []
|
|
|
|
end
|
|
|
|
|
|
|
|
def recognizes(*args)
|
|
|
|
recognized.concat(args)
|
|
|
|
end
|
|
|
|
|
|
|
|
def recognized
|
2011-10-17 15:12:23 -04:00
|
|
|
@recognized ||= [:connection_options]
|
2010-12-16 18:31:24 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def validate_options(options)
|
2011-11-08 10:13:53 -05:00
|
|
|
keys = []
|
|
|
|
for key, value in options
|
|
|
|
unless value.nil?
|
|
|
|
keys << key
|
|
|
|
end
|
|
|
|
end
|
|
|
|
missing = requirements - keys
|
2010-12-16 18:31:24 -05:00
|
|
|
unless missing.empty?
|
|
|
|
raise ArgumentError, "Missing required arguments: #{missing.join(', ')}"
|
|
|
|
end
|
|
|
|
|
|
|
|
unless recognizes.empty?
|
|
|
|
unrecognized = options.keys - requirements - recognized
|
|
|
|
unless unrecognized.empty?
|
|
|
|
raise ArgumentError, "Unrecognized arguments: #{unrecognized.join(', ')}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-06-12 14:13:49 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|