aws-sdk-core 2.0.0.rc1 → 2.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/README.md +6 -3
  4. data/Rakefile +2 -0
  5. data/apis/AutoScaling-2011-01-01.json +1 -0
  6. data/apis/CloudFormation-2010-05-15.json +75 -0
  7. data/apis/CloudFront-2012-05-05.json +1 -0
  8. data/apis/CloudFront-2013-05-12.json +1 -0
  9. data/apis/CloudFront-2013-08-26.json +1 -0
  10. data/apis/CloudSearch-2011-02-01.json +1 -0
  11. data/apis/CloudWatch-2010-08-01.json +1 -0
  12. data/apis/DataPipeline-2012-10-29.json +1 -0
  13. data/apis/DirectConnect-2012-10-25.json +1 -0
  14. data/apis/DynamoDB-2011-12-05.json +1 -0
  15. data/apis/DynamoDB-2012-08-10.json +1 -0
  16. data/apis/EC2-2013-06-15.json +1 -0
  17. data/apis/EC2-2013-10-01.json +1 -0
  18. data/apis/EMR-2009-03-31.json +1 -0
  19. data/apis/ElastiCache-2012-11-15.json +1 -0
  20. data/apis/ElastiCache-2013-06-15.json +1 -0
  21. data/apis/ElasticBeanstalk-2010-12-01.json +1 -0
  22. data/apis/ElasticLoadBalancing-2012-06-01.json +73 -0
  23. data/apis/ElasticTranscoder-2012-09-25.json +231 -0
  24. data/apis/Glacier-2012-06-01.json +2 -0
  25. data/apis/IAM-2010-05-08.json +1 -0
  26. data/apis/ImportExport-2010-06-01.json +1 -0
  27. data/apis/OpsWorks-2013-02-18.json +1 -0
  28. data/apis/RDS-2013-01-10.json +1 -0
  29. data/apis/RDS-2013-02-12.json +1 -0
  30. data/apis/RDS-2013-05-15.json +1 -0
  31. data/apis/Redshift-2012-12-01.json +1 -0
  32. data/apis/Route53-2012-12-12.json +1 -0
  33. data/apis/S3-2006-03-01.json +5 -0
  34. data/apis/SDB-2009-04-15.json +1 -0
  35. data/apis/SES-2010-12-01.json +1 -0
  36. data/apis/SNS-2010-03-31.json +1 -0
  37. data/apis/SQS-2012-11-05.json +1 -0
  38. data/apis/STS-2011-06-15.json +1 -0
  39. data/apis/SWF-2012-01-25.json +1 -0
  40. data/apis/StorageGateway-2012-06-30.json +1 -0
  41. data/apis/StorageGateway-2013-06-30.json +2018 -0
  42. data/apis/Support-2013-04-15.json +1 -0
  43. data/apis/source/cloudformation-2010-05-15.json +118 -12
  44. data/apis/source/elasticloadbalancing-2012-06-01.json +347 -220
  45. data/apis/source/elastictranscoder-2012-09-25.json +315 -5
  46. data/apis/source/s3-2006-03-01.json +3 -0
  47. data/apis/source/storagegateway-2013-06-30.json +12560 -0
  48. data/apis/source/storagegateway-2013-06-30.paginators.json +28 -0
  49. data/doc-src/plugins/apis.rb +44 -1
  50. data/doc-src/templates/default/fulldoc/html/setup.rb +1 -1
  51. data/features/common/step_definitions.rb +3 -5
  52. data/features/env.rb +2 -0
  53. data/features/glacier/client.feature +8 -0
  54. data/features/glacier/step_definitions.rb +7 -7
  55. data/features/s3/step_definitions.rb +2 -3
  56. data/lib/aws.rb +75 -69
  57. data/lib/aws/api/service_translators/glacier.rb +1 -0
  58. data/lib/aws/api/translator.rb +13 -8
  59. data/lib/aws/credentials.rb +5 -5
  60. data/lib/aws/instance_profile_credentials.rb +113 -0
  61. data/lib/aws/plugins/credentials.rb +2 -1
  62. data/lib/aws/plugins/glacier_account_id.rb +11 -0
  63. data/lib/aws/plugins/glacier_checksums.rb +7 -3
  64. data/lib/aws/plugins/instance_profile_credentials.rb +14 -0
  65. data/lib/aws/plugins/s3_bucket_dns.rb +17 -14
  66. data/lib/aws/plugins/s3_md5s.rb +3 -3
  67. data/lib/aws/service.rb +10 -9
  68. data/lib/aws/signers/s3.rb +2 -2
  69. data/lib/aws/signers/v2.rb +1 -1
  70. data/lib/aws/signers/v4.rb +2 -2
  71. data/lib/aws/version.rb +1 -1
  72. data/lib/aws/xml/serializer.rb +1 -1
  73. data/spec/aws/instance_profile_credentials_spec.rb +94 -0
  74. data/spec/aws/operations_spec.rb +1 -1
  75. data/spec/aws/plugins/credentials_spec.rb +2 -2
  76. data/spec/fixtures/operations/glacier/account_id_param.yml +13 -0
  77. data/spec/fixtures/operations/glacier/custom_account_id.yml +11 -0
  78. data/spec/fixtures/operations/glacier/default_account_id.yml +10 -0
  79. data/spec/fixtures/operations/s3/content_type_header.yml +12 -0
  80. data/spec/fixtures/operations/s3/md5_checksum_disabled.yml +1 -1
  81. data/tasks/apis.rake +2 -2
  82. data/tasks/docs.rake +2 -1
  83. data/tasks/handlers.rake +30 -0
  84. data/vendor/seahorse/lib/seahorse/client.rb +1 -0
  85. data/vendor/seahorse/lib/seahorse/client/base.rb +0 -18
  86. data/vendor/seahorse/lib/seahorse/client/block_io.rb +0 -7
  87. data/vendor/seahorse/lib/seahorse/client/configuration.rb +57 -37
  88. data/vendor/seahorse/lib/seahorse/client/handler_list.rb +115 -78
  89. data/vendor/seahorse/lib/seahorse/client/http/endpoint.rb +19 -15
  90. data/vendor/seahorse/lib/seahorse/client/http/request.rb +0 -15
  91. data/vendor/seahorse/lib/seahorse/client/logging/formatter.rb +0 -7
  92. data/vendor/seahorse/lib/seahorse/client/managed_file.rb +14 -0
  93. data/vendor/seahorse/lib/seahorse/client/net_http/handler.rb +1 -3
  94. data/vendor/seahorse/lib/seahorse/client/plugins/content_length.rb +1 -1
  95. data/vendor/seahorse/lib/seahorse/client/plugins/endpoint.rb +81 -10
  96. data/vendor/seahorse/lib/seahorse/client/plugins/restful_bindings.rb +1 -71
  97. data/vendor/seahorse/lib/seahorse/client/request.rb +26 -3
  98. data/vendor/seahorse/spec/seahorse/client/base_spec.rb +1 -5
  99. data/vendor/seahorse/spec/seahorse/client/configuration_spec.rb +1 -10
  100. data/vendor/seahorse/spec/seahorse/client/handler_list_spec.rb +10 -10
  101. data/vendor/seahorse/spec/seahorse/client/http/endpoint_spec.rb +46 -14
  102. data/vendor/seahorse/spec/seahorse/client/http/request_spec.rb +1 -42
  103. data/vendor/seahorse/spec/seahorse/client/logging/formatter_spec.rb +1 -6
  104. data/vendor/seahorse/spec/seahorse/client/logging/handler_spec.rb +1 -1
  105. data/vendor/seahorse/spec/seahorse/client/net_http/handler_spec.rb +5 -4
  106. data/vendor/seahorse/spec/seahorse/client/param_converter_spec.rb +1 -0
  107. data/vendor/seahorse/spec/seahorse/client/plugins/{restful_bindings/uri_path_builder_spec.rb → endpoint/request_uri_builder_spec.rb} +3 -3
  108. data/vendor/seahorse/spec/seahorse/client/plugins/endpoint_spec.rb +1 -11
  109. data/vendor/seahorse/spec/seahorse/client/request_spec.rb +63 -13
  110. metadata +21 -3
