runbooks 1.1.4__py3-none-any.whl → 1.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- runbooks/__init__.py +31 -2
- runbooks/__init___optimized.py +18 -4
- runbooks/_platform/__init__.py +1 -5
- runbooks/_platform/core/runbooks_wrapper.py +141 -138
- runbooks/aws2/accuracy_validator.py +812 -0
- runbooks/base.py +7 -0
- runbooks/cfat/assessment/compliance.py +1 -1
- runbooks/cfat/assessment/runner.py +1 -0
- runbooks/cfat/cloud_foundations_assessment.py +227 -239
- runbooks/cli/__init__.py +1 -1
- runbooks/cli/commands/cfat.py +64 -23
- runbooks/cli/commands/finops.py +1005 -54
- runbooks/cli/commands/inventory.py +135 -91
- runbooks/cli/commands/operate.py +9 -36
- runbooks/cli/commands/security.py +42 -18
- runbooks/cli/commands/validation.py +432 -18
- runbooks/cli/commands/vpc.py +81 -17
- runbooks/cli/registry.py +22 -10
- runbooks/cloudops/__init__.py +20 -27
- runbooks/cloudops/base.py +96 -107
- runbooks/cloudops/cost_optimizer.py +544 -542
- runbooks/cloudops/infrastructure_optimizer.py +5 -4
- runbooks/cloudops/interfaces.py +224 -225
- runbooks/cloudops/lifecycle_manager.py +5 -4
- runbooks/cloudops/mcp_cost_validation.py +252 -235
- runbooks/cloudops/models.py +78 -53
- runbooks/cloudops/monitoring_automation.py +5 -4
- runbooks/cloudops/notebook_framework.py +177 -213
- runbooks/cloudops/security_enforcer.py +125 -159
- runbooks/common/accuracy_validator.py +17 -12
- runbooks/common/aws_pricing.py +349 -326
- runbooks/common/aws_pricing_api.py +211 -212
- runbooks/common/aws_profile_manager.py +40 -36
- runbooks/common/aws_utils.py +74 -79
- runbooks/common/business_logic.py +126 -104
- runbooks/common/cli_decorators.py +36 -60
- runbooks/common/comprehensive_cost_explorer_integration.py +455 -463
- runbooks/common/cross_account_manager.py +197 -204
- runbooks/common/date_utils.py +27 -39
- runbooks/common/decorators.py +29 -19
- runbooks/common/dry_run_examples.py +173 -208
- runbooks/common/dry_run_framework.py +157 -155
- runbooks/common/enhanced_exception_handler.py +15 -4
- runbooks/common/enhanced_logging_example.py +50 -64
- runbooks/common/enhanced_logging_integration_example.py +65 -37
- runbooks/common/env_utils.py +16 -16
- runbooks/common/error_handling.py +40 -38
- runbooks/common/lazy_loader.py +41 -23
- runbooks/common/logging_integration_helper.py +79 -86
- runbooks/common/mcp_cost_explorer_integration.py +476 -493
- runbooks/common/mcp_integration.py +99 -79
- runbooks/common/memory_optimization.py +140 -118
- runbooks/common/module_cli_base.py +37 -58
- runbooks/common/organizations_client.py +175 -193
- runbooks/common/patterns.py +23 -25
- runbooks/common/performance_monitoring.py +67 -71
- runbooks/common/performance_optimization_engine.py +283 -274
- runbooks/common/profile_utils.py +111 -37
- runbooks/common/rich_utils.py +315 -141
- runbooks/common/sre_performance_suite.py +177 -186
- runbooks/enterprise/__init__.py +1 -1
- runbooks/enterprise/logging.py +144 -106
- runbooks/enterprise/security.py +187 -204
- runbooks/enterprise/validation.py +43 -56
- runbooks/finops/__init__.py +26 -30
- runbooks/finops/account_resolver.py +1 -1
- runbooks/finops/advanced_optimization_engine.py +980 -0
- runbooks/finops/automation_core.py +268 -231
- runbooks/finops/business_case_config.py +184 -179
- runbooks/finops/cli.py +660 -139
- runbooks/finops/commvault_ec2_analysis.py +157 -164
- runbooks/finops/compute_cost_optimizer.py +336 -320
- runbooks/finops/config.py +20 -20
- runbooks/finops/cost_optimizer.py +484 -618
- runbooks/finops/cost_processor.py +332 -214
- runbooks/finops/dashboard_runner.py +1006 -172
- runbooks/finops/ebs_cost_optimizer.py +991 -657
- runbooks/finops/elastic_ip_optimizer.py +317 -257
- runbooks/finops/enhanced_mcp_integration.py +340 -0
- runbooks/finops/enhanced_progress.py +32 -29
- runbooks/finops/enhanced_trend_visualization.py +3 -2
- runbooks/finops/enterprise_wrappers.py +223 -285
- runbooks/finops/executive_export.py +203 -160
- runbooks/finops/helpers.py +130 -288
- runbooks/finops/iam_guidance.py +1 -1
- runbooks/finops/infrastructure/__init__.py +80 -0
- runbooks/finops/infrastructure/commands.py +506 -0
- runbooks/finops/infrastructure/load_balancer_optimizer.py +866 -0
- runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +832 -0
- runbooks/finops/markdown_exporter.py +337 -174
- runbooks/finops/mcp_validator.py +1952 -0
- runbooks/finops/nat_gateway_optimizer.py +1512 -481
- runbooks/finops/network_cost_optimizer.py +657 -587
- runbooks/finops/notebook_utils.py +226 -188
- runbooks/finops/optimization_engine.py +1136 -0
- runbooks/finops/optimizer.py +19 -23
- runbooks/finops/rds_snapshot_optimizer.py +367 -411
- runbooks/finops/reservation_optimizer.py +427 -363
- runbooks/finops/scenario_cli_integration.py +64 -65
- runbooks/finops/scenarios.py +1277 -438
- runbooks/finops/schemas.py +218 -182
- runbooks/finops/snapshot_manager.py +2289 -0
- runbooks/finops/types.py +3 -3
- runbooks/finops/validation_framework.py +259 -265
- runbooks/finops/vpc_cleanup_exporter.py +189 -144
- runbooks/finops/vpc_cleanup_optimizer.py +591 -573
- runbooks/finops/workspaces_analyzer.py +171 -182
- runbooks/integration/__init__.py +89 -0
- runbooks/integration/mcp_integration.py +1920 -0
- runbooks/inventory/CLAUDE.md +816 -0
- runbooks/inventory/__init__.py +2 -2
- runbooks/inventory/aws_decorators.py +2 -3
- runbooks/inventory/check_cloudtrail_compliance.py +2 -4
- runbooks/inventory/check_controltower_readiness.py +152 -151
- runbooks/inventory/check_landingzone_readiness.py +85 -84
- runbooks/inventory/cloud_foundations_integration.py +144 -149
- runbooks/inventory/collectors/aws_comprehensive.py +1 -1
- runbooks/inventory/collectors/aws_networking.py +109 -99
- runbooks/inventory/collectors/base.py +4 -0
- runbooks/inventory/core/collector.py +495 -313
- runbooks/inventory/core/formatter.py +11 -0
- runbooks/inventory/draw_org_structure.py +8 -9
- runbooks/inventory/drift_detection_cli.py +69 -96
- runbooks/inventory/ec2_vpc_utils.py +2 -2
- runbooks/inventory/find_cfn_drift_detection.py +5 -7
- runbooks/inventory/find_cfn_orphaned_stacks.py +7 -9
- runbooks/inventory/find_cfn_stackset_drift.py +5 -6
- runbooks/inventory/find_ec2_security_groups.py +48 -42
- runbooks/inventory/find_landingzone_versions.py +4 -6
- runbooks/inventory/find_vpc_flow_logs.py +7 -9
- runbooks/inventory/inventory_mcp_cli.py +48 -46
- runbooks/inventory/inventory_modules.py +103 -91
- runbooks/inventory/list_cfn_stacks.py +9 -10
- runbooks/inventory/list_cfn_stackset_operation_results.py +1 -3
- runbooks/inventory/list_cfn_stackset_operations.py +79 -57
- runbooks/inventory/list_cfn_stacksets.py +8 -10
- runbooks/inventory/list_config_recorders_delivery_channels.py +49 -39
- runbooks/inventory/list_ds_directories.py +65 -53
- runbooks/inventory/list_ec2_availability_zones.py +2 -4
- runbooks/inventory/list_ec2_ebs_volumes.py +32 -35
- runbooks/inventory/list_ec2_instances.py +23 -28
- runbooks/inventory/list_ecs_clusters_and_tasks.py +26 -34
- runbooks/inventory/list_elbs_load_balancers.py +22 -20
- runbooks/inventory/list_enis_network_interfaces.py +26 -33
- runbooks/inventory/list_guardduty_detectors.py +2 -4
- runbooks/inventory/list_iam_policies.py +2 -4
- runbooks/inventory/list_iam_roles.py +5 -7
- runbooks/inventory/list_iam_saml_providers.py +4 -6
- runbooks/inventory/list_lambda_functions.py +38 -38
- runbooks/inventory/list_org_accounts.py +6 -8
- runbooks/inventory/list_org_accounts_users.py +55 -44
- runbooks/inventory/list_rds_db_instances.py +31 -33
- runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
- runbooks/inventory/list_route53_hosted_zones.py +3 -5
- runbooks/inventory/list_servicecatalog_provisioned_products.py +37 -41
- runbooks/inventory/list_sns_topics.py +2 -4
- runbooks/inventory/list_ssm_parameters.py +4 -7
- runbooks/inventory/list_vpc_subnets.py +2 -4
- runbooks/inventory/list_vpcs.py +7 -10
- runbooks/inventory/mcp_inventory_validator.py +554 -468
- runbooks/inventory/mcp_vpc_validator.py +359 -442
- runbooks/inventory/organizations_discovery.py +63 -55
- runbooks/inventory/recover_cfn_stack_ids.py +7 -8
- runbooks/inventory/requirements.txt +0 -1
- runbooks/inventory/rich_inventory_display.py +35 -34
- runbooks/inventory/run_on_multi_accounts.py +3 -5
- runbooks/inventory/unified_validation_engine.py +281 -253
- runbooks/inventory/verify_ec2_security_groups.py +1 -1
- runbooks/inventory/vpc_analyzer.py +735 -697
- runbooks/inventory/vpc_architecture_validator.py +293 -348
- runbooks/inventory/vpc_dependency_analyzer.py +384 -380
- runbooks/inventory/vpc_flow_analyzer.py +1 -1
- runbooks/main.py +49 -34
- runbooks/main_final.py +91 -60
- runbooks/main_minimal.py +22 -10
- runbooks/main_optimized.py +131 -100
- runbooks/main_ultra_minimal.py +7 -2
- runbooks/mcp/__init__.py +36 -0
- runbooks/mcp/integration.py +679 -0
- runbooks/monitoring/performance_monitor.py +9 -4
- runbooks/operate/dynamodb_operations.py +3 -1
- runbooks/operate/ec2_operations.py +145 -137
- runbooks/operate/iam_operations.py +146 -152
- runbooks/operate/networking_cost_heatmap.py +29 -8
- runbooks/operate/rds_operations.py +223 -254
- runbooks/operate/s3_operations.py +107 -118
- runbooks/operate/vpc_operations.py +646 -616
- runbooks/remediation/base.py +1 -1
- runbooks/remediation/commons.py +10 -7
- runbooks/remediation/commvault_ec2_analysis.py +70 -66
- runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
- runbooks/remediation/multi_account.py +24 -21
- runbooks/remediation/rds_snapshot_list.py +86 -60
- runbooks/remediation/remediation_cli.py +92 -146
- runbooks/remediation/universal_account_discovery.py +83 -79
- runbooks/remediation/workspaces_list.py +46 -41
- runbooks/security/__init__.py +19 -0
- runbooks/security/assessment_runner.py +1150 -0
- runbooks/security/baseline_checker.py +812 -0
- runbooks/security/cloudops_automation_security_validator.py +509 -535
- runbooks/security/compliance_automation_engine.py +17 -17
- runbooks/security/config/__init__.py +2 -2
- runbooks/security/config/compliance_config.py +50 -50
- runbooks/security/config_template_generator.py +63 -76
- runbooks/security/enterprise_security_framework.py +1 -1
- runbooks/security/executive_security_dashboard.py +519 -508
- runbooks/security/multi_account_security_controls.py +959 -1210
- runbooks/security/real_time_security_monitor.py +422 -444
- runbooks/security/security_baseline_tester.py +1 -1
- runbooks/security/security_cli.py +143 -112
- runbooks/security/test_2way_validation.py +439 -0
- runbooks/security/two_way_validation_framework.py +852 -0
- runbooks/sre/production_monitoring_framework.py +167 -177
- runbooks/tdd/__init__.py +15 -0
- runbooks/tdd/cli.py +1071 -0
- runbooks/utils/__init__.py +14 -17
- runbooks/utils/logger.py +7 -2
- runbooks/utils/version_validator.py +50 -47
- runbooks/validation/__init__.py +6 -6
- runbooks/validation/cli.py +9 -3
- runbooks/validation/comprehensive_2way_validator.py +745 -704
- runbooks/validation/mcp_validator.py +906 -228
- runbooks/validation/terraform_citations_validator.py +104 -115
- runbooks/validation/terraform_drift_detector.py +461 -454
- runbooks/vpc/README.md +617 -0
- runbooks/vpc/__init__.py +8 -1
- runbooks/vpc/analyzer.py +577 -0
- runbooks/vpc/cleanup_wrapper.py +476 -413
- runbooks/vpc/cli_cloudtrail_commands.py +339 -0
- runbooks/vpc/cli_mcp_validation_commands.py +480 -0
- runbooks/vpc/cloudtrail_audit_integration.py +717 -0
- runbooks/vpc/config.py +92 -97
- runbooks/vpc/cost_engine.py +411 -148
- runbooks/vpc/cost_explorer_integration.py +553 -0
- runbooks/vpc/cross_account_session.py +101 -106
- runbooks/vpc/enhanced_mcp_validation.py +917 -0
- runbooks/vpc/eni_gate_validator.py +961 -0
- runbooks/vpc/heatmap_engine.py +185 -160
- runbooks/vpc/mcp_no_eni_validator.py +680 -639
- runbooks/vpc/nat_gateway_optimizer.py +358 -0
- runbooks/vpc/networking_wrapper.py +15 -8
- runbooks/vpc/pdca_remediation_planner.py +528 -0
- runbooks/vpc/performance_optimized_analyzer.py +219 -231
- runbooks/vpc/runbooks_adapter.py +1167 -241
- runbooks/vpc/tdd_red_phase_stubs.py +601 -0
- runbooks/vpc/test_data_loader.py +358 -0
- runbooks/vpc/tests/conftest.py +314 -4
- runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
- runbooks/vpc/tests/test_cost_engine.py +0 -2
- runbooks/vpc/topology_generator.py +326 -0
- runbooks/vpc/unified_scenarios.py +1297 -1124
- runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
- runbooks-1.1.6.dist-info/METADATA +327 -0
- runbooks-1.1.6.dist-info/RECORD +489 -0
- runbooks/finops/README.md +0 -414
- runbooks/finops/accuracy_cross_validator.py +0 -647
- runbooks/finops/business_cases.py +0 -950
- runbooks/finops/dashboard_router.py +0 -922
- runbooks/finops/ebs_optimizer.py +0 -973
- runbooks/finops/embedded_mcp_validator.py +0 -1629
- runbooks/finops/enhanced_dashboard_runner.py +0 -527
- runbooks/finops/finops_dashboard.py +0 -584
- runbooks/finops/finops_scenarios.py +0 -1218
- runbooks/finops/legacy_migration.py +0 -730
- runbooks/finops/multi_dashboard.py +0 -1519
- runbooks/finops/single_dashboard.py +0 -1113
- runbooks/finops/unlimited_scenarios.py +0 -393
- runbooks-1.1.4.dist-info/METADATA +0 -800
- runbooks-1.1.4.dist-info/RECORD +0 -468
- {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/WHEEL +0 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/entry_points.txt +0 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/licenses/LICENSE +0 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.6.dist-info}/top_level.txt +0 -0
runbooks/common/patterns.py
CHANGED
@@ -81,17 +81,17 @@ class DRYPatternManager:
|
|
81
81
|
return
|
82
82
|
|
83
83
|
# Common import patterns
|
84
|
-
cls._patterns[
|
85
|
-
cls._patterns[
|
84
|
+
cls._patterns["click"] = click
|
85
|
+
cls._patterns["console"] = cls.get_console()
|
86
86
|
|
87
87
|
# Error handling patterns
|
88
|
-
cls._patterns[
|
88
|
+
cls._patterns["error_handlers"] = cls._create_error_handlers()
|
89
89
|
|
90
90
|
# Click group patterns
|
91
|
-
cls._patterns[
|
91
|
+
cls._patterns["click_group"] = cls._create_click_group_pattern()
|
92
92
|
|
93
93
|
# Common CLI decorators reference
|
94
|
-
cls._patterns[
|
94
|
+
cls._patterns["common_decorators"] = cls._get_common_decorators()
|
95
95
|
|
96
96
|
cls._loaded = True
|
97
97
|
|
@@ -119,9 +119,9 @@ class DRYPatternManager:
|
|
119
119
|
console.print(f"[dim]{details}[/dim]")
|
120
120
|
|
121
121
|
return {
|
122
|
-
|
123
|
-
|
124
|
-
|
122
|
+
"module_not_available": module_not_available_error,
|
123
|
+
"operation_failed": operation_failed_error,
|
124
|
+
"success": success_message,
|
125
125
|
}
|
126
126
|
|
127
127
|
@classmethod
|
@@ -131,6 +131,7 @@ class DRYPatternManager:
|
|
131
131
|
|
132
132
|
Eliminates 6 instances of identical @click.group patterns.
|
133
133
|
"""
|
134
|
+
|
134
135
|
def create_group(name: str, help_text: str, invoke_without_command: bool = True):
|
135
136
|
"""Create standardized Click group with common options."""
|
136
137
|
|
@@ -153,15 +154,12 @@ class DRYPatternManager:
|
|
153
154
|
def _get_common_decorators(cls):
|
154
155
|
"""Reference to common decorators - avoid importing in every module."""
|
155
156
|
try:
|
156
|
-
from runbooks.common.decorators import
|
157
|
-
|
158
|
-
common_output_options,
|
159
|
-
common_filter_options
|
160
|
-
)
|
157
|
+
from runbooks.common.decorators import common_aws_options, common_output_options, common_filter_options
|
158
|
+
|
161
159
|
return {
|
162
|
-
|
163
|
-
|
164
|
-
|
160
|
+
"aws_options": common_aws_options,
|
161
|
+
"output_options": common_output_options,
|
162
|
+
"filter_options": common_filter_options,
|
165
163
|
}
|
166
164
|
except ImportError:
|
167
165
|
# Graceful degradation if decorators not available
|
@@ -176,17 +174,17 @@ def get_console() -> Console:
|
|
176
174
|
|
177
175
|
def get_error_handlers() -> Dict[str, Callable]:
|
178
176
|
"""Get standardized error handlers."""
|
179
|
-
return DRYPatternManager.get_pattern(
|
177
|
+
return DRYPatternManager.get_pattern("error_handlers")
|
180
178
|
|
181
179
|
|
182
180
|
def get_click_group_creator() -> Callable:
|
183
181
|
"""Get standardized Click group creator."""
|
184
|
-
return DRYPatternManager.get_pattern(
|
182
|
+
return DRYPatternManager.get_pattern("click_group")
|
185
183
|
|
186
184
|
|
187
185
|
def get_common_decorators() -> Dict[str, Any]:
|
188
186
|
"""Get common CLI decorators."""
|
189
|
-
return DRYPatternManager.get_pattern(
|
187
|
+
return DRYPatternManager.get_pattern("common_decorators")
|
190
188
|
|
191
189
|
|
192
190
|
# Pattern registry status for monitoring
|
@@ -198,9 +196,9 @@ def get_pattern_registry_status() -> Dict[str, Any]:
|
|
198
196
|
Dictionary containing registry status, loaded patterns, and memory efficiency metrics
|
199
197
|
"""
|
200
198
|
return {
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
}
|
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,
|
29
|
-
|
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
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
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(
|
111
|
-
|
112
|
-
|
113
|
-
|
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(
|
170
|
-
metrics.resources_processed = result.get(
|
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
|
-
|
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
|
-
|
371
|
-
table.add_row("
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
table.add_row(
|
378
|
-
|
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
|
-
|
440
|
-
|
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,
|
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
|
+
]
|