runbooks 1.1.3__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 (247) 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/WEIGHT_CONFIG_README.md +1 -1
  8. runbooks/cfat/assessment/compliance.py +8 -8
  9. runbooks/cfat/assessment/runner.py +1 -0
  10. runbooks/cfat/cloud_foundations_assessment.py +227 -239
  11. runbooks/cfat/models.py +6 -2
  12. runbooks/cfat/tests/__init__.py +6 -1
  13. runbooks/cli/__init__.py +13 -0
  14. runbooks/cli/commands/cfat.py +274 -0
  15. runbooks/cli/commands/finops.py +1164 -0
  16. runbooks/cli/commands/inventory.py +379 -0
  17. runbooks/cli/commands/operate.py +239 -0
  18. runbooks/cli/commands/security.py +248 -0
  19. runbooks/cli/commands/validation.py +825 -0
  20. runbooks/cli/commands/vpc.py +310 -0
  21. runbooks/cli/registry.py +107 -0
  22. runbooks/cloudops/__init__.py +23 -30
  23. runbooks/cloudops/base.py +96 -107
  24. runbooks/cloudops/cost_optimizer.py +549 -547
  25. runbooks/cloudops/infrastructure_optimizer.py +5 -4
  26. runbooks/cloudops/interfaces.py +226 -227
  27. runbooks/cloudops/lifecycle_manager.py +5 -4
  28. runbooks/cloudops/mcp_cost_validation.py +252 -235
  29. runbooks/cloudops/models.py +78 -53
  30. runbooks/cloudops/monitoring_automation.py +5 -4
  31. runbooks/cloudops/notebook_framework.py +179 -215
  32. runbooks/cloudops/security_enforcer.py +125 -159
  33. runbooks/common/accuracy_validator.py +11 -0
  34. runbooks/common/aws_pricing.py +349 -326
  35. runbooks/common/aws_pricing_api.py +211 -212
  36. runbooks/common/aws_profile_manager.py +341 -0
  37. runbooks/common/aws_utils.py +75 -80
  38. runbooks/common/business_logic.py +127 -105
  39. runbooks/common/cli_decorators.py +36 -60
  40. runbooks/common/comprehensive_cost_explorer_integration.py +456 -464
  41. runbooks/common/cross_account_manager.py +198 -205
  42. runbooks/common/date_utils.py +27 -39
  43. runbooks/common/decorators.py +235 -0
  44. runbooks/common/dry_run_examples.py +173 -208
  45. runbooks/common/dry_run_framework.py +157 -155
  46. runbooks/common/enhanced_exception_handler.py +15 -4
  47. runbooks/common/enhanced_logging_example.py +50 -64
  48. runbooks/common/enhanced_logging_integration_example.py +65 -37
  49. runbooks/common/env_utils.py +16 -16
  50. runbooks/common/error_handling.py +40 -38
  51. runbooks/common/lazy_loader.py +41 -23
  52. runbooks/common/logging_integration_helper.py +79 -86
  53. runbooks/common/mcp_cost_explorer_integration.py +478 -495
  54. runbooks/common/mcp_integration.py +63 -74
  55. runbooks/common/memory_optimization.py +140 -118
  56. runbooks/common/module_cli_base.py +37 -58
  57. runbooks/common/organizations_client.py +176 -194
  58. runbooks/common/patterns.py +204 -0
  59. runbooks/common/performance_monitoring.py +67 -71
  60. runbooks/common/performance_optimization_engine.py +283 -274
  61. runbooks/common/profile_utils.py +248 -39
  62. runbooks/common/rich_utils.py +643 -92
  63. runbooks/common/sre_performance_suite.py +177 -186
  64. runbooks/enterprise/__init__.py +1 -1
  65. runbooks/enterprise/logging.py +144 -106
  66. runbooks/enterprise/security.py +187 -204
  67. runbooks/enterprise/validation.py +43 -56
  68. runbooks/finops/__init__.py +29 -33
  69. runbooks/finops/account_resolver.py +1 -1
  70. runbooks/finops/advanced_optimization_engine.py +980 -0
  71. runbooks/finops/automation_core.py +268 -231
  72. runbooks/finops/business_case_config.py +184 -179
  73. runbooks/finops/cli.py +660 -139
  74. runbooks/finops/commvault_ec2_analysis.py +157 -164
  75. runbooks/finops/compute_cost_optimizer.py +336 -320
  76. runbooks/finops/config.py +20 -20
  77. runbooks/finops/cost_optimizer.py +488 -622
  78. runbooks/finops/cost_processor.py +332 -214
  79. runbooks/finops/dashboard_runner.py +1006 -172
  80. runbooks/finops/ebs_cost_optimizer.py +991 -657
  81. runbooks/finops/elastic_ip_optimizer.py +317 -257
  82. runbooks/finops/enhanced_mcp_integration.py +340 -0
  83. runbooks/finops/enhanced_progress.py +40 -37
  84. runbooks/finops/enhanced_trend_visualization.py +3 -2
  85. runbooks/finops/enterprise_wrappers.py +230 -292
  86. runbooks/finops/executive_export.py +203 -160
  87. runbooks/finops/helpers.py +130 -288
  88. runbooks/finops/iam_guidance.py +1 -1
  89. runbooks/finops/infrastructure/__init__.py +80 -0
  90. runbooks/finops/infrastructure/commands.py +506 -0
  91. runbooks/finops/infrastructure/load_balancer_optimizer.py +866 -0
  92. runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +832 -0
  93. runbooks/finops/markdown_exporter.py +338 -175
  94. runbooks/finops/mcp_validator.py +1952 -0
  95. runbooks/finops/nat_gateway_optimizer.py +1513 -482
  96. runbooks/finops/network_cost_optimizer.py +657 -587
  97. runbooks/finops/notebook_utils.py +226 -188
  98. runbooks/finops/optimization_engine.py +1136 -0
  99. runbooks/finops/optimizer.py +25 -29
  100. runbooks/finops/rds_snapshot_optimizer.py +367 -411
  101. runbooks/finops/reservation_optimizer.py +427 -363
  102. runbooks/finops/scenario_cli_integration.py +77 -78
  103. runbooks/finops/scenarios.py +1278 -439
  104. runbooks/finops/schemas.py +218 -182
  105. runbooks/finops/snapshot_manager.py +2289 -0
  106. runbooks/finops/tests/test_finops_dashboard.py +3 -3
  107. runbooks/finops/tests/test_reference_images_validation.py +2 -2
  108. runbooks/finops/tests/test_single_account_features.py +17 -17
  109. runbooks/finops/tests/validate_test_suite.py +1 -1
  110. runbooks/finops/types.py +3 -3
  111. runbooks/finops/validation_framework.py +263 -269
  112. runbooks/finops/vpc_cleanup_exporter.py +191 -146
  113. runbooks/finops/vpc_cleanup_optimizer.py +593 -575
  114. runbooks/finops/workspaces_analyzer.py +171 -182
  115. runbooks/hitl/enhanced_workflow_engine.py +1 -1
  116. runbooks/integration/__init__.py +89 -0
  117. runbooks/integration/mcp_integration.py +1920 -0
  118. runbooks/inventory/CLAUDE.md +816 -0
  119. runbooks/inventory/README.md +3 -3
  120. runbooks/inventory/Tests/common_test_data.py +30 -30
  121. runbooks/inventory/__init__.py +2 -2
  122. runbooks/inventory/cloud_foundations_integration.py +144 -149
  123. runbooks/inventory/collectors/aws_comprehensive.py +28 -11
  124. runbooks/inventory/collectors/aws_networking.py +111 -101
  125. runbooks/inventory/collectors/base.py +4 -0
  126. runbooks/inventory/core/collector.py +495 -313
  127. runbooks/inventory/discovery.md +2 -2
  128. runbooks/inventory/drift_detection_cli.py +69 -96
  129. runbooks/inventory/find_ec2_security_groups.py +1 -1
  130. runbooks/inventory/inventory_mcp_cli.py +48 -46
  131. runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
  132. runbooks/inventory/mcp_inventory_validator.py +549 -465
  133. runbooks/inventory/mcp_vpc_validator.py +359 -442
  134. runbooks/inventory/organizations_discovery.py +56 -52
  135. runbooks/inventory/rich_inventory_display.py +33 -32
  136. runbooks/inventory/unified_validation_engine.py +278 -251
  137. runbooks/inventory/vpc_analyzer.py +733 -696
  138. runbooks/inventory/vpc_architecture_validator.py +293 -348
  139. runbooks/inventory/vpc_dependency_analyzer.py +382 -378
  140. runbooks/inventory/vpc_flow_analyzer.py +3 -3
  141. runbooks/main.py +152 -9147
  142. runbooks/main_final.py +91 -60
  143. runbooks/main_minimal.py +22 -10
  144. runbooks/main_optimized.py +131 -100
  145. runbooks/main_ultra_minimal.py +7 -2
  146. runbooks/mcp/__init__.py +36 -0
  147. runbooks/mcp/integration.py +679 -0
  148. runbooks/metrics/dora_metrics_engine.py +2 -2
  149. runbooks/monitoring/performance_monitor.py +9 -4
  150. runbooks/operate/dynamodb_operations.py +3 -1
  151. runbooks/operate/ec2_operations.py +145 -137
  152. runbooks/operate/iam_operations.py +146 -152
  153. runbooks/operate/mcp_integration.py +1 -1
  154. runbooks/operate/networking_cost_heatmap.py +33 -10
  155. runbooks/operate/privatelink_operations.py +1 -1
  156. runbooks/operate/rds_operations.py +223 -254
  157. runbooks/operate/s3_operations.py +107 -118
  158. runbooks/operate/vpc_endpoints.py +1 -1
  159. runbooks/operate/vpc_operations.py +648 -618
  160. runbooks/remediation/base.py +1 -1
  161. runbooks/remediation/commons.py +10 -7
  162. runbooks/remediation/commvault_ec2_analysis.py +71 -67
  163. runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
  164. runbooks/remediation/multi_account.py +24 -21
  165. runbooks/remediation/rds_snapshot_list.py +91 -65
  166. runbooks/remediation/remediation_cli.py +92 -146
  167. runbooks/remediation/universal_account_discovery.py +83 -79
  168. runbooks/remediation/workspaces_list.py +49 -44
  169. runbooks/security/__init__.py +19 -0
  170. runbooks/security/assessment_runner.py +1150 -0
  171. runbooks/security/baseline_checker.py +812 -0
  172. runbooks/security/cloudops_automation_security_validator.py +509 -535
  173. runbooks/security/compliance_automation_engine.py +17 -17
  174. runbooks/security/config/__init__.py +2 -2
  175. runbooks/security/config/compliance_config.py +50 -50
  176. runbooks/security/config_template_generator.py +63 -76
  177. runbooks/security/enterprise_security_framework.py +1 -1
  178. runbooks/security/executive_security_dashboard.py +519 -508
  179. runbooks/security/integration_test_enterprise_security.py +5 -3
  180. runbooks/security/multi_account_security_controls.py +959 -1210
  181. runbooks/security/real_time_security_monitor.py +422 -444
  182. runbooks/security/run_script.py +1 -1
  183. runbooks/security/security_baseline_tester.py +1 -1
  184. runbooks/security/security_cli.py +143 -112
  185. runbooks/security/test_2way_validation.py +439 -0
  186. runbooks/security/two_way_validation_framework.py +852 -0
  187. runbooks/sre/mcp_reliability_engine.py +6 -6
  188. runbooks/sre/production_monitoring_framework.py +167 -177
  189. runbooks/tdd/__init__.py +15 -0
  190. runbooks/tdd/cli.py +1071 -0
  191. runbooks/utils/__init__.py +14 -17
  192. runbooks/utils/logger.py +7 -2
  193. runbooks/utils/version_validator.py +51 -48
  194. runbooks/validation/__init__.py +6 -6
  195. runbooks/validation/cli.py +9 -3
  196. runbooks/validation/comprehensive_2way_validator.py +754 -708
  197. runbooks/validation/mcp_validator.py +906 -228
  198. runbooks/validation/terraform_citations_validator.py +104 -115
  199. runbooks/validation/terraform_drift_detector.py +447 -451
  200. runbooks/vpc/README.md +617 -0
  201. runbooks/vpc/__init__.py +8 -1
  202. runbooks/vpc/analyzer.py +577 -0
  203. runbooks/vpc/cleanup_wrapper.py +476 -413
  204. runbooks/vpc/cli_cloudtrail_commands.py +339 -0
  205. runbooks/vpc/cli_mcp_validation_commands.py +480 -0
  206. runbooks/vpc/cloudtrail_audit_integration.py +717 -0
  207. runbooks/vpc/config.py +92 -97
  208. runbooks/vpc/cost_engine.py +411 -148
  209. runbooks/vpc/cost_explorer_integration.py +553 -0
  210. runbooks/vpc/cross_account_session.py +101 -106
  211. runbooks/vpc/enhanced_mcp_validation.py +917 -0
  212. runbooks/vpc/eni_gate_validator.py +961 -0
  213. runbooks/vpc/heatmap_engine.py +190 -162
  214. runbooks/vpc/mcp_no_eni_validator.py +681 -640
  215. runbooks/vpc/nat_gateway_optimizer.py +358 -0
  216. runbooks/vpc/networking_wrapper.py +15 -8
  217. runbooks/vpc/pdca_remediation_planner.py +528 -0
  218. runbooks/vpc/performance_optimized_analyzer.py +219 -231
  219. runbooks/vpc/runbooks_adapter.py +1167 -241
  220. runbooks/vpc/tdd_red_phase_stubs.py +601 -0
  221. runbooks/vpc/test_data_loader.py +358 -0
  222. runbooks/vpc/tests/conftest.py +314 -4
  223. runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
  224. runbooks/vpc/tests/test_cost_engine.py +0 -2
  225. runbooks/vpc/topology_generator.py +326 -0
  226. runbooks/vpc/unified_scenarios.py +1302 -1129
  227. runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
  228. runbooks-1.1.5.dist-info/METADATA +328 -0
  229. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/RECORD +233 -200
  230. runbooks/finops/README.md +0 -414
  231. runbooks/finops/accuracy_cross_validator.py +0 -647
  232. runbooks/finops/business_cases.py +0 -950
  233. runbooks/finops/dashboard_router.py +0 -922
  234. runbooks/finops/ebs_optimizer.py +0 -956
  235. runbooks/finops/embedded_mcp_validator.py +0 -1629
  236. runbooks/finops/enhanced_dashboard_runner.py +0 -527
  237. runbooks/finops/finops_dashboard.py +0 -584
  238. runbooks/finops/finops_scenarios.py +0 -1218
  239. runbooks/finops/legacy_migration.py +0 -730
  240. runbooks/finops/multi_dashboard.py +0 -1519
  241. runbooks/finops/single_dashboard.py +0 -1113
  242. runbooks/finops/unlimited_scenarios.py +0 -393
  243. runbooks-1.1.3.dist-info/METADATA +0 -799
  244. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/WHEEL +0 -0
  245. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/entry_points.txt +0 -0
  246. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/licenses/LICENSE +0 -0
  247. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,204 @@
1
+ """
2
+ DRY Pattern Manager - Eliminate Pattern Duplication
3
+
4
+ Following Claude Code best practices for memory efficiency and enterprise
5
+ architecture patterns for systematic deduplication.
6
+
7
+ Official Claude Code Limitation: Context window optimization requires eliminating
8
+ redundant patterns to maximize available context for complex operations.
9
+
10
+ Enterprise Best Practice: Single source of truth for all reusable patterns
11
+ prevents inconsistencies and reduces maintenance overhead.
12
+ """
13
+
14
+ from typing import Any, Dict, Optional, Callable
15
+ from functools import lru_cache
16
+ import click
17
+ from rich.console import Console
18
+ from rich.markup import escape
19
+
20
+
21
+ class DRYPatternManager:
22
+ """
23
+ Don't Repeat Yourself - Load patterns once, reference everywhere.
24
+
25
+ Following Claude Code optimization principles:
26
+ - Single pattern registry (no duplicates)
27
+ - Reference-based access (@ notation concept)
28
+ - Memory efficiency through lazy loading
29
+ - Consistent patterns across all modules
30
+
31
+ Enterprise Architecture:
32
+ - Centralized pattern management
33
+ - Type-safe pattern access
34
+ - Cached pattern instances
35
+ - Extensible pattern registry
36
+ """
37
+
38
+ _patterns: Dict[str, Any] = {}
39
+ _console: Optional[Console] = None
40
+ _loaded: bool = False
41
+
42
+ @classmethod
43
+ @lru_cache(maxsize=None)
44
+ def get_console(cls) -> Console:
45
+ """
46
+ Single console instance for all modules.
47
+
48
+ Claude Code Best Practice: Reuse console objects to reduce memory overhead
49
+ and ensure consistent formatting across all CLI operations.
50
+ """
51
+ if cls._console is None:
52
+ cls._console = Console()
53
+ return cls._console
54
+
55
+ @classmethod
56
+ def get_pattern(cls, name: str) -> Any:
57
+ """
58
+ Get pattern by name with lazy loading.
59
+
60
+ Args:
61
+ name: Pattern identifier (e.g., 'error_handlers', 'click_group')
62
+
63
+ Returns:
64
+ Cached pattern instance
65
+
66
+ Raises:
67
+ KeyError: If pattern not found
68
+ """
69
+ if not cls._loaded:
70
+ cls._load_all_patterns()
71
+
72
+ if name not in cls._patterns:
73
+ raise KeyError(f"Pattern '{name}' not found. Available: {list(cls._patterns.keys())}")
74
+
75
+ return cls._patterns[name]
76
+
77
+ @classmethod
78
+ def _load_all_patterns(cls):
79
+ """Load all patterns once - DRY principle implementation."""
80
+ if cls._loaded:
81
+ return
82
+
83
+ # Common import patterns
84
+ cls._patterns["click"] = click
85
+ cls._patterns["console"] = cls.get_console()
86
+
87
+ # Error handling patterns
88
+ cls._patterns["error_handlers"] = cls._create_error_handlers()
89
+
90
+ # Click group patterns
91
+ cls._patterns["click_group"] = cls._create_click_group_pattern()
92
+
93
+ # Common CLI decorators reference
94
+ cls._patterns["common_decorators"] = cls._get_common_decorators()
95
+
96
+ cls._loaded = True
97
+
98
+ @classmethod
99
+ def _create_error_handlers(cls) -> Dict[str, Callable]:
100
+ """
101
+ Centralized error handling patterns.
102
+
103
+ Eliminates 19 instances of duplicated error messages across CLI modules.
104
+ """
105
+ console = cls.get_console()
106
+
107
+ def module_not_available_error(module_name: str, error: Exception):
108
+ """Standardized 'module not available' error handler."""
109
+ console.print(f"[red]❌ {module_name} module not available: {error}[/red]")
110
+
111
+ def operation_failed_error(operation_name: str, error: Exception):
112
+ """Standardized 'operation failed' error handler."""
113
+ console.print(f"[red]❌ {operation_name} failed: {error}[/red]")
114
+
115
+ def success_message(message: str, details: Optional[str] = None):
116
+ """Standardized success message."""
117
+ console.print(f"[green]✅ {message}[/green]")
118
+ if details:
119
+ console.print(f"[dim]{details}[/dim]")
120
+
121
+ return {
122
+ "module_not_available": module_not_available_error,
123
+ "operation_failed": operation_failed_error,
124
+ "success": success_message,
125
+ }
126
+
127
+ @classmethod
128
+ def _create_click_group_pattern(cls) -> Callable:
129
+ """
130
+ Standardized Click group creation pattern.
131
+
132
+ Eliminates 6 instances of identical @click.group patterns.
133
+ """
134
+
135
+ def create_group(name: str, help_text: str, invoke_without_command: bool = True):
136
+ """Create standardized Click group with common options."""
137
+
138
+ @click.group(invoke_without_command=invoke_without_command)
139
+ @click.pass_context
140
+ def group(ctx):
141
+ if ctx.invoked_subcommand is None:
142
+ click.echo(f"{name.title()} Commands:")
143
+ click.echo(help_text)
144
+
145
+ # Apply consistent group naming
146
+ group.name = name
147
+ group.__doc__ = help_text
148
+
149
+ return group
150
+
151
+ return create_group
152
+
153
+ @classmethod
154
+ def _get_common_decorators(cls):
155
+ """Reference to common decorators - avoid importing in every module."""
156
+ try:
157
+ from runbooks.common.decorators import common_aws_options, common_output_options, common_filter_options
158
+
159
+ return {
160
+ "aws_options": common_aws_options,
161
+ "output_options": common_output_options,
162
+ "filter_options": common_filter_options,
163
+ }
164
+ except ImportError:
165
+ # Graceful degradation if decorators not available
166
+ return {}
167
+
168
+
169
+ # Convenience functions for direct pattern access
170
+ def get_console() -> Console:
171
+ """Get shared console instance - replaces individual console = Console() calls."""
172
+ return DRYPatternManager.get_console()
173
+
174
+
175
+ def get_error_handlers() -> Dict[str, Callable]:
176
+ """Get standardized error handlers."""
177
+ return DRYPatternManager.get_pattern("error_handlers")
178
+
179
+
180
+ def get_click_group_creator() -> Callable:
181
+ """Get standardized Click group creator."""
182
+ return DRYPatternManager.get_pattern("click_group")
183
+
184
+
185
+ def get_common_decorators() -> Dict[str, Any]:
186
+ """Get common CLI decorators."""
187
+ return DRYPatternManager.get_pattern("common_decorators")
188
+
189
+
190
+ # Pattern registry status for monitoring
191
+ def get_pattern_registry_status() -> Dict[str, Any]:
192
+ """
193
+ Get DRY pattern registry status for monitoring and optimization.
194
+
195
+ Returns:
196
+ Dictionary containing registry status, loaded patterns, and memory efficiency metrics
197
+ """
198
+ return {
199
+ "loaded": DRYPatternManager._loaded,
200
+ "pattern_count": len(DRYPatternManager._patterns),
201
+ "available_patterns": list(DRYPatternManager._patterns.keys()),
202
+ "console_shared": DRYPatternManager._console is not None,
203
+ "memory_efficiency": "Single instance sharing active",
204
+ }
@@ -25,14 +25,21 @@ from datetime import datetime
25
25
  import json