@@ -31,10 +31,11 @@ module Aws
31
31
  }
32
32
 
33
33
  option(:credentials) do |config|
34
- Aws::Credentials.new(
34
+ credentials = Aws::Credentials.new(
35
35
  config.access_key_id,
36
36
  config.secret_access_key,
37
37
  config.session_token)
38
+ credentials.set? ? credentials : nil
38
39
  end
39
40
 
40
41
  def after_initialize(client)
@@ -0,0 +1,11 @@
1
+ module Aws
2
+ module Plugins
3
+ class GlacierAccountId < Seahorse::Client::Plugin
4
+ option :account_id, '-'
5
+
6
+ handle_request(step: :validate, priority: 99) do |context|
7
+ context.params[:account_id] ||= context.config.account_id
8
+ end
9
+ end
10
+ end
11
+ end
@@ -59,14 +59,18 @@ module Aws
59
59
  tree_digest = OpenSSL::Digest::Digest.new('sha256')
60
60
  tree_parts = []
61
61
 
62
- until body.eof?
62
+ # if the body is empty/EOF, then we should compute the
63
+ # digests of the empty string
64
+ if body.size == 0
65
+ tree_parts << tree_digest.update('').digest
66
+ digest.update('')
67
+ end
63
68
 
69
+ until body.eof?
64
70
  chunk = body.read(1024 * 1024) # read 1MB
65
71
  tree_parts << tree_digest.update(chunk).digest
66
72
  tree_digest.reset
67
-
68
73
  digest.update(chunk)
69
-
70
74
  end
71
75
 
72
76
  body.rewind
@@ -0,0 +1,14 @@
1
+ module Aws
2
+ module Plugins
3
+ # Adds support for loading access credentials from the EC2 instance
4
+ # metada service.
5
+ class InstanceProfileCredentials < Seahorse::Client::Plugin
6
+
7
+ option(:credentials) do
8
+ credentials = Aws::InstanceProfileCredentials.new
9
+ credentials.set? ? credentials : nil
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -19,37 +19,40 @@ module Aws
19
19
  # the classic region.
20
20
  option(:force_path_style, false)
21
21
 
22
+ def add_handlers(handlers, config)
23
+ handlers.add(Handler) unless config.force_path_style
24
+ end
25
+
22
26
  # @api private
23
27
  class Handler < Seahorse::Client::Handler
24
28
 
25
29
  def call(context)
26
- unless context.config.force_path_style
27
- move_dns_compat_bucket_to_subdomain(context)
28
- end
30
+ move_dns_compat_bucket_to_subdomain(context)
29
31
  @handler.call(context)
30
32
  end
31
33
 
32
34
  private
33
35
 
34
36
  def move_dns_compat_bucket_to_subdomain(context)
35
- if bucket_name = context.params[:bucket]
36
- req = context.http_request
37
- if S3BucketDns.dns_compatible?(bucket_name, req.endpoint.https?)
38
- move_bucket_to_subdomain(bucket_name, req)
39
- end
37
+ bucket_name = context.params[:bucket]
38
+ endpoint = context.http_request.endpoint
39
+ if
40
+ bucket_name &&
41
+ S3BucketDns.dns_compatible?(bucket_name, endpoint.https?)
42
+ then
43
+ move_bucket_to_subdomain(bucket_name, endpoint)
40
44
  end
41
45
  end
42
46
 
43
- def move_bucket_to_subdomain(bucket_name, req)
44
- req.endpoint.host = "#{bucket_name}.#{req.endpoint.host}"
45
- req.path = req.path[(bucket_name.size + 1)..-1]
46
- req.path = "/#{req.path}" unless req.path.match(/^\//)
47
+ def move_bucket_to_subdomain(bucket_name, endpoint)
48
+ endpoint.host = "#{bucket_name}.#{endpoint.host}"
49
+ request_uri = endpoint.request_uri.sub("/#{bucket_name}", '')
50
+ request_uri = "/#{request_uri}" unless request_uri.match(/^\//)
51
+ endpoint.request_uri = request_uri
47
52
  end
48
53
 
49
54
  end
50
55
 
51
- handler(Handler)
52
-
53
56
  class << self
54
57
 
55
58
  # @param [String] bucket_name
@@ -4,7 +4,7 @@ require 'base64'
4
4
  module Aws
5
5
  module Plugins
6
6
 
7
- # @seahorse.client.option [Boolean] :compute_optional_md5s (true)
7
+ # @seahorse.client.option [Boolean] :compute_checksums (true)
8
8
  # When `true` a MD5 checksum will be computed for all requests that
9
9
  # accept the optional `Content-MD5` header. Checksum errors returned
10
10
  # by Amazon S3 are automatically retried up to `:retry_limit` times.
@@ -41,7 +41,7 @@ module Aws
41
41
 
42
42
  end
43
43
 
44
- option(:compute_optional_md5s, true)
44
+ option(:compute_checksums, true)
45
45
 
46
46
  def add_handlers(handlers, config)
47
47
  options = {
@@ -49,7 +49,7 @@ module Aws
49
49
  step: :build, # the request is built but before it is signed
50
50
  }
51
51
 
52
- if !config.compute_optional_md5s
52
+ if !config.compute_checksums
53
53
  options[:operations] = REQUIRED_OPERATIONS
54
54
  end
55
55
 
@@ -176,6 +176,16 @@ module Aws
176
176
  klass
177
177
  end
178
178
 
179
+ # @api private
180
+ def const_missing(constant)
181
+ if constant =~ /^V\d{8}$/
182
+ api = api(api_version(constant))
183
+ const_set(constant, Seahorse::Client.define(api: api))
184
+ else
185
+ super
186
+ end
187
+ end
188
+
179
189
  private
180
190
 
181
191
  def svc_locked_version
@@ -196,15 +206,6 @@ module Aws
196
206
  @apis ||= {}
197
207
  end
198
208
 
199
- def const_missing(constant)
200
- if constant =~ /^V\d{8}$/
201
- api = api(api_version(constant))
202
- const_set(constant, Seahorse::Client.define(api: api))
203
- else
204
- super
205
- end
206
- end
207
-
208
209
  def api(api_version)
209
210
  api = apis[api_version]
210
211
  case api
@@ -137,7 +137,7 @@ module Aws
137
137
  end
138
138
 
139
139
  # append the path name (no querystring)
140
- parts << request.path.split('?')[0]
140
+ parts << request.endpoint.path
141
141
 
142
142
  # lastly any sub resource querystring params need to be appened
143
143
  # in lexigraphical ordered joined by '&' and prefixed by '?'
@@ -152,7 +152,7 @@ module Aws
152
152
  end
153
153
 
154
154
  def signed_querystring_params(request)
155
- request.querystring.to_s.split('&').select do |p|
155
+ request.endpoint.querystring.to_s.split('&').select do |p|
156
156
  SIGNED_QUERYSTRING_PARAMS.include?(p.split('=')[0])
157
157
  end.map { |p| URI.decode(p) }
158
158
  end
@@ -26,7 +26,7 @@ module Aws
26
26
  [
27
27
  http_request.http_method,
28
28
  host(http_request),
29
- http_request.pathname,
29
+ http_request.endpoint.path,
30
30
  params.to_s,
31
31
  ].join("\n")
32
32
  end
@@ -77,8 +77,8 @@ module Aws
77
77
  def canonical_request(request)
78
78
  [
79
79
  request.http_method,
80
- request.pathname,
81
- request.querystring,
80
+ request.endpoint.path,
81
+ request.endpoint.querystring,
82
82
  canonical_headers(request) + "\n",
83
83
  signed_headers(request),
84
84
  request.headers['X-Amz-Content-Sha256']
@@ -1,3 +1,3 @@
1
1
  module Aws
2
- VERSION = '2.0.0.rc1'
2
+ VERSION = '2.0.0.rc2'
3
3
  end
@@ -4,7 +4,7 @@ module Aws
4
4
  class Serializer
5
5
 
6
6
  def setup_request(context)
7
- context.http_request.headers['Content-Type'] = 'application/xml'
7
+ context.http_request.headers['Content-Type'] ||= 'application/xml'
8
8
  end
9
9
 
10
10
  def serialize_params(context, rules, params)
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ module Aws
4
+ describe InstanceProfileCredentials do
5
+
6
+ let(:path) { '/latest/meta-data/iam/security-credentials/' }
7
+
8
+ describe 'without instance metadata service present' do
9
+
10
+ [
11
+ Errno::EHOSTUNREACH,
12
+ Errno::ECONNREFUSED,
13
+ SocketError,
14
+ Timeout::Error,
15
+ ].each do |error_class|
16
+ it "returns no credentials for #{error_class}" do
17
+ stub_request(:get, "http://169.254.169.254#{path}").to_raise(error_class)
18
+ expect(InstanceProfileCredentials.new.set?).to be(false)
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ describe 'with instance metadata service present' do
25
+
26
+ let(:expiration) { Time.now.utc + 3600 }
27
+ let(:expiration2) { expiration + 3600 }
28
+
29
+ let(:resp) { <<-JSON.strip }
30
+ {
31
+ "Code" : "Success",
32
+ "LastUpdated" : "2013-11-22T20:03:48Z",
33
+ "Type" : "AWS-HMAC",
34
+ "AccessKeyId" : "akid",
35
+ "SecretAccessKey" : "secret",
36
+ "Token" : "session-token",
37
+ "Expiration" : "#{expiration.strftime('%Y-%m-%dT%H:%M:%SZ')}"
38
+ }
39
+ JSON
40
+
41
+ let(:resp2) { <<-JSON.strip }
42
+ {
43
+ "Code" : "Success",
44
+ "LastUpdated" : "2013-11-22T20:03:48Z",
45
+ "Type" : "AWS-HMAC",
46
+ "AccessKeyId" : "akid-2",
47
+ "SecretAccessKey" : "secret-2",
48
+ "Token" : "session-token-2",
49
+ "Expiration" : "#{(expiration2).strftime('%Y-%m-%dT%H:%M:%SZ')}"
50
+ }
51
+ JSON
52
+
53
+ before(:each) do
54
+ stub_request(:get, "http://169.254.169.254#{path}").
55
+ to_return(:status => 200, :body => "profile-name\n")
56
+ stub_request(:get, "http://169.254.169.254#{path}profile-name").
57
+ to_return(:status => 200, :body => resp).
58
+ to_return(:status => 200, :body => resp2)
59
+ end
60
+
61
+ it 'populates credentials from the instance profile' do
62
+ c = InstanceProfileCredentials.new
63
+ expect(c.access_key_id).to eq('akid')
64
+ expect(c.secret_access_key).to eq('secret')
65
+ expect(c.session_token).to eq('session-token')
66
+ expect(c.expiration.to_s).to eq(expiration.to_s)
67
+ end
68
+
69
+ it 're-queries the metadata service when #refresh! is called' do
70
+ c = InstanceProfileCredentials.new
71
+ c.refresh!
72
+ expect(c.access_key_id).to eq('akid-2')
73
+ expect(c.secret_access_key).to eq('secret-2')
74
+ expect(c.session_token).to eq('session-token-2')
75
+ expect(c.expiration.to_s).to eq(expiration2.to_s)
76
+ end
77
+
78
+ describe 'auto refreshing' do
79
+
80
+ # expire in 4 minutes
81
+ let(:expiration) { Time.now.utc + 299 }
82
+
83
+ it 'auto-refreshes within 5 minutes from expiration' do
84
+ c = InstanceProfileCredentials.new
85
+ expect(c.access_key_id).to eq('akid-2')
86
+ expect(c.secret_access_key).to eq('secret-2')
87
+ expect(c.session_token).to eq('session-token-2')
88
+ expect(c.expiration.to_s).to eq(expiration2.to_s)
89
+ end
90
+
91
+ end
92
+ end
93
+ end
94
+ end
@@ -84,7 +84,7 @@ module Aws
84
84
  if f.request
85
85
  expect(http_req.endpoint.host).to eq(f.request.host) if f.request.host
86
86
  expect(http_req.http_method).to eq(f.request.method) if f.request.method
87
- expect(http_req.path).to eq(f.request.path) if f.request.path
87
+ expect(http_req.endpoint.request_uri).to eq(f.request.path) if f.request.path
88
88
  if f.request.headers
89
89
  f.request.headers.each_pair do |header, value|
90
90
  expected_value = value.nil? ? nil : value.to_s
@@ -21,9 +21,9 @@ module Aws
21
21
  expect(config.build!).to respond_to(:credentials)
22
22
  end
23
23
 
24
- it 'defaults to a Credentials object' do
24
+ it 'defaults to nil when credentials not set' do
25
25
  plugin.add_options(config)
26
- expect(config.build!.credentials).to be_kind_of(Aws::Credentials)
26
+ expect(config.build!.credentials).to be(nil)
27
27
  end
28
28
 
29
29
  it 'hydrates credentials from the env (AWS_)' do
@@ -0,0 +1,13 @@
1
+ # This test ensures the `:account_id` param can be specified and that
2
+ # it will override the default configured account id.
3
+ config:
4
+ account_id: 'CONFIG-ACCOUNT-ID'
5
+ operation: list_vaults
6
+ params:
7
+ :account_id: 'PARAM-ACCOUNT-ID'
8
+ request:
9
+ path: /PARAM-ACCOUNT-ID/vaults
10
+ response:
11
+ status_code: 200
12
+ body: |
13
+ {"Marker":null,"VaultList":[]}
@@ -0,0 +1,11 @@
1
+ # This test ensures the default `:account_id` of '-' can be replaced via config
2
+ config:
3
+ account_id: 'ACCOUNT-ID'
4
+ operation: list_vaults
5
+ params: {}
6
+ request:
7
+ path: /ACCOUNT-ID/vaults
8
+ response:
9
+ status_code: 200
10
+ body: |
11
+ {"Marker":null,"VaultList":[]}
@@ -0,0 +1,10 @@
1
+ # This test ensures the `:account_id` need not be supplied and that it defaults
2
+ # to the '-' string, which means current account
3
+ operation: list_vaults
4
+ params: {}
5
+ request:
6
+ path: /-/vaults
7
+ response:
8
+ status_code: 200
9
+ body: |
10
+ {"Marker":null,"VaultList":[]}
@@ -0,0 +1,12 @@
1
+ # This test ensures that the content type param makes it to the Content-Type
2
+ # header. There was a bug that caused S3 to always set the content
3
+ # type to application/xml.
4
+ operation: put_object
5
+ params:
6
+ :bucket: 'bucket-name'
7
+ :key: 'key'
8
+ :body: 'abc'
9
+ :content_type: 'text/plain'
10
+ request:
11
+ headers:
12
+ Content-Type: 'text/plain'
@@ -1,5 +1,5 @@
1
1
  config:
2
- compute_optional_md5s: false
2
+ compute_checksums: false
3
3
  operation: put_object
4
4
  params:
5
5
  :bucket: 'bucket-name'
@@ -8,7 +8,6 @@ namespace :api do
8
8
 
9
9
  desc "Lists the supported services and their API versions"
10
10
  task :versions do
11
- require 'aws-sdk-core'
12
11
  supported = []
13
12
  Aws.service_classes.each do |key, svc|
14
13
  name = svc.default_client_class.api.metadata['service_full_name']
@@ -26,6 +25,8 @@ namespace :api do
26
25
  svc_task = "translate:#{svc}"
27
26
  version_task = "translate:#{svc}:#{version}"
28
27
  task(version_task) { translate_api(path) }
28
+
29
+ desc "Translate source APIs for #{svc}" if ENV['ALL']
29
30
  task(svc_task => version_task)
30
31
 
31
32
  desc "Translate source APIs into Seahorse APIs"
@@ -36,7 +37,6 @@ namespace :api do
36
37
  end
37
38
 
38
39
  def translate_api(path)
39
- require 'aws-sdk-core'
40
40
  api = Aws::Api::Translator.translate(
41
41
  JSON.parse(File.read(path), max_nesting: false), documentation: false,
42
42
  errors: false)
@@ -1,11 +1,13 @@
1
1
  namespace :doc do
2
2
 
3
+ desc "Delete the locally generated docs" if ENV['ALL']
3
4
  task :clobber do
4
5
  rm_rf ".yardoc"
5
6
  rm_rf "doc"
6
7
  end
7
8
 
8
9
  # Updates the list of supported services and versions in the README
10
+ desc "Updated the list of supported services in the README" if ENV['ALL']
9
11
  task :readme do
10
12
  lines = []
11
13
  skip = false
@@ -35,7 +37,6 @@ def supported_services_table
35
37
  line = "| %-35s | %-25s | %-30s |\n"
36
38
 
37
39
  lines = []
38
- require 'aws-sdk-core'
39
40
  Aws.service_classes.keys.sort_by(&:downcase).each do |svc|
40
41
  svc = Aws.service_classes[svc]
41
42
  client = svc.default_client_class