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
@@ -86,7 +86,9 @@ def setup_logging(debug: bool = False, log_file: Optional[str] = None) -> None:
86
86
  log_path.parent.mkdir(parents=True, exist_ok=True)
87
87
  file_handler = logging.FileHandler(log_path)
88
88
  file_handler.setLevel(log_level_value)
89
- formatter = logging.Formatter("%(asctime)s | %(levelname)-8s | %(name)s:%(funcName)s:%(lineno)d - %(message)s")
89
+ formatter = logging.Formatter(
90
+ "%(asctime)s | %(levelname)-8s | %(name)s:%(funcName)s:%(lineno)d - %(message)s"
91
+ )
90
92
  file_handler.setFormatter(formatter)
91
93
  logging.getLogger().addHandler(file_handler)
92
94
 
@@ -94,7 +96,7 @@ def setup_logging(debug: bool = False, log_file: Optional[str] = None) -> None:
94
96
  def setup_enhanced_logging(log_level: str = "INFO", json_output: bool = False, debug: bool = False) -> None:
95
97
  """
96
98
  Configure enhanced enterprise logging with Rich CLI integration and user-type specific output.
97
-
99
+
98
100
  This function initializes the global enhanced logger that provides:
99
101
  - User-type specific formatting (DEBUG=tech, INFO=standard, WARNING=business, ERROR=all)
100
102
  - Rich CLI integration with beautiful formatting
@@ -102,7 +104,7 @@ def setup_enhanced_logging(log_level: str = "INFO", json_output: bool = False, d
102
104
  - AWS API tracing for technical users
103
105
  - Business recommendations for warning level
104
106
  - Clear error solutions for all users
105
-
107
+
106
108
  Args:
107
109
  log_level: Log level (DEBUG, INFO, WARNING, ERROR)
108
110
  json_output: Enable structured JSON output for programmatic use
@@ -111,41 +113,36 @@ def setup_enhanced_logging(log_level: str = "INFO", json_output: bool = False, d
111
113
  try:
112
114
  from runbooks.enterprise.logging import configure_enterprise_logging, get_context_logger
113
115
  from runbooks.common.rich_utils import get_context_aware_console
114
-
116
+
115
117
  # Override level if debug flag is set (backward compatibility)
116
118
  if debug:
117
119
  log_level = "DEBUG"
118
-
120
+
119
121
  # Get context-aware console for Rich CLI integration
120
122
  try:
121
123
  rich_console = get_context_aware_console()
122
124
  except ImportError:
123
125
  rich_console = None
124
-
126
+
125
127
  # Configure global enhanced logger
126
- logger = configure_enterprise_logging(
127
- level=log_level,
128
- rich_console=rich_console,
129
- json_output=json_output
130
- )
131
-
128
+ logger = configure_enterprise_logging(level=log_level, rich_console=rich_console, json_output=json_output)
129
+
132
130
  # Log initialization success with user-type appropriate message
133
131
  if log_level == "DEBUG":
134
132
  logger.debug_tech(
135
133
  "Enhanced logging initialized with Rich CLI integration",
136
134
  aws_api={"service": "logging", "operation": "initialize"},
137
- duration=0.001
135
+ duration=0.001,
138
136
  )
139
137
  elif log_level == "INFO":
140
138
  logger.info_standard("CloudOps Runbooks logging initialized")
141
139
  elif log_level == "WARNING":
142
140
  logger.warning_business(
143
- "Business-focused logging enabled",
144
- recommendation="Use --log-level INFO for standard operations"
141
+ "Business-focused logging enabled", recommendation="Use --log-level INFO for standard operations"
145
142
  )
146
143
  else:
147
144
  logger.error_all("Minimal error-only logging enabled")
148
-
145
+
149
146
  except ImportError as e:
150
147
  # Fallback to standard logging if enhanced logging not available
151
148
  setup_logging(debug=debug)
@@ -272,7 +269,7 @@ __all__ = [
272
269
  "configure_logger",
273
270
  # Version management
274
271
  "check_pyproject_version",
275
- "get_all_module_versions",
272
+ "get_all_module_versions",
276
273
  "print_version_report",
277
274
  "validate_version_consistency",
278
275
  "VersionDriftError",
runbooks/utils/logger.py CHANGED
@@ -1,4 +1,6 @@
1
1
  import logging
2
+ import os
3
+ import tempfile
2
4
 
3
5
 
4
6
  ## ==============================
@@ -24,8 +26,11 @@ def configure_logger(module_name: str) -> logging.Logger:
24
26
  console_handler = logging.StreamHandler()
25
27
  console_handler.setFormatter(formatter)
26
28
 
27
- ## File Handler
28
- file_handler = logging.FileHandler(f"{module_name}.log")
29
+ ## File Handler - Fix: Use user directory instead of root
30
+ log_dir = os.path.expanduser("~/.runbooks/logs")
31
+ os.makedirs(log_dir, exist_ok=True)
32
+ log_file = os.path.join(log_dir, f"{module_name.replace('.', '_')}.log")
33
+ file_handler = logging.FileHandler(log_file)
29
34
  file_handler.setFormatter(formatter)
30
35
 
31
36
  ## Add handlers if not already added
@@ -17,59 +17,61 @@ CENTRAL_VERSION = "latest version" # Must match runbooks.__init__.__version__
17
17
 
18
18
  class VersionDriftError(Exception):
19
19
  """Raised when version drift is detected in CI/CD pipeline."""
20
+
20
21
  pass
21
22
 
22
23
 
23
24
  def get_all_module_versions() -> Dict[str, str]:
24
25
  """
