fog-aws 3.3.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +10 -12
- data/fog-aws.gemspec +1 -1
- data/lib/fog/aws/compute.rb +2 -0
- data/lib/fog/aws/models/compute/address.rb +1 -0
- data/lib/fog/aws/models/compute/flavors.rb +440 -0
- data/lib/fog/aws/models/rds/cluster.rb +9 -1
- data/lib/fog/aws/models/rds/server.rb +3 -3
- data/lib/fog/aws/models/storage/directory.rb +35 -0
- data/lib/fog/aws/parsers/compute/describe_addresses.rb +30 -9
- data/lib/fog/aws/parsers/compute/describe_image_attribute.rb +122 -0
- data/lib/fog/aws/parsers/compute/describe_security_groups.rb +1 -1
- data/lib/fog/aws/requests/compute/describe_image_attribute.rb +74 -0
- data/lib/fog/aws/requests/compute/describe_security_groups.rb +12 -1
- data/lib/fog/aws/requests/compute/modify_instance_placement.rb +33 -0
- data/lib/fog/aws/requests/dns/change_resource_record_sets.rb +1 -1
- data/lib/fog/aws/requests/dynamodb/update_item.rb +6 -5
- data/lib/fog/aws/requests/storage/get_bucket_location.rb +2 -3
- data/lib/fog/aws/requests/storage/get_service.rb +2 -2
- data/lib/fog/aws/requests/storage/put_object.rb +5 -3
- data/lib/fog/aws/storage.rb +9 -2
- data/lib/fog/aws/version.rb +1 -1
- data/tests/credentials_tests.rb +38 -37
- data/tests/helper.rb +2 -2
- data/tests/helpers/collection_helper.rb +3 -4
- data/tests/helpers/compute/flavors_helper.rb +1 -5
- data/tests/helpers/compute/server_helper.rb +1 -3
- data/tests/helpers/compute/servers_helper.rb +0 -2
- data/tests/helpers/dns_helper.rb +32 -31
- data/tests/helpers/formats_helper.rb +58 -56
- data/tests/helpers/formats_helper_tests.rb +22 -25
- data/tests/helpers/mock_helper.rb +96 -96
- data/tests/helpers/model_helper.rb +4 -5
- data/tests/helpers/responds_to_helper.rb +1 -1
- data/tests/helpers/schema_validator_tests.rb +21 -24
- data/tests/helpers/succeeds_helper.rb +1 -1
- data/tests/parsers/compute/describe_images_tests.rb +1 -1
- data/tests/parsers/elb/describe_load_balancers.rb +1 -1
- data/tests/requests/compute/image_tests.rb +9 -0
- data/tests/requests/sts/assume_role_with_web_identity_tests.rb +2 -0
- data/tests/signaturev4_tests.rb +21 -22
- data/tests/signed_params_tests.rb +7 -7
- data/tests/storage_tests.rb +1 -1
- metadata +8 -6
@@ -12,7 +12,7 @@ module Fog
|
|
12
12
|
# * body [Hash]:
|
13
13
|
# * LocationConstraint [String] - Location constraint of the bucket
|
14
14
|
#
|
15
|
-
# @see
|
15
|
+
# @see https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html
|
16
16
|
|
17
17
|
def get_bucket_location(bucket_name)
|
18
18
|
request({
|
@@ -22,8 +22,7 @@ module Fog
|
|
22
22
|
:idempotent => true,
|
23
23
|
:method => 'GET',
|
24
24
|
:parser => Fog::Parsers::AWS::Storage::GetBucketLocation.new,
|
25
|
-
:query => {'location' => nil}
|
26
|
-
:path_style => true
|
25
|
+
:query => {'location' => nil}
|
27
26
|
})
|
28
27
|
end
|
29
28
|
end
|
@@ -15,13 +15,13 @@ module Fog
|
|
15
15
|
# * DisplayName [String] - Display name of bucket owner
|
16
16
|
# * ID [String] - Id of bucket owner
|
17
17
|
#
|
18
|
-
# @see
|
18
|
+
# @see https://docs.aws.amazon.com/AmazonS3/latest/API/RESTServiceGET.html
|
19
19
|
#
|
20
20
|
def get_service
|
21
21
|
request({
|
22
22
|
:expects => 200,
|
23
23
|
:headers => {},
|
24
|
-
:host =>
|
24
|
+
:host => 's3.amazonaws.com',
|
25
25
|
:idempotent => true,
|
26
26
|
:method => 'GET',
|
27
27
|
:parser => Fog::Parsers::AWS::Storage::GetService.new
|
@@ -18,8 +18,10 @@ module Fog
|
|
18
18
|
# @option options x-amz-acl [String] Permissions, must be in ['private', 'public-read', 'public-read-write', 'authenticated-read']
|
19
19
|
# @option options x-amz-storage-class [String] Default is 'STANDARD', set to 'REDUCED_REDUNDANCY' for non-critical, reproducable data
|
20
20
|
# @option options x-amz-meta-#{name} Headers to be returned with object, note total size of request without body must be less than 8 KB. Each name, value pair must conform to US-ASCII.
|
21
|
-
# @option options encryption [String] Sets HTTP header for server-side encryption. Set to 'AES256' for SSE-S3 and SSE-C. Set to 'aws:kms' for SSE-KMS
|
22
|
-
# @option options
|
21
|
+
# @option options x-amz-server-side-encryption [String] Sets HTTP header for server-side encryption. Set to 'AES256' for SSE-S3 and SSE-C. Set to 'aws:kms' for SSE-KMS
|
22
|
+
# @option options x-amz-server-side-encryption-customer-algorithm [String] Algorithm to use to when encrypting the object for SSE-C.
|
23
|
+
# @option options x-amz-server-side-encryption-customer-key [String] Encryption customer key for SSE-C
|
24
|
+
# @option options x-amz-server-side-encryption-customer-key-MD5 [String] MD5 digest of the encryption key for SSE-C
|
23
25
|
# @option options x-amz-server-side-encryption-aws-kms-key-id [String] KMS key ID of the encryption key for SSE-KMS
|
24
26
|
# @option options x-amz-server-side-encryption-context [String] Encryption context for SSE-KMS
|
25
27
|
#
|
@@ -27,7 +29,7 @@ module Fog
|
|
27
29
|
# * headers [Hash]:
|
28
30
|
# * ETag [String] etag of new object
|
29
31
|
#
|
30
|
-
# @see
|
32
|
+
# @see https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html
|
31
33
|
|
32
34
|
def self.conforming_to_us_ascii!(keys, hash)
|
33
35
|
keys.each do |k|
|
data/lib/fog/aws/storage.rb
CHANGED
@@ -6,6 +6,7 @@ module Fog
|
|
6
6
|
COMPLIANT_BUCKET_NAMES = /^(?:[a-z]|\d(?!\d{0,2}(?:\.\d{1,3}){3}$))(?:[a-z0-9]|\.(?![\.\-])|\-(?![\.])){1,61}[a-z0-9]$/
|
7
7
|
|
8
8
|
DEFAULT_REGION = 'us-east-1'
|
9
|
+
ACCELERATION_HOST = 's3-accelerate.amazonaws.com'
|
9
10
|
|
10
11
|
DEFAULT_SCHEME = 'https'
|
11
12
|
DEFAULT_SCHEME_PORT = {
|
@@ -42,7 +43,7 @@ module Fog
|
|
42
43
|
]
|
43
44
|
|
44
45
|
requires :aws_access_key_id, :aws_secret_access_key
|
45
|
-
recognizes :endpoint, :region, :host, :port, :scheme, :persistent, :use_iam_profile, :aws_session_token, :aws_credentials_expire_at, :path_style, :instrumentor, :instrumentor_name, :aws_signature_version
|
46
|
+
recognizes :endpoint, :region, :host, :port, :scheme, :persistent, :use_iam_profile, :aws_session_token, :aws_credentials_expire_at, :path_style, :acceleration, :instrumentor, :instrumentor_name, :aws_signature_version, :virtual_host, :cname
|
46
47
|
|
47
48
|
secrets :aws_secret_access_key, :hmac
|
48
49
|
|
@@ -288,7 +289,11 @@ module Fog
|
|
288
289
|
end
|
289
290
|
end
|
290
291
|
|
291
|
-
if
|
292
|
+
# uses the bucket name as host if `virtual_host: true`, you can also
|
293
|
+
# manually specify the cname if required.
|
294
|
+
if params[:virtual_host]
|
295
|
+
host = params.fetch(:cname, bucket_name)
|
296
|
+
elsif path_style
|
292
297
|
path = bucket_to_path bucket_name, path
|
293
298
|
else
|
294
299
|
host = [bucket_name, host].join('.')
|
@@ -499,6 +504,7 @@ module Fog
|
|
499
504
|
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.storage'
|
500
505
|
@connection_options = options[:connection_options] || {}
|
501
506
|
@persistent = options.fetch(:persistent, false)
|
507
|
+
@acceleration = options.fetch(:acceleration, false)
|
502
508
|
@signature_version = options.fetch(:aws_signature_version, 4)
|
503
509
|
validate_signature_version!
|
504
510
|
@path_style = options[:path_style] || false
|
@@ -516,6 +522,7 @@ module Fog
|
|
516
522
|
@port = options[:port] || DEFAULT_SCHEME_PORT[@scheme]
|
517
523
|
end
|
518
524
|
|
525
|
+
@host = ACCELERATION_HOST if @acceleration
|
519
526
|
setup_credentials(options)
|
520
527
|
end
|
521
528
|
|
data/lib/fog/aws/version.rb
CHANGED
data/tests/credentials_tests.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
Shindo.tests('AWS | credentials', ['aws']) do
|
2
4
|
old_mock_value = Excon.defaults[:mock]
|
3
5
|
fog_was_mocked = Fog.mocking?
|
@@ -5,8 +7,8 @@ Shindo.tests('AWS | credentials', ['aws']) do
|
|
5
7
|
Fog.unmock!
|
6
8
|
begin
|
7
9
|
Excon.defaults[:mock] = true
|
8
|
-
Excon.stub({:
|
9
|
-
Excon.stub({:
|
10
|
+
Excon.stub({ method: :get, path: '/latest/meta-data/iam/security-credentials/' }, { status: 200, body: 'arole' })
|
11
|
+
Excon.stub({ method: :get, path: '/latest/meta-data/placement/availability-zone/' }, { status: 200, body: 'us-west-1a' })
|
10
12
|
|
11
13
|
expires_at = Time.at(Time.now.to_i + 500)
|
12
14
|
credentials = {
|
@@ -16,69 +18,68 @@ Shindo.tests('AWS | credentials', ['aws']) do
|
|
16
18
|
'Expiration' => expires_at.xmlschema
|
17
19
|
}
|
18
20
|
|
19
|
-
Excon.stub({:
|
21
|
+
Excon.stub({ method: :get, path: '/latest/meta-data/iam/security-credentials/arole' }, { status: 200, body: Fog::JSON.encode(credentials) })
|
20
22
|
|
21
|
-
tests(
|
22
|
-
returns(
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
tests('#fetch_credentials') do
|
24
|
+
returns(aws_access_key_id: 'dummykey',
|
25
|
+
aws_secret_access_key: 'dummysecret',
|
26
|
+
aws_session_token: 'dummytoken',
|
27
|
+
region: 'us-west-1',
|
28
|
+
aws_credentials_expire_at: expires_at) { Fog::AWS::Compute.fetch_credentials(use_iam_profile: true) }
|
27
29
|
end
|
28
30
|
|
29
|
-
ENV[
|
30
|
-
Excon.stub({:
|
31
|
+
ENV['AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'] = '/v1/credentials?id=task_id'
|
32
|
+
Excon.stub({ method: :get, path: '/v1/credentials?id=task_id' }, { status: 200, body: Fog::JSON.encode(credentials) })
|
31
33
|
|
32
|
-
tests(
|
33
|
-
returns(
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
tests('#fetch_credentials') do
|
35
|
+
returns(aws_access_key_id: 'dummykey',
|
36
|
+
aws_secret_access_key: 'dummysecret',
|
37
|
+
aws_session_token: 'dummytoken',
|
38
|
+
region: 'us-west-1',
|
39
|
+
aws_credentials_expire_at: expires_at) { Fog::AWS::Compute.fetch_credentials(use_iam_profile: true) }
|
38
40
|
end
|
39
41
|
|
40
|
-
ENV[
|
42
|
+
ENV['AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'] = nil
|
41
43
|
|
42
|
-
compute = Fog::AWS::Compute.new(:
|
44
|
+
compute = Fog::AWS::Compute.new(use_iam_profile: true)
|
43
45
|
|
44
|
-
tests(
|
45
|
-
returns(nil){compute.refresh_credentials_if_expired}
|
46
|
+
tests('#refresh_credentials_if_expired') do
|
47
|
+
returns(nil) { compute.refresh_credentials_if_expired }
|
46
48
|
end
|
47
49
|
|
48
50
|
credentials['AccessKeyId'] = 'newkey'
|
49
51
|
credentials['SecretAccessKey'] = 'newsecret'
|
50
52
|
credentials['Expiration'] = (expires_at + 10).xmlschema
|
51
53
|
|
52
|
-
Excon.stub({:
|
54
|
+
Excon.stub({ method: :get, path: '/latest/meta-data/iam/security-credentials/arole' }, { status: 200, body: Fog::JSON.encode(credentials) })
|
53
55
|
|
54
56
|
Fog::Time.now = expires_at + 1
|
55
|
-
tests(
|
56
|
-
returns(true){compute.refresh_credentials_if_expired}
|
57
|
-
returns(
|
57
|
+
tests('#refresh_credentials_if_expired') do
|
58
|
+
returns(true) { compute.refresh_credentials_if_expired }
|
59
|
+
returns('newkey') { compute.instance_variable_get(:@aws_access_key_id) }
|
58
60
|
end
|
59
61
|
Fog::Time.now = Time.now
|
60
62
|
|
61
63
|
default_credentials = Fog::AWS::Compute.fetch_credentials({})
|
62
|
-
tests(
|
63
|
-
Excon.stub({:
|
64
|
-
Excon.stub({:
|
65
|
-
returns(default_credentials) {Fog::AWS::Compute.fetch_credentials(:
|
64
|
+
tests('#fetch_credentials when the url 404s') do
|
65
|
+
Excon.stub({ method: :get, path: '/latest/meta-data/iam/security-credentials/' }, { status: 404, body: 'not bound' })
|
66
|
+
Excon.stub({ method: :get, path: '/latest/meta-data/placement/availability-zone/' }, { status: 400, body: 'not found' })
|
67
|
+
returns(default_credentials) { Fog::AWS::Compute.fetch_credentials(use_iam_profile: true) }
|
66
68
|
end
|
67
69
|
|
68
70
|
mocked_credentials = {
|
69
|
-
:
|
70
|
-
:
|
71
|
-
:
|
72
|
-
:
|
71
|
+
aws_access_key_id: 'access-key-id',
|
72
|
+
aws_secret_access_key: 'secret-access-key',
|
73
|
+
aws_session_token: 'session-token',
|
74
|
+
aws_credentials_expire_at: Time.at(Time.now.to_i + 500).xmlschema
|
73
75
|
}
|
74
|
-
tests(
|
76
|
+
tests('#fetch_credentials when mocking') do
|
75
77
|
Fog.mock!
|
76
78
|
Fog::AWS::Compute::Mock.data[:iam_role_based_creds] = mocked_credentials
|
77
|
-
returns(mocked_credentials) {Fog::AWS::Compute.fetch_credentials(:
|
79
|
+
returns(mocked_credentials) { Fog::AWS::Compute.fetch_credentials(use_iam_profile: true) }
|
78
80
|
end
|
79
|
-
|
80
81
|
ensure
|
81
|
-
ENV[
|
82
|
+
ENV['AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'] = nil
|
82
83
|
Excon.stubs.clear
|
83
84
|
Excon.defaults[:mock] = old_mock_value
|
84
85
|
Fog.mock! if fog_was_mocked
|
data/tests/helper.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
begin
|
2
2
|
require 'simplecov'
|
3
3
|
SimpleCov.start
|
4
|
-
SimpleCov.command_name
|
4
|
+
SimpleCov.command_name 'Shindo'
|
5
5
|
rescue LoadError => e
|
6
6
|
$stderr.puts "not recording test coverage: #{e.inspect}"
|
7
7
|
end
|
@@ -10,7 +10,7 @@ require File.expand_path('../../lib/fog/aws', __FILE__)
|
|
10
10
|
|
11
11
|
Bundler.require(:test)
|
12
12
|
|
13
|
-
Excon.defaults.merge!(:
|
13
|
+
Excon.defaults.merge!(debug_request: true, debug_response: true)
|
14
14
|
|
15
15
|
require File.expand_path(File.join(File.dirname(__FILE__), 'helpers', 'mock_helper'))
|
16
16
|
|
@@ -1,6 +1,5 @@
|
|
1
1
|
def collection_tests(collection, params = {}, mocks_implemented = true)
|
2
2
|
tests('success') do
|
3
|
-
|
4
3
|
tests("#new(#{params.inspect})").succeeds do
|
5
4
|
pending if Fog.mocking? && !mocks_implemented
|
6
5
|
collection.new(params)
|
@@ -34,7 +33,7 @@ def collection_tests(collection, params = {}, mocks_implemented = true)
|
|
34
33
|
pending if Fog.mocking? && !mocks_implemented
|
35
34
|
|
36
35
|
methods = [
|
37
|
-
'all?', 'any?', 'find',
|
36
|
+
'all?', 'any?', 'find', 'detect', 'collect', 'map',
|
38
37
|
'find_index', 'flat_map', 'collect_concat', 'group_by',
|
39
38
|
'none?', 'one?'
|
40
39
|
]
|
@@ -43,7 +42,7 @@ def collection_tests(collection, params = {}, mocks_implemented = true)
|
|
43
42
|
if collection.respond_to?(enum_method)
|
44
43
|
tests("##{enum_method}").succeeds do
|
45
44
|
block_called = false
|
46
|
-
collection.send(enum_method) {
|
45
|
+
collection.send(enum_method) { block_called = true }
|
47
46
|
block_called
|
48
47
|
end
|
49
48
|
end
|
@@ -55,7 +54,7 @@ def collection_tests(collection, params = {}, mocks_implemented = true)
|
|
55
54
|
if collection.respond_to?(enum_method)
|
56
55
|
tests("##{enum_method}").succeeds do
|
57
56
|
block_called = false
|
58
|
-
collection.send(enum_method) {
|
57
|
+
collection.send(enum_method) { block_called = true; 0 }
|
59
58
|
block_called
|
60
59
|
end
|
61
60
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
def flavors_tests(connection, params = {}, mocks_implemented = true)
|
2
2
|
tests('success') do
|
3
|
-
|
4
|
-
tests("#all").succeeds do
|
3
|
+
tests('#all').succeeds do
|
5
4
|
pending if Fog.mocking? && !mocks_implemented
|
6
5
|
connection.flavors.all
|
7
6
|
end
|
@@ -14,11 +13,9 @@ def flavors_tests(connection, params = {}, mocks_implemented = true)
|
|
14
13
|
pending if Fog.mocking? && !mocks_implemented
|
15
14
|
connection.flavors.get(@identity)
|
16
15
|
end
|
17
|
-
|
18
16
|
end
|
19
17
|
|
20
18
|
tests('failure') do
|
21
|
-
|
22
19
|
if !Fog.mocking? || mocks_implemented
|
23
20
|
invalid_flavor_identity = connection.flavors.first.identity.to_s.gsub(/\w/, '0')
|
24
21
|
end
|
@@ -27,6 +24,5 @@ def flavors_tests(connection, params = {}, mocks_implemented = true)
|
|
27
24
|
pending if Fog.mocking? && !mocks_implemented
|
28
25
|
connection.flavors.get(invalid_flavor_identity)
|
29
26
|
end
|
30
|
-
|
31
27
|
end
|
32
28
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
def server_tests(connection, params = {}, mocks_implemented = true)
|
2
2
|
model_tests(connection.servers, params, mocks_implemented) do
|
3
|
-
|
4
3
|
tests('#reload').returns(true) do
|
5
4
|
pending if Fog.mocking? && !mocks_implemented
|
6
5
|
@instance.wait_for { ready? }
|
@@ -8,7 +7,7 @@ def server_tests(connection, params = {}, mocks_implemented = true)
|
|
8
7
|
!identity.nil? && identity == @instance.reload.identity
|
9
8
|
end
|
10
9
|
|
11
|
-
responds_to([
|
10
|
+
responds_to(%i[ready state])
|
12
11
|
yield if block_given?
|
13
12
|
|
14
13
|
tests('#reboot').succeeds do
|
@@ -20,6 +19,5 @@ def server_tests(connection, params = {}, mocks_implemented = true)
|
|
20
19
|
if !Fog.mocking? || mocks_implemented
|
21
20
|
@instance.wait_for { ready? }
|
22
21
|
end
|
23
|
-
|
24
22
|
end
|
25
23
|
end
|
data/tests/helpers/dns_helper.rb
CHANGED
@@ -1,54 +1,55 @@
|
|
1
1
|
def dns_providers
|
2
2
|
{
|
3
|
-
:
|
4
|
-
:
|
3
|
+
aws: {
|
4
|
+
mocked: false
|
5
5
|
},
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
6
|
+
bluebox: {
|
7
|
+
mocked: false,
|
8
|
+
zone_attributes: {
|
9
|
+
ttl: 60
|
10
10
|
}
|
11
11
|
},
|
12
|
-
:
|
13
|
-
:
|
12
|
+
dnsimple: {
|
13
|
+
mocked: false
|
14
14
|
},
|
15
|
-
:
|
16
|
-
:
|
15
|
+
dnsmadeeasy: {
|
16
|
+
mocked: false
|
17
17
|
},
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
18
|
+
dynect: {
|
19
|
+
mocked: false,
|
20
|
+
zone_attributes: {
|
21
|
+
email: 'fog@example.com'
|
22
22
|
}
|
23
23
|
},
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
24
|
+
linode: {
|
25
|
+
mocked: false,
|
26
|
+
zone_attributes: {
|
27
|
+
email: 'fog@example.com'
|
28
28
|
}
|
29
29
|
},
|
30
|
-
:
|
31
|
-
:
|
30
|
+
zerigo: {
|
31
|
+
mocked: false
|
32
32
|
},
|
33
|
-
:
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
33
|
+
rackspace: {
|
34
|
+
mocked: false,
|
35
|
+
zone_attributes: {
|
36
|
+
email: 'fog@example.com'
|
37
37
|
}
|
38
38
|
},
|
39
|
-
:
|
40
|
-
:
|
39
|
+
rage4: {
|
40
|
+
mocked: false
|
41
41
|
}
|
42
42
|
}
|
43
43
|
end
|
44
44
|
|
45
|
-
def generate_unique_domain(
|
46
|
-
#get time (with 1/100th of sec accuracy)
|
47
|
-
#want unique domain name and if provider is fast,
|
48
|
-
|
45
|
+
def generate_unique_domain(with_trailing_dot = false)
|
46
|
+
# get time (with 1/100th of sec accuracy)
|
47
|
+
# want unique domain name and if provider is fast,
|
48
|
+
# this can be called more than once per second
|
49
|
+
time = (Time.now.to_f * 100).to_i
|
49
50
|
domain = 'test-' + time.to_s + '.com'
|
50
51
|
if with_trailing_dot
|
51
|
-
domain+= '.'
|
52
|
+
domain += '.'
|
52
53
|
end
|
53
54
|
|
54
55
|
domain
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fog/schema/data_validator'
|
2
4
|
|
3
5
|
# format related hackery
|
4
6
|
# allows both true.is_a?(Fog::Boolean) and false.is_a?(Fog::Boolean)
|
@@ -15,62 +17,62 @@ module Fog
|
|
15
17
|
module Array; end
|
16
18
|
end
|
17
19
|
end
|
18
|
-
[FalseClass, TrueClass].each {|klass| klass.send(:include, Fog::Boolean)}
|
19
|
-
[FalseClass, TrueClass, NilClass, Fog::Boolean].each {|klass| klass.send(:include, Fog::Nullable::Boolean)}
|
20
|
-
[NilClass, String].each {|klass| klass.send(:include, Fog::Nullable::String)}
|
21
|
-
[NilClass, Time].each {|klass| klass.send(:include, Fog::Nullable::Time)}
|
22
|
-
[Integer, NilClass].each {|klass| klass.send(:include, Fog::Nullable::Integer)}
|
23
|
-
[Float, NilClass].each {|klass| klass.send(:include, Fog::Nullable::Float)}
|
24
|
-
[Hash, NilClass].each {|klass| klass.send(:include, Fog::Nullable::Hash)}
|
25
|
-
[Array, NilClass].each {|klass| klass.send(:include, Fog::Nullable::Array)}
|
20
|
+
[FalseClass, TrueClass].each { |klass| klass.send(:include, Fog::Boolean) }
|
21
|
+
[FalseClass, TrueClass, NilClass, Fog::Boolean].each { |klass| klass.send(:include, Fog::Nullable::Boolean) }
|
22
|
+
[NilClass, String].each { |klass| klass.send(:include, Fog::Nullable::String) }
|
23
|
+
[NilClass, Time].each { |klass| klass.send(:include, Fog::Nullable::Time) }
|
24
|
+
[Integer, NilClass].each { |klass| klass.send(:include, Fog::Nullable::Integer) }
|
25
|
+
[Float, NilClass].each { |klass| klass.send(:include, Fog::Nullable::Float) }
|
26
|
+
[Hash, NilClass].each { |klass| klass.send(:include, Fog::Nullable::Hash) }
|
27
|
+
[Array, NilClass].each { |klass| klass.send(:include, Fog::Nullable::Array) }
|
26
28
|
|
27
29
|
module Shindo
|
30
|
+
# Generates a Shindo test that compares a hash schema to the result
|
31
|
+
# of the passed in block returning true if they match.
|
32
|
+
#
|
33
|
+
# The schema that is passed in is a Hash or Array of hashes that
|
34
|
+
# have Classes in place of values. When checking the schema the
|
35
|
+
# value should match the Class.
|
36
|
+
#
|
37
|
+
# Strict mode will fail if the data has additional keys. Setting
|
38
|
+
# +strict+ to +false+ will allow additional keys to appear.
|
39
|
+
#
|
40
|
+
# @param [Hash] schema A Hash schema
|
41
|
+
# @param [Hash] options Options to change validation rules
|
42
|
+
# @option options [Boolean] :allow_extra_keys
|
43
|
+
# If +true+ does not fail when keys are in the data that are
|
44
|
+
# not specified in the schema. This allows new values to
|
45
|
+
# appear in API output without breaking the check.
|
46
|
+
# @option options [Boolean] :allow_optional_rules
|
47
|
+
# If +true+ does not fail if extra keys are in the schema
|
48
|
+
# that do not match the data. Not recommended!
|
49
|
+
# @yield Data to check with schema
|
50
|
+
#
|
51
|
+
# @example Using in a test
|
52
|
+
# Shindo.tests("comparing welcome data against schema") do
|
53
|
+
# data = {:welcome => "Hello" }
|
54
|
+
# data_matches_schema(:welcome => String) { data }
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# comparing welcome data against schema
|
58
|
+
# + data matches schema
|
59
|
+
#
|
60
|
+
# @example Example schema
|
61
|
+
# {
|
62
|
+
# "id" => String,
|
63
|
+
# "ram" => Integer,
|
64
|
+
# "disks" => [
|
65
|
+
# {
|
66
|
+
# "size" => Float
|
67
|
+
# }
|
68
|
+
# ],
|
69
|
+
# "dns_name" => Fog::Nullable::String,
|
70
|
+
# "active" => Fog::Boolean,
|
71
|
+
# "created" => DateTime
|
72
|
+
# }
|
73
|
+
#
|
74
|
+
# @return [Boolean]
|
28
75
|
class Tests
|
29
|
-
# Generates a Shindo test that compares a hash schema to the result
|
30
|
-
# of the passed in block returning true if they match.
|
31
|
-
#
|
32
|
-
# The schema that is passed in is a Hash or Array of hashes that
|
33
|
-
# have Classes in place of values. When checking the schema the
|
34
|
-
# value should match the Class.
|
35
|
-
#
|
36
|
-
# Strict mode will fail if the data has additional keys. Setting
|
37
|
-
# +strict+ to +false+ will allow additional keys to appear.
|
38
|
-
#
|
39
|
-
# @param [Hash] schema A Hash schema
|
40
|
-
# @param [Hash] options Options to change validation rules
|
41
|
-
# @option options [Boolean] :allow_extra_keys
|
42
|
-
# If +true+ does not fail when keys are in the data that are
|
43
|
-
# not specified in the schema. This allows new values to
|
44
|
-
# appear in API output without breaking the check.
|
45
|
-
# @option options [Boolean] :allow_optional_rules
|
46
|
-
# If +true+ does not fail if extra keys are in the schema
|
47
|
-
# that do not match the data. Not recommended!
|
48
|
-
# @yield Data to check with schema
|
49
|
-
#
|
50
|
-
# @example Using in a test
|
51
|
-
# Shindo.tests("comparing welcome data against schema") do
|
52
|
-
# data = {:welcome => "Hello" }
|
53
|
-
# data_matches_schema(:welcome => String) { data }
|
54
|
-
# end
|
55
|
-
#
|
56
|
-
# comparing welcome data against schema
|
57
|
-
# + data matches schema
|
58
|
-
#
|
59
|
-
# @example Example schema
|
60
|
-
# {
|
61
|
-
# "id" => String,
|
62
|
-
# "ram" => Integer,
|
63
|
-
# "disks" => [
|
64
|
-
# {
|
65
|
-
# "size" => Float
|
66
|
-
# }
|
67
|
-
# ],
|
68
|
-
# "dns_name" => Fog::Nullable::String,
|
69
|
-
# "active" => Fog::Boolean,
|
70
|
-
# "created" => DateTime
|
71
|
-
# }
|
72
|
-
#
|
73
|
-
# @return [Boolean]
|
74
76
|
def data_matches_schema(schema, options = {})
|
75
77
|
test('data matches schema') do
|
76
78
|
validator = Fog::Schema::DataValidator.new
|
@@ -84,9 +86,9 @@ module Shindo
|
|
84
86
|
def formats(format, strict = true)
|
85
87
|
test('has proper format') do
|
86
88
|
if strict
|
87
|
-
options = {:
|
89
|
+
options = { allow_extra_keys: false, allow_optional_rules: true }
|
88
90
|
else
|
89
|
-
options = {:
|
91
|
+
options = { allow_extra_keys: true, allow_optional_rules: true }
|
90
92
|
end
|
91
93
|
validator = Fog::Schema::DataValidator.new
|
92
94
|
valid = validator.validate(yield, format, options)
|