runbooks 1.1.4__py3-none-any.whl → 1.1.5__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 (228) 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 +138 -35
  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 +11 -0
  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 +63 -74
  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 +201 -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/cloud_foundations_integration.py +144 -149
  113. runbooks/inventory/collectors/aws_comprehensive.py +1 -1
  114. runbooks/inventory/collectors/aws_networking.py +109 -99
  115. runbooks/inventory/collectors/base.py +4 -0
  116. runbooks/inventory/core/collector.py +495 -313
  117. runbooks/inventory/drift_detection_cli.py +69 -96
  118. runbooks/inventory/inventory_mcp_cli.py +48 -46
  119. runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
  120. runbooks/inventory/mcp_inventory_validator.py +549 -465
  121. runbooks/inventory/mcp_vpc_validator.py +359 -442
  122. runbooks/inventory/organizations_discovery.py +55 -51
  123. runbooks/inventory/rich_inventory_display.py +33 -32
  124. runbooks/inventory/unified_validation_engine.py +278 -251
  125. runbooks/inventory/vpc_analyzer.py +732 -695
  126. runbooks/inventory/vpc_architecture_validator.py +293 -348
  127. runbooks/inventory/vpc_dependency_analyzer.py +382 -378
  128. runbooks/inventory/vpc_flow_analyzer.py +1 -1
  129. runbooks/main.py +49 -34
  130. runbooks/main_final.py +91 -60
  131. runbooks/main_minimal.py +22 -10
  132. runbooks/main_optimized.py +131 -100
  133. runbooks/main_ultra_minimal.py +7 -2
  134. runbooks/mcp/__init__.py +36 -0
  135. runbooks/mcp/integration.py +679 -0
  136. runbooks/monitoring/performance_monitor.py +9 -4
  137. runbooks/operate/dynamodb_operations.py +3 -1
  138. runbooks/operate/ec2_operations.py +145 -137
  139. runbooks/operate/iam_operations.py +146 -152
  140. runbooks/operate/networking_cost_heatmap.py +29 -8
  141. runbooks/operate/rds_operations.py +223 -254
  142. runbooks/operate/s3_operations.py +107 -118
  143. runbooks/operate/vpc_operations.py +646 -616
  144. runbooks/remediation/base.py +1 -1
  145. runbooks/remediation/commons.py +10 -7
  146. runbooks/remediation/commvault_ec2_analysis.py +70 -66
  147. runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
  148. runbooks/remediation/multi_account.py +24 -21
  149. runbooks/remediation/rds_snapshot_list.py +86 -60
  150. runbooks/remediation/remediation_cli.py +92 -146
  151. runbooks/remediation/universal_account_discovery.py +83 -79
  152. runbooks/remediation/workspaces_list.py +46 -41
  153. runbooks/security/__init__.py +19 -0
  154. runbooks/security/assessment_runner.py +1150 -0
  155. runbooks/security/baseline_checker.py +812 -0
  156. runbooks/security/cloudops_automation_security_validator.py +509 -535
  157. runbooks/security/compliance_automation_engine.py +17 -17
  158. runbooks/security/config/__init__.py +2 -2
  159. runbooks/security/config/compliance_config.py +50 -50
  160. runbooks/security/config_template_generator.py +63 -76
  161. runbooks/security/enterprise_security_framework.py +1 -1
  162. runbooks/security/executive_security_dashboard.py +519 -508
  163. runbooks/security/multi_account_security_controls.py +959 -1210
  164. runbooks/security/real_time_security_monitor.py +422 -444
  165. runbooks/security/security_baseline_tester.py +1 -1
  166. runbooks/security/security_cli.py +143 -112
  167. runbooks/security/test_2way_validation.py +439 -0
  168. runbooks/security/two_way_validation_framework.py +852 -0
  169. runbooks/sre/production_monitoring_framework.py +167 -177
  170. runbooks/tdd/__init__.py +15 -0
  171. runbooks/tdd/cli.py +1071 -0
  172. runbooks/utils/__init__.py +14 -17
  173. runbooks/utils/logger.py +7 -2
  174. runbooks/utils/version_validator.py +50 -47
  175. runbooks/validation/__init__.py +6 -6
  176. runbooks/validation/cli.py +9 -3
  177. runbooks/validation/comprehensive_2way_validator.py +745 -704
  178. runbooks/validation/mcp_validator.py +906 -228
  179. runbooks/validation/terraform_citations_validator.py +104 -115
  180. runbooks/validation/terraform_drift_detector.py +447 -451
  181. runbooks/vpc/README.md +617 -0
  182. runbooks/vpc/__init__.py +8 -1
  183. runbooks/vpc/analyzer.py +577 -0
  184. runbooks/vpc/cleanup_wrapper.py +476 -413
  185. runbooks/vpc/cli_cloudtrail_commands.py +339 -0
  186. runbooks/vpc/cli_mcp_validation_commands.py +480 -0
  187. runbooks/vpc/cloudtrail_audit_integration.py +717 -0
  188. runbooks/vpc/config.py +92 -97
  189. runbooks/vpc/cost_engine.py +411 -148
  190. runbooks/vpc/cost_explorer_integration.py +553 -0
  191. runbooks/vpc/cross_account_session.py +101 -106
  192. runbooks/vpc/enhanced_mcp_validation.py +917 -0
  193. runbooks/vpc/eni_gate_validator.py +961 -0
  194. runbooks/vpc/heatmap_engine.py +185 -160
  195. runbooks/vpc/mcp_no_eni_validator.py +680 -639
  196. runbooks/vpc/nat_gateway_optimizer.py +358 -0
  197. runbooks/vpc/networking_wrapper.py +15 -8
  198. runbooks/vpc/pdca_remediation_planner.py +528 -0
  199. runbooks/vpc/performance_optimized_analyzer.py +219 -231
  200. runbooks/vpc/runbooks_adapter.py +1167 -241
  201. runbooks/vpc/tdd_red_phase_stubs.py +601 -0
  202. runbooks/vpc/test_data_loader.py +358 -0
  203. runbooks/vpc/tests/conftest.py +314 -4
  204. runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
  205. runbooks/vpc/tests/test_cost_engine.py +0 -2
  206. runbooks/vpc/topology_generator.py +326 -0
  207. runbooks/vpc/unified_scenarios.py +1297 -1124
  208. runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
  209. runbooks-1.1.5.dist-info/METADATA +328 -0
  210. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/RECORD +214 -193
  211. runbooks/finops/README.md +0 -414
  212. runbooks/finops/accuracy_cross_validator.py +0 -647
  213. runbooks/finops/business_cases.py +0 -950
  214. runbooks/finops/dashboard_router.py +0 -922
  215. runbooks/finops/ebs_optimizer.py +0 -973
  216. runbooks/finops/embedded_mcp_validator.py +0 -1629
  217. runbooks/finops/enhanced_dashboard_runner.py +0 -527
  218. runbooks/finops/finops_dashboard.py +0 -584
  219. runbooks/finops/finops_scenarios.py +0 -1218
  220. runbooks/finops/legacy_migration.py +0 -730
  221. runbooks/finops/multi_dashboard.py +0 -1519
  222. runbooks/finops/single_dashboard.py +0 -1113
  223. runbooks/finops/unlimited_scenarios.py +0 -393
  224. runbooks-1.1.4.dist-info/METADATA +0 -800
  225. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/WHEEL +0 -0
  226. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/entry_points.txt +0 -0
  227. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/licenses/LICENSE +0 -0
  228. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/top_level.txt +0 -0
