diff --git a/local-app/python-tools/cross-organization/tag-checker.py b/local-app/python-tools/cross-organization/tag-checker.py index 3dd15601..9fbd76a9 100755 --- a/local-app/python-tools/cross-organization/tag-checker.py +++ b/local-app/python-tools/cross-organization/tag-checker.py @@ -12,7 +12,7 @@ from botocore.exceptions import ClientError from tqdm import tqdm -__version__ = "1.1.6" +__version__ = "1.1.7" def get_args(): parser = argparse.ArgumentParser(description=f"AWS Org Tag Scanner v{__version__}") @@ -72,16 +72,13 @@ def scan_account(account, management_session, role_name, partition, tag_keys, re global_tags_found = set() regional_data = [] - # Fixed-width header alignment: "Lane 01 | {acc_id} {alias}" - label = f"{acc_id} {alias}".ljust(bar_width) + # Bar alignment fixed with bar_width + 1 + label = f"{acc_id} {alias}".ljust(bar_width + 1) pbar = tqdm(total=len(tag_keys), desc=f"Lane {lane_id:02d} | {label}", position=lane_id, leave=False, bar_format='{l_bar}{bar}| {n_fmt}/{total_fmt}') for key in tag_keys: - tag_key_found_globally = False for r in active_regions: - reg_hits = 0 - reg_resources = set() client = m_session.client('resourcegroupstaggingapi', region_name=r) try: paginator = client.get_paginator('get_resources') @@ -95,34 +92,32 @@ def scan_account(account, management_session, role_name, partition, tag_keys, re }) global_resources.add(arn) global_tags_found.add(key) - reg_resources.add(arn) - reg_hits += 1 - tag_key_found_globally = True except ClientError as e: if "Throttling" in str(e): time.sleep(1) pbar.update(1) pbar.close() - # Regional Metrics Breakdown for r in active_regions: r_findings = [f for f in findings if f['region'] == r] - r_tags = set([f['tag_name'] for f in r_findings]) + r_tags = sorted(list(set([f['tag_name'] for f in r_findings]))) r_res = set([f['arn'] for f in r_findings]) regional_data.append({ "region": r, "hits": len(r_findings), "unique_resources": len(r_res), - "tags_found": len(r_tags), - "tags_not_found": len(tag_keys) - len(r_tags) + "tags_found_count": len(r_tags), + "tags_found_list": r_tags, + "tags_not_found_count": len(tag_keys) - len(r_tags) }) metrics = { "global": { "hits": len(findings), "unique_resources": len(global_resources), - "tags_found": len(global_tags_found), - "tags_not_found": len(tag_keys) - len(global_tags_found), + "tags_found_count": len(global_tags_found), + "tags_found_list": sorted(list(global_tags_found)), + "tags_not_found_count": len(tag_keys) - len(global_tags_found), "elapsed_sec": round(time.time() - acc_start, 2) }, "regions": regional_data @@ -155,12 +150,12 @@ def main(): if args.limit > 0: all_accs = all_accs[:args.limit] - # Calculate bar width based on ID (12) + Name (alias fallback) + padding - # We add 1 for the space between ID and Alias as requested + # Calculate bar width for alignment + # Length of ID (12) + Space (1) + Name/Alias (max) max_label_len = max([12 + 1 + len(a['Name']) for a in all_accs]) if all_accs else 40 - print(f"\n{'='*80}\nAWS TAG CHECKER v{__version__}\n{'='*80}") - print(f"Workers: {args.max_workers} | Tags: {len(tag_keys)} | Targeted Accounts: {len(all_accs)}") + print(f"\n{'='*85}\nAWS TAG CHECKER v{__version__}\n{'='*85}") + print(f"Profile: {args.profile} | Workers: {args.max_workers} | Targets: {len(all_accs)}") all_findings = [] summary_data = []