aws-sdk-core 3.114.1 → 3.130.1
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 +4 -4
- data/CHANGELOG.md +216 -0
- data/VERSION +1 -1
- data/lib/aws-defaults/default_configuration.rb +153 -0
- data/lib/aws-defaults/defaults_mode_config_resolver.rb +107 -0
- data/lib/aws-defaults.rb +3 -0
- data/lib/aws-sdk-core/assume_role_credentials.rb +19 -0
- data/lib/aws-sdk-core/assume_role_web_identity_credentials.rb +7 -1
- data/lib/aws-sdk-core/client_stubs.rb +5 -1
- data/lib/aws-sdk-core/credential_provider_chain.rb +2 -1
- data/lib/aws-sdk-core/ec2_metadata.rb +27 -7
- data/lib/aws-sdk-core/ecs_credentials.rb +5 -0
- data/lib/aws-sdk-core/errors.rb +5 -1
- data/lib/aws-sdk-core/instance_profile_credentials.rb +119 -18
- data/lib/aws-sdk-core/json/json_engine.rb +10 -8
- data/lib/aws-sdk-core/json/oj_engine.rb +33 -6
- data/lib/aws-sdk-core/json/parser.rb +8 -0
- data/lib/aws-sdk-core/json.rb +8 -26
- data/lib/aws-sdk-core/log/param_filter.rb +9 -1
- data/lib/aws-sdk-core/pageable_response.rb +72 -26
- data/lib/aws-sdk-core/pager.rb +3 -0
- data/lib/aws-sdk-core/param_validator.rb +29 -0
- data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +340 -0
- data/lib/aws-sdk-core/plugins/credentials_configuration.rb +3 -1
- data/lib/aws-sdk-core/plugins/defaults_mode.rb +40 -0
- data/lib/aws-sdk-core/plugins/http_checksum.rb +8 -1
- data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +17 -0
- data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +16 -1
- data/lib/aws-sdk-core/plugins/recursion_detection.rb +27 -0
- data/lib/aws-sdk-core/plugins/regional_endpoint.rb +47 -1
- data/lib/aws-sdk-core/plugins/response_paging.rb +1 -1
- data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +5 -3
- data/lib/aws-sdk-core/plugins/retry_errors.rb +21 -5
- data/lib/aws-sdk-core/plugins/signature_v4.rb +15 -24
- data/lib/aws-sdk-core/plugins/stub_responses.rb +5 -1
- data/lib/aws-sdk-core/process_credentials.rb +3 -2
- data/lib/aws-sdk-core/refreshing_credentials.rb +40 -11
- data/lib/aws-sdk-core/rest/request/body.rb +19 -1
- data/lib/aws-sdk-core/rest/request/headers.rb +18 -6
- data/lib/aws-sdk-core/rest/response/headers.rb +3 -1
- data/lib/aws-sdk-core/shared_config.rb +27 -8
- data/lib/aws-sdk-core/shared_credentials.rb +7 -1
- data/lib/aws-sdk-core/sso_credentials.rb +8 -3
- data/lib/aws-sdk-core/structure.rb +10 -1
- data/lib/aws-sdk-core/xml/parser/engines/ox.rb +1 -1
- data/lib/aws-sdk-core/xml/parser/engines/rexml.rb +0 -8
- data/lib/aws-sdk-core/xml/parser/frame.rb +23 -0
- data/lib/aws-sdk-core.rb +6 -0
- data/lib/aws-sdk-sso/client.rb +27 -5
- data/lib/aws-sdk-sso.rb +1 -1
- data/lib/aws-sdk-sts/client.rb +424 -415
- data/lib/aws-sdk-sts/plugins/sts_regional_endpoints.rb +5 -1
- data/lib/aws-sdk-sts/presigner.rb +7 -1
- data/lib/aws-sdk-sts/types.rb +199 -181
- data/lib/aws-sdk-sts.rb +1 -1
- data/lib/seahorse/client/configuration.rb +4 -0
- data/lib/seahorse/client/h2/connection.rb +14 -11
- data/lib/seahorse/client/h2/handler.rb +4 -5
- data/lib/seahorse/client/net_http/connection_pool.rb +7 -0
- data/lib/seahorse/client/net_http/handler.rb +15 -7
- data/lib/seahorse/client/net_http/patches.rb +13 -84
- data/lib/seahorse/client/plugins/content_length.rb +11 -5
- data/lib/seahorse/client/plugins/net_http.rb +33 -2
- data/lib/seahorse/model/operation.rb +3 -0
- data/lib/seahorse/model/shapes.rb +25 -0
- metadata +11 -6
- data/lib/aws-sdk-sso/plugins/content_type.rb +0 -25
@@ -43,6 +43,10 @@ module Aws
|
|
43
43
|
# @option options [IO] :http_debug_output (nil) HTTP wire
|
44
44
|
# traces are sent to this object. You can specify something
|
45
45
|
# like $stdout.
|
46
|
+
# @option options [Callable] before_refresh Proc called before
|
47
|
+
# credentials are refreshed. `before_refresh` is called
|
48
|
+
# with an instance of this object when
|
49
|
+
# AWS credentials are required and need to be refreshed.
|
46
50
|
def initialize options = {}
|
47
51
|
@retries = options[:retries] || 5
|
48
52
|
@ip_address = options[:ip_address] || '169.254.170.2'
|
@@ -58,6 +62,7 @@ module Aws
|
|
58
62
|
@http_read_timeout = options[:http_read_timeout] || 5
|
59
63
|
@http_debug_output = options[:http_debug_output]
|
60
64
|
@backoff = backoff(options[:backoff])
|
65
|
+
@async_refresh = false
|
61
66
|
super
|
62
67
|
end
|
63
68
|
|
data/lib/aws-sdk-core/errors.rb
CHANGED
@@ -18,7 +18,7 @@ module Aws
|
|
18
18
|
@code = self.class.code
|
19
19
|
@context = context
|
20
20
|
@data = data
|
21
|
-
@message = message && !message.empty? ? message : self.class
|
21
|
+
@message = message && !message.empty? ? message : self.class.to_s
|
22
22
|
super(@message)
|
23
23
|
end
|
24
24
|
|
@@ -210,6 +210,10 @@ module Aws
|
|
210
210
|
# Raised when SSO Credentials are invalid
|
211
211
|
class InvalidSSOCredentials < RuntimeError; end
|
212
212
|
|
213
|
+
# Raised when there is a circular reference in chained
|
214
|
+
# source_profiles
|
215
|
+
class SourceProfileCircularReferenceError < RuntimeError; end
|
216
|
+
|
213
217
|
# Raised when a client is constructed and region is not specified.
|
214
218
|
class MissingRegionError < ArgumentError
|
215
219
|
def initialize(*args)
|
@@ -5,7 +5,6 @@ require 'net/http'
|
|
5
5
|
|
6
6
|
module Aws
|
7
7
|
class InstanceProfileCredentials
|
8
|
-
|
9
8
|
include CredentialProvider
|
10
9
|
include RefreshingCredentials
|
11
10
|
|
@@ -44,7 +43,13 @@ module Aws
|
|
44
43
|
# @param [Hash] options
|
45
44
|
# @option options [Integer] :retries (1) Number of times to retry
|
46
45
|
# when retrieving credentials.
|
47
|
-
# @option options [String] :
|
46
|
+
# @option options [String] :endpoint ('http://169.254.169.254') The IMDS
|
47
|
+
# endpoint. This option has precedence over the :endpoint_mode.
|
48
|
+
# @option options [String] :endpoint_mode ('IPv4') The endpoint mode for
|
49
|
+
# the instance metadata service. This is either 'IPv4' ('169.254.169.254')
|
50
|
+
# or 'IPv6' ('[fd00:ec2::254]').
|
51
|
+
# @option options [String] :ip_address ('169.254.169.254') Deprecated. Use
|
52
|
+
# :endpoint instead. The IP address for the endpoint.
|
48
53
|
# @option options [Integer] :port (80)
|
49
54
|
# @option options [Float] :http_open_timeout (1)
|
50
55
|
# @option options [Float] :http_read_timeout (1)
|
@@ -58,9 +63,14 @@ module Aws
|
|
58
63
|
# @option options [Integer] :token_ttl Time-to-Live in seconds for EC2
|
59
64
|
# Metadata Token used for fetching Metadata Profile Credentials, defaults
|
60
65
|
# to 21600 seconds
|
66
|
+
# @option options [Callable] before_refresh Proc called before
|
67
|
+
# credentials are refreshed. `before_refresh` is called
|
68
|
+
# with an instance of this object when
|
69
|
+
# AWS credentials are required and need to be refreshed.
|
61
70
|
def initialize(options = {})
|
62
71
|
@retries = options[:retries] || 1
|
63
|
-
|
72
|
+
endpoint_mode = resolve_endpoint_mode(options)
|
73
|
+
@endpoint = resolve_endpoint(options, endpoint_mode)
|
64
74
|
@port = options[:port] || 80
|
65
75
|
@http_open_timeout = options[:http_open_timeout] || 1
|
66
76
|
@http_read_timeout = options[:http_read_timeout] || 1
|
@@ -68,6 +78,8 @@ module Aws
|
|
68
78
|
@backoff = backoff(options[:backoff])
|
69
79
|
@token_ttl = options[:token_ttl] || 21_600
|
70
80
|
@token = nil
|
81
|
+
@no_refresh_until = nil
|
82
|
+
@async_refresh = false
|
71
83
|
super
|
72
84
|
end
|
73
85
|
|
@@ -78,6 +90,34 @@ module Aws
|
|
78
90
|
|
79
91
|
private
|
80
92
|
|
93
|
+
def resolve_endpoint_mode(options)
|
94
|
+
value = options[:endpoint_mode]
|
95
|
+
value ||= ENV['AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE']
|
96
|
+
value ||= Aws.shared_config.ec2_metadata_service_endpoint_mode(
|
97
|
+
profile: options[:profile]
|
98
|
+
)
|
99
|
+
value || 'IPv4'
|
100
|
+
end
|
101
|
+
|
102
|
+
def resolve_endpoint(options, endpoint_mode)
|
103
|
+
value = options[:endpoint] || options[:ip_address]
|
104
|
+
value ||= ENV['AWS_EC2_METADATA_SERVICE_ENDPOINT']
|
105
|
+
value ||= Aws.shared_config.ec2_metadata_service_endpoint(
|
106
|
+
profile: options[:profile]
|
107
|
+
)
|
108
|
+
|
109
|
+
return value if value
|
110
|
+
|
111
|
+
case endpoint_mode.downcase
|
112
|
+
when 'ipv4' then 'http://169.254.169.254'
|
113
|
+
when 'ipv6' then 'http://[fd00:ec2::254]'
|
114
|
+
else
|
115
|
+
raise ArgumentError,
|
116
|
+
':endpoint_mode is not valid, expected IPv4 or IPv6, '\
|
117
|
+
"got: #{endpoint_mode}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
81
121
|
def backoff(backoff)
|
82
122
|
case backoff
|
83
123
|
when Proc then backoff
|
@@ -87,18 +127,48 @@ module Aws
|
|
87
127
|
end
|
88
128
|
|
89
129
|
def refresh
|
130
|
+
if @no_refresh_until && @no_refresh_until > Time.now
|
131
|
+
warn_expired_credentials
|
132
|
+
return
|
133
|
+
end
|
134
|
+
|
90
135
|
# Retry loading credentials up to 3 times is the instance metadata
|
91
136
|
# service is responding but is returning invalid JSON documents
|
92
137
|
# in response to the GET profile credentials call.
|
93
138
|
begin
|
94
139
|
retry_errors([Aws::Json::ParseError, StandardError], max_retries: 3) do
|
95
140
|
c = Aws::Json.load(get_credentials.to_s)
|
96
|
-
@credentials
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
141
|
+
if empty_credentials?(@credentials)
|
142
|
+
@credentials = Credentials.new(
|
143
|
+
c['AccessKeyId'],
|
144
|
+
c['SecretAccessKey'],
|
145
|
+
c['Token']
|
146
|
+
)
|
147
|
+
@expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
|
148
|
+
if @expiration && @expiration < Time.now
|
149
|
+
@no_refresh_until = Time.now + refresh_offset
|
150
|
+
warn_expired_credentials
|
151
|
+
end
|
152
|
+
else
|
153
|
+
# credentials are already set, update them only if the new ones are not empty
|
154
|
+
if !c['AccessKeyId'] || c['AccessKeyId'].empty?
|
155
|
+
# error getting new credentials
|
156
|
+
@no_refresh_until = Time.now + refresh_offset
|
157
|
+
warn_expired_credentials
|
158
|
+
else
|
159
|
+
@credentials = Credentials.new(
|
160
|
+
c['AccessKeyId'],
|
161
|
+
c['SecretAccessKey'],
|
162
|
+
c['Token']
|
163
|
+
)
|
164
|
+
@expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
|
165
|
+
if @expiration && @expiration < Time.now
|
166
|
+
@no_refresh_until = Time.now + refresh_offset
|
167
|
+
warn_expired_credentials
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
102
172
|
end
|
103
173
|
rescue Aws::Json::ParseError
|
104
174
|
raise Aws::Errors::MetadataParserError
|
@@ -119,10 +189,11 @@ module Aws
|
|
119
189
|
begin
|
120
190
|
retry_errors(NETWORK_ERRORS, max_retries: @retries) do
|
121
191
|
unless token_set?
|
192
|
+
created_time = Time.now
|
122
193
|
token_value, ttl = http_put(
|
123
194
|
conn, METADATA_TOKEN_PATH, @token_ttl
|
124
195
|
)
|
125
|
-
@token = Token.new(token_value, ttl) if token_value && ttl
|
196
|
+
@token = Token.new(token_value, ttl, created_time) if token_value && ttl
|
126
197
|
end
|
127
198
|
end
|
128
199
|
rescue *NETWORK_ERRORS
|
@@ -132,9 +203,17 @@ module Aws
|
|
132
203
|
end
|
133
204
|
|
134
205
|
token = @token.value if token_set?
|
135
|
-
|
136
|
-
|
137
|
-
|
206
|
+
|
207
|
+
begin
|
208
|
+
metadata = http_get(conn, METADATA_PATH_BASE, token)
|
209
|
+
profile_name = metadata.lines.first.strip
|
210
|
+
http_get(conn, METADATA_PATH_BASE + profile_name, token)
|
211
|
+
rescue TokenExpiredError
|
212
|
+
# Token has expired, reset it
|
213
|
+
# The next retry should fetch it
|
214
|
+
@token = nil
|
215
|
+
raise Non200Response
|
216
|
+
end
|
138
217
|
end
|
139
218
|
end
|
140
219
|
rescue
|
@@ -152,7 +231,8 @@ module Aws
|
|
152
231
|
end
|
153
232
|
|
154
233
|
def open_connection
|
155
|
-
|
234
|
+
uri = URI.parse(@endpoint)
|
235
|
+
http = Net::HTTP.new(uri.hostname || @endpoint, @port || uri.port)
|
156
236
|
http.open_timeout = @http_open_timeout
|
157
237
|
http.read_timeout = @http_read_timeout
|
158
238
|
http.set_debug_output(@http_debug_output) if @http_debug_output
|
@@ -165,9 +245,15 @@ module Aws
|
|
165
245
|
headers = { 'User-Agent' => "aws-sdk-ruby3/#{CORE_GEM_VERSION}" }
|
166
246
|
headers['x-aws-ec2-metadata-token'] = token if token
|
167
247
|
response = connection.request(Net::HTTP::Get.new(path, headers))
|
168
|
-
raise Non200Response unless response.code.to_i == 200
|
169
248
|
|
170
|
-
response.
|
249
|
+
case response.code.to_i
|
250
|
+
when 200
|
251
|
+
response.body
|
252
|
+
when 401
|
253
|
+
raise TokenExpiredError
|
254
|
+
else
|
255
|
+
raise Non200Response
|
256
|
+
end
|
171
257
|
end
|
172
258
|
|
173
259
|
# PUT request fetch token with ttl
|
@@ -206,13 +292,28 @@ module Aws
|
|
206
292
|
end
|
207
293
|
end
|
208
294
|
|
295
|
+
def warn_expired_credentials
|
296
|
+
warn("Attempting credential expiration extension due to a credential "\
|
297
|
+
"service availability issue. A refresh of these credentials "\
|
298
|
+
"will be attempted again in 5 minutes.")
|
299
|
+
end
|
300
|
+
|
301
|
+
def empty_credentials?(creds)
|
302
|
+
!creds || !creds.access_key_id || creds.access_key_id.empty?
|
303
|
+
end
|
304
|
+
|
305
|
+
# Compute an offset for refresh with jitter
|
306
|
+
def refresh_offset
|
307
|
+
300 + rand(0..60)
|
308
|
+
end
|
309
|
+
|
209
310
|
# @api private
|
210
311
|
# Token used to fetch IMDS profile and credentials
|
211
312
|
class Token
|
212
|
-
def initialize(value, ttl)
|
313
|
+
def initialize(value, ttl, created_time = Time.now)
|
213
314
|
@ttl = ttl
|
214
315
|
@value = value
|
215
|
-
@created_time =
|
316
|
+
@created_time = created_time
|
216
317
|
end
|
217
318
|
|
218
319
|
# [String] token value
|
@@ -2,16 +2,18 @@
|
|
2
2
|
|
3
3
|
module Aws
|
4
4
|
module Json
|
5
|
-
|
5
|
+
module JSONEngine
|
6
|
+
class << self
|
7
|
+
def load(json)
|
8
|
+
JSON.parse(json)
|
9
|
+
rescue JSON::ParserError => e
|
10
|
+
raise ParseError.new(e)
|
11
|
+
end
|
6
12
|
|
7
|
-
|
8
|
-
|
13
|
+
def dump(value)
|
14
|
+
JSON.dump(value)
|
15
|
+
end
|
9
16
|
end
|
10
|
-
|
11
|
-
def self.dump(value)
|
12
|
-
JSON.dump(value)
|
13
|
-
end
|
14
|
-
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -2,16 +2,43 @@
|
|
2
2
|
|
3
3
|
module Aws
|
4
4
|
module Json
|
5
|
-
|
5
|
+
module OjEngine
|
6
|
+
# @api private
|
7
|
+
LOAD_OPTIONS = { mode: :compat, symbol_keys: false, empty_string: false }.freeze
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
9
|
+
# @api private
|
10
|
+
DUMP_OPTIONS = { mode: :compat }.freeze
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def load(json)
|
14
|
+
Oj.load(json, LOAD_OPTIONS)
|
15
|
+
rescue *PARSE_ERRORS => e
|
16
|
+
raise ParseError.new(e)
|
17
|
+
end
|
18
|
+
|
19
|
+
def dump(value)
|
20
|
+
Oj.dump(value, DUMP_OPTIONS)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
# Oj before 1.4.0 does not define Oj::ParseError and instead raises
|
26
|
+
# SyntaxError on failure
|
27
|
+
def detect_oj_parse_errors
|
28
|
+
require 'oj'
|
10
29
|
|
11
|
-
|
12
|
-
|
30
|
+
if Oj.const_defined?(:ParseError)
|
31
|
+
[Oj::ParseError, EncodingError, JSON::ParserError]
|
32
|
+
else
|
33
|
+
[SyntaxError]
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
nil
|
37
|
+
end
|
13
38
|
end
|
14
39
|
|
40
|
+
# @api private
|
41
|
+
PARSE_ERRORS = detect_oj_parse_errors
|
15
42
|
end
|
16
43
|
end
|
17
44
|
end
|
@@ -28,8 +28,16 @@ module Aws
|
|
28
28
|
member_name, member_ref = shape.member_by_location_name(key)
|
29
29
|
if member_ref
|
30
30
|
target[member_name] = parse_ref(member_ref, value)
|
31
|
+
elsif shape.union
|
32
|
+
target[:unknown] = { 'name' => key, 'value' => value }
|
31
33
|
end
|
32
34
|
end
|
35
|
+
if shape.union
|
36
|
+
# convert to subclass
|
37
|
+
member_subclass = shape.member_subclass(target.member).new
|
38
|
+
member_subclass[target.member] = target.value
|
39
|
+
target = member_subclass
|
40
|
+
end
|
33
41
|
target
|
34
42
|
end
|
35
43
|
|
data/lib/aws-sdk-core/json.rb
CHANGED
@@ -5,6 +5,8 @@ require_relative 'json/builder'
|
|
5
5
|
require_relative 'json/error_handler'
|
6
6
|
require_relative 'json/handler'
|
7
7
|
require_relative 'json/parser'
|
8
|
+
require_relative 'json/json_engine'
|
9
|
+
require_relative 'json/oj_engine'
|
8
10
|
|
9
11
|
module Aws
|
10
12
|
# @api private
|
@@ -20,9 +22,7 @@ module Aws
|
|
20
22
|
|
21
23
|
class << self
|
22
24
|
def load(json)
|
23
|
-
ENGINE.load(json
|
24
|
-
rescue *ENGINE_ERRORS => e
|
25
|
-
raise ParseError, e
|
25
|
+
ENGINE.load(json)
|
26
26
|
end
|
27
27
|
|
28
28
|
def load_file(path)
|
@@ -30,38 +30,20 @@ module Aws
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def dump(value)
|
33
|
-
ENGINE.dump(value
|
33
|
+
ENGINE.dump(value)
|
34
34
|
end
|
35
35
|
|
36
36
|
private
|
37
37
|
|
38
|
-
def
|
38
|
+
def select_engine
|
39
39
|
require 'oj'
|
40
|
-
|
41
|
-
Oj,
|
42
|
-
[{ mode: :compat, symbol_keys: false, empty_string: false }],
|
43
|
-
[{ mode: :compat }],
|
44
|
-
oj_parse_error
|
45
|
-
]
|
40
|
+
OjEngine
|
46
41
|
rescue LoadError
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
def json_engine
|
51
|
-
[JSON, [], [], [JSON::ParserError]]
|
52
|
-
end
|
53
|
-
|
54
|
-
def oj_parse_error
|
55
|
-
if Oj.const_defined?('ParseError')
|
56
|
-
[Oj::ParseError, EncodingError, JSON::ParserError]
|
57
|
-
else
|
58
|
-
[SyntaxError]
|
59
|
-
end
|
42
|
+
JSONEngine
|
60
43
|
end
|
61
44
|
end
|
62
45
|
|
63
46
|
# @api private
|
64
|
-
ENGINE
|
65
|
-
oj_engine || json_engine
|
47
|
+
ENGINE = select_engine
|
66
48
|
end
|
67
49
|
end
|
@@ -26,7 +26,8 @@ module Aws
|
|
26
26
|
|
27
27
|
def filter(values, type)
|
28
28
|
case values
|
29
|
-
when Struct
|
29
|
+
when Struct then filter_struct(values, type)
|
30
|
+
when Hash then filter_hash(values, type)
|
30
31
|
when Array then filter_array(values, type)
|
31
32
|
else values
|
32
33
|
end
|
@@ -34,6 +35,13 @@ module Aws
|
|
34
35
|
|
35
36
|
private
|
36
37
|
|
38
|
+
def filter_struct(values, type)
|
39
|
+
if values.class.include? Aws::Structure::Union
|
40
|
+
values = { values.member => values.value }
|
41
|
+
end
|
42
|
+
filter_hash(values, type)
|
43
|
+
end
|
44
|
+
|
37
45
|
def filter_hash(values, type)
|
38
46
|
if type.const_defined?('SENSITIVE')
|
39
47
|
filters = type::SENSITIVE + @additional_filters
|
@@ -48,11 +48,11 @@ module Aws
|
|
48
48
|
#
|
49
49
|
module PageableResponse
|
50
50
|
|
51
|
-
def self.
|
52
|
-
base.extend
|
53
|
-
base.
|
54
|
-
base.instance_variable_set(
|
55
|
-
base
|
51
|
+
def self.apply(base)
|
52
|
+
base.extend Extension
|
53
|
+
base.instance_variable_set(:@last_page, nil)
|
54
|
+
base.instance_variable_set(:@more_results, nil)
|
55
|
+
base
|
56
56
|
end
|
57
57
|
|
58
58
|
# @return [Paging::Pager]
|
@@ -62,39 +62,26 @@ module Aws
|
|
62
62
|
# when this method returns `false` will raise an error.
|
63
63
|
# @return [Boolean]
|
64
64
|
def last_page?
|
65
|
-
|
66
|
-
@last_page = !@pager.truncated?(self)
|
67
|
-
end
|
68
|
-
@last_page
|
65
|
+
# Actual implementation is in PageableResponse::Extension
|
69
66
|
end
|
70
67
|
|
71
68
|
# Returns `true` if there are more results. Calling {#next_page} will
|
72
69
|
# return the next response.
|
73
70
|
# @return [Boolean]
|
74
71
|
def next_page?
|
75
|
-
|
72
|
+
# Actual implementation is in PageableResponse::Extension
|
76
73
|
end
|
77
74
|
|
78
75
|
# @return [Seahorse::Client::Response]
|
79
76
|
def next_page(params = {})
|
80
|
-
|
81
|
-
raise LastPageError.new(self)
|
82
|
-
else
|
83
|
-
next_response(params)
|
84
|
-
end
|
77
|
+
# Actual implementation is in PageableResponse::Extension
|
85
78
|
end
|
86
79
|
|
87
80
|
# Yields the current and each following response to the given block.
|
88
81
|
# @yieldparam [Response] response
|
89
82
|
# @return [Enumerable,nil] Returns a new Enumerable if no block is given.
|
90
83
|
def each(&block)
|
91
|
-
|
92
|
-
response = self
|
93
|
-
yield(response)
|
94
|
-
until response.last_page?
|
95
|
-
response = response.next_page
|
96
|
-
yield(response)
|
97
|
-
end
|
84
|
+
# Actual implementation is in PageableResponse::Extension
|
98
85
|
end
|
99
86
|
alias each_page each
|
100
87
|
|
@@ -105,9 +92,7 @@ module Aws
|
|
105
92
|
# @return [Seahorse::Client::Response] Returns the next page of
|
106
93
|
# results.
|
107
94
|
def next_response(params)
|
108
|
-
|
109
|
-
request = context.client.build_request(context.operation_name, params)
|
110
|
-
request.send_request
|
95
|
+
# Actual implementation is in PageableResponse::Extension
|
111
96
|
end
|
112
97
|
|
113
98
|
# @param [Hash] params A hash of additional request params to
|
@@ -115,7 +100,7 @@ module Aws
|
|
115
100
|
# @return [Hash] Returns the hash of request parameters for the
|
116
101
|
# next page, merging any given params.
|
117
102
|
def next_page_params(params)
|
118
|
-
|
103
|
+
# Actual implementation is in PageableResponse::Extension
|
119
104
|
end
|
120
105
|
|
121
106
|
# Raised when calling {PageableResponse#next_page} on a pager that
|
@@ -162,5 +147,66 @@ module Aws
|
|
162
147
|
end
|
163
148
|
|
164
149
|
end
|
150
|
+
|
151
|
+
# The actual decorator module implementation. It is in a distinct module
|
152
|
+
# so that it can be used to extend objects without busting Ruby's constant cache.
|
153
|
+
# object.extend(mod) bust the constant cache only if `mod` contains constants of its own.
|
154
|
+
# @api private
|
155
|
+
module Extension
|
156
|
+
|
157
|
+
include Enumerable
|
158
|
+
include UnsafeEnumerableMethods
|
159
|
+
|
160
|
+
attr_accessor :pager
|
161
|
+
|
162
|
+
def last_page?
|
163
|
+
if @last_page.nil?
|
164
|
+
@last_page = !@pager.truncated?(self)
|
165
|
+
end
|
166
|
+
@last_page
|
167
|
+
end
|
168
|
+
|
169
|
+
def next_page?
|
170
|
+
!last_page?
|
171
|
+
end
|
172
|
+
|
173
|
+
def next_page(params = {})
|
174
|
+
if last_page?
|
175
|
+
raise LastPageError.new(self)
|
176
|
+
else
|
177
|
+
next_response(params)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def each(&block)
|
182
|
+
return enum_for(:each_page) unless block_given?
|
183
|
+
response = self
|
184
|
+
yield(response)
|
185
|
+
until response.last_page?
|
186
|
+
response = response.next_page
|
187
|
+
yield(response)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
alias each_page each
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
def next_response(params)
|
195
|
+
params = next_page_params(params)
|
196
|
+
request = context.client.build_request(context.operation_name, params)
|
197
|
+
request.send_request
|
198
|
+
end
|
199
|
+
|
200
|
+
def next_page_params(params)
|
201
|
+
# Remove all previous tokens from original params
|
202
|
+
# Sometimes a token can be nil and merge would not include it.
|
203
|
+
tokens = @pager.tokens.values.map(&:to_sym)
|
204
|
+
|
205
|
+
params_without_tokens = context[:original_params].reject { |k, _v| tokens.include?(k) }
|
206
|
+
params_without_tokens.merge!(@pager.next_tokens(self).merge(params))
|
207
|
+
params_without_tokens
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
165
211
|
end
|
166
212
|
end
|
data/lib/aws-sdk-core/pager.rb
CHANGED
@@ -70,6 +70,14 @@ module Aws
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
+
if @validate_required && shape.union
|
74
|
+
if values.length > 1
|
75
|
+
errors << "multiple values provided to union at #{context} - must contain exactly one of the supported types: #{shape.member_names.join(', ')}"
|
76
|
+
elsif values.length == 0
|
77
|
+
errors << "No values provided to union at #{context} - must contain exactly one of the supported types: #{shape.member_names.join(', ')}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
73
81
|
# validate non-nil members
|
74
82
|
values.each_pair do |name, value|
|
75
83
|
unless value.nil?
|
@@ -117,11 +125,32 @@ module Aws
|
|
117
125
|
end
|
118
126
|
end
|
119
127
|
|
128
|
+
def document(ref, value, errors, context)
|
129
|
+
document_types = [Hash, Array, Numeric, String, TrueClass, FalseClass, NilClass]
|
130
|
+
unless document_types.any? { |t| value.is_a?(t) }
|
131
|
+
errors << expected_got(context, "one of #{document_types.join(', ')}", value)
|
132
|
+
end
|
133
|
+
|
134
|
+
# recursively validate types for aggregated types
|
135
|
+
case value
|
136
|
+
when Hash
|
137
|
+
value.each do |k, v|
|
138
|
+
document(ref, v, errors, context + "[#{k}]")
|
139
|
+
end
|
140
|
+
when Array
|
141
|
+
value.each do |v|
|
142
|
+
document(ref, v, errors, context)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
120
148
|
def shape(ref, value, errors, context)
|
121
149
|
case ref.shape
|
122
150
|
when StructureShape then structure(ref, value, errors, context)
|
123
151
|
when ListShape then list(ref, value, errors, context)
|
124
152
|
when MapShape then map(ref, value, errors, context)
|
153
|
+
when DocumentShape then document(ref, value, errors, context)
|
125
154
|
when StringShape
|
126
155
|
unless value.is_a?(String)
|
127
156
|
errors << expected_got(context, "a String", value)
|