runbooks/main_minimal.py CHANGED
@@ -14,27 +14,31 @@ from datetime import datetime
14
14
  # Minimal imports - only what's absolutely necessary
15
15
  from runbooks import __version__
16
16
 
17
+
17
18
  # Simple console fallback
18
19
  class SimpleConsole:
19
20
  def print(self, *args, **kwargs):
20
21
  print(*args)
21
22
 
23
+
22
24
  console = SimpleConsole()
23
25
 
26
+
24
27
  @click.group()
25
28
  @click.version_option(version=__version__, prog_name="runbooks")
26
- @click.option('--debug', is_flag=True, help='Enable debug logging')
27
- @click.option('--profile', help='AWS profile to use')
29
+ @click.option("--debug", is_flag=True, help="Enable debug logging")
30
+ @click.option("--profile", help="AWS profile to use")
28
31
  @click.pass_context
29
32
  def cli(ctx: click.Context, debug: bool, profile: str):
30
33
  """
31
34
  CloudOps Runbooks - Enterprise AWS Automation Platform (Minimal Version)
32
-
35
+
33
36
  Performance optimized for sub-second response times.
34
37
  """
35
38
  ctx.ensure_object(dict)
36
- ctx.obj['profile'] = profile
37
- ctx.obj['debug'] = debug
39
+ ctx.obj["profile"] = profile
40
+ ctx.obj["debug"] = debug
41
+
38
42
 
