aws-sdk-core 3.171.1 → 3.199.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 +4 -4
- data/CHANGELOG.md +363 -0
- data/VERSION +1 -1
- data/lib/aws-defaults/default_configuration.rb +4 -4
- data/lib/aws-sdk-core/binary/decode_handler.rb +3 -9
- data/lib/aws-sdk-core/binary/encode_handler.rb +1 -1
- data/lib/aws-sdk-core/binary/event_builder.rb +34 -37
- data/lib/aws-sdk-core/binary/event_stream_decoder.rb +1 -0
- data/lib/aws-sdk-core/binary/event_stream_encoder.rb +4 -3
- data/lib/aws-sdk-core/cbor/cbor_engine.rb +19 -0
- data/lib/aws-sdk-core/cbor/decoder.rb +310 -0
- data/lib/aws-sdk-core/cbor/encoder.rb +243 -0
- data/lib/aws-sdk-core/cbor.rb +106 -0
- data/lib/aws-sdk-core/client_stubs.rb +18 -14
- data/lib/aws-sdk-core/credential_provider.rb +4 -1
- data/lib/aws-sdk-core/ec2_metadata.rb +1 -1
- data/lib/aws-sdk-core/ecs_credentials.rb +78 -11
- data/lib/aws-sdk-core/endpoints/matchers.rb +18 -10
- data/lib/aws-sdk-core/endpoints.rb +6 -2
- data/lib/aws-sdk-core/error_handler.rb +41 -0
- data/lib/aws-sdk-core/errors.rb +3 -3
- data/lib/aws-sdk-core/event_emitter.rb +0 -16
- data/lib/aws-sdk-core/ini_parser.rb +7 -0
- data/lib/aws-sdk-core/instance_profile_credentials.rb +55 -32
- data/lib/aws-sdk-core/json/builder.rb +8 -1
- data/lib/aws-sdk-core/json/error_handler.rb +15 -10
- data/lib/aws-sdk-core/json/handler.rb +12 -6
- data/lib/aws-sdk-core/json/json_engine.rb +3 -1
- data/lib/aws-sdk-core/json/oj_engine.rb +7 -1
- data/lib/aws-sdk-core/json/parser.rb +33 -3
- data/lib/aws-sdk-core/json.rb +43 -14
- data/lib/aws-sdk-core/log/formatter.rb +6 -0
- data/lib/aws-sdk-core/lru_cache.rb +75 -0
- data/lib/aws-sdk-core/pageable_response.rb +3 -1
- data/lib/aws-sdk-core/param_validator.rb +9 -4
- data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +5 -3
- data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +1 -0
- data/lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb +14 -2
- data/lib/aws-sdk-core/plugins/credentials_configuration.rb +2 -0
- data/lib/aws-sdk-core/plugins/global_configuration.rb +8 -9
- data/lib/aws-sdk-core/plugins/http_checksum.rb +2 -1
- data/lib/aws-sdk-core/plugins/invocation_id.rb +1 -11
- data/lib/aws-sdk-core/plugins/logging.rb +2 -0
- data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +3 -1
- data/lib/aws-sdk-core/plugins/protocols/ec2.rb +2 -24
- data/lib/aws-sdk-core/plugins/protocols/json_rpc.rb +6 -8
- data/lib/aws-sdk-core/plugins/protocols/query.rb +4 -2
- data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +3 -15
- data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +3 -0
- data/lib/aws-sdk-core/plugins/protocols/rpc_v2.rb +17 -0
- data/lib/aws-sdk-core/plugins/regional_endpoint.rb +109 -33
- data/lib/aws-sdk-core/plugins/request_compression.rb +226 -0
- data/lib/aws-sdk-core/plugins/retry_errors.rb +12 -3
- data/lib/aws-sdk-core/plugins/sign.rb +24 -13
- data/lib/aws-sdk-core/plugins/stub_responses.rb +1 -0
- data/lib/aws-sdk-core/plugins/user_agent.rb +152 -14
- data/lib/aws-sdk-core/process_credentials.rb +45 -27
- data/lib/aws-sdk-core/query/ec2_handler.rb +27 -0
- data/lib/aws-sdk-core/query/ec2_param_builder.rb +5 -7
- data/lib/aws-sdk-core/query/handler.rb +4 -4
- data/lib/aws-sdk-core/query/param_builder.rb +2 -2
- data/lib/aws-sdk-core/query.rb +2 -1
- data/lib/aws-sdk-core/refreshing_credentials.rb +12 -12
- data/lib/aws-sdk-core/rest/content_type_handler.rb +60 -0
- data/lib/aws-sdk-core/rest/handler.rb +3 -4
- data/lib/aws-sdk-core/rest/request/body.rb +32 -5
- data/lib/aws-sdk-core/rest/request/endpoint.rb +24 -4
- data/lib/aws-sdk-core/rest/request/headers.rb +15 -7
- data/lib/aws-sdk-core/rest/request/querystring_builder.rb +62 -36
- data/lib/aws-sdk-core/rest/response/body.rb +15 -1
- data/lib/aws-sdk-core/rest/response/header_list_parser.rb +79 -0
- data/lib/aws-sdk-core/rest/response/headers.rb +8 -3
- data/lib/aws-sdk-core/rest.rb +1 -0
- data/lib/aws-sdk-core/rpc_v2/builder.rb +62 -0
- data/lib/aws-sdk-core/rpc_v2/content_type_handler.rb +45 -0
- data/lib/aws-sdk-core/rpc_v2/error_handler.rb +84 -0
- data/lib/aws-sdk-core/rpc_v2/handler.rb +74 -0
- data/lib/aws-sdk-core/rpc_v2/parser.rb +90 -0
- data/lib/aws-sdk-core/rpc_v2.rb +6 -0
- data/lib/aws-sdk-core/shared_config.rb +48 -18
- data/lib/aws-sdk-core/sso_credentials.rb +1 -1
- data/lib/aws-sdk-core/stubbing/protocols/rpc_v2.rb +41 -0
- data/lib/aws-sdk-core/stubbing/stub_data.rb +11 -0
- data/lib/aws-sdk-core/util.rb +39 -0
- data/lib/aws-sdk-core/waiters/poller.rb +4 -2
- data/lib/aws-sdk-core/xml/builder.rb +17 -9
- data/lib/aws-sdk-core/xml/error_handler.rb +32 -42
- data/lib/aws-sdk-core/xml/parser/frame.rb +4 -20
- data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
- data/lib/aws-sdk-core/xml/parser.rb +2 -6
- data/lib/aws-sdk-core.rb +7 -2
- data/lib/aws-sdk-sso/client.rb +94 -46
- data/lib/aws-sdk-sso/endpoint_provider.rb +30 -24
- data/lib/aws-sdk-sso/endpoints.rb +1 -0
- data/lib/aws-sdk-sso/plugins/endpoints.rb +4 -2
- data/lib/aws-sdk-sso.rb +1 -1
- data/lib/aws-sdk-ssooidc/client.rb +479 -74
- data/lib/aws-sdk-ssooidc/client_api.rb +78 -1
- data/lib/aws-sdk-ssooidc/endpoint_provider.rb +30 -24
- data/lib/aws-sdk-ssooidc/endpoints.rb +15 -0
- data/lib/aws-sdk-ssooidc/errors.rb +52 -0
- data/lib/aws-sdk-ssooidc/plugins/endpoints.rb +6 -2
- data/lib/aws-sdk-ssooidc/types.rb +372 -51
- data/lib/aws-sdk-ssooidc.rb +1 -1
- data/lib/aws-sdk-sts/client.rb +219 -157
- data/lib/aws-sdk-sts/client_api.rb +20 -9
- data/lib/aws-sdk-sts/endpoint_provider.rb +81 -78
- data/lib/aws-sdk-sts/endpoints.rb +1 -0
- data/lib/aws-sdk-sts/plugins/endpoints.rb +4 -2
- data/lib/aws-sdk-sts/presigner.rb +1 -1
- data/lib/aws-sdk-sts/types.rb +49 -11
- data/lib/aws-sdk-sts.rb +1 -1
- data/lib/seahorse/client/async_base.rb +1 -1
- data/lib/seahorse/client/async_response.rb +19 -0
- data/lib/seahorse/client/base.rb +18 -7
- data/lib/seahorse/client/configuration.rb +0 -4
- data/lib/seahorse/client/h2/handler.rb +1 -0
- data/lib/seahorse/client/handler.rb +1 -1
- data/lib/seahorse/client/net_http/connection_pool.rb +3 -9
- data/lib/seahorse/client/net_http/patches.rb +1 -4
- data/lib/seahorse/client/plugin.rb +9 -0
- data/lib/seahorse/client/plugins/endpoint.rb +0 -1
- data/lib/seahorse/client/plugins/h2.rb +3 -3
- data/lib/seahorse/client/plugins/net_http.rb +48 -16
- data/lib/seahorse/client/plugins/request_callback.rb +31 -0
- data/lib/seahorse/client/response.rb +6 -0
- data/lib/seahorse/model/operation.rb +3 -0
- data/lib/seahorse/model/shapes.rb +2 -2
- data/sig/aws-sdk-core/client_stubs.rbs +10 -0
- data/sig/aws-sdk-core/errors.rbs +22 -0
- data/sig/aws-sdk-core/resources/collection.rbs +21 -0
- data/sig/aws-sdk-core/structure.rbs +4 -0
- data/sig/aws-sdk-core/waiters/errors.rbs +20 -0
- data/sig/aws-sdk-core.rbs +7 -0
- data/sig/seahorse/client/base.rbs +25 -0
- data/sig/seahorse/client/handler_builder.rbs +16 -0
- data/sig/seahorse/client/response.rbs +61 -0
- metadata +44 -17
- /data/lib/aws-sdk-core/xml/parser/{engines/libxml.rb → libxml_engine.rb} +0 -0
- /data/lib/aws-sdk-core/xml/parser/{engines/nokogiri.rb → nokogiri_engine.rb} +0 -0
- /data/lib/aws-sdk-core/xml/parser/{engines/oga.rb → oga_engine.rb} +0 -0
- /data/lib/aws-sdk-core/xml/parser/{engines/ox.rb → ox_engine.rb} +0 -0
- /data/lib/aws-sdk-core/xml/parser/{engines/rexml.rb → rexml_engine.rb} +0 -0
|
@@ -183,7 +183,7 @@ module Aws
|
|
|
183
183
|
|
|
184
184
|
def open_connection
|
|
185
185
|
uri = URI.parse(@endpoint)
|
|
186
|
-
http = Net::HTTP.new(uri.hostname || @endpoint,
|
|
186
|
+
http = Net::HTTP.new(uri.hostname || @endpoint, uri.port || @port)
|
|
187
187
|
http.open_timeout = @http_open_timeout
|
|
188
188
|
http.read_timeout = @http_read_timeout
|
|
189
189
|
http.set_debug_output(@http_debug_output) if @http_debug_output
|
|
@@ -6,7 +6,7 @@ require 'resolv'
|
|
|
6
6
|
|
|
7
7
|
module Aws
|
|
8
8
|
# An auto-refreshing credential provider that loads credentials from
|
|
9
|
-
# instances running in
|
|
9
|
+
# instances running in containers.
|
|
10
10
|
#
|
|
11
11
|
# ecs_credentials = Aws::ECSCredentials.new(retries: 3)
|
|
12
12
|
# ec2 = Aws::EC2::Client.new(credentials: ecs_credentials)
|
|
@@ -17,6 +17,12 @@ module Aws
|
|
|
17
17
|
# @api private
|
|
18
18
|
class Non200Response < RuntimeError; end
|
|
19
19
|
|
|
20
|
+
# Raised when the token file cannot be read.
|
|
21
|
+
class TokenFileReadError < RuntimeError; end
|
|
22
|
+
|
|
23
|
+
# Raised when the token file is invalid.
|
|
24
|
+
class InvalidTokenError < RuntimeError; end
|
|
25
|
+
|
|
20
26
|
# These are the errors we trap when attempting to talk to the
|
|
21
27
|
# instance metadata service. Any of these imply the service
|
|
22
28
|
# is not present, no responding or some other non-recoverable
|
|
@@ -41,7 +47,7 @@ module Aws
|
|
|
41
47
|
# is set and `credential_path` is not set.
|
|
42
48
|
# @option options [String] :credential_path By default, the value of the
|
|
43
49
|
# AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variable.
|
|
44
|
-
# @option options [String] :endpoint The
|
|
50
|
+
# @option options [String] :endpoint The container credential endpoint.
|
|
45
51
|
# By default, this is the value of the AWS_CONTAINER_CREDENTIALS_FULL_URI
|
|
46
52
|
# environment variable. This value is ignored if `credential_path` or
|
|
47
53
|
# ENV['AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'] is set.
|
|
@@ -64,7 +70,6 @@ module Aws
|
|
|
64
70
|
endpoint = options[:endpoint] ||
|
|
65
71
|
ENV['AWS_CONTAINER_CREDENTIALS_FULL_URI']
|
|
66
72
|
initialize_uri(options, credential_path, endpoint)
|
|
67
|
-
@authorization_token = ENV['AWS_CONTAINER_AUTHORIZATION_TOKEN']
|
|
68
73
|
|
|
69
74
|
@retries = options[:retries] || 5
|
|
70
75
|
@http_open_timeout = options[:http_open_timeout] || 5
|
|
@@ -103,11 +108,18 @@ module Aws
|
|
|
103
108
|
|
|
104
109
|
def initialize_full_uri(endpoint)
|
|
105
110
|
uri = URI.parse(endpoint)
|
|
111
|
+
validate_full_uri_scheme!(uri)
|
|
106
112
|
validate_full_uri!(uri)
|
|
107
|
-
@host = uri.
|
|
113
|
+
@host = uri.hostname
|
|
108
114
|
@port = uri.port
|
|
109
115
|
@scheme = uri.scheme
|
|
110
|
-
@credential_path = uri.
|
|
116
|
+
@credential_path = uri.request_uri
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def validate_full_uri_scheme!(full_uri)
|
|
120
|
+
return if full_uri.is_a?(URI::HTTP) || full_uri.is_a?(URI::HTTPS)
|
|
121
|
+
|
|
122
|
+
raise ArgumentError, "'#{full_uri}' must be a valid HTTP or HTTPS URI"
|
|
111
123
|
end
|
|
112
124
|
|
|
113
125
|
# Validate that the full URI is using a loopback address if scheme is http.
|
|
@@ -115,19 +127,24 @@ module Aws
|
|
|
115
127
|
return unless full_uri.scheme == 'http'
|
|
116
128
|
|
|
117
129
|
begin
|
|
118
|
-
return if
|
|
130
|
+
return if valid_ip_address?(IPAddr.new(full_uri.host))
|
|
119
131
|
rescue IPAddr::InvalidAddressError
|
|
120
132
|
addresses = Resolv.getaddresses(full_uri.host)
|
|
121
|
-
return if addresses.all? { |addr|
|
|
133
|
+
return if addresses.all? { |addr| valid_ip_address?(IPAddr.new(addr)) }
|
|
122
134
|
end
|
|
123
135
|
|
|
124
136
|
raise ArgumentError,
|
|
125
|
-
'AWS_CONTAINER_CREDENTIALS_FULL_URI must use a loopback '\
|
|
126
|
-
'address when using the http scheme.'
|
|
137
|
+
'AWS_CONTAINER_CREDENTIALS_FULL_URI must use a local loopback '\
|
|
138
|
+
'or an ECS or EKS link-local address when using the http scheme.'
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def valid_ip_address?(ip_address)
|
|
142
|
+
ip_loopback?(ip_address) || ecs_or_eks_ip?(ip_address)
|
|
127
143
|
end
|
|
128
144
|
|
|
129
145
|
# loopback? method is available in Ruby 2.5+
|
|
130
146
|
# Replicate the logic here.
|
|
147
|
+
# loopback (IPv4 127.0.0.0/8, IPv6 ::1/128)
|
|
131
148
|
def ip_loopback?(ip_address)
|
|
132
149
|
case ip_address.family
|
|
133
150
|
when Socket::AF_INET
|
|
@@ -139,6 +156,20 @@ module Aws
|
|
|
139
156
|
end
|
|
140
157
|
end
|
|
141
158
|
|
|
159
|
+
# Verify that the IP address is a link-local address from ECS or EKS.
|
|
160
|
+
# ECS container host (IPv4 `169.254.170.2`)
|
|
161
|
+
# EKS container host (IPv4 `169.254.170.23`, IPv6 `fd00:ec2::23`)
|
|
162
|
+
def ecs_or_eks_ip?(ip_address)
|
|
163
|
+
case ip_address.family
|
|
164
|
+
when Socket::AF_INET
|
|
165
|
+
[0xa9feaa02, 0xa9feaa17].include?(ip_address)
|
|
166
|
+
when Socket::AF_INET6
|
|
167
|
+
ip_address == 0xfd00_0ec2_0000_0000_0000_0000_0000_0023
|
|
168
|
+
else
|
|
169
|
+
false
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
142
173
|
def backoff(backoff)
|
|
143
174
|
case backoff
|
|
144
175
|
when Proc then backoff
|
|
@@ -174,10 +205,37 @@ module Aws
|
|
|
174
205
|
http_get(conn, @credential_path)
|
|
175
206
|
end
|
|
176
207
|
end
|
|
177
|
-
rescue
|
|
208
|
+
rescue TokenFileReadError, InvalidTokenError
|
|
209
|
+
raise
|
|
210
|
+
rescue StandardError => e
|
|
211
|
+
warn("Error retrieving ECS Credentials: #{e.message}")
|
|
178
212
|
'{}'
|
|
179
213
|
end
|
|
180
214
|
|
|
215
|
+
def fetch_authorization_token
|
|
216
|
+
if (path = ENV['AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE'])
|
|
217
|
+
fetch_authorization_token_file(path)
|
|
218
|
+
elsif (token = ENV['AWS_CONTAINER_AUTHORIZATION_TOKEN'])
|
|
219
|
+
token
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def fetch_authorization_token_file(path)
|
|
224
|
+
File.read(path).strip
|
|
225
|
+
rescue Errno::ENOENT
|
|
226
|
+
raise TokenFileReadError,
|
|
227
|
+
'AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE is set '\
|
|
228
|
+
"but the file doesn't exist: #{path}"
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def validate_authorization_token!(token)
|
|
232
|
+
return unless token.include?("\r\n")
|
|
233
|
+
|
|
234
|
+
raise InvalidTokenError,
|
|
235
|
+
'Invalid Authorization token: token contains '\
|
|
236
|
+
'a newline and carriage return character.'
|
|
237
|
+
end
|
|
238
|
+
|
|
181
239
|
def open_connection
|
|
182
240
|
http = Net::HTTP.new(@host, @port, nil)
|
|
183
241
|
http.open_timeout = @http_open_timeout
|
|
@@ -190,18 +248,27 @@ module Aws
|
|
|
190
248
|
|
|
191
249
|
def http_get(connection, path)
|
|
192
250
|
request = Net::HTTP::Get.new(path)
|
|
193
|
-
request
|
|
251
|
+
set_authorization_token(request)
|
|
194
252
|
response = connection.request(request)
|
|
195
253
|
raise Non200Response unless response.code.to_i == 200
|
|
196
254
|
|
|
197
255
|
response.body
|
|
198
256
|
end
|
|
199
257
|
|
|
258
|
+
def set_authorization_token(request)
|
|
259
|
+
if (authorization_token = fetch_authorization_token)
|
|
260
|
+
validate_authorization_token!(authorization_token)
|
|
261
|
+
request['Authorization'] = authorization_token
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
200
265
|
def retry_errors(error_classes, options = {})
|
|
201
266
|
max_retries = options[:max_retries]
|
|
202
267
|
retries = 0
|
|
203
268
|
begin
|
|
204
269
|
yield
|
|
270
|
+
rescue TokenFileReadError, InvalidTokenError
|
|
271
|
+
raise
|
|
205
272
|
rescue *error_classes => _e
|
|
206
273
|
raise unless retries < max_retries
|
|
207
274
|
|
|
@@ -28,7 +28,11 @@ module Aws
|
|
|
28
28
|
|
|
29
29
|
val = if (index = parts.first[BRACKET_REGEX, 1])
|
|
30
30
|
# remove brackets and index from part before indexing
|
|
31
|
-
|
|
31
|
+
if (base = parts.first.gsub(BRACKET_REGEX, '')) && !base.empty?
|
|
32
|
+
value[base][index.to_i]
|
|
33
|
+
else
|
|
34
|
+
value[index.to_i]
|
|
35
|
+
end
|
|
32
36
|
else
|
|
33
37
|
value[parts.first]
|
|
34
38
|
end
|
|
@@ -79,11 +83,11 @@ module Aws
|
|
|
79
83
|
return false if value.empty?
|
|
80
84
|
|
|
81
85
|
if allow_sub_domains
|
|
82
|
-
labels = value.split('.')
|
|
86
|
+
labels = value.split('.', -1)
|
|
83
87
|
return labels.all? { |l| valid_host_label?(l) }
|
|
84
88
|
end
|
|
85
89
|
|
|
86
|
-
value =~ /\A(?!-)[a-zA-Z0-9-]{1,63}(?<!-)\z/
|
|
90
|
+
!!(value =~ /\A(?!-)[a-zA-Z0-9-]{1,63}(?<!-)\z/)
|
|
87
91
|
end
|
|
88
92
|
|
|
89
93
|
# AWS
|
|
@@ -114,13 +118,17 @@ module Aws
|
|
|
114
118
|
|
|
115
119
|
# aws.isVirtualHostableS3Bucket(value: string, allowSubDomains: bool) bool
|
|
116
120
|
def self.aws_virtual_hostable_s3_bucket?(value, allow_sub_domains = false)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
return false if value.empty?
|
|
122
|
+
|
|
123
|
+
if allow_sub_domains
|
|
124
|
+
labels = value.split('.', -1)
|
|
125
|
+
return labels.all? { |l| aws_virtual_hostable_s3_bucket?(l) }
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# must be between 3 and 63 characters long, no uppercase
|
|
129
|
+
value =~ /\A(?!-)[a-z0-9-]{3,63}(?<!-)\z/ &&
|
|
130
|
+
# not an IP address
|
|
131
|
+
value !~ /(\d+\.){3}\d+/
|
|
124
132
|
end
|
|
125
133
|
end
|
|
126
134
|
end
|
|
@@ -39,7 +39,11 @@ module Aws
|
|
|
39
39
|
auth_scheme = { 'name' => 'sigv4' }
|
|
40
40
|
merge_signing_defaults(auth_scheme, context.config)
|
|
41
41
|
when 's3', 's3v4'
|
|
42
|
-
auth_scheme = {
|
|
42
|
+
auth_scheme = {
|
|
43
|
+
'name' => 'sigv4',
|
|
44
|
+
'disableDoubleEncoding' => true,
|
|
45
|
+
'disableNormalizePath' => true
|
|
46
|
+
}
|
|
43
47
|
merge_signing_defaults(auth_scheme, context.config)
|
|
44
48
|
when 'bearer'
|
|
45
49
|
{ 'name' => 'bearer' }
|
|
@@ -49,7 +53,7 @@ module Aws
|
|
|
49
53
|
end
|
|
50
54
|
|
|
51
55
|
def merge_signing_defaults(auth_scheme, config)
|
|
52
|
-
if %w[sigv4 sigv4a].include?(auth_scheme['name'])
|
|
56
|
+
if %w[sigv4 sigv4a sigv4-s3express].include?(auth_scheme['name'])
|
|
53
57
|
auth_scheme['signingName'] ||= sigv4_name(config)
|
|
54
58
|
if auth_scheme['name'] == 'sigv4a'
|
|
55
59
|
auth_scheme['signingRegionSet'] ||= ['*']
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Aws
|
|
4
|
+
class ErrorHandler < Seahorse::Client::Handler
|
|
5
|
+
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def error(context)
|
|
9
|
+
body = context.http_response.body_contents
|
|
10
|
+
if body.empty?
|
|
11
|
+
code, message, data = http_status_error(context)
|
|
12
|
+
else
|
|
13
|
+
code, message, data = extract_error(body, context)
|
|
14
|
+
end
|
|
15
|
+
build_error(context, code, message, data)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def build_error(context, code, message, data)
|
|
19
|
+
errors_module = context.client.class.errors_module
|
|
20
|
+
errors_module.error_class(code).new(context, message, data)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def http_status_error(context)
|
|
24
|
+
[http_status_error_code(context), '', EmptyStructure.new]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def http_status_error_code(context)
|
|
28
|
+
status_code = context.http_response.status_code
|
|
29
|
+
{
|
|
30
|
+
302 => 'MovedTemporarily',
|
|
31
|
+
304 => 'NotModified',
|
|
32
|
+
400 => 'BadRequest',
|
|
33
|
+
403 => 'Forbidden',
|
|
34
|
+
404 => 'NotFound',
|
|
35
|
+
412 => 'PreconditionFailed',
|
|
36
|
+
413 => 'RequestEntityTooLarge',
|
|
37
|
+
}[status_code] || "Http#{status_code}Error"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/aws-sdk-core/errors.rb
CHANGED
|
@@ -12,7 +12,7 @@ module Aws
|
|
|
12
12
|
class ServiceError < RuntimeError
|
|
13
13
|
|
|
14
14
|
# @param [Seahorse::Client::RequestContext] context
|
|
15
|
-
# @param [String] message
|
|
15
|
+
# @param [String, nil] message
|
|
16
16
|
# @param [Aws::Structure] data
|
|
17
17
|
def initialize(context, message, data = Aws::EmptyStructure.new)
|
|
18
18
|
@code = self.class.code
|
|
@@ -30,11 +30,11 @@ module Aws
|
|
|
30
30
|
attr_reader :context
|
|
31
31
|
|
|
32
32
|
# @return [Aws::Structure]
|
|
33
|
-
|
|
33
|
+
attr_accessor :data
|
|
34
34
|
|
|
35
35
|
class << self
|
|
36
36
|
|
|
37
|
-
# @return [String]
|
|
37
|
+
# @return [String, nil]
|
|
38
38
|
attr_accessor :code
|
|
39
39
|
|
|
40
40
|
end
|
|
@@ -6,7 +6,6 @@ module Aws
|
|
|
6
6
|
def initialize
|
|
7
7
|
@listeners = {}
|
|
8
8
|
@validate_event = true
|
|
9
|
-
@status = :sleep
|
|
10
9
|
@signal_queue = Queue.new
|
|
11
10
|
end
|
|
12
11
|
|
|
@@ -40,25 +39,10 @@ module Aws
|
|
|
40
39
|
Aws::ParamValidator.validate!(
|
|
41
40
|
@encoder.rules.shape.member(type), params)
|
|
42
41
|
end
|
|
43
|
-
_ready_for_events?
|
|
44
42
|
@stream.data(
|
|
45
43
|
@encoder.encode(type, params),
|
|
46
44
|
end_stream: type == :end_stream
|
|
47
45
|
)
|
|
48
46
|
end
|
|
49
|
-
|
|
50
|
-
private
|
|
51
|
-
|
|
52
|
-
def _ready_for_events?
|
|
53
|
-
return true if @status == :ready
|
|
54
|
-
|
|
55
|
-
# blocked until once initial 200 response is received
|
|
56
|
-
# signal will be available in @signal_queue
|
|
57
|
-
# and this check will no longer be blocked
|
|
58
|
-
@signal_queue.pop
|
|
59
|
-
@status = :ready
|
|
60
|
-
true
|
|
61
|
-
end
|
|
62
|
-
|
|
63
47
|
end
|
|
64
48
|
end
|
|
@@ -8,6 +8,8 @@ module Aws
|
|
|
8
8
|
def ini_parse(raw)
|
|
9
9
|
current_profile = nil
|
|
10
10
|
current_prefix = nil
|
|
11
|
+
item = nil
|
|
12
|
+
previous_item = nil
|
|
11
13
|
raw.lines.inject({}) do |acc, line|
|
|
12
14
|
line = line.split(/^|\s;/).first # remove comments
|
|
13
15
|
profile = line.match(/^\[([^\[\]]+)\]\s*(#.+)?$/) unless line.nil?
|
|
@@ -17,11 +19,16 @@ module Aws
|
|
|
17
19
|
current_profile = named_profile[1] if named_profile
|
|
18
20
|
elsif current_profile
|
|
19
21
|
unless line.nil?
|
|
22
|
+
previous_item = item
|
|
20
23
|
item = line.match(/^(.+?)\s*=\s*(.+?)\s*$/)
|
|
21
24
|
prefix = line.match(/^(.+?)\s*=\s*$/)
|
|
22
25
|
end
|
|
23
26
|
if item && item[1].match(/^\s+/)
|
|
24
27
|
# Need to add lines to a nested configuration.
|
|
28
|
+
if current_prefix.nil? && previous_item[2].strip.empty?
|
|
29
|
+
current_prefix = previous_item[1]
|
|
30
|
+
acc[current_profile][current_prefix] = {}
|
|
31
|
+
end
|
|
25
32
|
inner_item = line.match(/^\s*(.+?)\s*=\s*(.+?)\s*$/)
|
|
26
33
|
acc[current_profile] ||= {}
|
|
27
34
|
acc[current_profile][current_prefix] ||= {}
|
|
@@ -53,6 +53,8 @@ module Aws
|
|
|
53
53
|
# @option options [String] :endpoint_mode ('IPv4') The endpoint mode for
|
|
54
54
|
# the instance metadata service. This is either 'IPv4' ('169.254.169.254')
|
|
55
55
|
# or 'IPv6' ('[fd00:ec2::254]').
|
|
56
|
+
# @option options [Boolean] :disable_imds_v1 (false) Disable the use of the
|
|
57
|
+
# legacy EC2 Metadata Service v1.
|
|
56
58
|
# @option options [String] :ip_address ('169.254.169.254') Deprecated. Use
|
|
57
59
|
# :endpoint instead. The IP address for the endpoint.
|
|
58
60
|
# @option options [Integer] :port (80)
|
|
@@ -77,6 +79,9 @@ module Aws
|
|
|
77
79
|
endpoint_mode = resolve_endpoint_mode(options)
|
|
78
80
|
@endpoint = resolve_endpoint(options, endpoint_mode)
|
|
79
81
|
@port = options[:port] || 80
|
|
82
|
+
@disable_imds_v1 = resolve_disable_v1(options)
|
|
83
|
+
# Flag for if v2 flow fails, skip future attempts
|
|
84
|
+
@imds_v1_fallback = false
|
|
80
85
|
@http_open_timeout = options[:http_open_timeout] || 1
|
|
81
86
|
@http_read_timeout = options[:http_read_timeout] || 1
|
|
82
87
|
@http_debug_output = options[:http_debug_output]
|
|
@@ -123,6 +128,16 @@ module Aws
|
|
|
123
128
|
end
|
|
124
129
|
end
|
|
125
130
|
|
|
131
|
+
def resolve_disable_v1(options)
|
|
132
|
+
value = options[:disable_imds_v1]
|
|
133
|
+
value ||= ENV['AWS_EC2_METADATA_V1_DISABLED']
|
|
134
|
+
value ||= Aws.shared_config.ec2_metadata_v1_disabled(
|
|
135
|
+
profile: options[:profile]
|
|
136
|
+
)
|
|
137
|
+
value = value.to_s.downcase if value
|
|
138
|
+
Aws::Util.str_2_bool(value) || false
|
|
139
|
+
end
|
|
140
|
+
|
|
126
141
|
def backoff(backoff)
|
|
127
142
|
case backoff
|
|
128
143
|
when Proc then backoff
|
|
@@ -141,7 +156,7 @@ module Aws
|
|
|
141
156
|
# service is responding but is returning invalid JSON documents
|
|
142
157
|
# in response to the GET profile credentials call.
|
|
143
158
|
begin
|
|
144
|
-
retry_errors([Aws::Json::ParseError
|
|
159
|
+
retry_errors([Aws::Json::ParseError], max_retries: 3) do
|
|
145
160
|
c = Aws::Json.load(get_credentials.to_s)
|
|
146
161
|
if empty_credentials?(@credentials)
|
|
147
162
|
@credentials = Credentials.new(
|
|
@@ -173,7 +188,6 @@ module Aws
|
|
|
173
188
|
end
|
|
174
189
|
end
|
|
175
190
|
end
|
|
176
|
-
|
|
177
191
|
end
|
|
178
192
|
rescue Aws::Json::ParseError
|
|
179
193
|
raise Aws::Errors::MetadataParserError
|
|
@@ -191,42 +205,53 @@ module Aws
|
|
|
191
205
|
open_connection do |conn|
|
|
192
206
|
# attempt to fetch token to start secure flow first
|
|
193
207
|
# and rescue to failover
|
|
194
|
-
|
|
195
|
-
retry_errors(NETWORK_ERRORS, max_retries: @retries) do
|
|
196
|
-
unless token_set?
|
|
197
|
-
created_time = Time.now
|
|
198
|
-
token_value, ttl = http_put(
|
|
199
|
-
conn, METADATA_TOKEN_PATH, @token_ttl
|
|
200
|
-
)
|
|
201
|
-
@token = Token.new(token_value, ttl, created_time) if token_value && ttl
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
rescue *NETWORK_ERRORS
|
|
205
|
-
# token attempt failed, reset token
|
|
206
|
-
# fallback to non-token mode
|
|
207
|
-
@token = nil
|
|
208
|
-
end
|
|
209
|
-
|
|
208
|
+
fetch_token(conn) unless @imds_v1_fallback
|
|
210
209
|
token = @token.value if token_set?
|
|
211
210
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
# Token has expired, reset it
|
|
218
|
-
# The next retry should fetch it
|
|
219
|
-
@token = nil
|
|
220
|
-
raise Non200Response
|
|
221
|
-
end
|
|
211
|
+
# disable insecure flow if we couldn't get token
|
|
212
|
+
# and imds v1 is disabled
|
|
213
|
+
raise TokenRetrivalError if token.nil? && @disable_imds_v1
|
|
214
|
+
|
|
215
|
+
_get_credentials(conn, token)
|
|
222
216
|
end
|
|
223
217
|
end
|
|
224
|
-
rescue
|
|
218
|
+
rescue => e
|
|
219
|
+
warn("Error retrieving instance profile credentials: #{e}")
|
|
225
220
|
'{}'
|
|
226
221
|
end
|
|
227
222
|
end
|
|
228
223
|
end
|
|
229
224
|
|
|
225
|
+
def fetch_token(conn)
|
|
226
|
+
retry_errors(NETWORK_ERRORS, max_retries: @retries) do
|
|
227
|
+
unless token_set?
|
|
228
|
+
created_time = Time.now
|
|
229
|
+
token_value, ttl = http_put(
|
|
230
|
+
conn, METADATA_TOKEN_PATH, @token_ttl
|
|
231
|
+
)
|
|
232
|
+
@token = Token.new(token_value, ttl, created_time) if token_value && ttl
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
rescue *NETWORK_ERRORS
|
|
236
|
+
# token attempt failed, reset token
|
|
237
|
+
# fallback to non-token mode
|
|
238
|
+
@token = nil
|
|
239
|
+
@imds_v1_fallback = true
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# token is optional - if nil, uses v1 (insecure) flow
|
|
243
|
+
def _get_credentials(conn, token)
|
|
244
|
+
metadata = http_get(conn, METADATA_PATH_BASE, token)
|
|
245
|
+
profile_name = metadata.lines.first.strip
|
|
246
|
+
http_get(conn, METADATA_PATH_BASE + profile_name, token)
|
|
247
|
+
rescue TokenExpiredError
|
|
248
|
+
# Token has expired, reset it
|
|
249
|
+
# The next retry should fetch it
|
|
250
|
+
@token = nil
|
|
251
|
+
@imds_v1_fallback = false
|
|
252
|
+
raise Non200Response
|
|
253
|
+
end
|
|
254
|
+
|
|
230
255
|
def token_set?
|
|
231
256
|
@token && !@token.expired?
|
|
232
257
|
end
|
|
@@ -237,7 +262,7 @@ module Aws
|
|
|
237
262
|
|
|
238
263
|
def open_connection
|
|
239
264
|
uri = URI.parse(@endpoint)
|
|
240
|
-
http = Net::HTTP.new(uri.hostname || @endpoint,
|
|
265
|
+
http = Net::HTTP.new(uri.hostname || @endpoint, uri.port || @port)
|
|
241
266
|
http.open_timeout = @http_open_timeout
|
|
242
267
|
http.read_timeout = @http_read_timeout
|
|
243
268
|
http.set_debug_output(@http_debug_output) if @http_debug_output
|
|
@@ -276,8 +301,6 @@ module Aws
|
|
|
276
301
|
]
|
|
277
302
|
when 400
|
|
278
303
|
raise TokenRetrivalError
|
|
279
|
-
when 401
|
|
280
|
-
raise TokenExpiredError
|
|
281
304
|
else
|
|
282
305
|
raise Non200Response
|
|
283
306
|
end
|
|
@@ -8,7 +8,7 @@ module Aws
|
|
|
8
8
|
|
|
9
9
|
include Seahorse::Model::Shapes
|
|
10
10
|
|
|
11
|
-
def initialize(rules)
|
|
11
|
+
def initialize(rules, _options = {})
|
|
12
12
|
@rules = rules
|
|
13
13
|
end
|
|
14
14
|
|
|
@@ -20,6 +20,8 @@ module Aws
|
|
|
20
20
|
private
|
|
21
21
|
|
|
22
22
|
def structure(ref, values)
|
|
23
|
+
return nil if values.nil?
|
|
24
|
+
|
|
23
25
|
shape = ref.shape
|
|
24
26
|
values.each_pair.with_object({}) do |(key, value), data|
|
|
25
27
|
if shape.member?(key) && !value.nil?
|
|
@@ -31,11 +33,15 @@ module Aws
|
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
def list(ref, values)
|
|
36
|
+
return nil if values.nil?
|
|
37
|
+
|
|
34
38
|
member_ref = ref.shape.member
|
|
35
39
|
values.collect { |value| format(member_ref, value) }
|
|
36
40
|
end
|
|
37
41
|
|
|
38
42
|
def map(ref, values)
|
|
43
|
+
return nil if values.nil?
|
|
44
|
+
|
|
39
45
|
value_ref = ref.shape.value
|
|
40
46
|
values.each.with_object({}) do |(key, value), data|
|
|
41
47
|
data[key] = format(value_ref, value)
|
|
@@ -49,6 +55,7 @@ module Aws
|
|
|
49
55
|
when MapShape then map(ref, value)
|
|
50
56
|
when TimestampShape then timestamp(ref, value)
|
|
51
57
|
when BlobShape then encode(value)
|
|
58
|
+
when FloatShape then Util.serialize_number(value)
|
|
52
59
|
else value
|
|
53
60
|
end
|
|
54
61
|
end
|
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module Aws
|
|
4
4
|
module Json
|
|
5
|
-
class ErrorHandler <
|
|
5
|
+
class ErrorHandler < Aws::ErrorHandler
|
|
6
6
|
|
|
7
|
-
# @param [Seahorse::Client::RequestContext] context
|
|
8
|
-
# @return [Seahorse::Client::Response]
|
|
9
7
|
def call(context)
|
|
10
8
|
@handler.call(context).on(300..599) do |response|
|
|
11
9
|
response.error = error(context)
|
|
@@ -19,7 +17,7 @@ module Aws
|
|
|
19
17
|
json = Json.load(body)
|
|
20
18
|
code = error_code(json, context)
|
|
21
19
|
message = error_message(code, json)
|
|
22
|
-
data = parse_error_data(context, code)
|
|
20
|
+
data = parse_error_data(context, body, code)
|
|
23
21
|
[code, message, data]
|
|
24
22
|
rescue Json::ParseError
|
|
25
23
|
[http_status_error_code(context), '', EmptyStructure.new]
|
|
@@ -48,7 +46,7 @@ module Aws
|
|
|
48
46
|
end
|
|
49
47
|
|
|
50
48
|
def remove_prefix(error_code, context)
|
|
51
|
-
if prefix = context.config.api.metadata['errorPrefix']
|
|
49
|
+
if (prefix = context.config.api.metadata['errorPrefix'])
|
|
52
50
|
error_code.sub(/^#{prefix}/, '')
|
|
53
51
|
else
|
|
54
52
|
error_code
|
|
@@ -63,22 +61,29 @@ module Aws
|
|
|
63
61
|
end
|
|
64
62
|
end
|
|
65
63
|
|
|
66
|
-
def parse_error_data(context, code)
|
|
64
|
+
def parse_error_data(context, body, code)
|
|
67
65
|
data = EmptyStructure.new
|
|
68
|
-
if error_rules = context.operation.errors
|
|
66
|
+
if (error_rules = context.operation.errors)
|
|
69
67
|
error_rules.each do |rule|
|
|
70
68
|
# match modeled shape name with the type(code) only
|
|
71
69
|
# some type(code) might contains invalid characters
|
|
72
70
|
# such as ':' (efs) etc
|
|
73
71
|
match = rule.shape.name == code.gsub(/[^^a-zA-Z0-9]/, '')
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
next unless match && rule.shape.members.any?
|
|
73
|
+
|
|
74
|
+
data = Parser.new(rule).parse(body)
|
|
75
|
+
# errors support HTTP bindings
|
|
76
|
+
apply_error_headers(rule, context, data)
|
|
77
77
|
end
|
|
78
78
|
end
|
|
79
79
|
data
|
|
80
80
|
end
|
|
81
81
|
|
|
82
|
+
def apply_error_headers(rule, context, data)
|
|
83
|
+
headers = Aws::Rest::Response::Headers.new(rule)
|
|
84
|
+
headers.apply(context.http_response, data)
|
|
85
|
+
end
|
|
86
|
+
|
|
82
87
|
end
|
|
83
88
|
end
|
|
84
89
|
end
|