AmmarFahmy
adding all files
105b369
from typing import Optional, Any, Dict, List, Union
from phi.aws.api_client import AwsApiClient
from phi.aws.resource.base import AwsResource
from phi.aws.resource.reference import AwsReference
from phi.aws.resource.cloudformation.stack import CloudFormationStack
from phi.cli.console import print_info
from phi.utils.log import logger
class CacheSubnetGroup(AwsResource):
"""
Reference:
- https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/elasticache.html#ElastiCache.Client.create_cache_subnet_group
Creates a cache subnet group.
"""
resource_type: Optional[str] = "CacheSubnetGroup"
service_name: str = "elasticache"
# A name for the cache subnet group. This value is stored as a lowercase string.
# Constraints: Must contain no more than 255 alphanumeric characters or hyphens.
name: str
# A description for the cache subnet group.
description: Optional[str] = None
# A list of VPC subnet IDs for the cache subnet group.
subnet_ids: Optional[Union[List[str], AwsReference]] = None
# Get Subnet IDs from a VPC CloudFormationStack
# First gets private subnets from the vpc stack, then public subnets
vpc_stack: Optional[CloudFormationStack] = None
# A list of tags to be added to this resource.
tags: Optional[List[Dict[str, str]]] = None
def get_subnet_ids(self, aws_client: AwsApiClient) -> List[str]:
"""Returns the subnet_ids for the CacheSubnetGroup
Args:
aws_client: The AwsApiClient for the current cluster
"""
subnet_ids = []
if self.subnet_ids is not None:
if isinstance(self.subnet_ids, list):
logger.debug("Getting subnet_ids from list")
subnet_ids = self.subnet_ids
elif isinstance(self.subnet_ids, AwsReference):
logger.debug("Getting subnet_ids from reference")
subnet_ids = self.subnet_ids.get_reference(aws_client=aws_client)
if len(subnet_ids) == 0 and self.vpc_stack is not None:
logger.debug("Getting private subnet_ids from vpc stack")
private_subnet_ids = self.vpc_stack.get_private_subnets(aws_client=aws_client)
if private_subnet_ids is not None:
subnet_ids.extend(private_subnet_ids)
if len(subnet_ids) == 0:
logger.debug("Getting public subnet_ids from vpc stack")
public_subnet_ids = self.vpc_stack.get_public_subnets(aws_client=aws_client)
if public_subnet_ids is not None:
subnet_ids.extend(public_subnet_ids)
return subnet_ids
def _create(self, aws_client: AwsApiClient) -> bool:
"""Creates the CacheSubnetGroup
Args:
aws_client: The AwsApiClient for the current cluster
"""
print_info(f"Creating {self.get_resource_type()}: {self.get_resource_name()}")
try:
# Get subnet_ids
subnet_ids = self.get_subnet_ids(aws_client=aws_client)
# create a dict of args which are not null, otherwise aws type validation fails
not_null_args: Dict[str, Any] = {}
if self.tags:
not_null_args["Tags"] = self.tags
# Create CacheSubnetGroup
service_client = self.get_service_client(aws_client)
create_response = service_client.create_cache_subnet_group(
CacheSubnetGroupName=self.name,
CacheSubnetGroupDescription=self.description or f"Created for {self.name}",
SubnetIds=subnet_ids,
**not_null_args,
)
logger.debug(f"create_response type: {type(create_response)}")
logger.debug(f"create_response: {create_response}")
self.active_resource = create_response.get("CacheSubnetGroup", None)
if self.active_resource is not None:
print_info(f"{self.get_resource_type()}: {self.get_resource_name()} created")
logger.debug(f"CacheSubnetGroup: {self.active_resource}")
return True
except Exception as e:
logger.error(f"{self.get_resource_type()} could not be created.")
logger.error(e)
return False
def _read(self, aws_client: AwsApiClient) -> Optional[Any]:
"""Returns the CacheSubnetGroup
Args:
aws_client: The AwsApiClient for the current cluster
"""
from botocore.exceptions import ClientError
logger.debug(f"Reading {self.get_resource_type()}: {self.get_resource_name()}")
try:
service_client = self.get_service_client(aws_client)
describe_response = service_client.describe_cache_subnet_groups(CacheSubnetGroupName=self.name)
logger.debug(f"describe_response type: {type(describe_response)}")
logger.debug(f"describe_response: {describe_response}")
cache_subnet_group_list = describe_response.get("CacheSubnetGroups", None)
if cache_subnet_group_list is not None and isinstance(cache_subnet_group_list, list):
for _cache_subnet_group in cache_subnet_group_list:
_cache_sg_name = _cache_subnet_group.get("CacheSubnetGroupName", None)
if _cache_sg_name == self.name:
self.active_resource = _cache_subnet_group
break
if self.active_resource is None:
logger.debug(f"No {self.get_resource_type()} found")
return None
logger.debug(f"CacheSubnetGroup: {self.active_resource}")
except ClientError as ce:
logger.debug(f"ClientError: {ce}")
except Exception as e:
logger.error(f"Error reading {self.get_resource_type()}.")
logger.error(e)
return self.active_resource
def _delete(self, aws_client: AwsApiClient) -> bool:
"""Deletes the CacheSubnetGroup
Args:
aws_client: The AwsApiClient for the current cluster
"""
print_info(f"Deleting {self.get_resource_type()}: {self.get_resource_name()}")
try:
service_client = self.get_service_client(aws_client)
self.active_resource = None
delete_response = service_client.delete_cache_subnet_group(CacheSubnetGroupName=self.name)
logger.debug(f"delete_response: {delete_response}")
return True
except Exception as e:
logger.error(f"{self.get_resource_type()} could not be deleted.")
logger.error("Please try again or delete resources manually.")
logger.error(e)
return False
def _update(self, aws_client: AwsApiClient) -> bool:
"""Updates the CacheSubnetGroup
Args:
aws_client: The AwsApiClient for the current cluster
"""
print_info(f"Updating {self.get_resource_type()}: {self.get_resource_name()}")
try:
# Get subnet_ids
subnet_ids = self.get_subnet_ids(aws_client=aws_client)
# Update CacheSubnetGroup
service_client = self.get_service_client(aws_client)
update_response = service_client.modify_cache_subnet_group(
CacheSubnetGroupName=self.name,
CacheSubnetGroupDescription=self.description or f"Created for {self.name}",
SubnetIds=subnet_ids,
)
logger.debug(f"update_response: {update_response}")
self.active_resource = update_response.get("CacheSubnetGroup", None)
if self.active_resource is not None:
print_info(f"{self.get_resource_type()}: {self.get_resource_name()} updated")
return True
except Exception as e:
logger.error(f"{self.get_resource_type()} could not be updated.")
logger.error(e)
return False