From a15e202e5b0556f221916e4960c6f53679bc422d Mon Sep 17 00:00:00 2001 From: badra001 Date: Tue, 10 Mar 2026 14:36:40 -0400 Subject: [PATCH] add precheck --- .../cross-organization/remediate_tgw.py | 10 ---- .../cross-organization/remediate_tgw_dns.py | 53 +++++++++++++++---- 2 files changed, 43 insertions(+), 20 deletions(-) delete mode 100755 local-app/python-tools/cross-organization/remediate_tgw.py diff --git a/local-app/python-tools/cross-organization/remediate_tgw.py b/local-app/python-tools/cross-organization/remediate_tgw.py deleted file mode 100755 index 14556cc6..00000000 --- a/local-app/python-tools/cross-organization/remediate_tgw.py +++ /dev/null @@ -1,10 +0,0 @@ -def modify_attachment_dns(account_session, region, attachment_id): - """ - Action Plugin: Disables DNS support for a specific attachment. - """ - ec2 = account_session.client('ec2', region_name=region) - response = ec2.modify_transit_gateway_vpc_attachment( - TransitGatewayAttachmentId=attachment_id, - Options={'DnsSupport': 'disable'} - ) - return response['TransitGatewayVpcAttachment']['State'] diff --git a/local-app/python-tools/cross-organization/remediate_tgw_dns.py b/local-app/python-tools/cross-organization/remediate_tgw_dns.py index 65873605..6244ab9c 100755 --- a/local-app/python-tools/cross-organization/remediate_tgw_dns.py +++ b/local-app/python-tools/cross-organization/remediate_tgw_dns.py @@ -2,14 +2,13 @@ from datetime import datetime # --- VERSIONING --- -__version__ = "1.3.0" +__version__ = "1.4.0" def get_child_session(base_session, account_id, role_name, partition): """ Assumes role in child account using the detected partition. """ sts = base_session.client('sts') - # Use dynamic partition for the ARN role_arn = f"arn:{partition}:iam::{account_id}:role/{role_name}" try: response = sts.assume_role( @@ -28,7 +27,7 @@ def get_child_session(base_session, account_id, role_name, partition): def remediate_task(instruction_line, base_session, role_name, partition, dry_run=True, rollback=False): """ - Executes TGW DNS modification honoring the resource's specific region. + Executes TGW DNS modification with a pre-check to prevent redundant calls. """ if not instruction_line.startswith("MODIFY_TGW_ATTACHMENT:"): return None @@ -36,30 +35,64 @@ def remediate_task(instruction_line, base_session, role_name, partition, dry_run try: parts = instruction_line.split(":")[-1].strip().split("|") acc_id = parts[0].strip() - region = parts[1].strip() # Honor the region from the .txt file + region = parts[1].strip() attach_id = parts[2].strip() except Exception as e: return {"error": f"Parse failure: {str(e)}", "line": instruction_line} desired_state = "enable" if rollback else "disable" + log_entry = { + "account_id": acc_id, + "region": region, + "resource": attach_id, + "action": f"DnsSupport={desired_state}", + "status": "PENDING", + "timestamp": datetime.now().isoformat() + } + if dry_run: print(f"[DRY-RUN] Account {acc_id} | Region {region} | {attach_id} -> {desired_state}") - return {"account_id": acc_id, "region": region, "resource": attach_id, "status": "DRY_RUN_SKIPPED"} + log_entry["status"] = "DRY_RUN_SKIPPED" + return log_entry session = get_child_session(base_session, acc_id, role_name, partition) if not session: - return {"account_id": acc_id, "resource": attach_id, "status": "AUTH_FAILED"} + log_entry["status"] = "AUTH_FAILED" + return log_entry try: - # Honor the specific region for the resource ec2 = session.client('ec2', region_name=region) + + # --- PRE-CHECK LOGIC --- + # Describe the specific attachment to check its current status + desc = ec2.describe_transit_gateway_vpc_attachments(TransitGatewayAttachmentIds=[attach_id]) + attachments = desc.get('TransitGatewayVpcAttachments', []) + + if not attachments: + print(f" NOT_FOUND: {attach_id} no longer exists in {acc_id} ({region})") + log_entry["status"] = "NOT_FOUND" + return log_entry + + current_options = attachments[0].get('Options', {}) + current_dns = current_options.get('DnsSupport', 'disabled') + + if current_dns == desired_state: + print(f" SKIPPING: {attach_id} in {acc_id} is already '{desired_state}'") + log_entry["status"] = "ALREADY_COMPLIANT" + return log_entry + + # --- EXECUTE MODIFICATION --- ec2.modify_transit_gateway_vpc_attachment( TransitGatewayAttachmentId=attach_id, Options={'DnsSupport': desired_state} ) print(f"SUCCESS: {attach_id} set to {desired_state} in {acc_id} ({region})") - return {"account_id": acc_id, "region": region, "resource": attach_id, "status": "SUCCESS"} + log_entry["status"] = "SUCCESS" + except Exception as e: - print(f"FAILED: {attach_id} in {acc_id} ({region}) - {str(e)}") - return {"account_id": acc_id, "region": region, "resource": attach_id, "status": f"ERROR: {str(e)}"} + error_msg = str(e) + print(f"FAILED: {attach_id} in {acc_id} ({region}) - {error_msg}") + log_entry["status"] = f"ERROR: {error_msg}" + + return log_entry