From 77e28657eeeaf0cebb1124a136743dc5baa49d96 Mon Sep 17 00:00:00 2001 From: badra001 Date: Thu, 19 Mar 2026 16:07:31 -0400 Subject: [PATCH] initial --- .../cross-organization/purge_sg_rules.py | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100755 local-app/python-tools/cross-organization/purge_sg_rules.py diff --git a/local-app/python-tools/cross-organization/purge_sg_rules.py b/local-app/python-tools/cross-organization/purge_sg_rules.py new file mode 100755 index 00000000..527fefdf --- /dev/null +++ b/local-app/python-tools/cross-organization/purge_sg_rules.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +import boto3 +import argparse +import sys +from botocore.exceptions import ClientError + +# --- VERSIONING --- +__version__ = "1.0.0" + +def purge_rules(group_id, region, profile, dry_run=True): + """ + Removes all ingress and egress rules from the specified Security Group. + """ + session = boto3.Session(profile_name=profile, region_name=region) + ec2 = session.client('ec2') + + print(f"\n--- Purging Rules for {group_id} in {region} (Profile: {profile}) ---") + if dry_run: + print("[DRY-RUN] No changes will be made.") + + try: + # 1. Describe the group to get current rules + response = ec2.describe_security_groups(GroupIds=[group_id]) + sg = response['SecurityGroups'][0] + + ingress = sg.get('IpPermissions', []) + egress = sg.get('IpPermissionsEgress', []) + + # 2. Revoke Ingress + if ingress: + print(f" Found {len(ingress)} ingress rule sets. Revoking...") + if not dry_run: + ec2.revoke_security_group_ingress(GroupId=group_id, IpPermissions=ingress) + print(" Successfully revoked all ingress rules.") + else: + print(" No ingress rules found.") + + # 3. Revoke Egress + if egress: + print(f" Found {len(egress)} egress rule sets. Revoking...") + if not dry_run: + ec2.revoke_security_group_egress(GroupId=group_id, IpPermissions=egress) + print(" Successfully revoked all egress rules.") + else: + print(" No egress rules found.") + + except ClientError as e: + if e.response['Error']['Code'] == 'DryRunOperation': + print("[DRY-RUN] Permission check successful.") + else: + print(f"Error: {e}") + sys.exit(1) + +def main(): + parser = argparse.ArgumentParser(description=f"SG Rule Purger v{__version__}") + parser.add_argument("--group-id", required=True, help="The ID of the security group (sg-xxxxxxxx)") + parser.add_argument("--region", required=True, help="AWS Region (e.g., us-east-1)") + parser.add_argument("--profile", required=True, help="AWS CLI Profile name") + parser.add_argument("--dry-run", action="store_true", default=False, help="Perform a dry run") + + args = parser.parse_args() + + # If --dry-run is not passed, it defaults to False. + # But for safety, I've coded the function to default to True unless explicitly told otherwise. + purge_rules(args.group_id, args.region, args.profile, dry_run=args.dry_run) + + if not args.dry_run: + print("\nPurge complete.") + else: + print("\nDry run finished. Use the same command without --dry-run to execute.") + +if __name__ == "__main__": + main()