AmmarFahmy
adding all files
105b369
from typing import Optional, Any, Dict
from typing_extensions import Literal
from phi.aws.api_client import AwsApiClient
from phi.aws.resource.base import AwsResource
from phi.cli.console import print_info
from phi.utils.log import logger
class EksAddon(AwsResource):
"""
Reference:
- https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/eks.html
"""
resource_type: Optional[str] = "EksAddon"
service_name: str = "eks"
# Addon name
name: str
# EKS cluster name
cluster_name: str
# Addon version
version: Optional[str] = None
service_account_role_arn: Optional[str] = None
resolve_conflicts: Optional[Literal["OVERWRITE", "NONE", "PRESERVE"]] = None
client_request_token: Optional[str] = None
tags: Optional[Dict[str, str]] = None
preserve: Optional[bool] = False
# provided by api on create
created_at: Optional[str] = None
status: Optional[str] = None
wait_for_create: bool = False
wait_for_delete: bool = False
wait_for_update: bool = False
def _create(self, aws_client: AwsApiClient) -> bool:
"""Creates the EksAddon
Args:
aws_client: The AwsApiClient for the current cluster
"""
print_info(f"Creating {self.get_resource_type()}: {self.get_resource_name()}")
# create a dict of args which are not null, otherwise aws type validation fails
not_null_args: Dict[str, Any] = {}
if self.version:
not_null_args["addonVersion"] = self.version
if self.service_account_role_arn:
not_null_args["serviceAccountRoleArn"] = self.service_account_role_arn
if self.resolve_conflicts:
not_null_args["resolveConflicts"] = self.resolve_conflicts
if self.client_request_token:
not_null_args["clientRequestToken"] = self.client_request_token
if self.tags:
not_null_args["tags"] = self.tags
# Step 1: Create EksAddon
service_client = self.get_service_client(aws_client)
try:
create_response = service_client.create_addon(
clusterName=self.cluster_name,
addonName=self.name,
**not_null_args,
)
logger.debug(f"EksAddon: {create_response}")
# logger.debug(f"EksAddon type: {type(create_response)}")
# Validate Cluster creation
self.created_at = create_response.get("addon", {}).get("createdAt", None)
self.status = create_response.get("addon", {}).get("status", None)
logger.debug(f"created_at: {self.created_at}")
logger.debug(f"status: {self.status}")
if self.created_at is not None:
print_info(f"EksAddon created: {self.name}")
self.active_resource = create_response
return True
except service_client.exceptions.ResourceInUseException:
print_info(f"Addon already exists: {self.name}")
return True
except Exception as e:
logger.error(f"{self.get_resource_type()} could not be created.")
logger.error(e)
return False
def post_create(self, aws_client: AwsApiClient) -> bool:
# Wait for Addon to be created
if self.wait_for_create:
try:
print_info(f"Waiting for {self.get_resource_type()} to be active.")
waiter = self.get_service_client(aws_client).get_waiter("addon_active")
waiter.wait(
clusterName=self.cluster_name,
addonName=self.name,
WaiterConfig={
"Delay": self.waiter_delay,
"MaxAttempts": self.waiter_max_attempts,
},
)
except Exception:
# logger.error(f"Waiter failed: {awe}")
pass
return True
def _read(self, aws_client: AwsApiClient) -> Optional[Any]:
"""Returns the EksAddon
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()}")
service_client = self.get_service_client(aws_client)
try:
describe_response = service_client.describe_addon(clusterName=self.cluster_name, addonName=self.name)
# logger.debug(f"EksAddon: {describe_response}")
# logger.debug(f"EksAddon type: {type(describe_response)}")
addon_dict = describe_response.get("addon", {})
self.created_at = addon_dict.get("createdAt", None)
self.status = addon_dict.get("status", None)
logger.debug(f"EksAddon created_at: {self.created_at}")
logger.debug(f"EksAddon status: {self.status}")
if self.created_at is not None:
logger.debug(f"EksAddon found: {self.name}")
self.active_resource = describe_response
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 EksAddon
Args:
aws_client: The AwsApiClient for the current cluster
"""
print_info(f"Deleting {self.get_resource_type()}: {self.get_resource_name()}")
# create a dict of args which are not null, otherwise aws type validation fails
not_null_args: Dict[str, Any] = {}
if self.preserve:
not_null_args["preserve"] = self.preserve
# Step 1: Delete EksAddon
service_client = self.get_service_client(aws_client)
self.active_resource = None
try:
delete_response = service_client.delete_addon(
clusterName=self.cluster_name, addonName=self.name, **not_null_args
)
logger.debug(f"EksAddon: {delete_response}")
# logger.debug(f"EksAddon type: {type(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 post_delete(self, aws_client: AwsApiClient) -> bool:
# Wait for Addon to be deleted
if self.wait_for_delete:
try:
print_info(f"Waiting for {self.get_resource_type()} to be deleted.")
waiter = self.get_service_client(aws_client).get_waiter("addon_deleted")
waiter.wait(
clusterName=self.cluster_name,
addonName=self.name,
WaiterConfig={
"Delay": self.waiter_delay,
"MaxAttempts": self.waiter_max_attempts,
},
)
except Exception as awe:
logger.error(f"Waiter failed: {awe}")
return True