Skip to content

Commit

Permalink
Use aiobotocore instead of botocore for recipe
Browse files Browse the repository at this point in the history
ElastiCacheIAMProvider interacts with boto to generate a token
for authentication. Since the
  • Loading branch information
alisaifee committed Dec 6, 2024
1 parent eb5b014 commit b18fc6a
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 17 deletions.
30 changes: 15 additions & 15 deletions coredis/recipes/credentials/iam_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

from urllib.parse import ParseResult, urlencode, urlunparse

# botocore and cachetools will need to be installed in addition
# to coredis' dependencies
import botocore.session
# aiobotocore, botocore and cachetools will need to be installed in addition
# to coredis dependencies. These can also be requested by installing coredis
# as coredis[recipes]
import aiobotocore.session
from aiobotocore.signers import AioRequestSigner
from botocore.model import ServiceId
from botocore.signers import RequestSigner
from cachetools import TTLCache, cached

from coredis.credentials import AbstractCredentialProvider, UserPass
Expand All @@ -23,15 +24,7 @@ def __init__(self, user: str, cluster_name: str, region: str = "us-east-1") -> N
self.cluster_name: str = cluster_name
self.region: str = region

session = botocore.session.get_session()
self.request_signer = RequestSigner(
ServiceId("elasticache"),
self.region,
"elasticache",
"v4",
session.get_credentials(),
session.get_component("event_emitter"),
)
self.session = aiobotocore.session.get_session()

@cached(cache=TTLCache(maxsize=128, ttl=900)) # type: ignore[misc]
async def get_credentials(self) -> UserPass:
Expand All @@ -40,6 +33,14 @@ async def get_credentials(self) -> UserPass:
IAM enabled Elasticache instance. The token will be cached for
its lifetime (15 minutes) to avoid unnecessary requests.
"""
request_signer = AioRequestSigner(
ServiceId("elasticache"),
self.region,
"elasticache",
"v4",
await self.session.get_credentials(),
self.session.get_component("event_emitter"),
)
query_params = {"Action": "connect", "User": self.user}
url = urlunparse(
ParseResult(
Expand All @@ -51,12 +52,11 @@ async def get_credentials(self) -> UserPass:
fragment="",
)
)
signed_url = self.request_signer.generate_presigned_url(
signed_url = await request_signer.generate_presigned_url(
{"method": "GET", "url": url, "body": {}, "headers": {}, "context": {}},
operation_name="connect",
expires_in=900,
region_name=self.region,
)

# Need to strip the protocol so that Elasticache accepts it
return UserPass(self.user, signed_url.removeprefix("https://"))
2 changes: 1 addition & 1 deletion docs/source/recipes/credentials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The implementation is based on `the Elasticache IAM provider described in redis

The :class:`~coredis.recipes.credentials.ElastiCacheIAMProvider` implements the
:class:`~coredis.credentials.AbstractCredentialProvider` interface.
It uses :pypi:`botocore` to generate a short-lived authentication token
It uses :pypi:`aiobotocore` to generate a short-lived authentication token
which can be used to authenticate with an IAM enabled Elasticache cluster.
The token is cached for its lifetime of 15 minutes to reduce the number
of unnecessary requests.
Expand Down
2 changes: 1 addition & 1 deletion requirements/recipes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
botocore
aiobotocore
cachetools

0 comments on commit b18fc6a

Please sign in to comment.