26
26
 
27
27
  from runbooks.common.rich_utils import (
28
- console, print_success, print_warning, print_info, print_error,
29
- create_table, create_progress_bar, STATUS_INDICATORS
28
+ console,
29
+ print_success,
30
+ print_warning,
31
+ print_info,
32
+ print_error,
33
+ create_table,
34
+ create_progress_bar,
35
+ STATUS_INDICATORS,
30
36
  )
31
37
 
32
38
 
33
39
  @dataclass
34
40
  class PerformanceMetrics:
35
41
  """Enterprise performance metrics tracking."""
42
+
36
43
  operation_name: str
37
44
  module_name: str
38
45
  start_time: float
@@ -68,21 +75,22 @@ class PerformanceMetrics:
68
75
  "api_calls": self.api_calls_count,
69
76
  "success": self.success,
70
77
  "business_value": self.business_value,
71
- "resources_processed": self.resources_processed
78
+ "resources_processed": self.resources_processed,
72
79
  }
73
80
 
74
81
 
75
82
  @dataclass
76
83
  class ModulePerformanceTargets:
77
84
  """Module-specific performance targets for enterprise operations."""
78
- finops: int = 15 # FinOps cost analysis operations
79
- inventory: int = 45 # Multi-account discovery operations
80
- operate: int = 15 # Resource operations with safety validation
81
- security: int = 45 # Comprehensive security assessments
82
- cfat: int = 60 # Cloud foundations assessments
83
- vpc: int = 30 # Network analysis with cost integration
84
- remediation: int = 15 # Automated security remediation
85
- sre: int = 30 # Site reliability engineering operations
85
+
86
+ finops: int = 15 # FinOps cost analysis operations
87
+ inventory: int = 45 # Multi-account discovery operations
88
+ operate: int = 15 # Resource operations with safety validation
89
+ security: int = 45 # Comprehensive security assessments
90
+ cfat: int = 60 # Cloud foundations assessments
91
+ vpc: int = 30 # Network analysis with cost integration
92
+ remediation: int = 15 # Automated security remediation
93
+ sre: int = 30 # Site reliability engineering operations
86
94
 
