From 4a54e019f7907b0879611760e74f65047faa6289 Mon Sep 17 00:00:00 2001 From: "Matthew C. Morgan" Date: Fri, 14 Mar 2025 18:11:23 -0400 Subject: [PATCH] extend tag logic to all resrouces --- .../gfl-resource-actions/managers/base.py | 6 +++- .../gfl-resource-actions/managers/ec2.py | 11 +++++++ .../gfl-resource-actions/managers/eks.py | 18 ++++++++++ .../gfl-resource-actions/managers/emr.py | 33 +++++++++++++++++++ .../gfl-resource-actions/managers/rds.py | 20 +++++++++++ 5 files changed, 87 insertions(+), 1 deletion(-) diff --git a/local-app/python-tools/gfl-resource-actions/managers/base.py b/local-app/python-tools/gfl-resource-actions/managers/base.py index 8d5d756d..de2273c6 100644 --- a/local-app/python-tools/gfl-resource-actions/managers/base.py +++ b/local-app/python-tools/gfl-resource-actions/managers/base.py @@ -3,7 +3,7 @@ """ import datetime import config -from aws_utils import create_boto3_client +from aws_utils import create_boto3_client, get_partition_for_region from logging_utils import setup_logging logger = setup_logging() @@ -44,3 +44,7 @@ def log_action(self, resource_id, region, action, resource_name=None, dry_run=Fa def should_exclude(self, resource): """Check if resource should be excluded based on tags.""" return config.EXCLUSION_TAG in resource.get("tags", {}) + + def get_partition_for_region(self, region): + """Get AWS partition for region.""" + return get_partition_for_region(region) diff --git a/local-app/python-tools/gfl-resource-actions/managers/ec2.py b/local-app/python-tools/gfl-resource-actions/managers/ec2.py index fbf55841..fc3ef2f9 100644 --- a/local-app/python-tools/gfl-resource-actions/managers/ec2.py +++ b/local-app/python-tools/gfl-resource-actions/managers/ec2.py @@ -83,6 +83,17 @@ def start(self, instances, dry_run=False): logger.info(f"{'[DRY RUN] Would start' if dry_run else 'Starting'} EC2 instance {instance['id']} in region {region}") if not dry_run: ec2_client.start_instances(InstanceIds=[instance['id']]) + + # Remove the stop tag after successful start + logger.info(f"Removing {config.STOP_TAG} tag from EC2 instance {instance['id']}") + ec2_client.delete_tags( + Resources=[instance['id']], + Tags=[ + { + 'Key': config.STOP_TAG + } + ] + ) # Log with detailed information self.log_action(instance['id'], region, "start", dry_run=dry_run) diff --git a/local-app/python-tools/gfl-resource-actions/managers/eks.py b/local-app/python-tools/gfl-resource-actions/managers/eks.py index 2e2c9261..ac0f12ed 100644 --- a/local-app/python-tools/gfl-resource-actions/managers/eks.py +++ b/local-app/python-tools/gfl-resource-actions/managers/eks.py @@ -34,6 +34,16 @@ def stop(self, clusters, dry_run=False): timestamp = self.get_timestamp() + # Tag the cluster before scaling down + logger.info(f"{'[DRY RUN] Would tag' if dry_run else 'Tagging'} EKS cluster {cluster['name']} with {config.STOP_TAG}={timestamp}") + if not dry_run: + eks_client.tag_resource( + resourceArn=f"arn:{self.get_partition_for_region(region)}:eks:{region}:{self.account_id}:cluster/{cluster['name']}", + tags={ + config.STOP_TAG: timestamp + } + ) + # Scale down each nodegroup for nodegroup in nodegroups: ng_info = eks_client.describe_nodegroup( @@ -188,6 +198,14 @@ def start(self, clusters, dry_run=False): else: logger.info(f"ASG {asg_name} already has capacity. Skipping scale up.") + # Remove the stop tag after successful scale up + if not dry_run: + logger.info(f"Removing {config.STOP_TAG} tag from EKS cluster {cluster['name']}") + eks_client.untag_resource( + resourceArn=f"arn:{self.get_partition_for_region(region)}:eks:{region}:{self.account_id}:cluster/{cluster['name']}", + tagKeys=[config.STOP_TAG] + ) + # Log with detailed information self.log_action(cluster['name'], region, "scale_up", dry_run=dry_run) diff --git a/local-app/python-tools/gfl-resource-actions/managers/emr.py b/local-app/python-tools/gfl-resource-actions/managers/emr.py index 02cb8ef5..07865373 100644 --- a/local-app/python-tools/gfl-resource-actions/managers/emr.py +++ b/local-app/python-tools/gfl-resource-actions/managers/emr.py @@ -29,6 +29,19 @@ def stop(self, clusters, dry_run=False): timestamp = self.get_timestamp() + # Tag the cluster before stopping + logger.info(f"{'[DRY RUN] Would tag' if dry_run else 'Tagging'} EMR cluster {cluster['name']} ({cluster['id']}) with {config.STOP_TAG}={timestamp}") + if not dry_run: + emr_client.add_tags( + ResourceId=cluster['id'], + Tags=[ + { + 'Key': config.STOP_TAG, + 'Value': timestamp + } + ] + ) + logger.info(f"{'[DRY RUN] Would stop' if dry_run else 'Stopping'} EMR cluster {cluster['name']} ({cluster['id']}) in region {region}") if not dry_run: emr_client.stop_cluster(ClusterId=cluster['id']) @@ -46,6 +59,19 @@ def stop(self, clusters, dry_run=False): timestamp = self.get_timestamp() + # Tag the cluster before terminating + logger.info(f"{'[DRY RUN] Would tag' if dry_run else 'Tagging'} EMR cluster {cluster['name']} ({cluster['id']}) with {config.STOP_TAG}={timestamp}") + if not dry_run: + emr_client.add_tags( + ResourceId=cluster['id'], + Tags=[ + { + 'Key': config.STOP_TAG, + 'Value': timestamp + } + ] + ) + logger.info(f"{'[DRY RUN] Would terminate' if dry_run else 'Terminating'} EMR cluster {cluster['name']} ({cluster['id']}) in region {region} (cannot stop a cluster in {cluster['status']} state)") if not dry_run: emr_client.terminate_job_flows(JobFlowIds=[cluster['id']]) @@ -74,6 +100,13 @@ def start(self, clusters, dry_run=False): logger.info(f"{'[DRY RUN] Would start' if dry_run else 'Starting'} EMR cluster {cluster['name']} ({cluster['id']}) in region {region}") if not dry_run: emr_client.start_cluster(ClusterId=cluster['id']) + + # Remove the stop tag after successful start + logger.info(f"Removing {config.STOP_TAG} tag from EMR cluster {cluster['id']}") + emr_client.remove_tags( + ResourceId=cluster['id'], + TagKeys=[config.STOP_TAG] + ) # Log with detailed information self.log_action(cluster['id'], region, "start", resource_name=cluster['name'], dry_run=dry_run) diff --git a/local-app/python-tools/gfl-resource-actions/managers/rds.py b/local-app/python-tools/gfl-resource-actions/managers/rds.py index 003ed155..2e903d83 100644 --- a/local-app/python-tools/gfl-resource-actions/managers/rds.py +++ b/local-app/python-tools/gfl-resource-actions/managers/rds.py @@ -26,6 +26,19 @@ def stop(self, instances, dry_run=False): # Create ISO 8601 timestamp timestamp = self.get_timestamp() + # Tag the instance before stopping + logger.info(f"{'[DRY RUN] Would tag' if dry_run else 'Tagging'} RDS instance {instance['id']} with {config.STOP_TAG}={timestamp}") + if not dry_run: + rds_client.add_tags_to_resource( + ResourceName=f"arn:{self.get_partition_for_region(region)}:rds:{region}:{self.account_id}:db:{instance['id']}", + Tags=[ + { + 'Key': config.STOP_TAG, + 'Value': timestamp + } + ] + ) + logger.info(f"{'[DRY RUN] Would stop' if dry_run else 'Stopping'} RDS instance {instance['id']} in region {region}") if not dry_run: rds_client.stop_db_instance(DBInstanceIdentifier=instance['id']) @@ -52,6 +65,13 @@ def start(self, instances, dry_run=False): logger.info(f"{'[DRY RUN] Would start' if dry_run else 'Starting'} RDS instance {instance['id']} in region {region}") if not dry_run: rds_client.start_db_instance(DBInstanceIdentifier=instance['id']) + + # Remove the stop tag after successful start + logger.info(f"Removing {config.STOP_TAG} tag from RDS instance {instance['id']}") + rds_client.remove_tags_from_resource( + ResourceName=f"arn:{self.get_partition_for_region(region)}:rds:{region}:{self.account_id}:db:{instance['id']}", + TagKeys=[config.STOP_TAG] + ) # Log with detailed information self.log_action(instance['id'], region, "start", dry_run=dry_run)