25
26
  Collect versions from all runbooks modules.
26
-
27
+
27
28
  Returns:
28
29
  Dict mapping module names to their reported versions
29
30
  """
30
31
  modules = [
31
32
  "runbooks",
32
33
  "runbooks.finops",
33
- "runbooks.operate",
34
+ "runbooks.operate",
34
35
  "runbooks.security",
35
36
  "runbooks.cfat",
36
37
  "runbooks.inventory",
37
38
  "runbooks.remediation",
38
39
  "runbooks.vpc",
39
40
  "runbooks.sre",
40
- "runbooks.cloudops"
41
+ "runbooks.cloudops",
41
42
  ]
42
-
43
+
43
44
  versions = {}
44
-
45
+
45
46
  for module_name in modules:
46
47
  try:
47
48
  # Import the module
48
49
  module = importlib.import_module(module_name)
49
-
50
+
50
51
  # Get version
51
- if hasattr(module, '__version__'):
52
+ if hasattr(module, "__version__"):
52
53
  versions[module_name] = module.__version__
53
54
  else:
54
55
  versions[module_name] = "No version found"
55
-
56
+
56
57
  except ImportError as e:
57
58
  versions[module_name] = f"Import error: {e}"
58
59
  except Exception as e:
59
60
  versions[module_name] = f"Error: {e}"
60
-
61
+
61
62
  return versions
62
63
 
63
64
 
64
65
  def check_pyproject_version() -> Tuple[bool, str, str]:
65
66
  """
66
67
  Check if pyproject.toml version matches centralized version.
67
-
68
+
68
69
  Returns:
69
70
  Tuple of (is_matching, pyproject_version, central_version)
70
71
  """
71
72
  try:
72
73
  from importlib.metadata import version as _pkg_version
74
+
73
75
  pyproject_version = _pkg_version("runbooks")
74
76
  return (pyproject_version == CENTRAL_VERSION, pyproject_version, CENTRAL_VERSION)
75
77
  except Exception as e:
@@ -79,13 +81,13 @@ def check_pyproject_version() -> Tuple[bool, str, str]:
79
81
  def validate_version_consistency(strict: bool = False) -> Dict[str, any]:
80
82
  """
81
83
  Validate version consistency across all modules.
82
-
84
+
83
85
  Args:
84
86
  strict: If True, raise VersionDriftError on inconsistencies
85
-
87
+
86
88
  Returns:
87
89
  Dictionary with validation results
88
-
90
+
89
91
  Raises:
90
92
  VersionDriftError: If strict=True and inconsistencies found
