Commit 335f4b54 authored by Praveen Arimbrathodiyil's avatar Praveen Arimbrathodiyil
Browse files

Merge tag 'upstream/1.30.0'

Upstream version 1.30.0

# gpg: Signature made Friday 10 April 2015 11:53:22 AM IST using RSA key ID 4512C22A
# gpg: Good signature from "Praveen Arimbrathodiyil (piratepin) <praveen@debian.org>"
# gpg:                 aka "Pirate Praveen (pirates.org.in) <praveen@onenetbeyond.org>"
# gpg:                 aka "Pirate Praveen (piratesin) <me@j4v4m4n.in>"
parents 2eb80396 e53fead1
......@@ -13,6 +13,8 @@ rvm:
- jruby-19mode
- jruby-head
sudo: false
script: bundle exec rake travis
matrix:
......@@ -52,4 +54,4 @@ notifications:
- "[#%{build_number}] %{compare_url}"
on_success: always
on_failure: always
use_notice: false
\ No newline at end of file
use_notice: false
* Anatol <anatol.pomozov@gmail.com>
* Bryan Paxton <starbelly@pobox.com>
* Chris Johnson <wchrisjohnson@gmail.com>
* Chris Sinjakli <chris@sinjakli.co.uk>
* Dominic Cleal <dcleal@redhat.com>
* Evan Light <evan@tripledogdare.net>
* Jake Bell <jake@theunraveler.com>
* Josh Kalderimis <josh.kalderimis@gmail.com>
* Kevin Menard <kevin@nirvdrum.com>
* Matt Bostock <matt@mattbostock.com>
* Matt Darby <darby@mittdarko.com>
* Matt Darby <matt.darby@rackspace.com>
* Mike Hagedorn <mike@silverchairsolutions.com>
* Naoto TAKAHASHI <tnaoto@gmail.com>
* Paul Thornthwaite <paul@brightbox.co.uk>
* Paul Thornthwaite <tokengeek@gmail.com>
* Paulo Henrique Lopes Ribeiro <plribeiro3000@gmail.com>
* Wesley Beary <geemus+github@gmail.com>
* Wesley Beary <geemus@gmail.com>
* geemus <geemus@gmail.com>
* mountkin <moutkin@gmail.com>
\ No newline at end of file
......@@ -24,7 +24,7 @@ TODO: Write usage instructions here
## Contributing
1. Fork it ( http://github.com/<my-github-username>/fog-core/fork )
1. Fork it ( http://github.com/fog/fog-core/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
......
1.30.0 04/02/2015
==========================================================
bump excon dep
use float times, instead of integers for Fog::Time
don't raise if final wait_for yield true
fix bug around formatador and #map on models
fix around `to_time` to avoid conflicts with Rails monkey patches
update specs
update style
fix `WhitelistKeys` for 1.8.7
remove unreachable code
convert hash helpers to minispec
fix require order for coverage
fix ruby 2.2 warning
bump excon dependency
fix readme link
1.29.0 02/19/2015
==========================================================
minor refactoring
add ability to add additional user agent info to requests
1.28.0 01/30/2015
==========================================================
add Fog::Baremetal
1.27.4 01/26/2015
==========================================================
model fix for new formatador usage
fixes around formatador delegation
1.27.3 12/01/2014
==========================================================
rubocop fixes for fog collection
simpler ruby version checking/skipping
fix requires_one
1.27.2 18/12/2014
==========================================================
fix several requires in service abstraction code
1.27.1 12/12/2014
==========================================================
fix typo in model load paths fix
1.27.0 12/12/2014
==========================================================
return fog/bin stuff to fog/fog
add support for multiple request/model load paths
1.26.0 12/02/2014
==========================================================
remove rackspace logic
use new travis builds
fix error handling around credential fetch
move fog/bin stuff to fog-core
fix circular reference in collection.rb
1.25.0 11/18/2014
==========================================================
......
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'fog/core/version'
require "fog/core/version"
Gem::Specification.new do |spec|
spec.name = "fog-core"
spec.version = Fog::Core::VERSION
spec.authors = ["Evan Light", "Wesley Beary"]
spec.email = ["evan@tripledogdare.net", "geemus@gmail.com"]
spec.summary = %q{Shared classes and tests for fog providers and services.}
spec.description = %q{Shared classes and tests for fog providers and services.}
spec.summary = "Shared classes and tests for fog providers and services."
spec.description = "Shared classes and tests for fog providers and services."
spec.homepage = "https://github.com/fog/fog-core"
spec.license = "MIT"
spec.files = `git ls-files`.split($/)
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_dependency('builder')
spec.add_dependency('excon', '~>0.38')
spec.add_dependency('formatador', '~>0.2')
spec.add_dependency('mime-types')
spec.add_dependency('net-scp', '~>1.1')
spec.add_dependency('net-ssh', '>=2.1.3')
spec.add_dependency("builder")
spec.add_dependency("excon", "~> 0.45")
spec.add_dependency("formatador", "~> 0.2")
spec.add_dependency("mime-types")
spec.add_dependency("net-scp", "~> 1.1")
spec.add_dependency("net-ssh", ">= 2.1.3")
spec.add_development_dependency('rake')
spec.add_development_dependency('yard')
spec.add_development_dependency('thor')
spec.add_development_dependency('minitest')
spec.add_development_dependency('minitest-stub-const')
spec.add_development_dependency('pry')
spec.add_development_dependency('coveralls')
spec.add_development_dependency('rubocop') if RUBY_VERSION.to_s >= '1.9.3'
spec.add_development_dependency("coveralls")
spec.add_development_dependency("minitest")
spec.add_development_dependency("minitest-stub-const")
spec.add_development_dependency("pry")
spec.add_development_dependency("rake")
spec.add_development_dependency("rubocop") if RUBY_VERSION.to_s >= "1.9.3"
spec.add_development_dependency("thor")
spec.add_development_dependency("yard")
end
......@@ -9,7 +9,7 @@ module Fog
provider = attributes.delete(:provider).to_s.downcase.to_sym
if provider == :stormondemand
require "fog/storm_on_demand/account"
require "fog/account/storm_on_demand"
Fog::Account::StormOnDemand.new(attributes)
else
raise ArgumentError, "#{provider} has no account service"
......@@ -17,7 +17,7 @@ module Fog
end
def self.providers
Fog.services[:account]
Fog.services[:account] || []
end
end
end
module Fog
module Baremetal
def self.[](provider)
new(:provider => provider)
end
def self.new(attributes)
attributes = attributes.dup # Prevent delete from having side effects
provider = attributes.delete(:provider).to_s.downcase.to_sym
if providers.include?(provider)
require "fog/#{provider}/baremetal"
return Fog::Baremetal.const_get(Fog.providers[provider]).new(attributes)
end
raise ArgumentError, "#{provider} has no baremetal service"
end
def self.providers
Fog.services[:baremetal]
end
end
end
......@@ -8,7 +8,7 @@ module Fog
attributes = attributes.dup
provider = attributes.delete(:provider).to_s.downcase.to_sym
if provider == :stormondemand
require "fog/storm_on_demand/billing"
require "fog/billing/storm_on_demand"
Fog::Billing::StormOnDemand.new(attributes)
else
raise ArgumentError, "#{provider} has no billing service"
......
......@@ -42,7 +42,7 @@ module Fog
Fog::Compute::RackspaceV2.new(attributes)
end
when :stormondemand
require "fog/storm_on_demand/compute"
require "fog/compute/storm_on_demand"
Fog::Compute::StormOnDemand.new(attributes)
when :vcloud
require "fog/vcloud/compute"
......@@ -52,7 +52,11 @@ module Fog
Fog::Compute::VcloudDirector.new(attributes)
else
if providers.include?(provider)
require "fog/#{provider}/compute"
begin
require "fog/#{provider}/compute"
rescue LoadError
require "fog/compute/#{provider}"
end
begin
Fog::Compute.const_get(Fog.providers[provider])
rescue
......
......@@ -52,6 +52,7 @@ require "fog/core/whitelist_keys"
# service wrappers
require "fog/account"
require "fog/baremetal"
require "fog/billing"
require "fog/cdn"
require "fog/compute"
......@@ -66,3 +67,6 @@ require "fog/storage"
require "fog/support"
require "fog/volume"
require "fog/vpn"
# Utility
require 'fog/formatador'
......@@ -155,7 +155,8 @@ module Fog
end
def requires_one(*args)
return unless missing_attributes(args).length == args.length
missing = missing_attributes(args)
return unless missing.length == args.length
raise(ArgumentError, "#{missing[0...-1].join(", ")} or #{missing[-1]} are required for this operation")
end
......
......@@ -10,6 +10,8 @@ module Fog
def #{name}=(new_#{name})
attributes[:#{name}] = if new_#{name}.nil? || new_#{name} == "" || new_#{name}.is_a?(::Time)
new_#{name}
elsif ::String === new_#{name}
::Time.parse(new_#{name})
elsif new_#{name}.respond_to?(:to_time)
new_#{name}.to_time
else
......
require "fog/core/deprecated_connection_accessors"
module Fog
# Fog::Collection
class Collection < Array
extend Fog::Attributes::ClassMethods
include Fog::Attributes::InstanceMethods
include Fog::Core::DeprecatedConnectionAccessors
attr_reader :service
......@@ -41,8 +43,7 @@ module Fog
end
def clear
@loaded = true
super
@loaded = super
end
def create(attributes = {})
......@@ -52,8 +53,7 @@ module Fog
end
def destroy(identity)
object = new(:identity => identity)
object.destroy
new(:identity => identity).destroy
end
# Creates a new Fog::Collection based around the passed service
......@@ -70,34 +70,11 @@ module Fog
end
def inspect
Thread.current[:formatador] ||= Formatador.new
data = "#{Thread.current[:formatador].indentation}<#{self.class.name}\n"
Thread.current[:formatador].indent do
unless self.class.attributes.empty?
data << "#{Thread.current[:formatador].indentation}"
data << self.class.attributes.map { |attribute| "#{attribute}=#{send(attribute).inspect}" }.join(",\n#{Thread.current[:formatador].indentation}")
data << "\n"
end
data << "#{Thread.current[:formatador].indentation}["
unless self.empty?
data << "\n"
Thread.current[:formatador].indent do
data << map(&:inspect).join(", \n")
data << "\n"
end
data << Thread.current[:formatador].indentation
end
data << "]\n"
end
data << "#{Thread.current[:formatador].indentation}>"
data
Fog::Formatador.format(self)
end
def load(objects)
clear
objects.each do |object|
self << new(object)
end
clear && objects.each { |object| self << new(object) }
self
end
......@@ -118,13 +95,12 @@ module Fog
end
def reload
clear
lazy_load
clear && lazy_load
self
end
def table(attributes = nil)
Formatador.display_table(map(&:attributes), attributes)
Fog::Formatador.display_table(map(&:attributes), attributes)
end
def to_json(_options = {})
......@@ -137,18 +113,20 @@ module Fog
all
end
end
# Base class for collection classes whose 'all' method returns only a single page of results and passes the
# 'Marker' option along as self.filters[:marker]
# Base class for collection classes whose 'all' method returns only a single
# page of results and passes the 'Marker' option along as
# self.filters[:marker]
class PagedCollection < Collection
def each(filters = filters)
def each(collection_filters = filters)
if block_given?
begin
page = all(filters)
# We need to explicitly use the base 'each' method here on the page, otherwise we get infinite recursion
Kernel.loop do
break unless filters[:marker]
page = all(collection_filters)
# We need to explicitly use the base 'each' method here on the page,
# otherwise we get infinite recursion
base_each = Fog::Collection.instance_method(:each)
base_each.bind(page).call { |item| yield item }
end while self.filters[:marker]
end
end
self
end
......
......@@ -6,6 +6,26 @@ module Fog
# modifications such as authentication or response object.
#
class Connection
class << self
@@user_agents = []
def add_user_agent(str)
if /\S+\/[\d|.]+/.match(str)
@@user_agents << str
else
raise "User Agent must be in <app name>/<app version> notation."
end
end
def user_agents
agents = @@user_agents.dup
agents << "fog/#{Fog::VERSION}" if defined?(Fog::VERSION)
agents << "fog-core/#{Fog::Core::VERSION}"
agents.uniq.compact.join(" ")
end
end
# Prepares the connection and sets defaults for any future requests.
#
# @param [String] url The destination URL
......@@ -34,10 +54,8 @@ module Fog
params[:debug_response] = true unless params.key?(:debug_response)
params[:headers] ||= {}
user_agent = "fog-core/#{Fog::Core::VERSION}"
user_agent = "fog/#{Fog::VERSION} #{user_agent}" if defined?(Fog::VERSION)
params[:headers]["User-Agent"] ||= user_agent
params.merge!(:persistent => params.fetch(:persistent, persistent))
params[:headers]["User-Agent"] ||= user_agent
@excon = Excon.new(url, params)
end
......@@ -77,6 +95,10 @@ module Fog
private
def user_agent
self.class.user_agents
end
def handle_path_prefix_for(params)
return params unless @path_prefix
......
......@@ -31,9 +31,9 @@ module Fog
channel = @channels[key]
if channel
message = if channel.tty?
value.gsub(Formatador::PARSE_REGEX) { "\e[#{Formatador::STYLES[$1.to_sym]}m" }.gsub(Formatador::INDENT_REGEX, "")
value.gsub(Fog::Formatador::PARSE_REGEX) { "\e[#{Fog::Formatador::STYLES[$1.to_sym]}m" }.gsub(Fog::Formatador::INDENT_REGEX, "")
else
value.gsub(Formatador::PARSE_REGEX, "").gsub(Formatador::INDENT_REGEX, "")
value.gsub(Fog::Formatador::PARSE_REGEX, "").gsub(Fog::Formatador::INDENT_REGEX, "")
end
channel.write(message)
end
......
......@@ -21,16 +21,7 @@ module Fog
end
def inspect
Thread.current[:formatador] ||= Formatador.new
data = "#{Thread.current[:formatador].indentation}<#{self.class.name}"
Thread.current[:formatador].indent do
unless self.class.attributes.empty?
data << "\n#{Thread.current[:formatador].indentation}"
data << self.class.attributes.map { |attribute| "#{attribute}=#{send(attribute).inspect}" }.join(",\n#{Thread.current[:formatador].indentation}")
end
end
data << "\n#{Thread.current[:formatador].indentation}>"
data
Fog::Formatador.format(self)
end
def reload
......
......@@ -120,7 +120,7 @@ module Fog
def fetch_credentials(_options)
# attempt to load credentials from config file
Fog.credentials.reject { |key, _value| !(recognized | requirements).include?(key) }
rescue LoadError
rescue ::Fog::Errors::LoadError
# if there are no configured credentials, do nothing
{}
end
......@@ -145,10 +145,15 @@ module Fog
@model_path = new_path
end
def collection(new_collection)
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
......@@ -158,7 +163,7 @@ module Fog
value_string = value.to_s.downcase
if value.nil?
options.delete(key)
elsif value == value_string.to_i.to_s
elsif value_string.to_i.to_s == value
options[key] = value.to_i
else
options[key] = case value_string
......@@ -177,8 +182,13 @@ module Fog
@mocked_requests ||= []
end
def model(new_model)
models << new_model
def model(new_model, path = nil)
model_files << [path, new_model]
models << [new_model]
end
def model_files
@model_files ||= []
end
def models
......@@ -189,8 +199,8 @@ module Fog
@request_path = new_path
end
def request(new_request)
requests << new_request
def request(new_request, path = nil)
requests << [path, new_request]
end
def requests
......@@ -261,17 +271,15 @@ module Fog
# This will attempt to require all model files declared by the service using fog"s DSL
def require_models
models.each do |model|
require File.join(@model_path, model.to_s)
end
model_files.each { |model| require_item(model, @model_path) }
end
def require_collections_and_define
collections.each do |collection|
require File.join(@model_path, collection.to_s)
constant = camel_case_collection_name(collection)
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}(attributes = {})
def #{collection.last}(attributes = {})
#{service}::#{constant}.new({ :service => self }.merge(attributes))
end
EOS
......@@ -290,18 +298,31 @@ module Fog
# 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 File.join(@request_path, request.to_s)
if service::Mock.method_defined?(request)
mocked_requests << 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}(*args)
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
......@@ -109,14 +109,14 @@ module Fog
def display_stdout
data = stdout.split("\r\n")
if data.is_a?(String)
Formatador.display_line(data)
Fog::Formatador.display_line(data)
elsif data.is_a?(Array)
Formatador.display_lines(data)
Fog::Formatador.display_lines(data)
end
end
def display_stderr
Formatador.display_line(stderr.split("\r\n"))
Fog::Formatador.display_line(stderr.split("\r\n"))
end
def initialize(command)
......