class Fog::Service
Public Class Methods
# File lib/fog/core/service.rb, line 161 def coerce_options(options) options.each do |key, value| value_string = value.to_s.downcase if value.nil? options.delete(key) elsif value_string.to_i.to_s == value options[key] = value.to_i else options[key] = case value_string when "false" false when "true" true else value end end end end
# File lib/fog/core/service.rb, line 148 def collection(new_collection, path = nil) collection_files << [path, new_collection] collections << new_collection end
# File lib/fog/core/service.rb, line 153 def collection_files @collection_files ||= [] end
# File lib/fog/core/service.rb, line 157 def collections @collections ||= [] end
@deprecated
# File lib/fog/core/service.rb, line 120 def fetch_credentials(_options) # attempt to load credentials from config file Fog.credentials.reject { |key, _value| !(recognized | requirements).include?(key) } rescue ::Fog::Errors::LoadError # if there are no configured credentials, do nothing {} end
# File lib/fog/core/service.rb, line 33 def inherited(child) child.class_eval <<-EOS, __FILE__, __LINE__ class Error < Fog::Service::Error; end class NotFound < Fog::Service::NotFound; end module Collections include Fog::Service::Collections def service #{child} end end def self.service #{child} end EOS end
# File lib/fog/core/service.rb, line 181 def mocked_requests @mocked_requests ||= [] end
# File lib/fog/core/service.rb, line 185 def model(new_model, path = nil) model_files << [path, new_model] models << [new_model] end
# File lib/fog/core/service.rb, line 190 def model_files @model_files ||= [] end
@note This path is used to require model and collection files
# File lib/fog/core/service.rb, line 144 def model_path(new_path) @model_path = new_path end
# File lib/fog/core/service.rb, line 194 def models @models ||= [] end
{Fog::Service} is (unfortunately) both a builder class and the subclass for any fog service.
Creating a {new} instance using the builder will return either an instance of +Fog::<Service>::<Provider>::Real+ or +Fog::<Service>::<Provider>::Mock+ based on the value of {Fog.mock?} when the builder is used.
Each provider can require or recognize different settings (often prefixed with the providers name). These settings map to keys in the +~/.fog+ file.
Settings can be passed as either a Hash or an object that responds to
config_service?
with true
. This object will be
passed through unchanged to the Real
or Mock
service that is created. It is up to providers to adapt services to use
these config objects.
@abstract Subclass and implement real or mock code
@param [Hash,#config_service?] config
Settings or an object used to build a service instance
@option config [Hash] :headers
Passed to the underlying {Fog::Core::Connection} unchanged
@return [Fog::Service::Provider::Real] if created while mocking is disabled @return [Fog::Service::Provider::Mock] if created while mocking is enabled @raise [ArgumentError] if a setting required by the provider was not passed in
@example Minimal options (dependent on ~/.fog)
@service = Fog::Compute::Example.new # => <#Fog::Compute::Example::Real>
@example Mocked service
Fog.mock! @service = Fog::Compute::Example.new # => <#Fog::Compute::Example::Mock>
@example Configured using many options (options merged into ~/.fog)
@options = { :example_username => "fog", :example_password => "fog" } @service = Fog::Compute::Example.new(@options)
@example Configured using external config object (~/.fog ignored completely)
@config = Fog::Example::Config.new(...) @service = Fog::Compute::Example.new(@config)
# File lib/fog/core/service.rb, line 94 def new(config = {}) if config.respond_to?(:config_service?) && config.config_service? cleaned_settings = config else cleaned_settings = handle_settings(config) end setup_requirements svc = service if Fog.mocking? while svc != Fog::Service service::Mock.send(:include, svc::Collections) svc = svc.superclass end service::Mock.new(cleaned_settings) else while svc != Fog::Service service::Real.send(:include, svc::Collections) svc = svc.superclass end service::Real.send(:include, service::NoLeakInspector) service::Real.new(cleaned_settings) end end
# File lib/fog/core/service.rb, line 232 def recognized @recognized ||= [:connection_options] end
# File lib/fog/core/service.rb, line 228 def recognizes(*args) recognized.concat(args) end
# File lib/fog/core/service.rb, line 202 def request(new_request, path = nil) requests << [path, new_request] end
# File lib/fog/core/service.rb, line 198 def request_path(new_path) @request_path = new_path end
# File lib/fog/core/service.rb, line 206 def requests @requests ||= [] end
# File lib/fog/core/service.rb, line 224 def requirements @requirements ||= [] end
# File lib/fog/core/service.rb, line 220 def requires(*args) requirements.concat(args) end
# File lib/fog/core/service.rb, line 210 def secrets(*args) if args.empty? @secrets ||= [] else args.reduce(secrets) do |secrets, secret| secrets << "@#{secret}".to_sym end end end
# File lib/fog/core/service.rb, line 128 def setup_requirements if superclass.respond_to?(:setup_requirements) superclass.setup_requirements end @required ||= false return false if @required require_models require_collections_and_define require_requests_and_mock @required = true end
# File lib/fog/core/service.rb, line 236 def validate_options(options) keys = [] options.each_pair do |key, value| keys << key unless value.nil? end missing = requirements - keys unless missing.empty? raise ArgumentError, "Missing required arguments: #{missing.join(", ")}" end unless recognizes.empty? unrecognized = options.keys - requirements - recognized unless unrecognized.empty? Fog::Logger.warning("Unrecognized arguments: #{unrecognized.join(", ")}") end end end
Private Class Methods
This converts names of collections from Symbols as defined in the DSL
(:database_server
) into CamelCase version
(DatabaseServer
) for metaprogramming skulduggery.
@param [String,Symbol] collection The name of the collection broken with underscores @return [String] in camel case
# File lib/fog/core/service.rb, line 294 def camel_case_collection_name(collection) collection.to_s.split("_").map(&:capitalize).join end
This is the original way service settings were handled. Settings from +~/.fog+ were merged together with the passed options, keys are turned to symbols and coerced into Boolean or Fixnums.
If the class has declared any required settings then {ArgumentError} will be raised.
Any setting that is not whitelisted will cause a warning to be output.
# File lib/fog/core/service.rb, line 265 def handle_settings(settings) combined_settings = fetch_credentials(settings).merge(settings) prepared_settings = Fog::Core::Utils.prepare_service_settings(combined_settings) validate_options(prepared_settings) coerce_options(prepared_settings) end
# File lib/fog/core/service.rb, line 277 def require_collections_and_define collection_files.each do |collection| require_item(collection, @model_path) constant = camel_case_collection_name(collection.last) service::Collections.module_eval <<-EOS, __FILE__, __LINE__ def #{collection.last}(attributes = {}) #{service}::#{constant}.new({ :service => self }.merge(attributes)) end EOS end end
Requires the correct file for an item (collection, model, or request).
@param [Array] item
An item to require. Should be an array in the form of [path, file].
@param [String] fallback_dir
The directory to look for the file in if the first element of `item` is nil.
@return [Boolean] Returns the same as `Kernel#require`.
# File lib/fog/core/service.rb, line 322 def require_item(item, fallback_dir) path, file = item require File.join(path || fallback_dir, file.to_s) end
This will attempt to require all model files declared by the service using fog“s DSL
# File lib/fog/core/service.rb, line 273 def require_models model_files.each { |model| require_item(model, @model_path) } end
This will attempt to require all request files declared in the service using fog“s DSL
# File lib/fog/core/service.rb, line 299 def require_requests_and_mock requests.each do |request| require_item(request, @request_path) if service::Mock.method_defined?(request.last) mocked_requests << request.last else service::Mock.module_eval <<-EOS, __FILE__, __LINE__ def #{request.last}(*args) Fog::Mock.not_implemented end EOS end end end