91
93
  """
@@ -94,25 +96,25 @@ def validate_version_consistency(strict: bool = False) -> Dict[str, any]:
94
96
  "module_versions": get_all_module_versions(),
95
97
  "pyproject_check": check_pyproject_version(),
96
98
  "inconsistencies": [],
97
- "all_consistent": True
99
+ "all_consistent": True,
98
100
  }
99
-
101
+
100
102
  # Check module versions
101
103
  for module_name, module_version in results["module_versions"].items():
102
104
  if module_name == "runbooks":
103
105
  continue # Skip root module
104
-
106
+
105
107
  if isinstance(module_version, str) and not module_version.startswith(("Error:", "No version", "Import error:")):
106
108
  if module_version != CENTRAL_VERSION:
107
109
  inconsistency = {
108
110
  "module": module_name,
109
111
  "expected": CENTRAL_VERSION,
110
112
  "found": module_version,
111
- "type": "module_version_mismatch"
113
+ "type": "module_version_mismatch",
112
114
  }
113
115
  results["inconsistencies"].append(inconsistency)
114
116
  results["all_consistent"] = False
115
-
117
+
116
118
  # Check pyproject.toml
117
119
  is_matching, pyproject_version, _ = results["pyproject_check"]
118
120
  if not is_matching and not pyproject_version.startswith("Error:"):
@@ -120,18 +122,18 @@ def validate_version_consistency(strict: bool = False) -> Dict[str, any]:
120
122
  "module": "pyproject.toml",
121
123
  "expected": CENTRAL_VERSION,
122
124
  "found": pyproject_version,
123
- "type": "pyproject_version_mismatch"
125
+ "type": "pyproject_version_mismatch",
124
126
  }
125
127
  results["inconsistencies"].append(inconsistency)
126
128
  results["all_consistent"] = False
127
-
129
+
128
130
  # Raise error in strict mode
129
131
  if strict and not results["all_consistent"]:
130
132
  error_msg = f"Version drift detected:\n"
131
133
  for inc in results["inconsistencies"]:
132
134
  error_msg += f" - {inc['module']}: expected {inc['expected']}, got {inc['found']}\n"
133
135
  raise VersionDriftError(error_msg)
134
-
136
+
135
137
  return results
136
138
 
137
139
 
@@ -141,23 +143,25 @@ def print_version_report() -> None:
141
143
  from rich.console import Console
142
144
  from rich.table import Table
143
145
  from rich.panel import Panel
144
-
146
+
145
147
  console = Console()
146
148
  validation_results = validate_version_consistency()
147
-
149
+
148
150
  # Header
149
- console.print(Panel(
150
- f"[bold blue]Version Management Report[/bold blue]\n"
151
- f"Central Version: [green]{validation_results['central_version']}[/green]",
152
- title="Runbooks Version Validation"
153
- ))
154
-
151
+ console.print(
152
+ Panel(
153
+ f"[bold blue]Version Management Report[/bold blue]\n"
154
+ f"Central Version: [green]{validation_results['central_version']}[/green]",
155
+ title="Runbooks Version Validation",
156
+ )
157
+ )
158
+
155
159
  # Module versions table
156
160
  table = Table(title="Module Version Status")
157
161
  table.add_column("Module", style="cyan")
158
162
  table.add_column("Version", style="green")
159
163
  table.add_column("Status", style="magenta")
160
-
164
+
161
165
  for module_name, version in validation_results["module_versions"].items():
162
166
  if isinstance(version, str) and version.startswith(("Error:", "No version", "Import error:")):
163
167
  status = "[red]Error[/red]"
@@ -168,18 +172,18 @@ def print_version_report() -> None:
168
172
  else:
169
173
  status = "[red]✗ Mismatch[/red]"
170
174
  version_display = f"[red]{version}[/red]"
171
-
175
+
172
176
  table.add_row(module_name, version_display, status)
173
-
177
+
174
178
  console.print(table)
175
-
179
+
176
180
  # Pyproject.toml check
177
181
  is_matching, pyproject_version, central_version = validation_results["pyproject_check"]
178
182
  if is_matching:
179
183
  console.print("[green]✓ pyproject.toml version matches central version[/green]")
180
184
  else:
181
185
  console.print(f"[red]✗ pyproject.toml version mismatch: {pyproject_version} vs {central_version}[/red]")
182
-
186
+
183
187
  # Overall status
184
188
  if validation_results["all_consistent"]:
185
189
  console.print("\n[bold green]✓ All versions are consistent[/bold green]")
@@ -187,24 +191,24 @@ def print_version_report() -> None:
187
191
  console.print("\n[bold red]✗ Version inconsistencies detected[/bold red]")
188
192
  for inc in validation_results["inconsistencies"]:
189
193
  console.print(f" - {inc['module']}: expected {inc['expected']}, got {inc['found']}")
190
-
194
+
191
195
  except ImportError:
192
196
  # Fallback without Rich
193
197
  validation_results = validate_version_consistency()
194
-
198
+
195
199
  print(f"=== Version Management Report ===")
196
200
  print(f"Central Version: {validation_results['central_version']}")
197
201
  print()
198
-
202
+
199
203
  print("Module Versions:")
200
204
  for module_name, version in validation_results["module_versions"].items():
201
205
  status = "OK" if version == validation_results["central_version"] else "MISMATCH"
202
206
  print(f" {module_name}: {version} ({status})")
203
-
207
+
204
208
  is_matching, pyproject_version, _ = validation_results["pyproject_check"]
205
209
  pyproject_status = "OK" if is_matching else "MISMATCH"
206
210
  print(f" pyproject.toml: {pyproject_version} ({pyproject_status})")
207
-
211
+
208
212
  if validation_results["all_consistent"]:
209
213
  print("\n✓ All versions are consistent")
210
214
  else:
@@ -216,19 +220,18 @@ def print_version_report() -> None:
216
220
  def cli_main():
217
221
  """CLI entry point for version validation."""
218
222
  import argparse
219
-
223
+
220
224
  parser = argparse.ArgumentParser(description="Validate runbooks version consistency")
221
- parser.add_argument("--strict", action="store_true",
222
- help="Exit with error code if inconsistencies found")
223
-
225
+ parser.add_argument("--strict", action="store_true", help="Exit with error code if inconsistencies found")
226
+
224
227
  args = parser.parse_args()
225
-
228
+
226
229
  try:
227
230
  print_version_report()
228
-
231
+
229
232
  if args.strict:
230
233
  validate_version_consistency(strict=True)
231
-
234
+
232
235
  except VersionDriftError as e:
233
236
  print(f"\nERROR: {e}")
234
237
  sys.exit(1)
@@ -238,4 +241,4 @@ def cli_main():
238
241
 
239
242
 
240
243
  if __name__ == "__main__":
241
- cli_main()
244
+ cli_main()
@@ -15,16 +15,16 @@ ENHANCED CAPABILITIES:
15
15
  from .mcp_validator import MCPValidator, ValidationReport, ValidationResult, ValidationStatus
16
16
  from .comprehensive_2way_validator import (
17
17
  Comprehensive2WayValidator,
18
- ValidationDiscrepancy,
19
- Comprehensive2WayValidationResult
18
+ ValidationDiscrepancy,
19
+ Comprehensive2WayValidationResult,
20
20
  )
21
21
 
22
22
  __all__ = [
23
- "MCPValidator",
24
- "ValidationResult",
25
- "ValidationReport",
23
+ "MCPValidator",
24
+ "ValidationResult",
25
+ "ValidationReport",
26
26
  "ValidationStatus",
27
27
  "Comprehensive2WayValidator",
28
28
  "ValidationDiscrepancy",
29
- "Comprehensive2WayValidationResult"
29
+ "Comprehensive2WayValidationResult",
30
30
  ]
@@ -88,7 +88,9 @@ def validate_all(tolerance: float, performance_target: float, save_report: bool,
88
88
 
89
89
 
90
90
  @cli.command()
91
- @click.option("--profile", default=lambda: os.getenv("BILLING_PROFILE", "default-billing-profile"), help="AWS billing profile")
91
+ @click.option(
92
+ "--profile", default=lambda: os.getenv("BILLING_PROFILE", "default-billing-profile"), help="AWS billing profile"
93
+ )
92
94
  @click.option("--tolerance", default=5.0, help="Cost variance tolerance percentage")
93
95
  def validate_costs(profile: str, tolerance: float):
94
96
  """Validate Cost Explorer data accuracy."""
@@ -140,7 +142,11 @@ def validate_costs(profile: str, tolerance: float):
140
142
 
141
143
 
142
144
  @cli.command()
143
- @click.option("--profile", default=lambda: os.getenv("MANAGEMENT_PROFILE", "default-management-profile"), help="AWS management profile")
145
+ @click.option(
146
+ "--profile",
147
+ default=lambda: os.getenv("MANAGEMENT_PROFILE", "default-management-profile"),
148
+ help="AWS management profile",
149
+ )
144
150
  def validate_organizations(profile: str):
145
151
  """Validate Organizations API data accuracy."""
146
152
 
@@ -322,7 +328,7 @@ def status():
322
328
 
323
329
  # Check MCP integration
324
330
  try:
325
- from notebooks.mcp_integration import MCPIntegrationManager
331
+ from runbooks.mcp import MCPIntegrationManager
326
332
 
327
333
  table.add_row("MCP Integration", "[green]✅ Available[/green]", "Ready for validation")
328
334
  except ImportError: