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
@@ -609,7 +609,7 @@ class VPCFlowAnalyzer(BaseInventory):
609
609
  if i != j: # Cross-AZ traffic
610
610
  # REMOVED: Random traffic simulation violates enterprise standards
611
611
  # TODO: Calculate actual cross-AZ traffic from VPC Flow Logs
612
-
612
+
613
613
  traffic_bytes = 500000 * time_range_hours # Deterministic baseline
614
614
  az_pair = f"{source_az}-to-{dest_az}"
615
615
 
runbooks/main.py CHANGED
@@ -22,45 +22,46 @@ Enterprise Features Preserved:
22
22
  - Safety controls and audit trails
23
23
  """
24
24
 
25
+ import os
25
26
  import sys
26
27
  from datetime import datetime
27
28
  from pathlib import Path
28
29
  from typing import Optional
29
- import os
30
30
 
31
31
  import click
32
32
  from loguru import logger
33
33
 
34
34
  try:
35
35
  from rich.console import Console
36
- from rich.table import Table
37
36
  from rich.markup import escape
37
+ from rich.table import Table
38
+
38
39
  _HAS_RICH = True
39
40
  except ImportError:
40
41
  _HAS_RICH = False
42
+
41
43
  # Fallback console implementation
42
44
  class Console:
43
45
  def print(self, *args, **kwargs):
44
46
  output = " ".join(str(arg) for arg in args)
45
47
  print(output)
46
48
 
49
+
47
50
  import boto3
48
51
 
49
52
  from runbooks import __version__
50
53
  from runbooks.cli.registry import DRYCommandRegistry
51
- from runbooks.common.performance_monitor import get_performance_benchmark
52
-
53
- # Initialize Rich console
54
- console = Console()
55
-
56
- # Common decorators and options
57
54
  from runbooks.common.decorators import (
58
55
  common_aws_options,
59
- common_output_options,
60
56
  common_filter_options,
57
+ common_output_options,
58
+ error_handler,
61
59
  performance_timing,
62
- error_handler
63
60
  )
61
+ from runbooks.common.performance_monitor import get_performance_benchmark
62
+
63
+ # Initialize Rich console
64
+ console = Console()
64
65
 
65
66
 
66
67
  def display_banner():
@@ -81,9 +82,12 @@ def display_banner():
81
82
  @click.group()
82
83
  @click.version_option(version=__version__)
83
84
  @click.option("--debug", is_flag=True, help="Enable debug logging")
84
- @click.option("--log-level",
85
- type=click.Choice(['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']),
86
- default='INFO', help="Set logging level")
85
+ @click.option(
86
+ "--log-level",
87
+ type=click.Choice(["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]),
88
+ default="INFO",
89
+ help="Set logging level",
90
+ )
87
91
  @click.option("--json-output", is_flag=True, help="Enable structured JSON output for programmatic use")
88
92
  @common_aws_options
89
93
  @click.option("--config", type=click.Path(), help="Configuration file path")
@@ -120,22 +124,28 @@ def main(ctx, debug, log_level, json_output, profile, region, dry_run, config):
120
124
 
121
125
  # Configure logging
122
126
  if debug:
123
- log_level = 'DEBUG'
127
+ log_level = "DEBUG"
124
128
 
125
129
  logger.remove()
126
- logger.add(sys.stderr, level=log_level, format="<green>{time}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>")
130
+ logger.add(
131
+ sys.stderr,
132
+ level=log_level,
133
+ format="<green>{time}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
134
+ )
127
135
 
128
136
  # Store global options in context
129
- ctx.obj.update({
130
- 'debug': debug,
131
- 'log_level': log_level,
132
- 'json_output': json_output,
133
- 'profile': profile,
134
- 'region': region,
135
- 'dry_run': dry_run,
136
- 'config': config,
137
- 'start_time': datetime.now()
138
- })
137
+ ctx.obj.update(
138
+ {
139
+ "debug": debug,
140
+ "log_level": log_level,
141
+ "json_output": json_output,
142
+ "profile": profile,
143
+ "region": region,
144
+ "dry_run": dry_run,
145
+ "config": config,
146
+ "start_time": datetime.now(),
147
+ }
148
+ )
139
149
 
140
150
  # Display banner for interactive use
141
151
  if not json_output and ctx.invoked_subcommand is None:
@@ -167,18 +177,19 @@ except Exception as e:
167
177
  @click.pass_context
168
178
  def version(ctx):
169
179
  """Display version information and performance metrics."""
170
- performance_data = get_performance_benchmark()
180
+ performance_data = get_performance_benchmark("main")
171
181
 
172
182
  version_info = {
173
183
  "version": __version__,
174
184
  "python_version": sys.version.split()[0],
175
185
  "platform": sys.platform,
176
186
  "commands_loaded": len(DRYCommandRegistry.list_commands()),
177
- "performance": performance_data
187
+ "performance": performance_data,
178
188
  }
179
189
 
180
- if ctx.obj.get('json_output'):
190
+ if ctx.obj.get("json_output"):
181
191
  import json
192
+
182
193
  click.echo(json.dumps(version_info, indent=2))
183
194
  else:
184
195
  console.print(f"[bold]CloudOps Runbooks v{__version__}[/bold]")
@@ -187,23 +198,27 @@ def version(ctx):
187
198
  console.print(f"Commands: {version_info['commands_loaded']} groups loaded")
188
199
 
189
200
  if performance_data:
190
- console.print(f"Performance: {performance_data.get('avg_execution_time', 'N/A')}s avg execution")
201
+ avg_time = getattr(performance_data, "avg_execution_time", "N/A")
202
+ console.print(f"Performance: {avg_time}s avg execution")
191
203
 
192
204
 
193
205
  @main.command()
194
- @click.option("--format", "output_format", type=click.Choice(['table', 'json', 'yaml']),
195
- default='table', help="Output format")
206
+ @click.option(
207
+ "--format", "output_format", type=click.Choice(["table", "json", "yaml"]), default="table", help="Output format"
208
+ )
196
209
  @click.pass_context
197
210
  def list_commands(ctx, output_format):
198
211
  """List all available commands and their descriptions."""
199
212
  commands = DRYCommandRegistry.register_commands()
200
213
 
201
- if output_format == 'json':
214
+ if output_format == "json":
202
215
  import json
216
+
203
217
  command_data = {name: cmd.get_short_help_str() for name, cmd in commands.items()}
204
218
  click.echo(json.dumps(command_data, indent=2))
205
- elif output_format == 'yaml':
219
+ elif output_format == "yaml":
206
220
  import yaml
221
+
207
222
  command_data = {name: cmd.get_short_help_str() for name, cmd in commands.items()}
208
223
  click.echo(yaml.dump(command_data, default_flow_style=False))
209
224
  else:
@@ -225,4 +240,4 @@ def cli_entry_point():
225
240
 
226
241
 
227
242
  if __name__ == "__main__":
228
- main()
243
+ main()
runbooks/main_final.py CHANGED
@@ -4,7 +4,7 @@ CloudOps Runbooks - PERFORMANCE OPTIMIZED Enterprise CLI Interface
4
4
  ## Performance Optimizations Applied:
5
5
 
6
6
  1. **Import Chain Fix**: Direct version import avoids heavy finops chain
7
- 2. **Lazy Loading**: Heavy components loaded only when needed
7
+ 2. **Lazy Loading**: Heavy components loaded only when needed
8
8
  3. **Fast Operations**: --help, --version run in <0.5s
9
9
  4. **Progressive Disclosure**: Basic CLI → Enterprise features on demand
10
10
 
@@ -29,50 +29,67 @@ __version__ = "1.0.0" # Avoid 'from runbooks import __version__'
29
29
  # Fast Rich console loading
30
30
  try:
31
31
  from rich.console import Console
32
+
32
33
  _HAS_RICH = True
33
34
  except ImportError:
34
35
  _HAS_RICH = False
36
+
35
37
  class Console:
36
38
  def print(self, *args, **kwargs):
37
39
  print(*args)
38
40
 
41
+
39
42
  console = Console()
40
43
 
44
+
41
45
  # Lazy loading functions for heavy components
42
46
  def lazy_load_finops():
43
47
  """Lazy load FinOps components only when needed."""
44
48
  from runbooks.finops.dashboard_runner import run_dashboard
45
49
  from runbooks.finops import get_cost_data, get_trend
50
+
46
51
  return run_dashboard, get_cost_data, get_trend
47
52
 
53
+
48
54
  def lazy_load_inventory():
49
55
  """Lazy load inventory components only when needed."""
50
56
  from runbooks.inventory.core.collector import InventoryCollector
57
+
51
58
  return InventoryCollector
52
59
 
60
+
53
61
  def lazy_load_security():
54
62
  """Lazy load security components only when needed."""
55
63
  from runbooks.security.security_baseline_tester import SecurityBaselineTester
64
+
56
65
  return SecurityBaselineTester
57
66
 
67
+
58
68
  def lazy_load_cfat():
59
69
  """Lazy load CFAT components only when needed."""
60
70
  from runbooks.cfat.runner import AssessmentRunner
71
+
61
72
  return AssessmentRunner
62
73
 
74
+
63
75
  def lazy_load_profile_utils():
64
76
  """Lazy load profile utilities only when needed."""
65
77
  from runbooks.common.profile_utils import get_profile_for_operation
78
+
66
79
  return get_profile_for_operation
67
80
 
81
+
68
82
  def lazy_load_aws_session():
69
83
  """Lazy load AWS session creation."""
70
84
  import boto3
85
+
71
86
  return boto3.Session()
72
87
 
88
+
73
89
  # Performance monitoring
74
90
  def track_performance(operation_name: str):
75
91
  """Decorator to track operation performance."""
92
+
76
93
  def decorator(func):
77
94
  def wrapper(*args, **kwargs):
78
95
  start_time = datetime.now()
@@ -86,35 +103,41 @@ def track_performance(operation_name: str):
86
103
  duration = (datetime.now() - start_time).total_seconds()
87
104
  console.print(f"❌ {operation_name} failed after {duration:.3f}s: {e}")
88
105
  raise
106
+
89
107
  return wrapper
108
+
90
109
  return decorator
91
110
 
111
+
92
112
  # ============================================================================
93
113
  # CLI MAIN ENTRY POINT - OPTIMIZED
94
114
  # ============================================================================
95
115
 
116
+
96
117
  @click.group()
97
118
  @click.version_option(version=__version__, prog_name="runbooks")
98
- @click.option('--debug', is_flag=True, help='Enable debug logging')
99
- @click.option('--profile', help='AWS profile to use')
119
+ @click.option("--debug", is_flag=True, help="Enable debug logging")
120
+ @click.option("--profile", help="AWS profile to use")
100
121
  @click.pass_context
101
122
  def cli(ctx: click.Context, debug: bool, profile: str):
102
123
  """