87
95
  def get_target(self, module_name: str) -> int:
88
96
  """Get performance target for module."""
@@ -107,10 +115,12 @@ def reset_api_counter():
107
115
  _api_call_counter = 0
108
116
 
109
117
 
110
- def monitor_performance(module_name: str = "runbooks",
111
- operation_name: Optional[str] = None,
112
- target_seconds: Optional[int] = None,
113
- track_memory: bool = True):
118
+ def monitor_performance(
119
+ module_name: str = "runbooks",
120
+ operation_name: Optional[str] = None,
121
+ target_seconds: Optional[int] = None,
122
+ track_memory: bool = True,
123
+ ):
114
124
  """
115
125
  Decorator for comprehensive performance monitoring.
116
126
 
@@ -128,6 +138,7 @@ def monitor_performance(module_name: str = "runbooks",
128
138
  def analyze_costs(**kwargs):
129
139
  # Your operation code here
130
140
  """
141
+
131
142
  def decorator(f: Callable) -> Callable:
132
143
  @wraps(f)
133
144
  def wrapper(*args, **kwargs):
@@ -143,7 +154,7 @@ def monitor_performance(module_name: str = "runbooks",
143
154
  module_name=module_name,
144
155
  start_time=time.time(),
145
156
  end_time=0.0,
146
- target_seconds=target
157
+ target_seconds=target,
147
158
  )
