snapshot
This commit is contained in:
@@ -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()
|
||||
Reference in New Issue
Block a user