39
43
  @cli.command()
40
44
  def version():
@@ -42,6 +46,7 @@ def version():
42
46
  console.print(f"CloudOps Runbooks v{__version__}")
43
47
  console.print("Enterprise AWS Automation Platform")
44
48
 
49
+
45
50
  @cli.command()
46
51
  def status():
47
52
  """Show basic status."""
@@ -49,6 +54,7 @@ def status():
49
54
  console.print(f"Version: {__version__}")
50
55
  console.print("Status: Ready")
51
56
 
57
+
52
58
  @cli.command()
53
59
  def perf():
54
60
  """Test CLI performance baseline."""
@@ -58,27 +64,33 @@ def perf():
58
64
  duration = (end_time - start_time).total_seconds()
59
65
  console.print(f"Command execution: {duration:.3f}s")
60
66
 
67
+
61
68
  # Only include minimal commands for performance testing
62
69
  @cli.group()
63
70
  def finops():
64
71
  """Financial Operations (lazy loaded)"""
65
72
  pass
66
73
 
74
+
67
75
  @finops.command()
68
- @click.option('--profile', help='AWS profile to use')
76
+ @click.option("--profile", help="AWS profile to use")
69
77
  def dashboard(profile: str):
70
78
  """Run FinOps dashboard (will lazy load when needed)."""
71
79
  console.print("Loading FinOps dashboard...")
72
-
80
+
73
81
  # This is where we would lazy load the actual functionality
74
82
  start_time = datetime.now()
75
-
83
+
76
84
  # Simulate lazy loading
77
85
  try:
78
86
  from runbooks.finops.dashboard_runner import run_dashboard
87
+
79
88
  console.print(f"FinOps module loaded in {(datetime.now() - start_time).total_seconds():.3f}s")
80
89
  except ImportError:
81
- console.print(f"FinOps module not available (simulated lazy load: {(datetime.now() - start_time).total_seconds():.3f}s)")
90
+ console.print(
91
+ f"FinOps module not available (simulated lazy load: {(datetime.now() - start_time).total_seconds():.3f}s)"
92
+ )
93
+
82
94
 
83
95
  if __name__ == "__main__":
84
- cli()
96
+ cli()
@@ -21,7 +21,7 @@ PERFORMANCE OPTIMIZED CloudOps Runbooks - Enterprise CLI Interface
21
21
  - Basic CLI functionality remains fast
22
22
 
23
23
  ## Performance Targets:
24
- - Basic CLI operations < 0.5s
24
+ - Basic CLI operations < 0.5s
25
25
  - Zero warnings for --help, --version
26
26
  - Clean startup without overhead
