Spaces:
Runtime error
Runtime error
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 | |