runbooks 1.1.4__py3-none-any.whl → 1.1.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. runbooks/__init__.py +31 -2
  2. runbooks/__init___optimized.py +18 -4
  3. runbooks/_platform/__init__.py +1 -5
  4. runbooks/_platform/core/runbooks_wrapper.py +141 -138
  5. runbooks/aws2/accuracy_validator.py +812 -0
  6. runbooks/base.py +7 -0
  7. runbooks/cfat/assessment/compliance.py +1 -1
  8. runbooks/cfat/assessment/runner.py +1 -0
  9. runbooks/cfat/cloud_foundations_assessment.py +227 -239
  10. runbooks/cli/__init__.py +1 -1
  11. runbooks/cli/commands/cfat.py +64 -23
  12. runbooks/cli/commands/finops.py +1005 -54
  13. runbooks/cli/commands/inventory.py +135 -91
  14. runbooks/cli/commands/operate.py +9 -36
  15. runbooks/cli/commands/security.py +42 -18
  16. runbooks/cli/commands/validation.py +432 -18
  17. runbooks/cli/commands/vpc.py +81 -17
  18. runbooks/cli/registry.py +22 -10
  19. runbooks/cloudops/__init__.py +20 -27
  20. runbooks/cloudops/base.py +96 -107
  21. runbooks/cloudops/cost_optimizer.py +544 -542
  22. runbooks/cloudops/infrastructure_optimizer.py +5 -4
  23. runbooks/cloudops/interfaces.py +224 -225
  24. runbooks/cloudops/lifecycle_manager.py +5 -4
  25. runbooks/cloudops/mcp_cost_validation.py +252 -235
  26. runbooks/cloudops/models.py +78 -53
  27. runbooks/cloudops/monitoring_automation.py +5 -4
  28. runbooks/cloudops/notebook_framework.py +177 -213
  29. runbooks/cloudops/security_enforcer.py +125 -159
  30. runbooks/common/accuracy_validator.py +17 -12
  31. runbooks/common/aws_pricing.py +349 -326
  32. runbooks/common/aws_pricing_api.py +211 -212
  33. runbooks/common/aws_profile_manager.py +40 -36
  34. runbooks/common/aws_utils.py +74 -79
  35. runbooks/common/business_logic.py +126 -104
  36. runbooks/common/cli_decorators.py +36 -60
  37. runbooks/common/comprehensive_cost_explorer_integration.py +455 -463
  38. runbooks/common/cross_account_manager.py +197 -204
  39. runbooks/common/date_utils.py +27 -39
  40. runbooks/common/decorators.py +29 -19
  41. runbooks/common/dry_run_examples.py +173 -208
  42. runbooks/common/dry_run_framework.py +157 -155
  43. runbooks/common/enhanced_exception_handler.py +15 -4
  44. runbooks/common/enhanced_logging_example.py +50 -64
  45. runbooks/common/enhanced_logging_integration_example.py +65 -37
  46. runbooks/common/env_utils.py +16 -16
  47. runbooks/common/error_handling.py +40 -38
  48. runbooks/common/lazy_loader.py +41 -23
  49. runbooks/common/logging_integration_helper.py +79 -86
  50. runbooks/common/mcp_cost_explorer_integration.py +476 -493
  51. runbooks/common/mcp_integration.py +99 -79
  52. runbooks/common/memory_optimization.py +140 -118
  53. runbooks/common/module_cli_base.py +37 -58
  54. runbooks/common/organizations_client.py +175 -193
  55. runbooks/common/patterns.py +23 -25
  56. runbooks/common/performance_monitoring.py +67 -71
  57. runbooks/common/performance_optimization_engine.py +283 -274
  58. runbooks/common/profile_utils.py +111 -37
  59. runbooks/common/rich_utils.py +315 -141
  60. runbooks/common/sre_performance_suite.py +177 -186
  61. runbooks/enterprise/__init__.py +1 -1
  62. runbooks/enterprise/logging.py +144 -106
  63. runbooks/enterprise/security.py +187 -204
  64. runbooks/enterprise/validation.py +43 -56
  65. runbooks/finops/__init__.py +26 -30
  66. runbooks/finops/account_resolver.py +1 -1
  67. runbooks/finops/advanced_optimization_engine.py +980 -0
  68. runbooks/finops/automation_core.py +268 -231
  69. runbooks/finops/business_case_config.py +184 -179
  70. runbooks/finops/cli.py +660 -139
  71. runbooks/finops/commvault_ec2_analysis.py +157 -164
  72. runbooks/finops/compute_cost_optimizer.py +336 -320
  73. runbooks/finops/config.py +20 -20
  74. runbooks/finops/cost_optimizer.py +484 -618
  75. runbooks/finops/cost_processor.py +332 -214
  76. runbooks/finops/dashboard_runner.py +1006 -172
  77. runbooks/finops/ebs_cost_optimizer.py +991 -657
  78. runbooks/finops/elastic_ip_optimizer.py +317 -257
  79. runbooks/finops/enhanced_mcp_integration.py +340 -0
  80. runbooks/finops/enhanced_progress.py +32 -29
  81. runbooks/finops/enhanced_trend_visualization.py +3 -2
  82. runbooks/finops/enterprise_wrappers.py +223 -285
  83. runbooks/finops/executive_export.py +203 -160
  84. runbooks/finops/helpers.py +130 -288
  85. runbooks/finops/iam_guidance.py +1 -1
  86. runbooks/finops/infrastructure/__init__.py +80 -0
  87. runbooks/finops/infrastructure/commands.py +506 -0
  88. runbooks/finops/infrastructure/load_balancer_optimizer.py +866 -0
  89. runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +832 -0
  90. runbooks/finops/markdown_exporter.py +337 -174
  91. runbooks/finops/mcp_validator.py +1952 -0
  92. runbooks/finops/nat_gateway_optimizer.py +1512 -481
  93. runbooks/finops/network_cost_optimizer.py +657 -587
  94. runbooks/finops/notebook_utils.py +226 -188
  95. runbooks/finops/optimization_engine.py +1136 -0
  96. runbooks/finops/optimizer.py +19 -23
  97. runbooks/finops/rds_snapshot_optimizer.py +367 -411
  98. runbooks/finops/reservation_optimizer.py +427 -363
  99. runbooks/finops/scenario_cli_integration.py +64 -65
  100. runbooks/finops/scenarios.py +1277 -438
  101. runbooks/finops/schemas.py +218 -182
  102. runbooks/finops/snapshot_manager.py +2289 -0
  103. runbooks/finops/types.py +3 -3
  104. runbooks/finops/validation_framework.py +259 -265
  105. runbooks/finops/vpc_cleanup_exporter.py +189 -144
  106. runbooks/finops/vpc_cleanup_optimizer.py +591 -573
  107. runbooks/finops/workspaces_analyzer.py +171 -182
  108. runbooks/integration/__init__.py +89 -0
  109. runbooks/integration/mcp_integration.py +1920 -0
  110. runbooks/inventory/CLAUDE.md +816 -0
  111. runbooks/inventory/__init__.py +2 -2
  112. runbooks/inventory/aws_decorators.py +2 -3
  113. runbooks/inventory/check_cloudtrail_compliance.py +2 -4
  114. runbooks/inventory/check_controltower_readiness.py +152 -151
  115. runbooks/inventory/check_landingzone_readiness.py +85 -84
  116. runbooks/inventory/cloud_foundations_integration.py +144 -149
  117. runbooks/inventory/collectors/aws_comprehensive.py +1 -1
  118. runbooks/inventory/collectors/aws_networking.py +109 -99
  119. runbooks/inventory/collectors/base.py +4 -0
  120. runbooks/inventory/core/collector.py +495 -313
  121. runbooks/inventory/core/formatter.py +11 -0
  122. runbooks/inventory/draw_org_structure.py +8 -9
  123. runbooks/inventory/drift_detection_cli.py +69 -96
  124. runbooks/inventory/ec2_vpc_utils.py +2 -2
  125. runbooks/inventory/find_cfn_drift_detection.py +5 -7
  126. runbooks/inventory/find_cfn_orphaned_stacks.py +7 -9
  127. runbooks/inventory/find_cfn_stackset_drift.py +5 -6
  128. runbooks/inventory/find_ec2_security_groups.py +48 -42
  129. runbooks/inventory/find_landingzone_versions.py +4 -6
  130. runbooks/inventory/find_vpc_flow_logs.py +7 -9
  131. runbooks/inventory/inventory_mcp_cli.py +48 -46
  132. runbooks/inventory/inventory_modules.py +103 -91
  133. runbooks/inventory/list_cfn_stacks.py +9 -10
  134. runbooks/inventory/list_cfn_stackset_operation_results.py +1 -3
  135. runbooks/inventory/list_cfn_stackset_operations.py +79 -57
  136. runbooks/inventory/list_cfn_stacksets.py +8 -10
  137. runbooks/inventory/list_config_recorders_delivery_channels.py +49 -39
  138. runbooks/inventory/list_ds_directories.py +65 -53
  139. runbooks/inventory/list_ec2_availability_zones.py +2 -4
  140. runbooks/inventory/list_ec2_ebs_volumes.py +32 -35
  141. runbooks/inventory/list_ec2_instances.py +23 -28
  142. runbooks/inventory/list_ecs_clusters_and_tasks.py +26 -34
  143. runbooks/inventory/list_elbs_load_balancers.py +22 -20
  144. runbooks/inventory/list_enis_network_interfaces.py +26 -33
  145. runbooks/inventory/list_guardduty_detectors.py +2 -4
  146. runbooks/inventory/list_iam_policies.py +2 -4
  147. runbooks/inventory/list_iam_roles.py +5 -7
  148. runbooks/inventory/list_iam_saml_providers.py +4 -6
  149. runbooks/inventory/list_lambda_functions.py +38 -38
  150. runbooks/inventory/list_org_accounts.py +6 -8
  151. runbooks/inventory/list_org_accounts_users.py +55 -44
  152. runbooks/inventory/list_rds_db_instances.py +31 -33
  153. runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
  154. runbooks/inventory/list_route53_hosted_zones.py +3 -5
  155. runbooks/inventory/list_servicecatalog_provisioned_products.py +37 -41
  156. runbooks/inventory/list_sns_topics.py +2 -4
  157. runbooks/inventory/list_ssm_parameters.py +4 -7
  158. runbooks/inventory/list_vpc_subnets.py +2 -4
  159. runbooks/inventory/list_vpcs.py +7 -10
  160. runbooks/inventory/mcp_inventory_validator.py +554 -468
  161. runbooks/inventory/mcp_vpc_validator.py +359 -442
  162. runbooks/inventory/organizations_discovery.py +63 -55
  163. runbooks/inventory/recover_cfn_stack_ids.py +7 -8
  164. runbooks/inventory/requirements.txt +0 -1
  165. runbooks/inventory/rich_inventory_display.py +35 -34
  166. runbooks/inventory/run_on_multi_accounts.py +3 -5
  167. runbooks/inventory/unified_validation_engine.py +281 -253
  168. runbooks/inventory/verify_ec2_security_groups.py +1 -1
  169. runbooks/inventory/vpc_analyzer.py +735 -697
  170. runbooks/inventory/vpc_architecture_validator.py +293 -348
  171. runbooks/inventory/vpc_dependency_analyzer.py +384 -380
  172. runbooks/inventory/vpc_flow_analyzer.py +1 -1
  173. runbooks/main.py +49 -34
  174. runbooks/main_final.py +91 -60
  175. runbooks/main_minimal.py +22 -10
  176. runbooks/main_optimized.py +131 -100
  177. runbooks/main_ultra_minimal.py +7 -2
  178. runbooks/mcp/__init__.py +36 -0
  179. runbooks/mcp/integration.py +679 -0
  180. runbooks/monitoring/performance_monitor.py +9 -4
  181. runbooks/operate/dynamodb_operations.py +3 -1
  182. runbooks/operate/ec2_operations.py +145 -137
  183. runbooks/operate/iam_operations.py +146 -152
  184. runbooks/operate/networking_cost_heatmap.py +29 -8
  185. runbooks/operate/rds_operations.py +223 -254
  186. runbooks/operate/s3_operations.py +107 -118
  187. runbooks/operate/vpc_operations.py +646 -616
  188. runbooks/remediation/base.py +1 -1
  189. runbooks/remediation/commons.py +10 -7
  190. runbooks/remediation/commvault_ec2_analysis.py +70 -66
  191. runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
  192. runbooks/remediation/multi_account.py +24 -21
  193. runbooks/remediation/rds_snapshot_list.py +86 -60
  194. runbooks/remediation/remediation_cli.py +92 -146
  195. runbooks/remediation/universal_account_discovery.py +83 -79
  196. runbooks/remediation/workspaces_list.py +46 -41
  197. runbooks/security/__init__.py +19 -0
  198. runbooks/security/assessment_runner.py +1150 -0
  199. runbooks/security/baseline_checker.py +812 -0
  200. runbooks/security/cloudops_automation_security_validator.py +509 -535
  201. runbooks/security/compliance_automation_engine.py +17 -17
  202. runbooks/security/config/__init__.py +2 -2
  203. runbooks/security/config/compliance_config.py +50 -50
  204. runbooks/security/config_template_generator.py +63 -76
  205. runbooks/security/enterprise_security_framework.py +1 -1
  206. runbooks/security/executive_security_dashboard.py +519 -508
  207. runbooks/security/multi_account_security_controls.py +959 -1210
  208. runbooks/security/real_time_security_monitor.py +422 -444
  209. runbooks/security/security_baseline_tester.py +1 -1
  210. runbooks/security/security_cli.py +143 -112
  211. runbooks/security/test_2way_validation.py +439 -0
  212. runbooks/security/two_way_validation_framework.py +852 -0
  213. runbooks/sre/production_monitoring_framework.py +167 -177
  214. runbooks/tdd/__init__.py +15 -0
  215. runbooks/tdd/cli.py +1071 -0
  216. runbooks/utils/__init__.py +14 -17
  217. runbooks/utils/logger.py +7 -2
  218. runbooks/utils/version_validator.py +50 -47
  219. runbooks/validation/__init__.py +6 -6
  220. runbooks/validation/cli.py +9 -3
  221. runbooks/validation/comprehensive_2way_validator.py +745 -704
  222. runbooks/validation/mcp_validator.py +906 -228
  223. runbooks/validation/terraform_citations_validator.py +104 -115
  224. runbooks/validation/terraform_drift_detector.py +461 -454
  225. runbooks/vpc/README.md +617 -0
  226. runbooks/vpc/__init__.py +8 -1
  227. runbooks/vpc/analyzer.py +577 -0
  228. runbooks/vpc/cleanup_wrapper.py +476 -413
  229. runbooks/vpc/cli_cloudtrail_commands.py +339 -0
  230. runbooks/vpc/cli_mcp_validation_commands.py +480 -0
  231. runbooks/vpc/cloudtrail_audit_integration.py +717 -0
  232. runbooks/vpc/config.py +92 -97
  233. runbooks/vpc/cost_engine.py +411 -148
  234. runbooks/vpc/cost_explorer_integration.py +553 -0
  235. runbooks/vpc/cross_account_session.py +101 -106
  236. runbooks/vpc/enhanced_mcp_validation.py +917 -0
  237. runbooks/vpc/eni_gate_validator.py +961 -0
  238. runbooks/vpc/heatmap_engine.py +185 -160
  239. runbooks/vpc/mcp_no_eni_validator.py +680 -639
  240. runbooks/vpc/nat_gateway_optimizer.py +358 -0
  241. runbooks/vpc/networking_wrapper.py +15 -8
  242. runbooks/vpc/pdca_remediation_planner.py +528 -0
  243. runbooks/vpc/performance_optimized_analyzer.py +219 -231
  244. runbooks/vpc/runbooks_adapter.py +1167 -241
  245. runbooks/vpc/tdd_red_phase_stubs.py +601 -0
  246. runbooks/vpc/test_data_loader.py +358 -0
  247. runbooks/vpc/tests/conftest.py +314 -4
  248. runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
  249. runbooks/vpc/tests/test_cost_engine.py +0 -2
  250. runbooks/vpc/topology_generator.py +326 -0
  251. runbooks/vpc/unified_scenarios.py +1297 -1124
  252. runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
  253. runbooks-1.1.6.dist-info/METADATA +327 -0
  254. runbooks-1.1.6.dist-info/RECORD +489 -0
  255. runbooks/finops/README.md +0 -414
  256. runbooks/finops/accuracy_cross_validator.py +0 -647
  257. runbooks/finops/business_cases.py +0 -950
  258. runbooks/finops/dashboard_router.py +0 -922
  259. runbooks/finops/ebs_optimizer.py +0 -973
  260. runbooks/finops/embedded_mcp_validator.py +0 -1629
  261. runbooks/finops/enhanced_dashboard_runner.py +0 -527
  262. runbooks/finops/finops_dashboard.py +0 -584
  263. runbooks/finops/finops_scenarios.py +0 -1218
  264. runbooks/finops/legacy_migration.py +0 -730
  265. runbooks/finops/multi_dashboard.py +0 -1519
  266. runbooks/finops/single_dashboard.py +0 -1113
  267. runbooks/finops/unlimited_scenarios.py +0 -393
  268. runbooks-1.1.4.dist-info/METADATA +0 -800
  269. runbooks-1.1.4.dist-info/RECORD +0 -468
  270. {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/WHEEL +0 -0
  271. {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/entry_points.txt +0 -0
  272. {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/licenses/LICENSE +0 -0
  273. {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/top_level.txt +0 -0
@@ -62,18 +62,17 @@ from time import time
62
62
 
63
63
  from ArgumentsClass import CommonArguments
64
64
  from botocore.exceptions import ClientError
65
- from colorama import Fore, init
65
+ from runbooks.common.rich_utils import console
66
66
  from Inventory_Modules import (
67
67
  display_results,
68
68
  find_references_to_security_groups2,
69
69
  find_security_groups2,
70
70
  get_all_credentials,
71
71
  )
72
- from tqdm.auto import tqdm
72
+ # Migrated to Rich.Progress - see rich_utils.py for enterprise UX standards
73
+ # from tqdm.auto import tqdm
73
74
 
74
- init()
75
75
  __version__ = "2024.09.24"
76
- ERASE_LINE = "\x1b[2K"
77
76
  begin_time = time()
78
77
 
79
78
 
@@ -387,7 +386,7 @@ def check_accounts_for_security_groups(
387
386
  logging.info(
388
387
  f"{ERASE_LINE}Finished finding security groups in account {c_account_credentials['AccountId']} in region {c_account_credentials['Region']}"
389
388
  )
390
- pbar.update()
389
+ pbar.update(pbar_task, advance=1) # Update Rich progress bar
391
390
  self.queue.task_done()
392
391
 
393
392
  ###########
@@ -406,43 +405,50 @@ def check_accounts_for_security_groups(
406
405
  # Initialize thread-safe work queue
407
406
  checkqueue = Queue()
408
407
 
409
- # Initialize progress bar for user feedback during long-running analysis
410
- pbar = tqdm(
411
- desc=f"Finding security groups from {len(fCredentialList)} locations",
412
- total=len(fCredentialList),
413
- unit=" locations",
414
- )
408
+ # Import Rich display utilities for professional progress tracking
409
+ from runbooks.common.rich_utils import create_progress_bar
410
+
411
+ # Initialize progress tracking for user feedback during long-running analysis
412
+ with create_progress_bar() as progress:
413
+ task = progress.add_task(
414
+ f"[cyan]Finding security groups from {len(fCredentialList)} locations...",
415
+ total=len(fCredentialList)
416
+ )
417
+
418
+ # Make progress object available to worker threads via global (multi-threaded pattern)
419
+ global pbar
420
+ pbar = progress
421
+ global pbar_task
422
+ pbar_task = task
423
+
424
+ # Start worker thread pool for concurrent security group analysis
425
+ for x in range(WorkerThreads):
426
+ worker = FindSecurityGroups(checkqueue)
427
+ # Daemon threads will terminate when main thread exits
428
+ # This prevents hanging if an exception occurs in main thread
429
+ worker.daemon = True
430
+ worker.start()
431
+
432
+ # Queue all credential work items for concurrent processing
433
+ for credential in fCredentialList:
434
+ logging.info(f"Connecting to account {credential['AccountId']}")
435
+ try:
436
+ # Add credential set and parameters to work queue for worker thread processing
437
+ checkqueue.put((credential, fFragment, fExact, fDefault))
438
+ except ClientError as my_Error:
439
+ # Handle credential validation errors during queue population
440
+ if "AuthFailure" in str(my_Error):
441
+ logging.error(
442
+ f"Authorization Failure accessing account {credential['AccountId']} in '{credential['Region']}' region"
443
+ )
444
+ logging.warning(f"It's possible that the region '{credential['Region']}' hasn't been opted-into")
445
+ # Continue queuing other credentials despite this failure
446
+ pass
415
447
 
416
- # Start worker thread pool for concurrent security group analysis
417
- for x in range(WorkerThreads):
418
- worker = FindSecurityGroups(checkqueue)
419
- # Daemon threads will terminate when main thread exits
420
- # This prevents hanging if an exception occurs in main thread
421
- worker.daemon = True
422
- worker.start()
423
-
424
- # Queue all credential work items for concurrent processing
425
- for credential in fCredentialList:
426
- logging.info(f"Connecting to account {credential['AccountId']}")
427
- try:
428
- # Add credential set and parameters to work queue for worker thread processing
429
- checkqueue.put((credential, fFragment, fExact, fDefault))
430
- except ClientError as my_Error:
431
- # Handle credential validation errors during queue population
432
- if "AuthFailure" in str(my_Error):
433
- logging.error(
434
- f"Authorization Failure accessing account {credential['AccountId']} in '{credential['Region']}' region"
435
- )
436
- logging.warning(f"It's possible that the region '{credential['Region']}' hasn't been opted-into")
437
- # Continue queuing other credentials despite this failure
438
- pass
439
-
440
- # Wait for all queued work items to be processed by worker threads
441
- # This blocks until all worker threads call task_done()
442
- checkqueue.join()
443
-
444
- # Clean up progress bar
445
- pbar.close()
448
+ # Wait for all queued work items to be processed by worker threads
449
+ # This blocks until all worker threads call task_done()
450
+ checkqueue.join()
451
+ # Progress bar auto-closes when exiting context manager
446
452
 
447
453
  return AllSecurityGroups
448
454
 
@@ -659,7 +665,7 @@ if __name__ == "__main__":
659
665
  print(f"Data has been saved to {saved_filename}")
660
666
  if pTiming:
661
667
  print(ERASE_LINE)
662
- print(f"{Fore.GREEN}This script took {time() - begin_time:.2f} seconds{Fore.RESET}")
668
+ print(f"[green]This script took {time() - begin_time:.2f} seconds")
663
669
 
664
670
  print(
665
671
  f"We found {len(AllSecurityGroups)} {'default ' if pDefault else ''}security group{'' if len(AllSecurityGroups) == 1 else 's'} across {len(AccountList)} accounts and {len(RegionList)} regions"
@@ -76,10 +76,9 @@ import boto3
76
76
  import Inventory_Modules
77
77
  from ArgumentsClass import CommonArguments
78
78
  from botocore.exceptions import ClientError, CredentialRetrievalError, InvalidConfigError
79
- from colorama import init
79
+ # colorama removed - migrated to Rich
80
80
 
81
81
  # Initialize colorama for cross-platform colored terminal output
82
- init()
83
82
 
84
83
  __version__ = "2023.05.31"
85
84
 
@@ -101,7 +100,6 @@ logging.basicConfig(
101
100
 
102
101
  ##########################
103
102
  # Terminal control and operational configuration constants
104
- ERASE_LINE = "\x1b[2K" # ANSI escape sequence for clearing terminal line during progress display
105
103
  SkipProfiles = ["default"] # Profile exclusion list for organizational Landing Zone discovery
106
104
 
107
105
  # Configure AWS profile discovery strategy based on user input
@@ -129,7 +127,7 @@ ALZProfiles = [] # Initialize Landing Zone profile collection for discovered Ma
129
127
 
130
128
  for profile in AllProfiles:
131
129
  # Display real-time progress during profile analysis with terminal line clearing
132
- print(f"{ERASE_LINE}Checking profile: {profile}", end="\r")
130
+ print(f"Checking profile: {profile}", end="\r")
133
131
 
134
132
  try:
135
133
  # Analyze current profile to determine if it represents an AWS Landing Zone Management Account
@@ -164,7 +162,7 @@ for profile in AllProfiles:
164
162
  pass
165
163
 
166
164
  # Clear progress display and initialize tabular output formatting for Landing Zone inventory
167
- print(ERASE_LINE)
165
+ console.print()
168
166
  fmt = "%-20s %-13s %-15s %-35s %-21s" # Column formatting for structured Landing Zone data display
169
167
  print(fmt % ("Profile", "Account", "Region", "ALZ Stack Name", "ALZ Version"))
170
168
  print(fmt % ("-------", "-------", "------", "--------------", "-----------"))
@@ -194,7 +192,7 @@ for item in ALZProfiles:
194
192
  )
195
193
 
196
194
  # Display comprehensive operational summary with discovery metrics
197
- print(ERASE_LINE)
195
+ console.print()
198
196
  print(f"Checked {len(AllProfiles)} accounts/ Orgs. Found {len(ALZProfiles)} ALZs")
199
197
  print()
200
198
  print("Thank you for using this script.")
@@ -93,13 +93,11 @@ from account_class import aws_acct_access
93
93
  from ArgumentsClass import CommonArguments
94
94
  from botocore.config import Config
95
95
  from botocore.exceptions import ClientError
96
- from colorama import Fore, init
96
+ from runbooks.common.rich_utils import console
97
97
  from Inventory_Modules import RemoveCoreAccounts, display_results, get_all_credentials, get_regions3
98
98
 
99
99
  # Initialize colorama for cross-platform colored terminal output
100
- init()
101
100
  __version__ = "2024.03.10"
102
- ERASE_LINE = "\x1b[2K" # ANSI escape sequence for clearing terminal line during progress display
103
101
  begin_time = time() # Script execution timing for performance monitoring
104
102
  sleep_interval = 5 # Default wait interval for CloudWatch Logs query processing
105
103
 
@@ -305,13 +303,13 @@ def setup_auth_accounts_and_regions(fProfile: str) -> (aws_acct_access, list, li
305
303
 
306
304
  # Display comprehensive operational context for user confirmation and audit logging
307
305
  print(f"You asked to sum flow log data")
308
- print(f"\tin these accounts: {Fore.RED}{AccountList}{Fore.RESET}")
309
- print(f"\tin these regions: {Fore.RED}{RegionList}{Fore.RESET}")
306
+ print(f"\tin these accounts: [red]{AccountList}")
307
+ print(f"\tin these regions: [red]{RegionList}")
310
308
  print(f"\tFrom: {pStartDate} until {pEndDate}")
311
309
 
312
310
  # Display account exclusion information for operational transparency
313
311
  if pSkipAccounts is not None:
314
- print(f"\tWhile skipping these accounts: {Fore.RED}{pSkipAccounts}{Fore.RESET}")
312
+ print(f"\tWhile skipping these accounts: [red]{pSkipAccounts}")
315
313
 
316
314
  return aws_acct, AccountList, RegionList
317
315
 
@@ -1040,13 +1038,13 @@ def get_cw_query_results(fquery_requests: list) -> list[dict]:
1040
1038
  # Implement timeout protection for long-running queries
1041
1039
  if waited_seconds_total > (SpannedDaysChecked * 5):
1042
1040
  print(
1043
- f"{ERASE_LINE}Query is still running... Waited {waited_seconds_total} seconds already, we'll have to check manually later. "
1041
+ f"Query is still running... Waited {waited_seconds_total} seconds already, we'll have to check manually later. "
1044
1042
  )
1045
1043
  break
1046
1044
 
1047
1045
  # Display real-time progress for query execution monitoring
1048
1046
  print(
1049
- f"{ERASE_LINE}Query for vpc {query['VPCId']} in account {query['AccountId']} in region {query['Region']} is still running... It's been {waited_seconds_total} seconds so far",
1047
+ f"Query for vpc {query['VPCId']} in account {query['AccountId']} in region {query['Region']} is still running... It's been {waited_seconds_total} seconds so far",
1050
1048
  end="\r",
1051
1049
  )
1052
1050
 
@@ -1181,7 +1179,7 @@ if __name__ == "__main__":
1181
1179
  f"Account {credential['AccountId']} was successfully connected via role {credential.get('Role', pAccessRole)} from {aws_acct.acct_number}"
1182
1180
  )
1183
1181
  print(
1184
- f"{ERASE_LINE}Checking account {Fore.BLUE}{credential['AccountId']}{Fore.RESET} in region {Fore.BLUE}{credential['Region']}{Fore.RESET}...",
1182
+ f"Checking account [blue]{credential['AccountId']} in region [blue]{credential['Region']}...",
1185
1183
  end="\r",
1186
1184
  )
1187
1185
  """
@@ -25,22 +25,28 @@ from .mcp_inventory_validator import create_inventory_mcp_validator
25
25
 
26
26
 
27
27
  @click.command()
28
- @click.option('--profile', help='AWS profile name (takes precedence over environment variables)')
29
- @click.option('--resource-types', multiple=True,
30
- type=click.Choice(['ec2', 's3', 'rds', 'lambda', 'vpc', 'iam', 'cloudformation']),
31
- default=['ec2', 's3', 'vpc'],
32
- help='Resource types to validate')
33
- @click.option('--test-mode', is_flag=True, default=True,
34
- help='Run in test mode with sample data')
35
- @click.option('--real-validation', is_flag=True, default=False,
36
- help='Run validation against real AWS APIs (requires valid profiles)')
28
+ @click.option("--profile", help="AWS profile name (takes precedence over environment variables)")
29
+ @click.option(
30
+ "--resource-types",
31
+ multiple=True,
32
+ type=click.Choice(["ec2", "s3", "rds", "lambda", "vpc", "iam", "cloudformation"]),
33
+ default=["ec2", "s3", "vpc"],
34
+ help="Resource types to validate",
35
+ )
36
+ @click.option("--test-mode", is_flag=True, default=True, help="Run in test mode with sample data")
37
+ @click.option(
38
+ "--real-validation",
39
+ is_flag=True,
40
+ default=False,
41
+ help="Run validation against real AWS APIs (requires valid profiles)",
42
+ )
37
43
  def validate_inventory_mcp(profile: Optional[str], resource_types: List[str], test_mode: bool, real_validation: bool):
38
44
  """
39
45
  Test inventory MCP validation functionality.
40
-
46
+
41
47
  This command demonstrates inventory MCP validation integration
42
48
  following proven enterprise patterns from FinOps module success.
43
-
49
+
44
50
  Examples:
45
51
  runbooks inventory validate-mcp --profile my-profile --resource-types ec2,s3
46
52
  runbooks inventory validate-mcp --test-mode --resource-types ec2,vpc,rds
@@ -48,7 +54,9 @@ def validate_inventory_mcp(profile: Optional[str], resource_types: List[str], te
48
54
  """
49
55
  try:
50
56
  console.print(f"[blue]🔍 Inventory MCP Validation Test[/blue]")
51
- console.print(f"[dim]Profile: {profile or 'environment fallback'} | Resources: {', '.join(resource_types)} | Test mode: {test_mode}[/dim]")
57
+ console.print(
58
+ f"[dim]Profile: {profile or 'environment fallback'} | Resources: {', '.join(resource_types)} | Test mode: {test_mode}[/dim]"
59
+ )
52
60
 
53
61
  # Apply profile priority system following proven patterns
54
62
  operational_profile = get_profile_for_operation("operational", profile)
@@ -61,7 +69,7 @@ def validate_inventory_mcp(profile: Optional[str], resource_types: List[str], te
61
69
  if test_mode and not real_validation:
62
70
  # Test mode: Use sample data to demonstrate validation
63
71
  print_info("Running test mode with sample inventory data")
64
-
72
+
65
73
  # Create sample inventory data for testing
66
74
  sample_inventory = {
67
75
  operational_profile: {
@@ -72,89 +80,83 @@ def validate_inventory_mcp(profile: Optional[str], resource_types: List[str], te
72
80
  "lambda": 12,
73
81
  "vpc": 4,
74
82
  "iam": 25,
75
- "cloudformation": 6
83
+ "cloudformation": 6,
76
84
  },
77
- "regions": ["us-east-1", "us-west-2"]
85
+ "regions": ["us-east-1", "us-west-2"],
78
86
  }
79
87
  }
80
-
88
+
81
89
  # Filter to requested resource types
82
90
  filtered_inventory = {
83
91
  operational_profile: {
84
92
  "resource_counts": {
85
- rt: sample_inventory[operational_profile]["resource_counts"].get(rt, 0)
86
- for rt in resource_types
93
+ rt: sample_inventory[operational_profile]["resource_counts"].get(rt, 0) for rt in resource_types
87
94
  },
88
- "regions": sample_inventory[operational_profile]["regions"]
95
+ "regions": sample_inventory[operational_profile]["regions"],
89
96
  }
90
97
  }
91
-
92
- print_info(f"Testing validation with sample resource counts: {filtered_inventory[operational_profile]['resource_counts']}")
93
-
98
+
99
+ print_info(
100
+ f"Testing validation with sample resource counts: {filtered_inventory[operational_profile]['resource_counts']}"
101
+ )
102
+
94
103
  # Note: In test mode, this will compare sample data against real AWS APIs
95
104
  # This demonstrates the validation mechanism without requiring mock data
96
105
  validation_results = validator.validate_inventory_data(filtered_inventory)
97
-
106
+
98
107
  elif real_validation:
99
108
  # Real validation mode: Requires actual inventory collection
100
109
  print_warning("Real validation mode requires actual inventory collection")
101
110
  print_info("This would typically be called from the main inventory collector")
102
-
111
+
103
112
  # For demonstration, we'll validate empty inventory (should show 0 vs actual counts)
104
113
  empty_inventory = {
105
- operational_profile: {
106
- "resource_counts": {rt: 0 for rt in resource_types},
107
- "regions": ["us-east-1"]
108
- }
114
+ operational_profile: {"resource_counts": {rt: 0 for rt in resource_types}, "regions": ["us-east-1"]}
109
115
  }
110
-
116
+
111
117
  print_info("Validating empty inventory against real AWS APIs (demonstrates detection capability)")
112
118
  validation_results = validator.validate_inventory_data(empty_inventory)
113
-
119
+
114
120
  else:
115
121
  # Resource count validation only
116
122
  print_info("Running resource count validation test")
117
-
118
- sample_counts = {
119
- "ec2": 10,
120
- "s3": 5,
121
- "vpc": 2
122
- }
123
-
123
+
124
+ sample_counts = {"ec2": 10, "s3": 5, "vpc": 2}
125
+
124
126
  # Filter to requested resource types
125
127
  test_counts = {rt: sample_counts.get(rt, 0) for rt in resource_types if rt in sample_counts}
126
-
128
+
127
129
  validation_results = validator.validate_resource_counts(test_counts)
128
130
 
129
131
  # Display results summary
130
132
  console.print(f"\n[bright_cyan]📊 Validation Test Results Summary[/]")
131
-
133
+
132
134
  if isinstance(validation_results, dict):
133
135
  if "total_accuracy" in validation_results:
134
136
  accuracy = validation_results.get("total_accuracy", 0)
135
137
  passed = validation_results.get("passed_validation", False)
136
-
138
+
137
139
  if passed:
138
140
  print_success(f"✅ Test validation completed: {accuracy:.1f}% accuracy")
139
141
  else:
140
142
  print_warning(f"⚠️ Test validation: {accuracy:.1f}% accuracy (target: ≥99.5%)")
141
-
143
+
142
144
  profiles_validated = validation_results.get("profiles_validated", 0)
143
145
  console.print(f"[dim]Profiles validated: {profiles_validated}[/dim]")
144
-
146
+
145
147
  # Show resource summary if available
146
148
  resource_summary = validation_results.get("resource_validation_summary", {})
147
149
  if resource_summary:
148
150
  console.print(f"[dim]Resource types validated: {len(resource_summary)}[/dim]")
149
-
151
+
150
152
  elif "validated_count" in validation_results:
151
153
  validated_count = validation_results.get("validated_count", 0)
152
154
  passed_count = validation_results.get("passed_count", 0)
153
155
  print_info(f"Resource count validation: {passed_count}/{validated_count} passed")
154
-
156
+
155
157
  else:
156
158
  print_info("Validation completed - see detailed output above")
157
-
159
+
158
160
  # Integration guidance
159
161
  console.print(f"\n[bright_cyan]💡 Integration Information[/]")
160
162
  console.print(f"[dim]This MCP validator is automatically integrated into:[/dim]")
@@ -168,4 +170,4 @@ def validate_inventory_mcp(profile: Optional[str], resource_types: List[str], te
168
170
 
169
171
 
170
172
  if __name__ == "__main__":
171
- validate_inventory_mcp()
173
+ validate_inventory_mcp()