This commit is contained in:
2024-12-24 20:49:41 +03:00
parent f8febafacb
commit 2b3521544b
35 changed files with 2043 additions and 767 deletions
+107
View File
@@ -0,0 +1,107 @@
import logging
import typing
import boto3
import botocore.client
def paginate_by_marker(
func: callable,
list_field: str,
) -> typing.Iterable:
"""
Simplifies paginating over AWS results with a simpler interface than Paginators.
:param func: A function that accepts a parameter named `Marker`
:param list_field: Result field to iterate on
"""
marker = ""
while True:
result = func(Marker=marker)
items = result.get(list_field, [])
yield from items
if "Marker" not in result:
break
marker = result["Marker"]
logger = logging.getLogger(__name__)
class Rediser:
@classmethod
def new(cls):
return cls(boto3.client("elasticache", region_name='eu-central-1'))
def __init__(self, elasticache: botocore.client.BaseClient):
self.elasticache = elasticache
def _get_redis_acl(
self,
cluster_id: str = None,
status: str = "available",
) -> typing.Optional[dict]:
"""
Finds a Redis replication group by its ID
:param cluster_id: Replication group ID
:param status: Replication status. One of available/starting/modifying/deleting.
:return: RedisInstance or throws LookupError error
"""
try:
redis = self.elasticache.describe_replication_groups(ReplicationGroupId=cluster_id)["ReplicationGroups"][0]
if redis["Status"] != status:
raise Exception(f"Found redis with {cluster_id=} but its status={redis['Status']}")
except self.elasticache.exceptions.ReplicationGroupNotFoundFault:
return None
return dict(
cluster_id=redis["ReplicationGroupId"],
host=redis["NodeGroups"][0]["PrimaryEndpoint"]["Address"],
port=redis["NodeGroups"][0]["PrimaryEndpoint"]["Port"],
arn=redis["ARN"],
user_group_ids=redis["UserGroupIds"],
)
def create_redis_acl(
self,
*,
cluster_id: str,
cluster_description: typing.Optional[str] = None,
node_type: str,
subnet_group_name: str,
security_group_id: str,
):
redis = self._get_redis_acl(cluster_id=cluster_id)
if not redis:
res = self.elasticache.create_replication_group(
ReplicationGroupId=cluster_id,
ReplicationGroupDescription=cluster_description or cluster_id,
ReplicasPerNodeGroup=0,
Engine="redis",
EngineVersion="6.x",
CacheNodeType=node_type,
CacheSubnetGroupName=subnet_group_name,
TransitEncryptionEnabled=True, # must be True to use Redis ACL
UserGroupIds=[
user_group_id,
],
SecurityGroupIds=[
security_group_id,
],
Tags=[{"Key": k, "Value": v} for k, v in tags.items()],
MultiAZEnabled=False,
AutomaticFailoverEnabled=False,
)
def main():
r = Rediser.new()
res = r.create_redis_acl(cluster_id='hey', node_type='cache.t2.micro')
if __name__ == '__main__':
main()