Skip to content

Commit

Permalink
Set token create time before the request (#2650)
Browse files Browse the repository at this point in the history
  • Loading branch information
alextwoods authored Feb 14, 2022
1 parent a72e1f9 commit 1d23850
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 10 deletions.
2 changes: 2 additions & 0 deletions gems/aws-sdk-core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Unreleased Changes
------------------

* Issue - Set `create_time` on IMDS tokens before fetch to reduce chance of using expired tokens and retry failures due to using expired tokens.

3.126.0 (2022-02-03)
------------------

Expand Down
5 changes: 3 additions & 2 deletions gems/aws-sdk-core/lib/aws-sdk-core/ec2_metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,9 @@ def resolve_endpoint(endpoint, endpoint_mode)

def fetch_token
open_connection do |conn|
created_time = Time.now
token_value, token_ttl = http_put(conn, @token_ttl)
@token = Token.new(value: token_value, ttl: token_ttl)
@token = Token.new(value: token_value, ttl: token_ttl, created_time: created_time)
end
end

Expand Down Expand Up @@ -222,7 +223,7 @@ class Token
def initialize(options = {})
@ttl = options[:ttl]
@value = options[:value]
@created_time = Time.now
@created_time = options[:created_time] || Time.now
end

# [String] Returns the token value.
Expand Down
31 changes: 23 additions & 8 deletions gems/aws-sdk-core/lib/aws-sdk-core/instance_profile_credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,11 @@ def get_credentials
begin
retry_errors(NETWORK_ERRORS, max_retries: @retries) do
unless token_set?
created_time = Time.now
token_value, ttl = http_put(
conn, METADATA_TOKEN_PATH, @token_ttl
)
@token = Token.new(token_value, ttl) if token_value && ttl
@token = Token.new(token_value, ttl, created_time) if token_value && ttl
end
end
rescue *NETWORK_ERRORS
Expand All @@ -166,9 +167,17 @@ def get_credentials
end

token = @token.value if token_set?
metadata = http_get(conn, METADATA_PATH_BASE, token)
profile_name = metadata.lines.first.strip
http_get(conn, METADATA_PATH_BASE + profile_name, token)

begin
metadata = http_get(conn, METADATA_PATH_BASE, token)
profile_name = metadata.lines.first.strip
http_get(conn, METADATA_PATH_BASE + profile_name, token)
rescue TokenExpiredError
# Token has expired, reset it
# The next retry should fetch it
@token = nil
raise Non200Response
end
end
end
rescue
Expand Down Expand Up @@ -200,9 +209,15 @@ def http_get(connection, path, token = nil)
headers = { 'User-Agent' => "aws-sdk-ruby3/#{CORE_GEM_VERSION}" }
headers['x-aws-ec2-metadata-token'] = token if token
response = connection.request(Net::HTTP::Get.new(path, headers))
raise Non200Response unless response.code.to_i == 200

response.body
case response.code.to_i
when 200
response.body
when 401
raise TokenExpiredError
else
raise Non200Response
end
end

# PUT request fetch token with ttl
Expand Down Expand Up @@ -244,10 +259,10 @@ def retry_errors(error_classes, options = {}, &_block)
# @api private
# Token used to fetch IMDS profile and credentials
class Token
def initialize(value, ttl)
def initialize(value, ttl, created_time = Time.now)
@ttl = ttl
@value = value
@created_time = Time.now
@created_time = created_time
end

# [String] token value
Expand Down

0 comments on commit 1d23850

Please sign in to comment.