/usr/lib/ruby/vendor_ruby/fog/core/service.rb is in ruby-fog-core 1.45.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 | require "fog/core/utils"
module Fog
def self.services
@services ||= {}
end
class Service
class Error < Fog::Errors::Error; end
class NotFound < Fog::Errors::NotFound; end
module NoLeakInspector
def inspect
"#<#{self.class}:#{object_id} #{(instance_variables - service.secrets).map { |iv| [iv, instance_variable_get(iv).inspect].join("=") }.join(" ")}>"
end
end
module Collections
def collections
service.collections
end
def mocked_requests
service.mocked_requests
end
def requests
service.requests
end
end
class << self
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
# {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)
#
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
# @deprecated
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
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
# @note This path is used to require model and collection files
def model_path(new_path)
@model_path = new_path
end
def collection(new_collection, path = nil)
collection_files << [path, new_collection]
collections << new_collection
end
def collection_files
@collection_files ||= []
end
def collections
@collections ||= []
end
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
def mocked_requests
@mocked_requests ||= []
end
def model(new_model, path = nil)
model_files << [path, new_model]
models << [new_model]
end
def model_files
@model_files ||= []
end
def models
@models ||= []
end
def request_path(new_path)
@request_path = new_path
end
def request(new_request, path = nil)
requests << [path, new_request]
end
def requests
@requests ||= []
end
def secrets(*args)
if args.empty?
@secrets ||= []
else
args.reduce(secrets) do |secrets, secret|
secrets << "@#{secret}".to_sym
end
end
end
def requires(*args)
requirements.concat(args)
end
def requirements
@requirements ||= []
end
def recognizes(*args)
recognized.concat(args)
end
def recognized
@recognized ||= [:connection_options]
end
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
# 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.
#
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
# This will attempt to require all model files declared by the service using fog"s DSL
def require_models
model_files.each { |model| require_item(model, @model_path) }
end
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
# 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
def camel_case_collection_name(collection)
collection.to_s.split("_").map(&:capitalize).join
end
# This will attempt to require all request files declared in the service using fog"s DSL
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
# 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`.
def require_item(item, fallback_dir)
path, file = item
require File.join(path || fallback_dir, file.to_s)
end
end
end
end
|