27
27
  """
@@ -37,7 +37,7 @@ from loguru import logger
37
37
 
38
38
  # Import lazy loading architecture FIRST
39
39
  from runbooks.common.lazy_loader import (
40
- lazy_rich_console,
40
+ lazy_rich_console,
41
41
  lazy_aws_session,
42
42
  lazy_mcp_validator,
43
43
  lazy_performance_monitor,
@@ -46,7 +46,7 @@ from runbooks.common.lazy_loader import (
46
46
  fast_startup_mode,
47
47
  defer_expensive_imports,
48
48
  requires_aws,
49
- requires_mcp
49
+ requires_mcp,
50
50
  )
51
51
 
52
52
  # Enable deferred imports for startup optimization
@@ -57,24 +57,30 @@ try:
57
57
  from rich.console import Console
58
58
  from rich.table import Table
59
59
  from rich.markup import escape
60
+
60
61
  _HAS_RICH = True
61
62
  except ImportError:
62
63
  _HAS_RICH = False
64
+
63
65
  # Fallback console implementation
64
66
  class Console:
65
67
  def print(self, *args, **kwargs):
66
68
  output = " ".join(str(arg) for arg in args)
67
69
  print(output)
68
70
 
71
+
69
72
  # Basic imports only - no heavy AWS/MCP initialization
70
73
  from runbooks import __version__
71
74
 
75
+
72
76
  # Lazy imports for performance-critical operations
73
77
  def get_assessment_runner():
74
78
  """Lazy load CFAT assessment runner."""
75
79
  from runbooks.cfat.runner import AssessmentRunner
80
+
76
81
  return AssessmentRunner
77
82
 
83
+
78
84
  def get_profile_utils():
79
85
  """Lazy load profile utilities."""
80
86
  from runbooks.common.profile_utils import (
@@ -82,43 +88,51 @@ def get_profile_utils():
82
88
  create_operational_session,
83
89
  get_profile_for_operation,
84
90
  )
91
+
85
92
  return {
86
- 'create_management_session': create_management_session,
87
- 'create_operational_session': create_operational_session,
88
- 'get_profile_for_operation': get_profile_for_operation,
93
+ "create_management_session": create_management_session,
94
+ "create_operational_session": create_operational_session,
95
+ "get_profile_for_operation": get_profile_for_operation,
89
96
  }
90
97
 
98
+
91
99
  def get_rich_utils():
92
100
  """Lazy load Rich utilities."""
93
- from runbooks.common.rich_utils import (
94
- console, create_table, print_banner, print_header, print_status
95
- )
101
+ from runbooks.common.rich_utils import console, create_table, print_banner, print_header, print_status
102
+
96
103
  return {
97
- 'console': console,
98
- 'create_table': create_table,
99
- 'print_banner': print_banner,
100
- 'print_header': print_header,
101
- 'print_status': print_status,
104
+ "console": console,
105
+ "create_table": create_table,
106
+ "print_banner": print_banner,
107
+ "print_header": print_header,
108
+ "print_status": print_status,
102
109
  }
103
110
 
111
+
104
112
  def get_config_utils():
105
113
  """Lazy load configuration utilities."""
106
114
  from runbooks.config import load_config, save_config
107
- return {'load_config': load_config, 'save_config': save_config}
115
+
116
+ return {"load_config": load_config, "save_config": save_config}
117
+
108
118
 
109
119
  def get_logging_utils():
110
120
  """Lazy load logging utilities."""
111
121
  from runbooks.utils import setup_logging, setup_enhanced_logging
112
- return {'setup_logging': setup_logging, 'setup_enhanced_logging': setup_enhanced_logging}
122
+
123
+ return {"setup_logging": setup_logging, "setup_enhanced_logging": setup_enhanced_logging}
124
+
113
125
 
114
126
  def get_business_case_utils():
115
127
  """Lazy load business case utilities."""
116
128
  from runbooks.finops.business_case_config import get_business_case_config, format_business_achievement
129
+
117
130
  return {
118
- 'get_business_case_config': get_business_case_config,
119
- 'format_business_achievement': format_business_achievement
131
+ "get_business_case_config": get_business_case_config,
132
+ "format_business_achievement": format_business_achievement,
120
133
  }
121
134
 
135
+
122
136
  # Global console for basic operations
123
137
  console = Console()
124
138
 
@@ -126,82 +140,90 @@ console = Console()
126
140
  # CLI ARGUMENT FIXES - Handle Profile Tuples and Export Format Issues
127
141
  # ============================================================================
128
142
 
143
+
129
144
  def normalize_profile_parameter(profile_param):
130
145
  """
131
146
  Normalize profile parameter from Click multiple=True tuple to string.
132
-
147
+
133
148
  Args:
134
149
  profile_param: Profile parameter from Click (could be tuple, list, or string)
135
-
150
+
136
151
  Returns:
137
152
  str: Single profile name for AWS operations