103
124
  CloudOps Runbooks - Enterprise AWS Automation Platform
104
-
125
+
105
126
  Performance optimized: <0.5s for basic operations.
106
127
  """
107
128
  ctx.ensure_object(dict)
108
- ctx.obj['profile'] = profile
109
- ctx.obj['debug'] = debug
110
-
129
+ ctx.obj["profile"] = profile
130
+ ctx.obj["debug"] = debug
131
+
111
132
  if debug:
112
133
  logger.enable("runbooks")
113
134
 
135
+
114
136
  # ============================================================================
115
137
  # FAST BASIC COMMANDS
116
138
  # ============================================================================
117
139
 
140
+
118
141
  @cli.command("version-info")
119
142
  @track_performance("version")
120
143
  def version_info():
@@ -122,6 +145,7 @@ def version_info():
122
145
  console.print(f"[bold blue]CloudOps Runbooks[/bold blue] v{__version__}")
123
146
  console.print("Enterprise AWS Automation Platform")
124
147
 
148
+
125
149
  @cli.command()
126
150
  @track_performance("status")
127
151
  def status():
@@ -130,16 +154,17 @@ def status():
130
154
  console.print(f"Version: [green]{__version__}[/green]")
131
155
  console.print("Status: [green]Ready[/green]")
132
156
 
157
+
133
158
  @cli.command()
134
159
  @track_performance("perf")
135
160
  def perf():
136
161
  """Performance diagnostics and benchmarking."""
137
162
  start_time = datetime.now()
138
163
  console.print("🚀 [bold]Performance Diagnostics[/bold]")
139
-
164
+
140
165
  # Test component loading times
141
166
  console.print("\n📊 Component Loading Performance:")
142
-
167
+
143
168
  # Test FinOps loading
144
169
  try:
145
170
  load_start = datetime.now()
@@ -148,93 +173,95 @@ def perf():
148
173
  console.print(f"FinOps Module: [green]{load_time:.3f}s[/green]")
149
174
  except Exception as e:
150
175
  console.print(f"FinOps Module: [red]Error - {e}[/red]")
151
-
176
+
152
177
  # Test AWS session
153
178
  try:
154
- aws_start = datetime.now()
179
+ aws_start = datetime.now()
155
180
  lazy_load_aws_session()
156
181
  aws_time = (datetime.now() - aws_start).total_seconds()
157
182
  console.print(f"AWS Session: [green]{aws_time:.3f}s[/green]")
158
183
  except Exception as e:
159
184
  console.print(f"AWS Session: [yellow]No credentials - {e}[/yellow]")
160
-
185
+
161
186
  total_time = (datetime.now() - start_time).total_seconds()
162
187
  console.print(f"\n⏱️ [bold]Total Diagnostic Time: {total_time:.3f}s[/bold]")
163
188
 
189
+
164
190
  # ============================================================================
165
191
  # FINOPS COMMANDS - LAZY LOADED
166
192
  # ============================================================================
167
193
 
194
+
168
195
  @cli.group()
169
196
  def finops():
170
197
  """Financial Operations and Cost Analysis (lazy loaded)"""
171
198
  pass
172
199
 
200
+
173
201
  @finops.command()
174
- @click.option('--profile', help='AWS profile to use')
175
- @click.option('--export', type=click.Choice(['csv', 'json', 'html', 'pdf']), help='Export format')
176
- @click.option('--output-file', type=click.Path(), help='Output file path')
202
+ @click.option("--profile", help="AWS profile to use")
203
+ @click.option("--export", type=click.Choice(["csv", "json", "html", "pdf"]), help="Export format")
204
+ @click.option("--output-file", type=click.Path(), help="Output file path")
177
205
  @track_performance("finops_dashboard")
178
206
  def dashboard(profile: str, export: str, output_file: str):
179
207
  """Run FinOps cost analysis dashboard."""
180
208
  console.print("🚀 Loading FinOps Dashboard...")
181
-
209
+
182
210
  # Lazy load components
183
211
  run_dashboard, get_cost_data, get_trend = lazy_load_finops()
184
212
  get_profile_for_operation = lazy_load_profile_utils()
185
-
213
+
186
214
  try:
187
215
  # Resolve profile
188
216
  resolved_profile = get_profile_for_operation("billing", profile)
189
217
  console.print(f"Using profile: [blue]{resolved_profile}[/blue]")
190
-
218
+
191
219
  # Run dashboard
192
- result = run_dashboard(
193
- profile=resolved_profile,
194
- export_format=export,
195
- output_file=output_file
196
- )
220
+ result = run_dashboard(profile=resolved_profile, export_format=export, output_file=output_file)
197
221
  console.print("✅ FinOps analysis completed successfully")
198
222
  return result
199
223
  except Exception as e:
200
224
  console.print(f"❌ FinOps analysis failed: {e}")
201
225
  raise
202
226
 
227
+
203
228
  # ============================================================================
204
- # INVENTORY COMMANDS - LAZY LOADED
229
+ # INVENTORY COMMANDS - LAZY LOADED
205
230
  # ============================================================================
206
231
 
232
+
207
233
  @cli.group()
208
234
  def inventory():
209
235
  """Resource Discovery and Inventory Management (lazy loaded)"""
210
236
  pass
211
237
 
238
+
212
239
  @inventory.command()
213
- @click.option('--profile', help='AWS profile to use')
214
- @click.option('--regions', multiple=True, help='AWS regions to scan')
215
- @click.option('--services', multiple=True, help='AWS services to include')
240
+ @click.option("--profile", help="AWS profile to use")
241
+ @click.option("--regions", multiple=True, help="AWS regions to scan")
242
+ @click.option("--services", multiple=True, help="AWS services to include")
216
243
  @track_performance("inventory_collect")
217
244
  def collect(profile: str, regions: tuple, services: tuple):
218
245
  """Collect comprehensive inventory across AWS accounts."""
219
246
  console.print("🔍 Loading Inventory Collector...")
220
-
247
+
221
248
  # Lazy load components
222
249
  InventoryCollector = lazy_load_inventory()
223
250
  get_profile_for_operation = lazy_load_profile_utils()
224
251
  session = lazy_load_aws_session()
225
-
252
+
226
253
  try:
227
254
  # Resolve profile
228
255
  resolved_profile = get_profile_for_operation("management", profile)
229
256
  console.print(f"Using profile: [blue]{resolved_profile}[/blue]")
230
-
257
+
231
258
  # Create collector
232
259
  collector = InventoryCollector()
233
-
260
+
234
261
  result = collector.collect_services(
235
262
  profile=resolved_profile,
236
263
  regions=list(regions) if regions else None,
237
- services=list(services) if services else None
264
+ services=list(services) if services else None,
238
265
  )
239
266
  console.print("✅ Inventory collection completed")
240
267
  return result
@@ -242,117 +269,121 @@ def collect(profile: str, regions: tuple, services: tuple):
242
269
  console.print(f"❌ Inventory collection failed: {e}")
243
270
  raise
244
271
 
272
+
245
273
  # ============================================================================
246
274
  # SECURITY COMMANDS - LAZY LOADED
247
275
  # ============================================================================
248
276
 
277
+
249
278
  @cli.group()
250
279
  def security():
251
280
  """Security Assessment and Compliance (lazy loaded)"""
252
281
  pass
253
282
 
283
+
254
284
  @security.command()
255
- @click.option('--profile', help='AWS profile to use')
256
- @click.option('--frameworks', multiple=True, help='Compliance frameworks')
285
+ @click.option("--profile", help="AWS profile to use")
286
+ @click.option("--frameworks", multiple=True, help="Compliance frameworks")
257
287
  @track_performance("security_assess")
258
288
  def assess(profile: str, frameworks: tuple):
259
289
  """Run security baseline assessment."""
260
290
  console.print("🔒 Loading Security Assessment...")
261
-
291
+
262
292
  # Lazy load components
263
293
  SecurityBaselineTester = lazy_load_security()
264
294
  get_profile_for_operation = lazy_load_profile_utils()
265
-
295
+
266
296
  try:
267
297
  # Resolve profile
268
298
  resolved_profile = get_profile_for_operation("management", profile)
269
299
  console.print(f"Using profile: [blue]{resolved_profile}[/blue]")
270
-
300
+
271
301
  # Create tester
272
302
  tester = SecurityBaselineTester()
273
-
274
- result = tester.run_assessment(
275
- profile=resolved_profile,
276
- frameworks=list(frameworks) if frameworks else None
277
- )
303
+
304
+ result = tester.run_assessment(profile=resolved_profile, frameworks=list(frameworks) if frameworks else None)
278
305
  console.print("✅ Security assessment completed")
279
306
  return result
280
307
  except Exception as e:
281
308
  console.print(f"❌ Security assessment failed: {e}")
282
309
  raise
283
310
 
311
+
284
312
  # ============================================================================
285
313
  # CFAT COMMANDS - LAZY LOADED
286
314
  # ============================================================================
287
315
 
316
+
288
317
  @cli.group()
289
318
  def cfat():
290
319
  """Cloud Foundations Assessment Tool (lazy loaded)"""
291
320
  pass
292
321
 
322
+
293
323
  @cfat.command()
294
- @click.option('--profile', help='AWS profile to use')
295
- @click.option('--output-file', type=click.Path(), help='Report output file')
324
+ @click.option("--profile", help="AWS profile to use")
325
+ @click.option("--output-file", type=click.Path(), help="Report output file")
296
326
  @track_performance("cfat_assess")
297
327
  def assess(profile: str, output_file: str):
298
328
  """Run Cloud Foundations Assessment."""
299
329
  console.print("🏛️ Loading CFAT Assessment...")
300
-
330
+
301
331
  # Lazy load components
302
332
  AssessmentRunner = lazy_load_cfat()
303
333
  get_profile_for_operation = lazy_load_profile_utils()
304
-
334
+
305
335
  try:
306
336
  # Resolve profile
307
337
  resolved_profile = get_profile_for_operation("management", profile)
308
338
  console.print(f"Using profile: [blue]{resolved_profile}[/blue]")
309
-
339
+
310
340
  # Create runner
311
341
  runner = AssessmentRunner()
312
-
313
- result = runner.run_assessment(
314
- profile=resolved_profile,
315
- output_file=output_file
316
- )
342
+
343
+ result = runner.run_assessment(profile=resolved_profile, output_file=output_file)
317
344
  console.print("✅ CFAT assessment completed")
318
345
  return result
319
346
  except Exception as e:
320
347
  console.print(f"❌ CFAT assessment failed: {e}")
321
348
  raise
322
349
 
350
+
323
351
  # ============================================================================
324
352
  # OPERATE COMMANDS - LAZY LOADED
325
353
  # ============================================================================
326
354
 
355
+
327
356
  @cli.group()
328
357
  def operate():
329
358
  """AWS Resource Operations and Automation (lazy loaded)"""
330
359
  pass
331
360
 
361
+
332
362
  @operate.command()
333
- @click.option('--profile', help='AWS profile to use')
334
- @click.option('--dry-run', is_flag=True, default=True, help='Dry run mode')
363
+ @click.option("--profile", help="AWS profile to use")
364
+ @click.option("--dry-run", is_flag=True, default=True, help="Dry run mode")
335
365
  @track_performance("operate_list")
336
366
  def list(profile: str, dry_run: bool):
337
367
  """List AWS resources (placeholder for full operate functionality)."""
338
368
  console.print("⚡ Loading AWS Operations...")
339
-
369
+
340
370
  get_profile_for_operation = lazy_load_profile_utils()
341
371
  session = lazy_load_aws_session()
342
-
372
+
343
373
  try:
344
374
  resolved_profile = get_profile_for_operation("operational", profile)
345
375
  console.print(f"Using profile: [blue]{resolved_profile}[/blue]")
346
-
376
+
347
377
  if dry_run:
348
378
  console.print("🔒 [yellow]Running in dry-run mode[/yellow]")
349
-
379
+
350
380
  # Would load operate components here
351
381
  console.print("✅ Operations module ready")
352
-
382
+
353
383
  except Exception as e:
354
384
  console.print(f"❌ Operations failed: {e}")
355
385
  raise
356
386
 
387
+
357
388
  if __name__ == "__main__":
358
- cli()
389
+ cli()