148
159
 
149
160
  # Start memory tracking if enabled
@@ -166,8 +177,8 @@ def monitor_performance(module_name: str = "runbooks",
166
177
 
167
178
  # Extract business metrics if available
168
179
  if isinstance(result, dict):
169
- metrics.business_value = result.get('annual_savings', 0.0)
170
- metrics.resources_processed = result.get('resources_count', 0)
180
+ metrics.business_value = result.get("annual_savings", 0.0)
181
+ metrics.resources_processed = result.get("resources_count", 0)
171
182
 
172
183
  # Capture performance data
173
184
  metrics.api_calls_count = _api_call_counter
@@ -205,6 +216,7 @@ def monitor_performance(module_name: str = "runbooks",
205
216
  raise
206
217
 
207
218
  return wrapper
219
+
208
220
  return decorator
209
221
 
210
222
 
@@ -221,8 +233,7 @@ def _provide_performance_feedback(metrics: PerformanceMetrics):
221
233
  if execution_time <= target:
222
234
  # Performance target met
223
235
  print_success(
224
- f"⚡ Performance: {execution_time:.1f}s "
225
- f"(target: <{target}s) - {metrics.efficiency_score:.1f}% efficient"
236
+ f"⚡ Performance: {execution_time:.1f}s (target: <{target}s) - {metrics.efficiency_score:.1f}% efficient"
226
237
  )
227
238
 
228
239
  # Celebrate exceptional performance
@@ -232,8 +243,7 @@ def _provide_performance_feedback(metrics: PerformanceMetrics):
232
243
  else:
233
244
  # Performance target exceeded
234
245
  print_warning(
235
- f"⚠️ Performance: {execution_time:.1f}s "
236
- f"(exceeded {target}s target by {execution_time - target:.1f}s)"
246
+ f"⚠️ Performance: {execution_time:.1f}s (exceeded {target}s target by {execution_time - target:.1f}s)"
237
247
  )
238
248
 
239
249
  # Provide optimization recommendations
@@ -269,16 +279,10 @@ def _provide_optimization_recommendations(metrics: PerformanceMetrics):
269
279
  module_recommendations = {
270
280
  "finops": [
271
281
  "Use more specific date ranges to reduce Cost Explorer data",
272
- "Consider account filtering for large organizations"
282
+ "Consider account filtering for large organizations",
273
283
  ],
274
- "inventory": [
275
- "Use service-specific discovery instead of full scan",
276
- "Implement parallel account processing"
277
- ],
278
- "security": [
279
- "Focus on high-priority security checks first",
280
- "Use incremental scanning for large environments"
281
- ]
284
+ "inventory": ["Use service-specific discovery instead of full scan", "Implement parallel account processing"],
285
+ "security": ["Focus on high-priority security checks first", "Use incremental scanning for large environments"],
282
286
  }
283
287
 
284
288
  if metrics.module_name in module_recommendations:
@@ -286,8 +290,7 @@ def _provide_optimization_recommendations(metrics: PerformanceMetrics):
286
290
  print_info(f" • {rec}")
287
291
 
288
292
 
289
- def benchmark_operation(module_name: str, operation_name: str,
290
- target_calls: int = 10):
293
+ def benchmark_operation(module_name: str, operation_name: str, target_calls: int = 10):
291
294
  """
292
295
  Decorator for benchmarking operation performance over multiple runs.
293
296
 
@@ -301,6 +304,7 @@ def benchmark_operation(module_name: str, operation_name: str,
301
304
  def analyze_costs(**kwargs):
302
305
  # Your operation code here
303
306
  """
307
+
304
308
  def decorator(f: Callable) -> Callable:
305
309
  @wraps(f)
306
310
  def wrapper(*args, **kwargs):
@@ -313,8 +317,7 @@ def benchmark_operation(module_name: str, operation_name: str,
313
317
 
314
318
  # Execute with monitoring
315
319
  monitored_func = monitor_performance(
316
- module_name=module_name,
317
- operation_name=f"{operation_name}_benchmark_{run+1}"
320
+ module_name=module_name, operation_name=f"{operation_name}_benchmark_{run + 1}"
318
321
  )(f)
319
322
 
320
323
  result = monitored_func(*args, **kwargs)
@@ -329,6 +332,7 @@ def benchmark_operation(module_name: str, operation_name: str,
329
332
  return result
330
333
 
331
334
  return wrapper
335
+
332
336
  return decorator
333
337
 
334
338
 
@@ -360,28 +364,30 @@ def _analyze_benchmark_results(results: List[PerformanceMetrics], operation_name
360
364
  columns=[
361
365
  {"name": "Metric", "style": "cyan"},
362
366
  {"name": "Value", "style": "green"},
363
- {"name": "Assessment", "style": "yellow"}
364
- ]
367
+ {"name": "Assessment", "style": "yellow"},
368
+ ],
365
369
  )
366
370
 
367
371
  target = results[0].target_seconds
368
372
 
369
- table.add_row("Average Time", f"{avg_time:.2f}s",
370
- " Good" if avg_time <= target else "⚠️ Needs optimization")
371
- table.add_row("Best Time", f"{min_time:.2f}s",
372
- "🏆 Excellent" if min_time <= target * 0.5 else "✅ Good")
373
- table.add_row("Worst Time", f"{max_time:.2f}s",
374
- "⚠️ Investigate" if max_time > target * 1.5 else "✅ Acceptable")
375
- table.add_row("Success Rate", f"{len(execution_times)}/{len(results)}",
376
- "✅ Perfect" if len(execution_times) == len(results) else "⚠️ Some failures")
377
- table.add_row("Consistency", f"±{(max_time - min_time):.2f}s",
378
- "✅ Consistent" if (max_time - min_time) <= target * 0.2 else "⚠️ Variable")
373
+ table.add_row("Average Time", f"{avg_time:.2f}s", "✅ Good" if avg_time <= target else "⚠️ Needs optimization")
374
+ table.add_row("Best Time", f"{min_time:.2f}s", "🏆 Excellent" if min_time <= target * 0.5 else " Good")
375
+ table.add_row("Worst Time", f"{max_time:.2f}s", "⚠️ Investigate" if max_time > target * 1.5 else "✅ Acceptable")
376
+ table.add_row(
377
+ "Success Rate",
378
+ f"{len(execution_times)}/{len(results)}",
379
+ " Perfect" if len(execution_times) == len(results) else "⚠️ Some failures",
380
+ )
381
+ table.add_row(
382
+ "Consistency",
383
+ f"±{(max_time - min_time):.2f}s",
384
+ "✅ Consistent" if (max_time - min_time) <= target * 0.2 else "⚠️ Variable",
385
+ )
379
386
 
380
387
  console.print(table)
381
388
 
382
389
 
383
- def get_performance_report(module_name: Optional[str] = None,
384
- last_n_operations: int = 10) -> Dict[str, Any]:
390
+ def get_performance_report(module_name: Optional[str] = None, last_n_operations: int = 10) -> Dict[str, Any]:
385
391
  """
386
392
  Generate performance report for operations.
387
393
 
@@ -395,8 +401,7 @@ def get_performance_report(module_name: Optional[str] = None,
395
401
  # Filter operations
396
402
  filtered_operations = _performance_history
397
403
  if module_name:
398
- filtered_operations = [op for op in filtered_operations
399
- if op.module_name == module_name]
404
+ filtered_operations = [op for op in filtered_operations if op.module_name == module_name]
400
405
 
401
406
  # Get recent operations
402
407
  recent_operations = filtered_operations[-last_n_operations:]
@@ -418,10 +423,10 @@ def get_performance_report(module_name: Optional[str] = None,
418
423
  "failed_operations": len(failed_ops),
419
424
  "success_rate_percent": (len(successful_ops) / len(recent_operations)) * 100,
420
425
  "average_execution_time": round(avg_time, 2),
421
- "average_efficiency_score": round(avg_efficiency, 1)
426
+ "average_efficiency_score": round(avg_efficiency, 1),
422
427
  },
423
428
  "operations": [op.to_dict() for op in recent_operations],
424
- "recommendations": _generate_performance_recommendations(recent_operations)
429
+ "recommendations": _generate_performance_recommendations(recent_operations),
425
430
  }
426
431
 
427
432
  return report
@@ -435,17 +440,12 @@ def _generate_performance_recommendations(operations: List[PerformanceMetrics])
435
440
  return recommendations
436
441
 
437
442
  # Analyze patterns
438
- slow_operations = [op for op in operations
439
- if op.success and op.performance_ratio > 1.5]
440
- high_memory_operations = [op for op in operations
441
- if op.memory_peak_mb > 150]
442
- high_api_operations = [op for op in operations
443
- if op.api_calls_count > 50]
443
+ slow_operations = [op for op in operations if op.success and op.performance_ratio > 1.5]
444
+ high_memory_operations = [op for op in operations if op.memory_peak_mb > 150]
445
+ high_api_operations = [op for op in operations if op.api_calls_count > 50]
444
446
 
445
447
  if slow_operations:
446
- recommendations.append(
447
- f"⚠️ {len(slow_operations)} operations exceeded target by >50% - consider optimization"
448
- )
448
+ recommendations.append(f"⚠️ {len(slow_operations)} operations exceeded target by >50% - consider optimization")
449
449
 
450
450
  if high_memory_operations:
451
451
  recommendations.append(
@@ -453,16 +453,12 @@ def _generate_performance_recommendations(operations: List[PerformanceMetrics])
453
453
  )
454
454
 
455
455
  if high_api_operations:
456
- recommendations.append(
457
- f"🔄 {len(high_api_operations)} operations made >50 API calls - consider caching"
458
- )
456
+ recommendations.append(f"🔄 {len(high_api_operations)} operations made >50 API calls - consider caching")
459
457
 
460
458
  # Success rate recommendations
461
459
  failed_ops = [op for op in operations if not op.success]
462
460
  if len(failed_ops) > len(operations) * 0.1: # >10% failure rate
463
- recommendations.append(
464
- "❌ High failure rate detected - review error handling and retry logic"
465
- )
461
+ recommendations.append("❌ High failure rate detected - review error handling and retry logic")
466
462
 
467
463
  return recommendations
468
464
 
@@ -487,7 +483,7 @@ def export_performance_data(output_path: str = "performance_report.json") -> boo
487
483
  try:
488
484
  report = get_performance_report()
489
485
 
490
- with open(output_path, 'w') as f:
486
+ with open(output_path, "w") as f:
491
487
  json.dump(report, f, indent=2)
492
488
 
493
489
  print_success(f"Performance data exported to {output_path}")
@@ -508,5 +504,5 @@ __all__ = [
508
504
  "reset_api_counter",
509
505
  "get_performance_report",
510
506
  "clear_performance_history",
511
- "export_performance_data"
512
- ]
507
+ "export_performance_data",
508
+ ]