138
153
  """
139
154
  if profile_param is None:
140
155
  return None
141
-
156
+
142
157
  # Handle tuple/list from Click multiple=True
143
158
  if isinstance(profile_param, (tuple, list)):
144
159
  # Take the first profile if multiple provided
145
160
  return profile_param[0] if len(profile_param) > 0 else None
146
-
161
+
147
162
  # Handle string directly
148
163
  return profile_param
149
164
 
165
+
150
166
  # Performance monitoring decorator
151
167
  def track_performance(operation_name: str):
152
168
  """Decorator to track CLI operation performance."""
169
+
153
170
  def decorator(func):
154
171
  def wrapper(*args, **kwargs):
155
172
  if fast_startup_mode():
156
173
  # Skip performance tracking for fast operations
157
174
  return func(*args, **kwargs)
158
-
175
+
159
176
  start_time = datetime.now()
160
177
  try:
161
178
  result = func(*args, **kwargs)
162
179
  end_time = datetime.now()
163
180
  duration = (end_time - start_time).total_seconds()
164
-
181
+
165
182
  # Only log if operation takes >0.1s to avoid spam
166
183
  if duration > 0.1:
167
184
  logger.debug(f"Operation '{operation_name}' completed in {duration:.3f}s")
168
-
185
+
169
186
  return result
170
187
  except Exception as e:
171
188
  end_time = datetime.now()
172
189
  duration = (end_time - start_time).total_seconds()
173
190
  logger.error(f"Operation '{operation_name}' failed after {duration:.3f}s: {e}")
174
191
  raise
192
+
175
193
  return wrapper
194
+
176
195
  return decorator
177
196
 
197
+
178
198
  # ============================================================================
179
199
  # CLI MAIN ENTRY POINT - OPTIMIZED FOR PERFORMANCE
180
200
  # ============================================================================
181
201
 
202
+
182
203
  @click.group()
183
204
  @click.version_option(version=__version__, prog_name="runbooks")
184
- @click.option('--debug', is_flag=True, help='Enable debug logging')
185
- @click.option('--profile', help='AWS profile to use')
205
+ @click.option("--debug", is_flag=True, help="Enable debug logging")
206
+ @click.option("--profile", help="AWS profile to use")
186
207
  @click.pass_context
187
208
  def cli(ctx: click.Context, debug: bool, profile: str):
188
209
  """
189
210
  CloudOps Runbooks - Enterprise AWS Automation Platform
190
-
211
+
191
212
  Fast, enterprise-grade automation for CloudOps, DevOps, and SRE teams.
192
-
213
+
193
214
  Performance optimized for sub-second response times.
