Spaces:
Runtime error
Runtime error
File size: 8,141 Bytes
105b369 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
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 DbSubnetGroup(AwsResource):
"""
Reference:
- https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.create_db_subnet_group
Creates a new DB subnet group. DB subnet groups must contain at least one subnet in at least
two AZs in the Amazon Web Services Region.
"""
resource_type: Optional[str] = "DbSubnetGroup"
service_name: str = "rds"
# The name for the DB subnet group. This value is stored as a lowercase string.
# Constraints:
# Must contain no more than 255 letters, numbers, periods, underscores, spaces, or hyphens.
# Must not be default.
# First character must be a letter.
# Example: mydbsubnetgroup
name: str
# The description for the DB subnet group.
description: Optional[str] = None
# The EC2 Subnet IDs for the DB 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
# Tags to assign to the DB subnet group.
tags: Optional[List[Dict[str, str]]] = None
def get_subnet_ids(self, aws_client: AwsApiClient) -> List[str]:
"""Returns the subnet_ids for the DbSubnetGroup
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 DbSubnetGroup
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 DbSubnetGroup
service_client = self.get_service_client(aws_client)
create_response = service_client.create_db_subnet_group(
DBSubnetGroupName=self.name,
DBSubnetGroupDescription=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("DBSubnetGroup", None)
if self.active_resource is not None:
print_info(f"{self.get_resource_type()}: {self.get_resource_name()} created")
logger.debug(f"DbSubnetGroup: {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 DbSubnetGroup
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_db_subnet_groups(DBSubnetGroupName=self.name)
logger.debug(f"describe_response type: {type(describe_response)}")
logger.debug(f"describe_response: {describe_response}")
db_subnet_group_list = describe_response.get("DBSubnetGroups", None)
if db_subnet_group_list is not None and isinstance(db_subnet_group_list, list):
for _db_subnet_group in db_subnet_group_list:
_db_sg_name = _db_subnet_group.get("DBSubnetGroupName", None)
if _db_sg_name == self.name:
self.active_resource = _db_subnet_group
break
if self.active_resource is None:
logger.debug(f"No {self.get_resource_type()} found")
return None
logger.debug(f"DbSubnetGroup: {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 DbSubnetGroup
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_db_subnet_group(DBSubnetGroupName=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 DbSubnetGroup
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 DbSubnetGroup
service_client = self.get_service_client(aws_client)
update_response = service_client.modify_db_subnet_group(
DBSubnetGroupName=self.name,
DBSubnetGroupDescription=self.description or f"Created for {self.name}",
SubnetIds=subnet_ids,
)
logger.debug(f"update_response: {update_response}")
self.active_resource = update_response.get("DBSubnetGroup", 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("Please try again or update resources manually.")
logger.error(e)
return False
|