aws-sdk-core 3.226.1 → 3.246.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 +184 -0
- data/VERSION +1 -1
- data/lib/aws-sdk-core/assume_role_credentials.rb +8 -8
- data/lib/aws-sdk-core/assume_role_web_identity_credentials.rb +2 -2
- data/lib/aws-sdk-core/client_stubs.rb +6 -0
- data/lib/aws-sdk-core/credential_provider_chain.rb +72 -23
- data/lib/aws-sdk-core/ecs_credentials.rb +25 -15
- data/lib/aws-sdk-core/endpoints.rb +37 -13
- data/lib/aws-sdk-core/error_handler.rb +5 -0
- data/lib/aws-sdk-core/errors.rb +3 -0
- data/lib/aws-sdk-core/instance_profile_credentials.rb +160 -161
- data/lib/aws-sdk-core/json/error_handler.rb +14 -4
- data/lib/aws-sdk-core/login_credentials.rb +230 -0
- data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +147 -76
- data/lib/aws-sdk-core/plugins/credentials_configuration.rb +75 -59
- data/lib/aws-sdk-core/plugins/retries/clock_skew.rb +28 -16
- data/lib/aws-sdk-core/plugins/sign.rb +23 -28
- data/lib/aws-sdk-core/plugins/stub_responses.rb +6 -0
- data/lib/aws-sdk-core/plugins/user_agent.rb +6 -1
- data/lib/aws-sdk-core/refreshing_credentials.rb +8 -11
- data/lib/aws-sdk-core/rpc_v2/error_handler.rb +26 -16
- data/lib/aws-sdk-core/shared_config.rb +30 -0
- data/lib/aws-sdk-core/sso_credentials.rb +1 -1
- data/lib/aws-sdk-core/sso_token_provider.rb +1 -0
- data/lib/aws-sdk-core/static_token_provider.rb +1 -2
- data/lib/aws-sdk-core/token.rb +3 -3
- data/lib/aws-sdk-core/token_provider.rb +4 -0
- data/lib/aws-sdk-core/token_provider_chain.rb +2 -6
- data/lib/aws-sdk-core/waiters/poller.rb +2 -2
- data/lib/aws-sdk-core/xml/error_handler.rb +1 -0
- data/lib/aws-sdk-core.rb +4 -0
- data/lib/aws-sdk-signin/client.rb +604 -0
- data/lib/aws-sdk-signin/client_api.rb +119 -0
- data/lib/aws-sdk-signin/customizations.rb +1 -0
- data/lib/aws-sdk-signin/endpoint_parameters.rb +69 -0
- data/lib/aws-sdk-signin/endpoint_provider.rb +59 -0
- data/lib/aws-sdk-signin/endpoints.rb +20 -0
- data/lib/aws-sdk-signin/errors.rb +122 -0
- data/lib/aws-sdk-signin/plugins/endpoints.rb +77 -0
- data/lib/aws-sdk-signin/resource.rb +26 -0
- data/lib/aws-sdk-signin/types.rb +299 -0
- data/lib/aws-sdk-signin.rb +63 -0
- data/lib/aws-sdk-sso/client.rb +24 -17
- data/lib/aws-sdk-sso/endpoint_parameters.rb +4 -4
- data/lib/aws-sdk-sso/endpoint_provider.rb +2 -2
- data/lib/aws-sdk-sso.rb +1 -1
- data/lib/aws-sdk-ssooidc/client.rb +43 -23
- data/lib/aws-sdk-ssooidc/client_api.rb +5 -0
- data/lib/aws-sdk-ssooidc/endpoint_parameters.rb +4 -4
- data/lib/aws-sdk-ssooidc/errors.rb +10 -0
- data/lib/aws-sdk-ssooidc/types.rb +27 -15
- data/lib/aws-sdk-ssooidc.rb +1 -1
- data/lib/aws-sdk-sts/client.rb +159 -28
- data/lib/aws-sdk-sts/client_api.rb +73 -1
- data/lib/aws-sdk-sts/customizations.rb +0 -1
- data/lib/aws-sdk-sts/endpoint_parameters.rb +5 -5
- data/lib/aws-sdk-sts/errors.rb +64 -1
- data/lib/aws-sdk-sts/presigner.rb +2 -6
- data/lib/aws-sdk-sts/types.rb +175 -6
- data/lib/aws-sdk-sts.rb +1 -1
- data/lib/seahorse/client/h2/handler.rb +6 -1
- data/lib/seahorse/client/net_http/patches.rb +44 -11
- data/lib/seahorse/client/request_context.rb +2 -2
- metadata +27 -1
|
@@ -4,17 +4,39 @@ require 'time'
|
|
|
4
4
|
require 'net/http'
|
|
5
5
|
|
|
6
6
|
module Aws
|
|
7
|
-
# An auto-refreshing credential provider that loads credentials from
|
|
8
|
-
# EC2 instances.
|
|
7
|
+
# An auto-refreshing credential provider that loads credentials from EC2 instances.
|
|
9
8
|
#
|
|
10
9
|
# instance_credentials = Aws::InstanceProfileCredentials.new
|
|
11
10
|
# ec2 = Aws::EC2::Client.new(credentials: instance_credentials)
|
|
11
|
+
#
|
|
12
|
+
# ## Retries
|
|
13
|
+
# When initialized from the default credential chain, this provider defaults to `0` retries.
|
|
14
|
+
# Breakdown of retries is as follows:
|
|
15
|
+
#
|
|
16
|
+
# * **Configurable retries** (defaults to `1`): these retries handle errors when communicating
|
|
17
|
+
# with the IMDS endpoint. There are two separate retry mechanisms within the provider:
|
|
18
|
+
# * Entire token fetch and credential retrieval process
|
|
19
|
+
# * Token fetching
|
|
20
|
+
# * **JSON parsing retries**: Fixed at 3 attempts to handle cases when IMDS returns malformed JSON
|
|
21
|
+
# responses. These retries are separate from configurable retries.
|
|
22
|
+
#
|
|
23
|
+
# @see https://docs.aws.amazon.com/sdkref/latest/guide/feature-imds-credentials.html IMDS Credential Provider
|
|
12
24
|
class InstanceProfileCredentials
|
|
13
25
|
include CredentialProvider
|
|
14
26
|
include RefreshingCredentials
|
|
15
27
|
|
|
16
28
|
# @api private
|
|
17
|
-
class Non200Response < RuntimeError
|
|
29
|
+
class Non200Response < RuntimeError
|
|
30
|
+
attr_reader :status_code, :body
|
|
31
|
+
|
|
32
|
+
def initialize(status_code, body = nil)
|
|
33
|
+
@status_code = status_code
|
|
34
|
+
@body = body
|
|
35
|
+
msg = "HTTP #{status_code}"
|
|
36
|
+
msg += ": #{body}" if body && !body.empty?
|
|
37
|
+
super(msg)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
18
40
|
|
|
19
41
|
# @api private
|
|
20
42
|
class TokenRetrivalError < RuntimeError; end
|
|
@@ -22,10 +44,8 @@ module Aws
|
|
|
22
44
|
# @api private
|
|
23
45
|
class TokenExpiredError < RuntimeError; end
|
|
24
46
|
|
|
25
|
-
# These are the errors we trap when attempting to talk to the
|
|
26
|
-
#
|
|
27
|
-
# is not present, no responding or some other non-recoverable
|
|
28
|
-
# error.
|
|
47
|
+
# These are the errors we trap when attempting to talk to the instance metadata service.
|
|
48
|
+
# Any of these imply the service is not present, no responding or some other non-recoverable error.
|
|
29
49
|
# @api private
|
|
30
50
|
NETWORK_ERRORS = [
|
|
31
51
|
Errno::EHOSTUNREACH,
|
|
@@ -46,100 +66,113 @@ module Aws
|
|
|
46
66
|
METADATA_TOKEN_PATH = '/latest/api/token'.freeze
|
|
47
67
|
|
|
48
68
|
# @param [Hash] options
|
|
49
|
-
# @option options [Integer] :retries (1) Number of times to retry
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
# @option options [String] :
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
# @option options [String] :ip_address ('169.254.169.254') Deprecated. Use
|
|
59
|
-
#
|
|
69
|
+
# @option options [Integer] :retries (1) Number of times to retry when retrieving credentials.
|
|
70
|
+
# @option options [Numeric, Proc] :backoff By default, failures are retried with exponential back-off, i.e.
|
|
71
|
+
# `lambda { |num_failures| sleep(1.2 ** num_failures) }`. You can pass a number of seconds to sleep
|
|
72
|
+
# between failed attempts, or a Proc that accepts the number of failures.
|
|
73
|
+
# @option options [String] :endpoint ('http://169.254.169.254') The IMDS endpoint. This option has precedence
|
|
74
|
+
# over the `:endpoint_mode`.
|
|
75
|
+
# @option options [String] :endpoint_mode ('IPv4') The endpoint mode for the instance metadata service. This is
|
|
76
|
+
# either 'IPv4' (`169.254.169.254`) or IPv6' (`[fd00:ec2::254]`).
|
|
77
|
+
# @option options [Boolean] :disable_imds_v1 (false) Disable the use of the legacy EC2 Metadata Service v1.
|
|
78
|
+
# @option options [String] :ip_address ('169.254.169.254') Deprecated. Use `:endpoint` instead.
|
|
79
|
+
# The IP address for the endpoint.
|
|
60
80
|
# @option options [Integer] :port (80)
|
|
61
81
|
# @option options [Float] :http_open_timeout (1)
|
|
62
82
|
# @option options [Float] :http_read_timeout (1)
|
|
63
|
-
# @option options [
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
# @option options [
|
|
68
|
-
#
|
|
69
|
-
# like $stdout.
|
|
70
|
-
# @option options [Integer] :token_ttl Time-to-Live in seconds for EC2
|
|
71
|
-
# Metadata Token used for fetching Metadata Profile Credentials, defaults
|
|
72
|
-
# to 21600 seconds
|
|
73
|
-
# @option options [Callable] before_refresh Proc called before
|
|
74
|
-
# credentials are refreshed. `before_refresh` is called
|
|
75
|
-
# with an instance of this object when
|
|
76
|
-
# AWS credentials are required and need to be refreshed.
|
|
83
|
+
# @option options [IO] :http_debug_output (nil) HTTP wire traces are sent to this object.
|
|
84
|
+
# You can specify something like `$stdout`.
|
|
85
|
+
# @option options [Integer] :token_ttl (21600) Time-to-Live in seconds for EC2 Metadata Token used for fetching
|
|
86
|
+
# Metadata Profile Credentials.
|
|
87
|
+
# @option options [Proc] :before_refresh A Proc called before credentials are refreshed. `:before_refresh`
|
|
88
|
+
# is called with an instance of this object when AWS credentials are required and need to be refreshed.
|
|
77
89
|
def initialize(options = {})
|
|
78
|
-
@
|
|
79
|
-
endpoint_mode = resolve_endpoint_mode(options)
|
|
80
|
-
@endpoint = resolve_endpoint(options, endpoint_mode)
|
|
81
|
-
@port = options[:port] || 80
|
|
90
|
+
@backoff = resolve_backoff(options[:backoff])
|
|
82
91
|
@disable_imds_v1 = resolve_disable_v1(options)
|
|
83
|
-
|
|
84
|
-
@imds_v1_fallback = false
|
|
92
|
+
@endpoint = resolve_endpoint(options)
|
|
85
93
|
@http_open_timeout = options[:http_open_timeout] || 1
|
|
86
94
|
@http_read_timeout = options[:http_read_timeout] || 1
|
|
87
95
|
@http_debug_output = options[:http_debug_output]
|
|
88
|
-
@
|
|
96
|
+
@port = options[:port] || 80
|
|
97
|
+
@retries = options[:retries] || 1
|
|
89
98
|
@token_ttl = options[:token_ttl] || 21_600
|
|
90
|
-
|
|
91
|
-
@no_refresh_until = nil
|
|
99
|
+
|
|
92
100
|
@async_refresh = false
|
|
101
|
+
@imds_v1_fallback = false
|
|
102
|
+
@no_refresh_until = nil
|
|
103
|
+
@token = nil
|
|
93
104
|
@metrics = ['CREDENTIALS_IMDS']
|
|
94
105
|
super
|
|
95
106
|
end
|
|
96
107
|
|
|
97
|
-
# @return [
|
|
98
|
-
|
|
99
|
-
|
|
108
|
+
# @return [Boolean]
|
|
109
|
+
attr_reader :disable_imds_v1
|
|
110
|
+
|
|
111
|
+
# @return [Integer]
|
|
112
|
+
attr_reader :token_ttl
|
|
113
|
+
|
|
114
|
+
# @return [Integer]
|
|
100
115
|
attr_reader :retries
|
|
101
116
|
|
|
117
|
+
# @return [Proc]
|
|
118
|
+
attr_reader :backoff
|
|
119
|
+
|
|
120
|
+
# @return [String]
|
|
121
|
+
attr_reader :endpoint
|
|
122
|
+
|
|
123
|
+
# @return [Integer]
|
|
124
|
+
attr_reader :port
|
|
125
|
+
|
|
126
|
+
# @return [Integer]
|
|
127
|
+
attr_reader :http_open_timeout
|
|
128
|
+
|
|
129
|
+
# @return [Integer]
|
|
130
|
+
attr_reader :http_read_timeout
|
|
131
|
+
|
|
132
|
+
# @return [IO, nil]
|
|
133
|
+
attr_reader :http_debug_output
|
|
134
|
+
|
|
102
135
|
private
|
|
103
136
|
|
|
104
137
|
def resolve_endpoint_mode(options)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
)
|
|
110
|
-
value || 'IPv4'
|
|
138
|
+
options[:endpoint_mode] ||
|
|
139
|
+
ENV['AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE'] ||
|
|
140
|
+
Aws.shared_config.ec2_metadata_service_endpoint_mode(profile: options[:profile]) ||
|
|
141
|
+
'IPv4'
|
|
111
142
|
end
|
|
112
143
|
|
|
113
|
-
def resolve_endpoint(options
|
|
114
|
-
value = options[:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
)
|
|
144
|
+
def resolve_endpoint(options)
|
|
145
|
+
if (value = options[:ip_address])
|
|
146
|
+
warn('The `:ip_address` option is deprecated. Use `:endpoint` instead.')
|
|
147
|
+
return value
|
|
148
|
+
end
|
|
119
149
|
|
|
150
|
+
value =
|
|
151
|
+
options[:endpoint] ||
|
|
152
|
+
ENV['AWS_EC2_METADATA_SERVICE_ENDPOINT'] ||
|
|
153
|
+
Aws.shared_config.ec2_metadata_service_endpoint(profile: options[:profile]) ||
|
|
154
|
+
nil
|
|
120
155
|
return value if value
|
|
121
156
|
|
|
157
|
+
endpoint_mode = resolve_endpoint_mode(options)
|
|
122
158
|
case endpoint_mode.downcase
|
|
123
159
|
when 'ipv4' then 'http://169.254.169.254'
|
|
124
160
|
when 'ipv6' then 'http://[fd00:ec2::254]'
|
|
125
161
|
else
|
|
126
|
-
raise ArgumentError,
|
|
127
|
-
':endpoint_mode is not valid, expected IPv4 or IPv6, '\
|
|
128
|
-
"got: #{endpoint_mode}"
|
|
162
|
+
raise ArgumentError, ":endpoint_mode is not valid, expected IPv4 or IPv6, got: #{endpoint_mode}"
|
|
129
163
|
end
|
|
130
164
|
end
|
|
131
165
|
|
|
132
166
|
def resolve_disable_v1(options)
|
|
133
|
-
value =
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
profile: options[:profile]
|
|
137
|
-
|
|
138
|
-
value
|
|
139
|
-
Aws::Util.str_2_bool(value) || false
|
|
167
|
+
value =
|
|
168
|
+
options[:disable_imds_v1] ||
|
|
169
|
+
ENV['AWS_EC2_METADATA_V1_DISABLED'] ||
|
|
170
|
+
Aws.shared_config.ec2_metadata_v1_disabled(profile: options[:profile]) ||
|
|
171
|
+
'false'
|
|
172
|
+
Aws::Util.str_2_bool(value.to_s.downcase)
|
|
140
173
|
end
|
|
141
174
|
|
|
142
|
-
def
|
|
175
|
+
def resolve_backoff(backoff)
|
|
143
176
|
case backoff
|
|
144
177
|
when Proc then backoff
|
|
145
178
|
when Numeric then ->(_) { sleep(backoff) }
|
|
@@ -153,114 +186,86 @@ module Aws
|
|
|
153
186
|
return
|
|
154
187
|
end
|
|
155
188
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
@credentials = Credentials.new(
|
|
164
|
-
c['AccessKeyId'],
|
|
165
|
-
c['SecretAccessKey'],
|
|
166
|
-
c['Token']
|
|
167
|
-
)
|
|
168
|
-
@expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
|
|
169
|
-
if @expiration && @expiration < Time.now
|
|
170
|
-
@no_refresh_until = Time.now + refresh_offset
|
|
171
|
-
warn_expired_credentials
|
|
172
|
-
end
|
|
173
|
-
else
|
|
174
|
-
# credentials are already set, update them only if the new ones are not empty
|
|
175
|
-
if !c['AccessKeyId'] || c['AccessKeyId'].empty?
|
|
176
|
-
# error getting new credentials
|
|
177
|
-
@no_refresh_until = Time.now + refresh_offset
|
|
178
|
-
warn_expired_credentials
|
|
179
|
-
else
|
|
180
|
-
@credentials = Credentials.new(
|
|
181
|
-
c['AccessKeyId'],
|
|
182
|
-
c['SecretAccessKey'],
|
|
183
|
-
c['Token']
|
|
184
|
-
)
|
|
185
|
-
@expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
|
|
186
|
-
if @expiration && @expiration < Time.now
|
|
187
|
-
@no_refresh_until = Time.now + refresh_offset
|
|
188
|
-
warn_expired_credentials
|
|
189
|
-
end
|
|
190
|
-
end
|
|
189
|
+
new_creds =
|
|
190
|
+
begin
|
|
191
|
+
# Retry loading credentials up to 3 times is the instance metadata
|
|
192
|
+
# service is responding but is returning invalid JSON documents
|
|
193
|
+
# in response to the GET profile credentials call.
|
|
194
|
+
retry_errors([Aws::Json::ParseError], max_retries: 3) do
|
|
195
|
+
Aws::Json.load(retrieve_credentials.to_s)
|
|
191
196
|
end
|
|
197
|
+
rescue Aws::Json::ParseError
|
|
198
|
+
raise Aws::Errors::MetadataParserError
|
|
192
199
|
end
|
|
193
|
-
|
|
194
|
-
|
|
200
|
+
|
|
201
|
+
if @credentials&.set? && empty_credentials?(new_creds)
|
|
202
|
+
# credentials are already set, but there was an error getting new credentials
|
|
203
|
+
# so don't update the credentials and use stale ones (static stability)
|
|
204
|
+
@no_refresh_until = Time.now + rand(300..360)
|
|
205
|
+
warn_expired_credentials
|
|
206
|
+
else
|
|
207
|
+
# credentials are empty or successfully retrieved, update them
|
|
208
|
+
update_credentials(new_creds)
|
|
195
209
|
end
|
|
196
210
|
end
|
|
197
211
|
|
|
198
|
-
def
|
|
212
|
+
def retrieve_credentials
|
|
199
213
|
# Retry loading credentials a configurable number of times if
|
|
200
214
|
# the instance metadata service is not responding.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
# disable insecure flow if we couldn't get token
|
|
213
|
-
# and imds v1 is disabled
|
|
214
|
-
raise TokenRetrivalError if token.nil? && @disable_imds_v1
|
|
215
|
-
|
|
216
|
-
_get_credentials(conn, token)
|
|
217
|
-
end
|
|
215
|
+
begin
|
|
216
|
+
retry_errors(NETWORK_ERRORS, max_retries: @retries) do
|
|
217
|
+
open_connection do |conn|
|
|
218
|
+
# attempt to fetch token to start secure flow first
|
|
219
|
+
# and rescue to failover
|
|
220
|
+
fetch_token(conn) unless @imds_v1_fallback || (@token && !@token.expired?)
|
|
221
|
+
|
|
222
|
+
# disable insecure flow if we couldn't get token and imds v1 is disabled
|
|
223
|
+
raise TokenRetrivalError if @token.nil? && @disable_imds_v1
|
|
224
|
+
|
|
225
|
+
fetch_credentials(conn)
|
|
218
226
|
end
|
|
219
|
-
rescue => e
|
|
220
|
-
warn("Error retrieving instance profile credentials: #{e}")
|
|
221
|
-
'{}'
|
|
222
227
|
end
|
|
228
|
+
rescue StandardError => e
|
|
229
|
+
warn("Error retrieving instance profile credentials: #{e}")
|
|
230
|
+
'{}'
|
|
223
231
|
end
|
|
224
232
|
end
|
|
225
233
|
|
|
234
|
+
def update_credentials(creds)
|
|
235
|
+
@credentials = Credentials.new(creds['AccessKeyId'], creds['SecretAccessKey'], creds['Token'])
|
|
236
|
+
@expiration = creds['Expiration'] ? Time.iso8601(creds['Expiration']) : nil
|
|
237
|
+
return unless @expiration && @expiration < Time.now
|
|
238
|
+
|
|
239
|
+
@no_refresh_until = Time.now + rand(300..360)
|
|
240
|
+
warn_expired_credentials
|
|
241
|
+
end
|
|
242
|
+
|
|
226
243
|
def fetch_token(conn)
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
token_value, ttl = http_put(
|
|
231
|
-
conn, METADATA_TOKEN_PATH, @token_ttl
|
|
232
|
-
)
|
|
233
|
-
@token = Token.new(token_value, ttl, created_time) if token_value && ttl
|
|
234
|
-
end
|
|
235
|
-
end
|
|
244
|
+
created_time = Time.now
|
|
245
|
+
token_value, ttl = http_put(conn)
|
|
246
|
+
@token = Token.new(token_value, ttl, created_time) if token_value && ttl
|
|
236
247
|
rescue *NETWORK_ERRORS
|
|
237
248
|
# token attempt failed, reset token
|
|
238
249
|
# fallback to non-token mode
|
|
239
|
-
@token = nil
|
|
240
250
|
@imds_v1_fallback = true
|
|
241
251
|
end
|
|
242
252
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
metadata = http_get(conn, METADATA_PATH_BASE, token)
|
|
253
|
+
def fetch_credentials(conn)
|
|
254
|
+
metadata = http_get(conn, METADATA_PATH_BASE)
|
|
246
255
|
profile_name = metadata.lines.first.strip
|
|
247
|
-
http_get(conn, METADATA_PATH_BASE + profile_name
|
|
256
|
+
http_get(conn, METADATA_PATH_BASE + profile_name)
|
|
248
257
|
rescue TokenExpiredError
|
|
249
258
|
# Token has expired, reset it
|
|
250
259
|
# The next retry should fetch it
|
|
251
260
|
@token = nil
|
|
252
261
|
@imds_v1_fallback = false
|
|
253
|
-
raise Non200Response
|
|
262
|
+
raise Non200Response.new(401, 'Token expired')
|
|
254
263
|
end
|
|
255
264
|
|
|
256
265
|
def token_set?
|
|
257
266
|
@token && !@token.expired?
|
|
258
267
|
end
|
|
259
268
|
|
|
260
|
-
def _metadata_disabled?
|
|
261
|
-
ENV.fetch('AWS_EC2_METADATA_DISABLED', 'false').downcase == 'true'
|
|
262
|
-
end
|
|
263
|
-
|
|
264
269
|
def open_connection
|
|
265
270
|
uri = URI.parse(@endpoint)
|
|
266
271
|
http = Net::HTTP.new(uri.hostname || @endpoint, uri.port || @port)
|
|
@@ -272,9 +277,9 @@ module Aws
|
|
|
272
277
|
end
|
|
273
278
|
|
|
274
279
|
# GET request fetch profile and credentials
|
|
275
|
-
def http_get(connection, path
|
|
280
|
+
def http_get(connection, path)
|
|
276
281
|
headers = { 'User-Agent' => "aws-sdk-ruby3/#{CORE_GEM_VERSION}" }
|
|
277
|
-
headers['x-aws-ec2-metadata-token'] = token if token
|
|
282
|
+
headers['x-aws-ec2-metadata-token'] = @token.value if @token
|
|
278
283
|
response = connection.request(Net::HTTP::Get.new(path, headers))
|
|
279
284
|
|
|
280
285
|
case response.code.to_i
|
|
@@ -283,17 +288,17 @@ module Aws
|
|
|
283
288
|
when 401
|
|
284
289
|
raise TokenExpiredError
|
|
285
290
|
else
|
|
286
|
-
raise Non200Response
|
|
291
|
+
raise Non200Response.new(response.code.to_i, response.body)
|
|
287
292
|
end
|
|
288
293
|
end
|
|
289
294
|
|
|
290
295
|
# PUT request fetch token with ttl
|
|
291
|
-
def http_put(connection
|
|
296
|
+
def http_put(connection)
|
|
292
297
|
headers = {
|
|
293
298
|
'User-Agent' => "aws-sdk-ruby3/#{CORE_GEM_VERSION}",
|
|
294
|
-
'x-aws-ec2-metadata-token-ttl-seconds' =>
|
|
299
|
+
'x-aws-ec2-metadata-token-ttl-seconds' => @token_ttl.to_s
|
|
295
300
|
}
|
|
296
|
-
response = connection.request(Net::HTTP::Put.new(
|
|
301
|
+
response = connection.request(Net::HTTP::Put.new(METADATA_TOKEN_PATH, headers))
|
|
297
302
|
case response.code.to_i
|
|
298
303
|
when 200
|
|
299
304
|
[
|
|
@@ -303,7 +308,7 @@ module Aws
|
|
|
303
308
|
when 400
|
|
304
309
|
raise TokenRetrivalError
|
|
305
310
|
else
|
|
306
|
-
raise Non200Response
|
|
311
|
+
raise Non200Response.new(response.code.to_i, response.body)
|
|
307
312
|
end
|
|
308
313
|
end
|
|
309
314
|
|
|
@@ -322,18 +327,12 @@ module Aws
|
|
|
322
327
|
end
|
|
323
328
|
|
|
324
329
|
def warn_expired_credentials
|
|
325
|
-
warn(
|
|
326
|
-
|
|
327
|
-
"will be attempted again in 5 minutes.")
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
def empty_credentials?(creds)
|
|
331
|
-
!creds || !creds.access_key_id || creds.access_key_id.empty?
|
|
330
|
+
warn('Attempting credential expiration extension due to a credential service availability issue. '\
|
|
331
|
+
'A refresh of these credentials will be attempted again in 5 minutes.')
|
|
332
332
|
end
|
|
333
333
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
300 + rand(0..60)
|
|
334
|
+
def empty_credentials?(creds_hash)
|
|
335
|
+
!creds_hash['AccessKeyId'] || creds_hash['AccessKeyId'].empty?
|
|
337
336
|
end
|
|
338
337
|
|
|
339
338
|
# @api private
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Aws
|
|
4
4
|
module Json
|
|
5
|
+
# @api private
|
|
5
6
|
class ErrorHandler < Aws::ErrorHandler
|
|
6
7
|
|
|
7
8
|
def call(context)
|
|
@@ -24,18 +25,21 @@ module Aws
|
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
def error_code(json, context)
|
|
28
|
+
# This is not correct per protocol tests. awsQueryError is intended to populate the
|
|
29
|
+
# error code of the error class. The error class should come from __type. Query and
|
|
30
|
+
# query compatible services currently have dynamic errors raised from error codes instead
|
|
31
|
+
# of the modeled error class. However, changing this in this major version would break
|
|
32
|
+
# existing usage.
|
|
27
33
|
code =
|
|
28
34
|
if aws_query_error?(context)
|
|
29
|
-
|
|
30
|
-
error, _type = query_header.split(';') # type not supported
|
|
31
|
-
remove_prefix(error, context)
|
|
35
|
+
aws_query_error_code(context)
|
|
32
36
|
else
|
|
33
37
|
json['__type']
|
|
34
38
|
end
|
|
35
39
|
code ||= json['code']
|
|
36
40
|
code ||= context.http_response.headers['x-amzn-errortype']
|
|
37
41
|
if code
|
|
38
|
-
code.split('#').last
|
|
42
|
+
code.split('#').last.split(':').first
|
|
39
43
|
else
|
|
40
44
|
http_status_error_code(context)
|
|
41
45
|
end
|
|
@@ -46,6 +50,12 @@ module Aws
|
|
|
46
50
|
context.http_response.headers['x-amzn-query-error']
|
|
47
51
|
end
|
|
48
52
|
|
|
53
|
+
def aws_query_error_code(context)
|
|
54
|
+
query_header = context.http_response.headers['x-amzn-query-error']
|
|
55
|
+
error, _type = query_header.split(';') # type not supported
|
|
56
|
+
remove_prefix(error, context)
|
|
57
|
+
end
|
|
58
|
+
|
|
49
59
|
def remove_prefix(error_code, context)
|
|
50
60
|
if (prefix = context.config.api.metadata['errorPrefix'])
|
|
51
61
|
error_code.sub(/^#{prefix}/, '')
|