fog-core 1.22.0 → 1.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/Gemfile.1.8.7 +1 -0
- data/Rakefile +1 -1
- data/changelog.md +37 -0
- data/fog-core.gemspec +1 -1
- data/lib/fog/core.rb +10 -0
- data/lib/fog/core/attributes.rb +10 -85
- data/lib/fog/core/attributes/array.rb +13 -0
- data/lib/fog/core/attributes/boolean.rb +18 -0
- data/lib/fog/core/attributes/default.rb +55 -0
- data/lib/fog/core/attributes/float.rb +13 -0
- data/lib/fog/core/attributes/integer.rb +13 -0
- data/lib/fog/core/attributes/string.rb +13 -0
- data/lib/fog/core/attributes/time.rb +19 -0
- data/lib/fog/core/attributes/timestamp.rb +17 -0
- data/lib/fog/core/connection.rb +20 -2
- data/lib/fog/core/stringify_keys.rb +27 -0
- data/lib/fog/core/whitelist_keys.rb +8 -0
- data/lib/fog/dns.rb +7 -3
- data/lib/fog/identity.rb +1 -1
- data/lib/fog/version.rb +1 -1
- data/spec/connection_spec.rb +67 -0
- data/spec/fog_attribute_spec.rb +119 -3
- data/tests/core/stringify_keys_tests.rb +29 -0
- data/tests/core/whitelist_keys_tests.rb +24 -0
- metadata +17 -5
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ODU0ZTJhZDcwMGI0NzRiNmY1ODdjM2NmMDc2ZDMzYWM5NTk1ZjcwYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MzExN2UxODJlZDg5ZGQzZDIxNjM3YzUzMzc1MDI1MmZmMmJlNzg4Yg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MTIyZTRhZDg0ZWVjYWY3OTQyNTZhZmY4Y2YzYTBjMDYxYTZhZTQ5N2RiMGRh
|
10
|
+
OTMxODUyOGIxYTIwZmYyZGM3NWU4MTc0NTU0OTU4NjI2MzJkODVjYmYzOThl
|
11
|
+
OTI2N2MxZjdmOTJiN2IzOTVjZDUwODE5NmEyY2FiOGJmNWEwMGU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NmQ3NDdjZTM4OGY1ZTI1MTc0M2FiNWQ5YmRmM2FlYjlhNDE3MWNhYjEwMmY3
|
14
|
+
NDE0MDNhZDQ5ZTQyYmJhMTliMTI2NzhmZDUyYmVkZThlMDFhMDg0MDA1NTBi
|
15
|
+
OWRkMzNlMDUxNTYyYjM4ZDczNTljZWZmZmY5NDE5YTgwNDEzOTM=
|
data/Gemfile.1.8.7
CHANGED
data/Rakefile
CHANGED
@@ -24,7 +24,7 @@ end
|
|
24
24
|
#require "tasks/changelog_task"
|
25
25
|
#Fog::Rake::ChangelogTask.new
|
26
26
|
task :coveralls_push_workaround do
|
27
|
-
use_coveralls = (Gem::Version.new(RUBY_VERSION) > Gem::Version.new('1.9.2'))
|
27
|
+
use_coveralls = (Gem::Version.new(RUBY_VERSION.dup) > Gem::Version.new('1.9.2'))
|
28
28
|
if (ENV['COVERAGE'] != 'false') && use_coveralls
|
29
29
|
require 'coveralls/rake/task'
|
30
30
|
Coveralls::RakeTask.new
|
data/changelog.md
CHANGED
@@ -1,3 +1,40 @@
|
|
1
|
+
1.23.0 07/16/2014
|
2
|
+
==========================================================
|
3
|
+
|
4
|
+
attribute whitelisting
|
5
|
+
abstract out stringify for possible reuse
|
6
|
+
more specific naming
|
7
|
+
reorg
|
8
|
+
add path_prefix
|
9
|
+
fix time conversion to work with XMLRPC
|
10
|
+
add more specific per-type attribute tests
|
11
|
+
lock down rest-client for 1.8.7
|
12
|
+
allow namespace flipflop for dns
|
13
|
+
fix identity lookup
|
14
|
+
better default attribute value setting
|
15
|
+
bump excon
|
16
|
+
|
17
|
+
1.22.0 04/17/2014 1c086852e40e4c1ad7ed138834e4a1505ddb1416
|
18
|
+
==========================================================
|
19
|
+
|
20
|
+
attribute whitelisting
|
21
|
+
abstract out stringify for possible reuse
|
22
|
+
more specific naming
|
23
|
+
reorg
|
24
|
+
add path_prefix
|
25
|
+
fix time conversion to work with XMLRPC
|
26
|
+
add more specific per-type attribute tests
|
27
|
+
lock down rest-client for 1.8.7
|
28
|
+
allow namespace flipflop for dns
|
29
|
+
fix identity lookup
|
30
|
+
better default attribute value setting
|
31
|
+
bump excon
|
32
|
+
|
33
|
+
1.22.0 04/17/2014 1c086852e40e4c1ad7ed138834e4a1505ddb1416
|
34
|
+
==========================================================
|
35
|
+
|
36
|
+
tests/cleanup/fixes
|
37
|
+
|
1
38
|
1.21.1 03/18/2014 3a803405ba60ded421f4bd14677cd3c76cb7e6ab
|
2
39
|
==========================================================
|
3
40
|
|
data/fog-core.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_dependency('builder')
|
22
|
-
spec.add_dependency('excon', '~>0.
|
22
|
+
spec.add_dependency('excon', '~>0.38')
|
23
23
|
spec.add_dependency('formatador', '~>0.2')
|
24
24
|
spec.add_dependency('mime-types')
|
25
25
|
spec.add_dependency('net-scp', '~>1.1')
|
data/lib/fog/core.rb
CHANGED
@@ -13,6 +13,14 @@ require 'ipaddr'
|
|
13
13
|
# internal core dependencies
|
14
14
|
require "fog/version"
|
15
15
|
require 'fog/core/attributes'
|
16
|
+
require 'fog/core/attributes/default'
|
17
|
+
require 'fog/core/attributes/boolean'
|
18
|
+
require 'fog/core/attributes/float'
|
19
|
+
require 'fog/core/attributes/integer'
|
20
|
+
require 'fog/core/attributes/string'
|
21
|
+
require 'fog/core/attributes/time'
|
22
|
+
require 'fog/core/attributes/timestamp'
|
23
|
+
require 'fog/core/attributes/array'
|
16
24
|
require 'fog/core/collection'
|
17
25
|
require 'fog/core/connection'
|
18
26
|
require 'fog/core/credentials'
|
@@ -32,6 +40,8 @@ require 'fog/core/utils'
|
|
32
40
|
require 'fog/core/wait_for'
|
33
41
|
require 'fog/core/wait_for_defaults'
|
34
42
|
require 'fog/core/uuid'
|
43
|
+
require 'fog/core/stringify_keys'
|
44
|
+
require 'fog/core/whitelist_keys'
|
35
45
|
|
36
46
|
# service wrappers
|
37
47
|
require 'fog/account'
|
data/lib/fog/core/attributes.rb
CHANGED
@@ -14,92 +14,17 @@ module Fog
|
|
14
14
|
@attributes ||= []
|
15
15
|
end
|
16
16
|
|
17
|
+
def default_values
|
18
|
+
@default_values ||= {}
|
19
|
+
end
|
20
|
+
|
17
21
|
def attribute(name, options = {})
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
when :boolean
|
25
|
-
class_eval <<-EOS, __FILE__, __LINE__
|
26
|
-
def #{name}=(new_#{name})
|
27
|
-
attributes[:#{name}] = case new_#{name}
|
28
|
-
when true,'true'
|
29
|
-
true
|
30
|
-
when false,'false'
|
31
|
-
false
|
32
|
-
end
|
33
|
-
end
|
34
|
-
EOS
|
35
|
-
when :float
|
36
|
-
class_eval <<-EOS, __FILE__, __LINE__
|
37
|
-
def #{name}=(new_#{name})
|
38
|
-
attributes[:#{name}] = new_#{name}.to_f
|
39
|
-
end
|
40
|
-
EOS
|
41
|
-
when :integer
|
42
|
-
class_eval <<-EOS, __FILE__, __LINE__
|
43
|
-
def #{name}=(new_#{name})
|
44
|
-
attributes[:#{name}] = new_#{name}.to_i
|
45
|
-
end
|
46
|
-
EOS
|
47
|
-
when :string
|
48
|
-
class_eval <<-EOS, __FILE__, __LINE__
|
49
|
-
def #{name}=(new_#{name})
|
50
|
-
attributes[:#{name}] = new_#{name}.to_s
|
51
|
-
end
|
52
|
-
EOS
|
53
|
-
when :time
|
54
|
-
class_eval <<-EOS, __FILE__, __LINE__
|
55
|
-
def #{name}=(new_#{name})
|
56
|
-
attributes[:#{name}] = if new_#{name}.nil? || new_#{name} == "" || new_#{name}.is_a?(Time)
|
57
|
-
new_#{name}
|
58
|
-
else
|
59
|
-
Time.parse(new_#{name})
|
60
|
-
end
|
61
|
-
end
|
62
|
-
EOS
|
63
|
-
when :timestamp
|
64
|
-
class_eval <<-EOS, __FILE__, __LINE__
|
65
|
-
def #{name}=(new_#{name})
|
66
|
-
attributes[:#{name}] = Time.at(new_#{name}.to_i)
|
67
|
-
end
|
68
|
-
EOS
|
69
|
-
when :array
|
70
|
-
class_eval <<-EOS, __FILE__, __LINE__
|
71
|
-
def #{name}=(new_#{name})
|
72
|
-
attributes[:#{name}] = [*new_#{name}]
|
73
|
-
end
|
74
|
-
EOS
|
75
|
-
else
|
76
|
-
if squash = options[:squash]
|
77
|
-
class_eval <<-EOS, __FILE__, __LINE__
|
78
|
-
def #{name}=(new_data)
|
79
|
-
if new_data.is_a?(Hash)
|
80
|
-
if new_data.has_key?(:'#{squash}')
|
81
|
-
attributes[:#{name}] = new_data[:'#{squash}']
|
82
|
-
elsif new_data.has_key?("#{squash}")
|
83
|
-
attributes[:#{name}] = new_data["#{squash}"]
|
84
|
-
else
|
85
|
-
attributes[:#{name}] = [ new_data ]
|
86
|
-
end
|
87
|
-
else
|
88
|
-
attributes[:#{name}] = new_data
|
89
|
-
end
|
90
|
-
end
|
91
|
-
EOS
|
92
|
-
else
|
93
|
-
class_eval <<-EOS, __FILE__, __LINE__
|
94
|
-
def #{name}=(new_#{name})
|
95
|
-
attributes[:#{name}] = new_#{name}
|
96
|
-
end
|
97
|
-
EOS
|
98
|
-
end
|
99
|
-
end
|
100
|
-
@attributes ||= []
|
101
|
-
@attributes |= [name]
|
102
|
-
for new_alias in [*options[:aliases]]
|
22
|
+
type = options.fetch(:type, 'default').to_s.capitalize
|
23
|
+
default = options.fetch(:default, false)
|
24
|
+
Fog::Attributes::const_get(type).new(self, name, options).create
|
25
|
+
attributes << name
|
26
|
+
default_values[name] = default if default
|
27
|
+
Array(options[:aliases]).each do |new_alias|
|
103
28
|
aliases[new_alias] = name
|
104
29
|
end
|
105
30
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Fog
|
2
|
+
module Attributes
|
3
|
+
class Boolean < Default
|
4
|
+
def create_setter
|
5
|
+
model.class_eval <<-EOS, __FILE__, __LINE__
|
6
|
+
def #{name}=(new_#{name})
|
7
|
+
attributes[:#{name}] = case new_#{name}
|
8
|
+
when true,'true'
|
9
|
+
true
|
10
|
+
when false,'false'
|
11
|
+
false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
EOS
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Fog
|
2
|
+
module Attributes
|
3
|
+
class Default
|
4
|
+
attr_reader :model, :name, :squash
|
5
|
+
|
6
|
+
def initialize(model, name, options)
|
7
|
+
@model = model
|
8
|
+
@name = name
|
9
|
+
@squash = options.fetch(:squash, false)
|
10
|
+
end
|
11
|
+
|
12
|
+
def create
|
13
|
+
create_setter
|
14
|
+
create_getter
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_setter
|
18
|
+
if squash
|
19
|
+
model.class_eval <<-EOS, __FILE__, __LINE__
|
20
|
+
def #{name}=(new_data)
|
21
|
+
if new_data.is_a?(Hash)
|
22
|
+
if new_data.has_key?(:'#{squash}')
|
23
|
+
attributes[:#{name}] = new_data[:'#{squash}']
|
24
|
+
elsif new_data.has_key?("#{squash}")
|
25
|
+
attributes[:#{name}] = new_data["#{squash}"]
|
26
|
+
else
|
27
|
+
attributes[:#{name}] = [ new_data ]
|
28
|
+
end
|
29
|
+
else
|
30
|
+
attributes[:#{name}] = new_data
|
31
|
+
end
|
32
|
+
end
|
33
|
+
EOS
|
34
|
+
else
|
35
|
+
model.class_eval <<-EOS, __FILE__, __LINE__
|
36
|
+
def #{name}=(new_#{name})
|
37
|
+
attributes[:#{name}] = new_#{name}
|
38
|
+
end
|
39
|
+
EOS
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_getter
|
44
|
+
model.class_eval <<-EOS, __FILE__, __LINE__
|
45
|
+
def #{name}
|
46
|
+
if self.class.default_values[:#{name}] && !persisted?
|
47
|
+
return self.class.default_values[:#{name}]
|
48
|
+
end
|
49
|
+
attributes[:#{name}]
|
50
|
+
end
|
51
|
+
EOS
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Fog
|
2
|
+
module Attributes
|
3
|
+
class Time < Default
|
4
|
+
def create_setter
|
5
|
+
model.class_eval <<-EOS, __FILE__, __LINE__
|
6
|
+
def #{name}=(new_#{name})
|
7
|
+
attributes[:#{name}] = if new_#{name}.nil? || new_#{name} == "" || new_#{name}.is_a?(::Time)
|
8
|
+
new_#{name}
|
9
|
+
elsif new_#{name}.respond_to?(:to_time)
|
10
|
+
new_#{name}.to_time
|
11
|
+
else
|
12
|
+
::Time.parse(new_#{name})
|
13
|
+
end
|
14
|
+
end
|
15
|
+
EOS
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Fog
|
2
|
+
module Attributes
|
3
|
+
class Timestamp < Default
|
4
|
+
def create_setter
|
5
|
+
model.class_eval <<-EOS, __FILE__, __LINE__
|
6
|
+
def #{name}=(new_#{name})
|
7
|
+
if new_#{name}.respond_to?(:to_i)
|
8
|
+
attributes[:#{name}] = Fog::Time.at(new_#{name}.to_i)
|
9
|
+
else
|
10
|
+
attributes[:#{name}] = Fog::Time.parse(new_#{name}.to_s)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
EOS
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/fog/core/connection.rb
CHANGED
@@ -16,6 +16,7 @@ module Fog
|
|
16
16
|
# @option params [Hash<Symbol, String>] :headers The default headers to supply in a request. Only used if params[:headers] is not supplied to Connection#request
|
17
17
|
# @option params [String] :host The destination host's reachable DNS name or IP, in the form of a String
|
18
18
|
# @option params [String] :path Default path; appears after 'scheme://host:port/'. Only used if params[:path] is not supplied to Connection#request
|
19
|
+
# @option params [String] :path_prefix Sticky version of the "path" arg. :XSpath_prefix => "foo/bar" with a request with :path => "blech" sends a request to path "foo/bar/blech"
|
19
20
|
# @option params [Fixnum] :port The port on which to connect, to the destination host
|
20
21
|
# @option params [Hash] :query Default query; appended to the 'scheme://host:port/path/' in the form of '?key=value'. Will only be used if params[:query] is not supplied to Connection#request
|
21
22
|
# @option params [String] :scheme The protocol; 'https' causes OpenSSL to be used
|
@@ -23,8 +24,15 @@ module Fog
|
|
23
24
|
# @option params [Fixnum] :retry_limit Set how many times we'll retry a failed request. (Default 4)
|
24
25
|
# @option params [Class] :instrumentor Responds to #instrument as in ActiveSupport::Notifications
|
25
26
|
# @option params [String] :instrumentor_name Name prefix for #instrument events. Defaults to 'excon'
|
26
|
-
#
|
27
27
|
def initialize(url, persistent=false, params={})
|
28
|
+
if params[:path_prefix]
|
29
|
+
if params[:path]
|
30
|
+
raise ArgumentError, "optional arg 'path' is invalid when 'path_prefix' is provided"
|
31
|
+
end
|
32
|
+
|
33
|
+
@path_prefix = params.delete(:path_prefix)
|
34
|
+
end
|
35
|
+
|
28
36
|
unless params.has_key?(:debug_response)
|
29
37
|
params[:debug_response] = true
|
30
38
|
end
|
@@ -53,7 +61,7 @@ module Fog
|
|
53
61
|
# @raise [Excon::Errors::SocketError]
|
54
62
|
#
|
55
63
|
def request(params, &block)
|
56
|
-
@excon.request(params, &block)
|
64
|
+
@excon.request(handle_path_prefix_for(params), &block)
|
57
65
|
end
|
58
66
|
|
59
67
|
# Make {#request} available even when it has been overidden by a subclass
|
@@ -67,6 +75,16 @@ module Fog
|
|
67
75
|
def reset
|
68
76
|
@excon.reset
|
69
77
|
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def handle_path_prefix_for(params)
|
82
|
+
return params unless @path_prefix
|
83
|
+
|
84
|
+
params[:path] = params[:path].sub(/^\//, "")
|
85
|
+
params[:path] = "#{@path_prefix}/#{params[:path]}"
|
86
|
+
params
|
87
|
+
end
|
70
88
|
end
|
71
89
|
end
|
72
90
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Fog
|
2
|
+
module StringifyKeys
|
3
|
+
|
4
|
+
# Returns a new hash with all keys converted to strings.
|
5
|
+
def self.stringify(hash)
|
6
|
+
self.transform_hash(hash) {|hash, key, value|
|
7
|
+
hash[key.to_s] = value
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# http://devblog.avdi.org/2009/11/20/hash-transforms-in-ruby/
|
14
|
+
def self.transform_hash(original, options={}, &block)
|
15
|
+
original.inject({}){|result, (key,value)|
|
16
|
+
value = if (options[:deep] && Hash === value)
|
17
|
+
transform_hash(value, options, &block)
|
18
|
+
else
|
19
|
+
value
|
20
|
+
end
|
21
|
+
block.call(result,key,value)
|
22
|
+
result
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/lib/fog/dns.rb
CHANGED
@@ -14,10 +14,14 @@ module Fog
|
|
14
14
|
else
|
15
15
|
if self.providers.include?(provider)
|
16
16
|
require "fog/#{provider}/dns"
|
17
|
-
|
17
|
+
begin
|
18
|
+
Fog::DNS.const_get(Fog.providers[provider])
|
19
|
+
rescue
|
20
|
+
Fog::const_get(Fog.providers[provider])::DNS
|
21
|
+
end.new(attributes)
|
22
|
+
else
|
23
|
+
raise ArgumentError.new("#{provider} is not a recognized dns provider")
|
18
24
|
end
|
19
|
-
|
20
|
-
raise ArgumentError.new("#{provider} is not a recognized dns provider")
|
21
25
|
end
|
22
26
|
end
|
23
27
|
|
data/lib/fog/identity.rb
CHANGED
@@ -17,7 +17,7 @@ module Fog
|
|
17
17
|
begin
|
18
18
|
Fog::Identity.const_get(Fog.providers[provider]).new(attributes)
|
19
19
|
rescue
|
20
|
-
Fog::const_get(Fog.providers[provider])
|
20
|
+
Fog::const_get(Fog.providers[provider])::Identity.new(attributes)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
data/lib/fog/version.rb
CHANGED
data/spec/connection_spec.rb
CHANGED
@@ -30,4 +30,71 @@ describe Fog::Core::Connection do
|
|
30
30
|
}
|
31
31
|
Fog::Core::Connection.new("http://example.com", true, options)
|
32
32
|
end
|
33
|
+
|
34
|
+
describe ":path_prefix" do
|
35
|
+
it "does not emit a warning when provided this argument in the initializer" do
|
36
|
+
$stderr = StringIO.new
|
37
|
+
|
38
|
+
Fog::Core::Connection.new("http://example.com", false, :path_prefix => "foo")
|
39
|
+
|
40
|
+
assert_empty($stderr.string)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "raises when the 'path' arg is present and this arg is supplied" do
|
44
|
+
assert_raises(ArgumentError) do
|
45
|
+
Fog::Core::Connection.new("http://example.com", false, :path_prefix => "foo", :path => "bar")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#request" do
|
51
|
+
describe "default behavior" do
|
52
|
+
it "supplies the 'path' arg directly to Excon" do
|
53
|
+
spy = Object.new
|
54
|
+
spy.instance_eval do
|
55
|
+
def params
|
56
|
+
@params
|
57
|
+
end
|
58
|
+
def new(_, params)
|
59
|
+
@params = params
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
Object.stub_const("Excon", spy) do
|
64
|
+
c = Fog::Core::Connection.new("http://example.com", false, :path => "bar")
|
65
|
+
assert_equal("bar", spy.params[:path])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "with path_prefix supplied to the initializer" do
|
71
|
+
let(:spy) {
|
72
|
+
Object.new.tap { |spy|
|
73
|
+
spy.instance_eval do
|
74
|
+
def new(*args); self; end
|
75
|
+
def params; @params; end
|
76
|
+
def request(params)
|
77
|
+
@params = params
|
78
|
+
end
|
79
|
+
end
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
it "uses the initializer-supplied :path_prefix arg with #request :arg to formulate a path to send to Excon.request" do
|
84
|
+
Object.stub_const("Excon", spy) do
|
85
|
+
c = Fog::Core::Connection.new("http://example.com", false, :path_prefix => "foo")
|
86
|
+
c.request(:path => "bar")
|
87
|
+
assert_equal("foo/bar", spy.params[:path])
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it "does not introduce consecutive '/'s into the path if 'path' starts with a '/'" do
|
92
|
+
Object.stub_const("Excon", spy) do
|
93
|
+
c = Fog::Core::Connection.new("http://example.com", false, :path_prefix => "foo")
|
94
|
+
c.request(:path => "/bar")
|
95
|
+
assert_equal("foo/bar", spy.params[:path])
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
33
100
|
end
|
data/spec/fog_attribute_spec.rb
CHANGED
@@ -1,27 +1,39 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'xmlrpc/datetime'
|
2
3
|
|
3
4
|
class FogAttributeTestModel < Fog::Model
|
5
|
+
identity :id
|
4
6
|
attribute :key, :aliases => "keys", :squash => "id"
|
5
7
|
attribute :time, :type => :time
|
6
8
|
attribute :bool, :type => :boolean
|
9
|
+
attribute :float, :type => :float
|
10
|
+
attribute :integer, :type => :integer
|
11
|
+
attribute :string, :type => :string
|
12
|
+
attribute :timestamp, :type => :timestamp
|
13
|
+
attribute :array, :type => :array
|
14
|
+
attribute :default, :default => 'default_value'
|
7
15
|
end
|
8
16
|
|
9
17
|
describe "Fog::Attributes" do
|
10
|
-
|
18
|
+
|
11
19
|
let(:model) { FogAttributeTestModel.new }
|
12
20
|
|
21
|
+
it "should not create alias for nil" do
|
22
|
+
FogAttributeTestModel.aliases.must_equal({ "keys" => :key })
|
23
|
+
end
|
24
|
+
|
13
25
|
describe "squash 'id'" do
|
14
26
|
it "squashes if the key is a String" do
|
15
27
|
model.merge_attributes("keys" => {:id => "value"})
|
16
28
|
assert_equal"value", model.key
|
17
29
|
end
|
18
|
-
|
30
|
+
|
19
31
|
it "squashes if the key is a Symbol" do
|
20
32
|
model.merge_attributes("keys" => {"id" => "value"})
|
21
33
|
assert_equal "value", model.key
|
22
34
|
end
|
23
35
|
end
|
24
|
-
|
36
|
+
|
25
37
|
describe ":type => time" do
|
26
38
|
it "returns nil when provided nil" do
|
27
39
|
model.merge_attributes(:time => nil)
|
@@ -38,6 +50,12 @@ describe "Fog::Attributes" do
|
|
38
50
|
model.merge_attributes(:time => now.to_s)
|
39
51
|
assert_equal Time.parse(now.to_s), model.time
|
40
52
|
end
|
53
|
+
|
54
|
+
it "returns a Time object when passed a XMLRPC::DateTime object" do
|
55
|
+
now = XMLRPC::DateTime.new(2000, 7, 8, 10, 20, 34)
|
56
|
+
model.merge_attributes(:time => now)
|
57
|
+
assert_equal now.to_time, model.time
|
58
|
+
end
|
41
59
|
end
|
42
60
|
|
43
61
|
describe ":type => :boolean" do
|
@@ -66,4 +84,102 @@ describe "Fog::Attributes" do
|
|
66
84
|
refute model.bool
|
67
85
|
end
|
68
86
|
end
|
87
|
+
|
88
|
+
describe ":type => :float" do
|
89
|
+
it "returns an integer as float" do
|
90
|
+
model.merge_attributes(:float => 1)
|
91
|
+
assert_in_delta 1.0, model.float
|
92
|
+
end
|
93
|
+
|
94
|
+
it "returns a string as float" do
|
95
|
+
model.merge_attributes(:float => '1')
|
96
|
+
assert_in_delta 1.0, model.float
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe ":type => :integer" do
|
101
|
+
it "returns a float as integer" do
|
102
|
+
model.merge_attributes(:integer => 1.5)
|
103
|
+
assert_in_delta 1, model.integer
|
104
|
+
end
|
105
|
+
|
106
|
+
it "returns a string as integer" do
|
107
|
+
model.merge_attributes(:integer => '1')
|
108
|
+
assert_in_delta 1, model.integer
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe ":type => :string" do
|
113
|
+
it "returns a float as string" do
|
114
|
+
model.merge_attributes(:string => 1.5)
|
115
|
+
assert_equal '1.5', model.string
|
116
|
+
end
|
117
|
+
|
118
|
+
it "returns a integer as string" do
|
119
|
+
model.merge_attributes(:string => 1)
|
120
|
+
assert_equal '1', model.string
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe ":type => :timestamp" do
|
125
|
+
it "returns a date as time" do
|
126
|
+
model.merge_attributes(:timestamp => Date.new(2008, 10, 12))
|
127
|
+
assert_equal '2008-10-12 00:00', model.timestamp.strftime('%Y-%m-%d %M:%S')
|
128
|
+
assert_instance_of Fog::Time, model.timestamp
|
129
|
+
end
|
130
|
+
|
131
|
+
it "returns a time as time" do
|
132
|
+
model.merge_attributes(:timestamp => Time.mktime(2007, 11, 1, 15, 25))
|
133
|
+
assert_equal '2007-11-01 25:00', model.timestamp.strftime('%Y-%m-%d %M:%S')
|
134
|
+
assert_instance_of Fog::Time, model.timestamp
|
135
|
+
end
|
136
|
+
|
137
|
+
it "returns a date_time as time" do
|
138
|
+
model.merge_attributes(:timestamp => DateTime.new(2007, 11, 1, 15, 25, 0))
|
139
|
+
assert_equal '2007-11-01 25:00', model.timestamp.strftime('%Y-%m-%d %M:%S')
|
140
|
+
assert_instance_of Fog::Time, model.timestamp
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe ":type => :array" do
|
145
|
+
it "returns an empty array as an empty array" do
|
146
|
+
model.merge_attributes(:array => [])
|
147
|
+
assert_equal [], model.array
|
148
|
+
end
|
149
|
+
|
150
|
+
it "returns a single element as array" do
|
151
|
+
model.merge_attributes(:array => 1.5)
|
152
|
+
assert_equal [ 1.5 ], model.array
|
153
|
+
end
|
154
|
+
|
155
|
+
it "returns an array as array" do
|
156
|
+
model.merge_attributes(:array => [ 1, 2 ])
|
157
|
+
assert_equal [ 1, 2 ], model.array
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe ":default => 'default_value'" do
|
162
|
+
it "should return nil when default is not defined on a new object" do
|
163
|
+
assert_equal model.bool, nil
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should return the value of the object when default is not defined" do
|
167
|
+
model.merge_attributes({ :bool => false })
|
168
|
+
assert_equal model.bool, false
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should return the default value on a new object" do
|
172
|
+
assert_equal model.default, 'default_value'
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should return the value of the persisted object" do
|
176
|
+
model.merge_attributes({ :id => 'some-crazy-id', :default => 23 })
|
177
|
+
assert_equal model.default, 23
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should return nil on a persisted object without a value" do
|
181
|
+
model.merge_attributes({ :id => 'some-crazy-id' })
|
182
|
+
assert_equal model.default, nil
|
183
|
+
end
|
184
|
+
end
|
69
185
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
input_hash = {
|
2
|
+
:name => 'test-server',
|
3
|
+
:flavor => '123'
|
4
|
+
}
|
5
|
+
|
6
|
+
output_hash = {
|
7
|
+
'name' => 'test-server',
|
8
|
+
'flavor' => '123'
|
9
|
+
}
|
10
|
+
|
11
|
+
Shindo.tests('Fog::StringifyKeys', 'core') do
|
12
|
+
|
13
|
+
tests('keys') do
|
14
|
+
|
15
|
+
tests('stringifies symbols') do
|
16
|
+
returns(output_hash) {
|
17
|
+
Fog::StringifyKeys.stringify(input_hash)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
tests('skips strings') do
|
22
|
+
returns(output_hash) {
|
23
|
+
Fog::StringifyKeys.stringify(output_hash)
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
input_hash = {
|
2
|
+
:name => 'test-server',
|
3
|
+
:flavor => '123',
|
4
|
+
:size => '12345'
|
5
|
+
}
|
6
|
+
|
7
|
+
output_hash = {
|
8
|
+
'name' => 'test-server',
|
9
|
+
'flavor' => '123'
|
10
|
+
}
|
11
|
+
|
12
|
+
valid_keys = %w{flavor name}
|
13
|
+
|
14
|
+
Shindo.tests('Fog::WhitelistKeys', 'core') do
|
15
|
+
|
16
|
+
tests('whitelist_keys') do
|
17
|
+
tests('excludes invalid values') do
|
18
|
+
returns(output_hash) {
|
19
|
+
Fog::WhitelistKeys.whitelist(input_hash, valid_keys)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fog-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.23.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Light
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-07-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: builder
|
@@ -31,14 +31,14 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - ~>
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '0.
|
34
|
+
version: '0.38'
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - ~>
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: '0.
|
41
|
+
version: '0.38'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: formatador
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -219,6 +219,14 @@ files:
|
|
219
219
|
- lib/fog/compute/models/server.rb
|
220
220
|
- lib/fog/core.rb
|
221
221
|
- lib/fog/core/attributes.rb
|
222
|
+
- lib/fog/core/attributes/array.rb
|
223
|
+
- lib/fog/core/attributes/boolean.rb
|
224
|
+
- lib/fog/core/attributes/default.rb
|
225
|
+
- lib/fog/core/attributes/float.rb
|
226
|
+
- lib/fog/core/attributes/integer.rb
|
227
|
+
- lib/fog/core/attributes/string.rb
|
228
|
+
- lib/fog/core/attributes/time.rb
|
229
|
+
- lib/fog/core/attributes/timestamp.rb
|
222
230
|
- lib/fog/core/collection.rb
|
223
231
|
- lib/fog/core/connection.rb
|
224
232
|
- lib/fog/core/credentials.rb
|
@@ -234,11 +242,13 @@ files:
|
|
234
242
|
- lib/fog/core/scp.rb
|
235
243
|
- lib/fog/core/service.rb
|
236
244
|
- lib/fog/core/ssh.rb
|
245
|
+
- lib/fog/core/stringify_keys.rb
|
237
246
|
- lib/fog/core/time.rb
|
238
247
|
- lib/fog/core/utils.rb
|
239
248
|
- lib/fog/core/uuid.rb
|
240
249
|
- lib/fog/core/wait_for.rb
|
241
250
|
- lib/fog/core/wait_for_defaults.rb
|
251
|
+
- lib/fog/core/whitelist_keys.rb
|
242
252
|
- lib/fog/dns.rb
|
243
253
|
- lib/fog/identity.rb
|
244
254
|
- lib/fog/image.rb
|
@@ -280,6 +290,8 @@ files:
|
|
280
290
|
- spec/utils_spec.rb
|
281
291
|
- spec/uuid_spec.rb
|
282
292
|
- spec/wait_for_spec.rb
|
293
|
+
- tests/core/stringify_keys_tests.rb
|
294
|
+
- tests/core/whitelist_keys_tests.rb
|
283
295
|
homepage: https://github.com/fog/fog-core
|
284
296
|
licenses:
|
285
297
|
- MIT
|
@@ -300,7 +312,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
300
312
|
version: '0'
|
301
313
|
requirements: []
|
302
314
|
rubyforge_project:
|
303
|
-
rubygems_version: 2.
|
315
|
+
rubygems_version: 2.3.0
|
304
316
|
signing_key:
|
305
317
|
specification_version: 4
|
306
318
|
summary: Shared classes and tests for fog providers and services.
|