33import json
44import asyncio
55from dataclasses import dataclass
6- from datetime import datetime , timedelta
6+ from datetime import datetime , timedelta , timezone
77from typing import Literal
88
99from smithy_core import URI
@@ -38,11 +38,9 @@ def value(self) -> bytes:
3838
3939
4040class TokenCache :
41- """Holds the token needed to fetch instance metadata. In addition, it knows how to
42- refresh itself.
41+ """Holds the token needed to fetch instance metadata.
4342
44- :param HTTPClient http_client: The client used for making http requests.
45- :param int token_ttl: The time in seconds before a token expires.
43+ In addition, it knows how to refresh itself.
4644 """
4745
4846 _MIN_TTL = 5
@@ -109,6 +107,8 @@ async def get_token(self) -> Token:
109107class Config :
110108 """Configuration for EC2Metadata."""
111109
110+ _HOST_MAPPING = {"IPv4" : "169.254.169.254" , "IPv6" : "[fd00:ec2::254]" }
111+
112112 retry_strategy : RetryStrategy
113113 endpoint_uri : URI
114114 endpoint_mode : Literal ["IPv4" , "IPv6" ]
@@ -138,10 +138,9 @@ def _resolve_endpoint(
138138 if endpoint_uri is not None :
139139 return endpoint_uri
140140
141- host_mapping = {"IPv4" : "169.254.169.254" , "IPv6" : "[fd00:ec2::254]" }
142-
143141 return URI (
144- scheme = "http" , host = host_mapping .get (endpoint_mode , host_mapping ["IPv4" ])
142+ scheme = "http" ,
143+ host = self ._HOST_MAPPING .get (endpoint_mode , self ._HOST_MAPPING ["IPv4" ]),
145144 )
146145
147146
@@ -198,7 +197,11 @@ def __init__(self, http_client: HTTPClient, config: Config | None = None):
198197 async def get_identity (
199198 self , * , identity_properties : IdentityProperties
200199 ) -> AWSCredentialsIdentity :
201- if self ._credentials is not None :
200+ if (
201+ self ._credentials is not None
202+ and self ._credentials .expiration
203+ and datetime .now (timezone .utc ) < self ._credentials .expiration
204+ ):
202205 return self ._credentials
203206
204207 profile = self ._profile_name
@@ -214,6 +217,9 @@ async def get_identity(
214217 secret_access_key = creds .get ("SecretAccessKey" )
215218 session_token = creds .get ("Token" )
216219 account_id = creds .get ("AccountId" )
220+ expiration = creds .get ("Expiration" )
221+ if expiration is not None :
222+ expiration = datetime .fromisoformat (expiration ).replace (tzinfo = timezone .utc )
217223
218224 if access_key_id is None or secret_access_key is None :
219225 raise SmithyIdentityException (
@@ -224,6 +230,7 @@ async def get_identity(
224230 access_key_id = access_key_id ,
225231 secret_access_key = secret_access_key ,
226232 session_token = session_token ,
233+ expiration = expiration ,
227234 account_id = account_id ,
228235 )
229236 return self ._credentials
0 commit comments