194
215
  """
195
216
  # Fast context setup
196
217
  ctx.ensure_object(dict)
197
- ctx.obj['profile'] = profile
198
- ctx.obj['debug'] = debug
199
-
218
+ ctx.obj["profile"] = profile
219
+ ctx.obj["debug"] = debug
220
+
200
221
  # Only setup logging if not a fast operation
201
222
  if not fast_startup_mode() and debug:
202
- setup_logging = get_logging_utils()['setup_logging']
223
+ setup_logging = get_logging_utils()["setup_logging"]
203
224
  setup_logging(debug=debug)
204
225
 
226
+
205
227
  @cli.command()
206
228
  @track_performance("version")
207
229
  def version():
@@ -209,6 +231,7 @@ def version():
209
231
  console.print(f"CloudOps Runbooks v{__version__}")
210
232
  console.print("Enterprise AWS Automation Platform")
211
233
 
234
+
212
235
  @cli.command()
213
236
  @track_performance("status")
214
237
  def status():
@@ -216,12 +239,14 @@ def status():
216
239
  console.print("šŸš€ CloudOps Runbooks Status")
217
240
  console.print(f"Version: {__version__}")
218
241
  console.print("Status: Ready")
219
-
242
+
220
243
  # Only check AWS if explicitly requested (not for basic status)
221
244
  import sys
222
- if '--aws' in sys.argv:
245
+
246
+ if "--aws" in sys.argv:
223
247
  check_aws_status()
224
248
 
249
+
225
250
  def check_aws_status():
226
251
  """Check AWS connectivity (lazy loaded)."""
227
252
  try:
@@ -230,91 +255,93 @@ def check_aws_status():
230
255
  except Exception as e:
231
256
  console.print(f"AWS: Error - {e}")
232
257
 
258
+
233
259
  # ============================================================================
234
260
  # FINOPS COMMANDS - WITH LAZY LOADING
235
261
  # ============================================================================
236
262
 
263
+
237
264
  @cli.group()
238
265
  def finops():
239
266
  """Financial Operations and Cost Analysis"""
240
267
  pass
241
268
 
269
+
242
270
  @finops.command()
243
- @click.option('--profile', help='AWS profile to use')
244
- @click.option('--export', type=click.Choice(['csv', 'json', 'html', 'pdf']), help='Export format')
245
- @click.option('--output-file', type=click.Path(), help='Output file path')
246
- @click.option('--mcp-validation', is_flag=True, help='Enable MCP validation')
271
+ @click.option("--profile", help="AWS profile to use")
272
+ @click.option("--export", type=click.Choice(["csv", "json", "html", "pdf"]), help="Export format")
273
+ @click.option("--output-file", type=click.Path(), help="Output file path")
274
+ @click.option("--mcp-validation", is_flag=True, help="Enable MCP validation")
247
275
  @track_performance("finops_dashboard")
248
276
  @requires_aws
249
277
  def dashboard(profile: str, export: str, output_file: str, mcp_validation: bool):
250
278
  """Run FinOps cost analysis dashboard (lazy loaded)."""
251
279
  # Lazy load FinOps components only when needed
252
280
  from runbooks.finops.dashboard_runner import run_dashboard
253
-
281
+
254
282
  profile_utils = get_profile_utils()
255
283
  rich_utils = get_rich_utils()
256
-
284
+
257
285
  # Normalize profile parameter
258
286
  normalized_profile = normalize_profile_parameter(profile)
259
-
287
+
260
288
  console.print("šŸš€ Starting FinOps Dashboard Analysis...")
261
-
289
+
262
290
  # Optional MCP validation
263
291
  if mcp_validation:
264
292
  validator = lazy_mcp_validator()
265
293
  console.print("šŸ“Š MCP validation enabled")
266
-
294
+
267
295
  # Run dashboard with lazy-loaded components
268
296
  try:
269
- result = run_dashboard(
270
- profile=normalized_profile,
271
- export_format=export,
272
- output_file=output_file
273
- )
297
+ result = run_dashboard(profile=normalized_profile, export_format=export, output_file=output_file)
274
298
  console.print("āœ… FinOps analysis completed successfully")
275
299
  return result
276
300
  except Exception as e:
277
301
  console.print(f"āŒ FinOps analysis failed: {e}")
278
302
  raise
279
303
 
304
+
280
305
  # ============================================================================
281
- # INVENTORY COMMANDS - WITH LAZY LOADING
306
+ # INVENTORY COMMANDS - WITH LAZY LOADING
282
307
  # ============================================================================
283
308
 
309
+
284
310
  @cli.group()
285
311
  def inventory():
286
312
  """Resource Discovery and Inventory Management"""
287
313
  pass
288
314
 
315
+
289
316
  @inventory.command()
290
- @click.option('--profile', help='AWS profile to use')
291
- @click.option('--regions', multiple=True, help='AWS regions to scan')
292
- @click.option('--services', multiple=True, help='AWS services to include')
293
- @click.option('--export', type=click.Choice(['csv', 'json', 'yaml']), help='Export format')
317
+ @click.option("--profile", help="AWS profile to use")
318
+ @click.option("--regions", multiple=True, help="AWS regions to scan")
319
+ @click.option("--services", multiple=True, help="AWS services to include")
320
+ @click.option("--export", type=click.Choice(["csv", "json", "yaml"]), help="Export format")
294
321
  @track_performance("inventory_collect")
295
322
  @requires_aws
296
323
  def collect(profile: str, regions: tuple, services: tuple, export: str):
297
324
  """Collect comprehensive inventory across AWS accounts (lazy loaded)."""
298
325
  # Lazy load inventory collector only when needed
299
326
  InventoryCollector = lazy_inventory_collector()
300
-
327
+
301
328
  profile_utils = get_profile_utils()
302
-
329
+
303
330
  # Normalize profile parameter
304
331
  normalized_profile = normalize_profile_parameter(profile)
305
-
332
+
306
333
  console.print("šŸ” Starting inventory collection...")
307
-
334
+
308
335
  # Create collector with lazy-loaded session
309
336
  session = lazy_aws_session()
310
337
  collector = InventoryCollector(session=session)
311
-
338
+
312
339
  try:
313
340
  result = collector.collect_all(
314
341
  profile=normalized_profile,
315
342
  regions=list(regions) if regions else None,
316
343
  services=list(services) if services else None,
317
- export_format=export
344
+ export_format=export,
318
345
  )
319
346
  console.print("āœ… Inventory collection completed successfully")
320
347
  return result
@@ -322,42 +349,43 @@ def collect(profile: str, regions: tuple, services: tuple, export: str):
322
349
  console.print(f"āŒ Inventory collection failed: {e}")
323
350
  raise
324
351
 
352
+
325
353
  # ============================================================================
326
354
  # SECURITY COMMANDS - WITH LAZY LOADING
327
355
  # ============================================================================
328
356
 
357
+
329
358
  @cli.group()
330
359
  def security():
331
360
  """Security Assessment and Compliance"""
332
361
  pass
333
362
 
363
+
334
364
  @security.command()
335
- @click.option('--profile', help='AWS profile to use')
336
- @click.option('--frameworks', multiple=True, help='Compliance frameworks to check')
337
- @click.option('--export', type=click.Choice(['csv', 'json', 'html']), help='Export format')
365
+ @click.option("--profile", help="AWS profile to use")
366
+ @click.option("--frameworks", multiple=True, help="Compliance frameworks to check")
367
+ @click.option("--export", type=click.Choice(["csv", "json", "html"]), help="Export format")
338
368
  @track_performance("security_assess")
339
369
  @requires_aws
340
370
  def assess(profile: str, frameworks: tuple, export: str):
341
371
  """Run security baseline assessment (lazy loaded)."""
342
372
  # Lazy load security components only when needed
343
373
  from runbooks.security.security_baseline_tester import SecurityBaselineTester
344
-
374
+
345
375
  profile_utils = get_profile_utils()
346
-
376
+
347
377
  # Normalize profile parameter
348
378
  normalized_profile = normalize_profile_parameter(profile)
349
-
379
+
350
380
  console.print("šŸ”’ Starting security assessment...")
351
-
381
+
352
382
  # Create tester with lazy-loaded session
353
383
  session = lazy_aws_session()
354
384
  tester = SecurityBaselineTester(session=session)
355
-
385
+
356
386
  try:
357
387
  result = tester.run_assessment(
358
- profile=normalized_profile,
359
- frameworks=list(frameworks) if frameworks else None,
360
- export_format=export
388
+ profile=normalized_profile, frameworks=list(frameworks) if frameworks else None, export_format=export
361
389
  )
362
390
  console.print("āœ… Security assessment completed successfully")
363
391
  return result
@@ -365,109 +393,111 @@ def assess(profile: str, frameworks: tuple, export: str):
365
393
  console.print(f"āŒ Security assessment failed: {e}")
366
394
  raise
367
395
 
396
+
368
397
  # ============================================================================
369
398
  # OPERATE COMMANDS - WITH LAZY LOADING
370
399
  # ============================================================================
371
400
 
401
+
372
402
  @cli.group()
373
403
  def operate():
374
404
  """AWS Resource Operations and Automation"""
375
405
  pass
376
406
 
407
+
377
408
  @operate.command()
378
- @click.option('--profile', help='AWS profile to use')
379
- @click.option('--dry-run', is_flag=True, default=True, help='Dry run mode (default: enabled)')
409
+ @click.option("--profile", help="AWS profile to use")
410
+ @click.option("--dry-run", is_flag=True, default=True, help="Dry run mode (default: enabled)")
380
411
  @track_performance("operate_ec2")
381
412
  @requires_aws
382
413
  def ec2(profile: str, dry_run: bool):
383
414
  """EC2 resource operations (lazy loaded)."""
384
415
  # Lazy load EC2 operations only when needed
385
416
  from runbooks.operate.ec2_operations import EC2Operations
386
-
417
+
387
418
  # Normalize profile parameter
388
419
  normalized_profile = normalize_profile_parameter(profile)
389
-
420
+
390
421
  console.print("⚔ Starting EC2 operations...")
391
-
422
+
392
423
  if dry_run:
393
424
  console.print("šŸ”’ Running in dry-run mode (no changes will be made)")
394
-
425
+
395
426
  # Create operations with lazy-loaded session
396
427
  session = lazy_aws_session()
397
428
  ec2_ops = EC2Operations(session=session)
398
-
429
+
399
430
  try:
400
- result = ec2_ops.list_instances(
401
- profile=normalized_profile,
402
- dry_run=dry_run
403
- )
431
+ result = ec2_ops.list_instances(profile=normalized_profile, dry_run=dry_run)
404
432
  console.print("āœ… EC2 operations completed successfully")
405
433
  return result
406
434
  except Exception as e:
407
435
  console.print(f"āŒ EC2 operations failed: {e}")
408
436
  raise
409
437
 
438
+
410
439
  # ============================================================================
411
440
  # CFAT COMMANDS - WITH LAZY LOADING
412
441
  # ============================================================================
413
442
 
414
- @cli.group()
443
+
444
+ @cli.group()
415
445
  def cfat():
416
446
  """Cloud Foundations Assessment Tool"""
417
447
  pass
418
448
 
449
+
419
450
  @cfat.command()
420
- @click.option('--profile', help='AWS profile to use')
421
- @click.option('--output-file', type=click.Path(), help='Assessment report output file')
451
+ @click.option("--profile", help="AWS profile to use")
452
+ @click.option("--output-file", type=click.Path(), help="Assessment report output file")
422
453
  @track_performance("cfat_assess")
423
454
  @requires_aws
424
455
  def assess(profile: str, output_file: str):
425
456
  """Run Cloud Foundations Assessment (lazy loaded)."""
426
457
  # Lazy load CFAT components only when needed
427
458
  AssessmentRunner = get_assessment_runner()
428
-
459
+
429
460
  # Normalize profile parameter
430
461
  normalized_profile = normalize_profile_parameter(profile)
431
-
462
+
432
463
  console.print("šŸ›ļø Starting Cloud Foundations Assessment...")
433
-
464
+
434
465
  # Create runner with lazy-loaded session
435
466
  session = lazy_aws_session()
436
467
  runner = AssessmentRunner(session=session)
437
-
468
+
438
469
  try:
439
- result = runner.run_assessment(
440
- profile=normalized_profile,
441
- output_file=output_file
442
- )
470
+ result = runner.run_assessment(profile=normalized_profile, output_file=output_file)
443
471
  console.print("āœ… CFAT assessment completed successfully")
444
472
  return result
445
473
  except Exception as e:
446
474
  console.print(f"āŒ CFAT assessment failed: {e}")
447
475
  raise
448
476
 
477
+
449
478
  # ============================================================================
450
479
  # PERFORMANCE DIAGNOSTICS
451
480
  # ============================================================================
452
481
 
482
+
453
483
  @cli.command()
454
484
  @track_performance("perf_test")
455
485
  def perf():
456
486
  """Performance diagnostics and benchmarking."""
457
487
  start_time = datetime.now()
458
-
488
+
459
489
  console.print("šŸš€ Performance Diagnostics")
460
490
  console.print(f"Startup Time: {(datetime.now() - start_time).total_seconds():.3f}s")
461
-
491
+
462
492
  # Test lazy loading performance
463
493
  console.print("\nšŸ“Š Component Loading Times:")
464
-
494
+
465
495
  # Test Rich loading
466
496
  rich_start = datetime.now()
467
497
  lazy_rich_console()
468
498
  rich_time = (datetime.now() - rich_start).total_seconds()
469
499
  console.print(f"Rich Console: {rich_time:.3f}s")
470
-
500
+
471
501
  # Test AWS session (only if credentials available)
472
502
  try:
473
503
  aws_start = datetime.now()
@@ -476,7 +506,7 @@ def perf():
476
506
  console.print(f"AWS Session: {aws_time:.3f}s")
477
507
  except Exception:
478
508
  console.print("AWS Session: Not available (no credentials)")
479
-
509
+
480
510
  # Test MCP validator
481
511
  try:
482
512
  mcp_start = datetime.now()
@@ -485,9 +515,10 @@ def perf():
485
515
  console.print(f"MCP Validator: {mcp_time:.3f}s")
486
516
  except Exception:
487
517
  console.print("MCP Validator: Not available")
488
-
518
+
489
519
  total_time = (datetime.now() - start_time).total_seconds()
490
520
  console.print(f"\nā±ļø Total Diagnostic Time: {total_time:.3f}s")
491
521
 
522
+
492
523
  if __name__ == "__main__":
493
- cli()
524
+ cli()