diff --git a/local-app/python-tools/cross-organization/assess_check_scheduling.py b/local-app/python-tools/cross-organization/assess_check_scheduling.py index 382d6782..85fdcb78 100755 --- a/local-app/python-tools/cross-organization/assess_check_scheduling.py +++ b/local-app/python-tools/cross-organization/assess_check_scheduling.py @@ -4,7 +4,7 @@ from datetime import datetime # --- VERSIONING --- -__version__ = "1.6.1" +__version__ = "1.6.2" def find_latest_file(pattern): """Locates the most recent check_scheduling JSON file.""" @@ -12,7 +12,7 @@ def find_latest_file(pattern): return max(files, key=os.path.getctime) if files else None def main(): - parser = argparse.ArgumentParser(description="PowerSchedule Assessor - v1.6.1") + parser = argparse.ArgumentParser(description="PowerSchedule Assessor - v1.6.2") parser.add_argument("--input", help="JSON audit file") parser.add_argument("--csv", action="store_true", help="Export matrices to CSV") args = parser.parse_args() @@ -36,7 +36,7 @@ def main(): ec2_groups = Counter({"plain": 0, "asg": 0, "eks": 0}) total_resources = 0 all_envs = set() - created_files = [] # Track created files for summary + created_files = [] for account in data: acc_id = account.get('account_id') @@ -48,16 +48,13 @@ def main(): res_type = val.get("type", "unknown") if res_type == "eks_node": - cat = "eks_ec2" - ec2_groups["eks"] += 1 + cat, ec2_groups["eks"] = "eks_ec2", ec2_groups["eks"] + 1 elif res_type == "asg_member": - cat = "asg_ec2" - ec2_groups["asg"] += 1 + cat, ec2_groups["asg"] = "asg_ec2", ec2_groups["asg"] + 1 elif res_type == "rds": cat = "rds" else: - cat = "plain_ec2" - ec2_groups["plain"] += 1 + cat, ec2_groups["plain"] = "plain_ec2", ec2_groups["plain"] + 1 if val.get("eks_cluster") and val.get("eks_cluster") != "N/A": eks_clusters.add(f"{acc_id}:{val.get('eks_cluster')}") @@ -87,8 +84,47 @@ def main(): eks_node_count = type_totals['eks_ec2'] eks_avg = (eks_node_count / eks_cluster_count) if eks_cluster_count > 0 else 0 - # --- TERMINAL REPORTS (1, 2, 3) --- - # ... (Logic from v1.5.0 restored for terminal output) ... + # --- REPORT 1: BREAKDOWN BY ENVIRONMENT --- + print(f"\nREPORT 1: BREAKDOWN BY ENVIRONMENT") + print("-" * report_width) + for env in sorted_envs: + print(f"\nEnvironment: {env} (Total: {env_totals[env]})") + for sched, count in sorted(env_matrix[env].items()): + pct = (count / env_totals[env]) * 100 + print(f" {sched:<30} | {count:<5} | {pct:>5.1f}%") + + # --- REPORT 2: BREAKDOWN BY RESOURCE TYPE --- + print(f"\n\nREPORT 2: BREAKDOWN BY RESOURCE TYPE") + print("-" * report_width) + ec2_total = ec2_groups["plain"] + ec2_groups["asg"] + ec2_groups["eks"] + print(f"Resource Group: EC2 (Total: {ec2_total})") + print(f" -> Plain: {ec2_groups['plain']} | ASG: {ec2_groups['asg']} | EKS: {ec2_groups['eks']}") + print(f"Resource Group: RDS (Total: {type_totals['rds']})") + + # --- REPORT 3: SCHEDULING MATRIX BY CATEGORY --- + print(f"\n\nREPORT 3: SCHEDULING MATRIX BY CATEGORY") + for cat in ["plain_ec2", "asg_ec2", "eks_ec2", "rds"]: + cat_total = type_totals[cat] + if cat_total == 0: continue + + print(f"\n{cat.upper()} SCHEDULING DETAIL") + header = f"{'PowerSchedule Tag':<25} | {'Org Total (%%)':<16}" + for env in sorted_envs: header += f" | {env[:10]:<10}" + print("-" * len(header)) + print(header) + print("-" * len(header)) + + all_tags = sorted([t for t in r3_data[cat].keys() if not t.startswith("Scheduled:")]) + all_tags += ["Scheduled: True", "Scheduled: False"] + + for tag in all_tags: + row_total = sum(r3_data[cat][tag].values()) + row_pct = (row_total / cat_total) * 100 + line = f"{tag[:25]:<25} | {row_total:<5} ({row_pct:>3.0f}%)" + for env in sorted_envs: + count = r3_data[cat][tag][env] + line += f" | {count:<10}" + print(line) # --- CSV EXPORT --- if args.csv: @@ -99,10 +135,8 @@ def main(): with open(fname, 'w', newline='') as f: writer = csv.writer(f) writer.writerow(["PowerSchedule Tag", "Org Total Count", "Org Total %"] + sorted_envs) - all_tags = sorted([t for t in r3_data[cat].keys() if not t.startswith("Scheduled:")]) all_tags += ["Scheduled: True", "Scheduled: False"] - for tag in all_tags: row_total = sum(r3_data[cat][tag].values()) row_pct = (row_total / type_totals[cat]) * 100 @@ -117,12 +151,11 @@ def main(): print(f" Total Resources Scanned: {total_resources}") print(f" Total ASGs Identified: {len(asg_names)}") print(f" Total EKS Clusters: {eks_cluster_count}") + print(f" Total EKS Nodes: {eks_node_count}") print(f" Average Nodes/Cluster: {eks_avg:.1f}") - if created_files: print(f"\n FILES CREATED:") - for f in created_files: - print(f" - {f}") + for f in created_files: print(f" - {f}") print("=" * report_width) if __name__ == "__main__": main()