runbooks 1.1.2__py3-none-any.whl → 1.1.4__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 +1 -1
- runbooks/cfat/WEIGHT_CONFIG_README.md +1 -1
- runbooks/cfat/assessment/compliance.py +7 -7
- runbooks/cfat/models.py +6 -2
- runbooks/cfat/tests/__init__.py +6 -1
- runbooks/cli/__init__.py +13 -0
- runbooks/cli/commands/cfat.py +233 -0
- runbooks/cli/commands/finops.py +213 -0
- runbooks/cli/commands/inventory.py +276 -0
- runbooks/cli/commands/operate.py +266 -0
- runbooks/cli/commands/security.py +224 -0
- runbooks/cli/commands/validation.py +411 -0
- runbooks/cli/commands/vpc.py +246 -0
- runbooks/cli/registry.py +95 -0
- runbooks/cloudops/__init__.py +3 -3
- runbooks/cloudops/cost_optimizer.py +164 -28
- runbooks/cloudops/interfaces.py +2 -2
- runbooks/cloudops/mcp_cost_validation.py +3 -3
- runbooks/cloudops/notebook_framework.py +2 -2
- runbooks/common/aws_profile_manager.py +337 -0
- runbooks/common/aws_utils.py +1 -1
- runbooks/common/business_logic.py +3 -3
- runbooks/common/comprehensive_cost_explorer_integration.py +1 -1
- runbooks/common/cross_account_manager.py +1 -1
- runbooks/common/decorators.py +225 -0
- runbooks/common/mcp_cost_explorer_integration.py +2 -2
- runbooks/common/organizations_client.py +1 -1
- runbooks/common/patterns.py +206 -0
- runbooks/common/profile_utils.py +149 -14
- runbooks/common/rich_utils.py +507 -16
- runbooks/finops/README.md +11 -11
- runbooks/finops/__init__.py +4 -4
- runbooks/finops/business_cases.py +3 -3
- runbooks/finops/cli.py +169 -103
- runbooks/finops/cost_optimizer.py +4 -4
- runbooks/finops/dashboard_router.py +2 -2
- runbooks/finops/ebs_cost_optimizer.py +4 -4
- runbooks/finops/ebs_optimizer.py +19 -2
- runbooks/finops/embedded_mcp_validator.py +101 -23
- runbooks/finops/enhanced_progress.py +8 -8
- runbooks/finops/enterprise_wrappers.py +7 -7
- runbooks/finops/finops_scenarios.py +101 -27
- runbooks/finops/legacy_migration.py +8 -8
- runbooks/finops/markdown_exporter.py +2 -2
- runbooks/finops/multi_dashboard.py +1 -1
- runbooks/finops/nat_gateway_optimizer.py +1 -1
- runbooks/finops/optimizer.py +6 -6
- runbooks/finops/rds_snapshot_optimizer.py +1389 -0
- runbooks/finops/scenario_cli_integration.py +13 -13
- runbooks/finops/scenarios.py +16 -16
- runbooks/finops/single_dashboard.py +10 -10
- runbooks/finops/tests/test_finops_dashboard.py +3 -3
- runbooks/finops/tests/test_reference_images_validation.py +2 -2
- runbooks/finops/tests/test_single_account_features.py +17 -17
- runbooks/finops/tests/validate_test_suite.py +1 -1
- runbooks/finops/validation_framework.py +5 -5
- runbooks/finops/vpc_cleanup_exporter.py +3 -3
- runbooks/finops/vpc_cleanup_optimizer.py +3 -3
- runbooks/finops/workspaces_analyzer.py +31 -13
- runbooks/hitl/enhanced_workflow_engine.py +1 -1
- runbooks/inventory/README.md +3 -3
- runbooks/inventory/Tests/common_test_data.py +30 -30
- runbooks/inventory/collectors/aws_comprehensive.py +28 -11
- runbooks/inventory/collectors/aws_networking.py +2 -2
- runbooks/inventory/discovery.md +2 -2
- runbooks/inventory/find_ec2_security_groups.py +1 -1
- runbooks/inventory/list_rds_snapshots_aggregator.py +745 -0
- runbooks/inventory/organizations_discovery.py +1 -1
- runbooks/inventory/vpc_analyzer.py +1 -1
- runbooks/inventory/vpc_flow_analyzer.py +2 -2
- runbooks/main.py +143 -8882
- runbooks/metrics/dora_metrics_engine.py +2 -2
- runbooks/operate/mcp_integration.py +1 -1
- runbooks/operate/networking_cost_heatmap.py +4 -2
- runbooks/operate/privatelink_operations.py +1 -1
- runbooks/operate/vpc_endpoints.py +1 -1
- runbooks/operate/vpc_operations.py +2 -2
- runbooks/remediation/commvault_ec2_analysis.py +1 -1
- runbooks/remediation/rds_snapshot_list.py +5 -5
- runbooks/remediation/workspaces_list.py +5 -5
- runbooks/security/integration_test_enterprise_security.py +5 -3
- runbooks/security/run_script.py +1 -1
- runbooks/sre/mcp_reliability_engine.py +6 -6
- runbooks/utils/version_validator.py +1 -1
- runbooks/validation/comprehensive_2way_validator.py +9 -4
- runbooks/vpc/heatmap_engine.py +7 -4
- runbooks/vpc/mcp_no_eni_validator.py +1 -1
- runbooks/vpc/unified_scenarios.py +7 -7
- {runbooks-1.1.2.dist-info → runbooks-1.1.4.dist-info}/METADATA +53 -52
- {runbooks-1.1.2.dist-info → runbooks-1.1.4.dist-info}/RECORD +94 -80
- {runbooks-1.1.2.dist-info → runbooks-1.1.4.dist-info}/WHEEL +0 -0
- {runbooks-1.1.2.dist-info → runbooks-1.1.4.dist-info}/entry_points.txt +0 -0
- {runbooks-1.1.2.dist-info → runbooks-1.1.4.dist-info}/licenses/LICENSE +0 -0
- {runbooks-1.1.2.dist-info → runbooks-1.1.4.dist-info}/top_level.txt +0 -0
@@ -28,7 +28,7 @@ class SimplifiedScenarioMessaging:
|
|
28
28
|
"""
|
29
29
|
Simplified scenario messaging system for 75% console operation reduction.
|
30
30
|
|
31
|
-
|
31
|
+
Phase 2 Enhancement: Consolidates multiple console operations into
|
32
32
|
template-based single panel displays while preserving all information content.
|
33
33
|
|
34
34
|
Target: 75% reduction in console operations through panel consolidation.
|
@@ -101,7 +101,7 @@ class SimplifiedScenarioMessaging:
|
|
101
101
|
self.console.print(suggestion_panel)
|
102
102
|
|
103
103
|
def get_consolidation_metrics(self) -> Dict[str, Any]:
|
104
|
-
"""Get consolidation efficiency metrics for
|
104
|
+
"""Get consolidation efficiency metrics for Phase 2 validation."""
|
105
105
|
if self.operation_count == 0:
|
106
106
|
return {"efficiency": 0.0, "operations_saved": 0}
|
107
107
|
|
@@ -157,7 +157,7 @@ class ScenarioCliHelper:
|
|
157
157
|
"""
|
158
158
|
CLI integration helper for business scenario intelligence.
|
159
159
|
|
160
|
-
|
160
|
+
Phase 2 Enhanced: Integrates SimplifiedScenarioMessaging for 75% console
|
161
161
|
operation reduction while providing intelligent parameter recommendations.
|
162
162
|
"""
|
163
163
|
|
@@ -167,7 +167,7 @@ class ScenarioCliHelper:
|
|
167
167
|
self.business_config = get_business_case_config()
|
168
168
|
self.scenario_matrix = get_business_scenario_matrix()
|
169
169
|
|
170
|
-
#
|
170
|
+
# Phase 2 Enhancement: Integrate simplified messaging system
|
171
171
|
self.simplified_messaging = SimplifiedScenarioMessaging(self.console)
|
172
172
|
self.audit_trail = []
|
173
173
|
|
@@ -184,7 +184,7 @@ class ScenarioCliHelper:
|
|
184
184
|
"""
|
185
185
|
Display detailed help for a single scenario using simplified messaging.
|
186
186
|
|
187
|
-
|
187
|
+
Phase 2 Enhancement: Uses simplified messaging to reduce console operations
|
188
188
|
by 75% while preserving all information content.
|
189
189
|
"""
|
190
190
|
scenario_config = self.business_config.get_scenario(scenario_key)
|
@@ -192,13 +192,13 @@ class ScenarioCliHelper:
|
|
192
192
|
print_warning(f"Unknown scenario: {scenario_key}")
|
193
193
|
return
|
194
194
|
|
195
|
-
#
|
195
|
+
# Phase 2: Use simplified messaging for scenario overview (5 prints → 1 panel)
|
196
196
|
self.simplified_messaging.display_scenario_overview(scenario_config)
|
197
197
|
|
198
198
|
# Display parameter recommendations using simplified messaging
|
199
199
|
recommendations = self.scenario_matrix.get_parameter_recommendations(scenario_key)
|
200
200
|
if recommendations:
|
201
|
-
#
|
201
|
+
# Phase 2: Use simplified messaging for parameters (multiple prints → 1 panel)
|
202
202
|
self.simplified_messaging.display_parameter_recommendations(recommendations)
|
203
203
|
|
204
204
|
# Display optimal command in consolidated format
|
@@ -212,7 +212,7 @@ class ScenarioCliHelper:
|
|
212
212
|
else:
|
213
213
|
print_info("Using standard parameters for this scenario")
|
214
214
|
|
215
|
-
# Audit trail for
|
215
|
+
# Audit trail for Phase 2 compliance
|
216
216
|
self.audit_trail.append({
|
217
217
|
"action": "single_scenario_help",
|
218
218
|
"scenario": scenario_key,
|
@@ -318,12 +318,12 @@ class ScenarioCliHelper:
|
|
318
318
|
"""
|
319
319
|
Validate and provide suggestions using simplified messaging.
|
320
320
|
|
321
|
-
|
321
|
+
Phase 2 Enhancement: Uses simplified messaging to consolidate suggestion display.
|
322
322
|
"""
|
323
323
|
suggestions = self.scenario_matrix.validate_parameters_for_scenario(scenario_key, provided_params)
|
324
324
|
|
325
325
|
if suggestions:
|
326
|
-
#
|
326
|
+
# Phase 2: Use simplified messaging for suggestions
|
327
327
|
self.simplified_messaging.display_optimization_suggestions(scenario_key, suggestions)
|
328
328
|
|
329
329
|
# Audit trail
|
@@ -344,9 +344,9 @@ class ScenarioCliHelper:
|
|
344
344
|
base_help = self.business_config.get_scenario_help_text()
|
345
345
|
return f"{base_help}\n\nUse --scenario [scenario-name] for specific optimization analysis."
|
346
346
|
|
347
|
-
def
|
347
|
+
def get_console_performance_metrics(self) -> Dict[str, Any]:
|
348
348
|
"""
|
349
|
-
Get
|
349
|
+
Get Phase 2 performance metrics for enterprise audit compliance.
|
350
350
|
|
351
351
|
Returns consolidated metrics for:
|
352
352
|
- Message simplification efficiency (75% target)
|
@@ -356,7 +356,7 @@ class ScenarioCliHelper:
|
|
356
356
|
messaging_metrics = self.simplified_messaging.get_consolidation_metrics()
|
357
357
|
|
358
358
|
return {
|
359
|
-
"
|
359
|
+
"console_enhancement": "Console log improvements with message simplification",
|
360
360
|
"message_consolidation": messaging_metrics,
|
361
361
|
"audit_trail": {
|
362
362
|
"total_operations": len(self.audit_trail),
|
runbooks/finops/scenarios.py
CHANGED
@@ -6,8 +6,8 @@ scenarios in Jupyter notebooks and external applications. It abstracts the compl
|
|
6
6
|
of the underlying finops_scenarios.py and business_cases.py modules.
|
7
7
|
|
8
8
|
Strategic Achievement: $132,720+ annual savings (380-757% above targets)
|
9
|
-
- FinOps-24: WorkSpaces cleanup (
|
10
|
-
- FinOps-23: RDS snapshots optimization (
|
9
|
+
- FinOps-24: WorkSpaces cleanup (significant annual savings, 104% of target)
|
10
|
+
- FinOps-23: RDS snapshots optimization (significant annual savings, 498% of target)
|
11
11
|
- FinOps-25: Commvault EC2 investigation framework (methodology established)
|
12
12
|
|
13
13
|
API Functions for Notebook Integration:
|
@@ -72,7 +72,7 @@ def finops_workspaces(profile: Optional[str] = None, accounts: Optional[List[str
|
|
72
72
|
Clean API wrapper for Jupyter notebook consumption that provides
|
73
73
|
comprehensive WorkSpaces utilization analysis and cleanup recommendations.
|
74
74
|
|
75
|
-
Proven Result:
|
75
|
+
Proven Result: significant annual savings savings (104% of target achievement)
|
76
76
|
|
77
77
|
Args:
|
78
78
|
profile: AWS profile name for authentication (optional)
|
@@ -124,7 +124,7 @@ def finops_workspaces(profile: Optional[str] = None, accounts: Optional[List[str
|
|
124
124
|
'validation': {
|
125
125
|
'data_source': 'Error - AWS API unavailable',
|
126
126
|
'timestamp': datetime.now().isoformat(),
|
127
|
-
'version': '
|
127
|
+
'version': 'latest version'
|
128
128
|
}
|
129
129
|
}
|
130
130
|
|
@@ -168,7 +168,7 @@ def finops_workspaces(profile: Optional[str] = None, accounts: Optional[List[str
|
|
168
168
|
'data_source': 'Real AWS WorkSpaces API via runbooks',
|
169
169
|
'validation_method': 'Direct AWS API integration',
|
170
170
|
'timestamp': datetime.now().isoformat(),
|
171
|
-
'version': '
|
171
|
+
'version': 'latest version'
|
172
172
|
}
|
173
173
|
}
|
174
174
|
|
@@ -188,7 +188,7 @@ def finops_workspaces(profile: Optional[str] = None, accounts: Optional[List[str
|
|
188
188
|
'validation': {
|
189
189
|
'data_source': f'Error: {str(e)}',
|
190
190
|
'timestamp': datetime.now().isoformat(),
|
191
|
-
'version': '
|
191
|
+
'version': 'latest version'
|
192
192
|
}
|
193
193
|
}
|
194
194
|
|
@@ -200,7 +200,7 @@ def finops_snapshots(profile: Optional[str] = None, accounts: Optional[List[str]
|
|
200
200
|
Clean API wrapper for comprehensive RDS manual snapshots analysis
|
201
201
|
and storage cost optimization recommendations.
|
202
202
|
|
203
|
-
Proven Result:
|
203
|
+
Proven Result: significant annual savings savings (498% of target achievement)
|
204
204
|
|
205
205
|
Args:
|
206
206
|
profile: AWS profile name for authentication (optional)
|
@@ -253,7 +253,7 @@ def finops_snapshots(profile: Optional[str] = None, accounts: Optional[List[str]
|
|
253
253
|
'validation': {
|
254
254
|
'data_source': 'Error - AWS API unavailable',
|
255
255
|
'timestamp': datetime.now().isoformat(),
|
256
|
-
'version': '
|
256
|
+
'version': 'latest version'
|
257
257
|
}
|
258
258
|
}
|
259
259
|
|
@@ -301,7 +301,7 @@ def finops_snapshots(profile: Optional[str] = None, accounts: Optional[List[str]
|
|
301
301
|
'data_source': 'Real AWS RDS API via runbooks',
|
302
302
|
'validation_method': 'Direct AWS API integration',
|
303
303
|
'timestamp': datetime.now().isoformat(),
|
304
|
-
'version': '
|
304
|
+
'version': 'latest version'
|
305
305
|
}
|
306
306
|
}
|
307
307
|
|
@@ -321,7 +321,7 @@ def finops_snapshots(profile: Optional[str] = None, accounts: Optional[List[str]
|
|
321
321
|
'validation': {
|
322
322
|
'data_source': f'Error: {str(e)}',
|
323
323
|
'timestamp': datetime.now().isoformat(),
|
324
|
-
'version': '
|
324
|
+
'version': 'latest version'
|
325
325
|
}
|
326
326
|
}
|
327
327
|
|
@@ -384,7 +384,7 @@ def finops_commvault(profile: Optional[str] = None, account: Optional[str] = Non
|
|
384
384
|
'validation': {
|
385
385
|
'data_source': 'Error - Framework setup unavailable',
|
386
386
|
'timestamp': datetime.now().isoformat(),
|
387
|
-
'version': '
|
387
|
+
'version': 'latest version'
|
388
388
|
}
|
389
389
|
}
|
390
390
|
|
@@ -429,7 +429,7 @@ def finops_commvault(profile: Optional[str] = None, account: Optional[str] = Non
|
|
429
429
|
'validation_method': raw_analysis.get('investigation_results', {}).get('validation_method', 'Investigation framework'),
|
430
430
|
'framework_validation': 'Real AWS integration operational',
|
431
431
|
'timestamp': datetime.now().isoformat(),
|
432
|
-
'version': '
|
432
|
+
'version': 'latest version'
|
433
433
|
}
|
434
434
|
}
|
435
435
|
|
@@ -449,7 +449,7 @@ def finops_commvault(profile: Optional[str] = None, account: Optional[str] = Non
|
|
449
449
|
'validation': {
|
450
450
|
'data_source': f'Error: {str(e)}',
|
451
451
|
'timestamp': datetime.now().isoformat(),
|
452
|
-
'version': '
|
452
|
+
'version': 'latest version'
|
453
453
|
}
|
454
454
|
}
|
455
455
|
|
@@ -555,7 +555,7 @@ def get_business_scenarios_summary(scenarios: Optional[List[str]] = None) -> Dic
|
|
555
555
|
'accuracy_standard': '≥99.5% enterprise validation requirement',
|
556
556
|
'portfolio_validation': 'Cross-scenario validation operational',
|
557
557
|
'timestamp': datetime.now().isoformat(),
|
558
|
-
'version': '
|
558
|
+
'version': 'latest version'
|
559
559
|
}
|
560
560
|
}
|
561
561
|
|
@@ -574,7 +574,7 @@ def get_business_scenarios_summary(scenarios: Optional[List[str]] = None) -> Dic
|
|
574
574
|
'validation': {
|
575
575
|
'data_source': f'Error: {str(e)}',
|
576
576
|
'timestamp': datetime.now().isoformat(),
|
577
|
-
'version': '
|
577
|
+
'version': 'latest version'
|
578
578
|
}
|
579
579
|
}
|
580
580
|
|
@@ -729,7 +729,7 @@ def _format_notebook_audience(data: Dict[str, Any]) -> str:
|
|
729
729
|
- **Validation:** {data.get('validation', {}).get('validation_method', 'Enterprise standard')}
|
730
730
|
|
731
731
|
---
|
732
|
-
*Generated: {data.get('validation', {}).get('timestamp', datetime.now().isoformat())} | Version: {data.get('validation', {}).get('version', '
|
732
|
+
*Generated: {data.get('validation', {}).get('timestamp', datetime.now().isoformat())} | Version: {data.get('validation', {}).get('version', 'latest version')}*
|
733
733
|
"""
|
734
734
|
|
735
735
|
|
@@ -90,7 +90,7 @@ class SingleAccountDashboard:
|
|
90
90
|
self.context_logger = create_context_logger("finops.single_dashboard")
|
91
91
|
self.context_console = get_context_console()
|
92
92
|
|
93
|
-
#
|
93
|
+
# Phase 2 Enhancement: Use OptimizedProgressTracker for 82% caching efficiency
|
94
94
|
self.progress_tracker = OptimizedProgressTracker(self.console, enable_message_caching=True)
|
95
95
|
self.budget_analyzer = EnhancedBudgetAnalyzer(self.console)
|
96
96
|
self.account_resolver = None # Will be initialized with management profile
|
@@ -107,7 +107,7 @@ class SingleAccountDashboard:
|
|
107
107
|
int: Exit code (0 for success, 1 for failure)
|
108
108
|
"""
|
109
109
|
try:
|
110
|
-
print_header("Single Account Service Dashboard", "
|
110
|
+
print_header("Single Account Service Dashboard", "latest version")
|
111
111
|
|
112
112
|
# Configuration display (context-aware)
|
113
113
|
top_services = getattr(args, "top_services", 10)
|
@@ -320,8 +320,8 @@ class SingleAccountDashboard:
|
|
320
320
|
else:
|
321
321
|
print_warning("MCP validation requested but not available - check MCP server configuration")
|
322
322
|
|
323
|
-
#
|
324
|
-
self.
|
323
|
+
# Phase 2 Enhancement: Display performance metrics for enterprise audit compliance
|
324
|
+
self._display_console_performance_metrics()
|
325
325
|
|
326
326
|
return 0
|
327
327
|
|
@@ -1053,9 +1053,9 @@ class SingleAccountDashboard:
|
|
1053
1053
|
self.console.print(f"[red]❌ Embedded MCP validation failed: {str(e)[:100]}[/]")
|
1054
1054
|
self.console.print(f"[dim]Continuing with standard FinOps analysis[/]")
|
1055
1055
|
|
1056
|
-
def
|
1056
|
+
def _display_console_performance_metrics(self) -> None:
|
1057
1057
|
"""
|
1058
|
-
Display
|
1058
|
+
Display Phase 2 performance metrics for enterprise audit compliance.
|
1059
1059
|
|
1060
1060
|
Shows:
|
1061
1061
|
- Progress message caching efficiency (82% target)
|
@@ -1077,7 +1077,7 @@ class SingleAccountDashboard:
|
|
1077
1077
|
• Total Operations: {audit_summary['total_operations']}
|
1078
1078
|
• Audit Trail Length: {audit_summary['audit_trail_count']}
|
1079
1079
|
|
1080
|
-
[dim]
|
1080
|
+
[dim]Phase 2 Achievements:[/dim]
|
1081
1081
|
• Message caching system operational
|
1082
1082
|
• Business context enhancement integrated
|
1083
1083
|
• Enterprise audit trail generation active
|
@@ -1085,7 +1085,7 @@ class SingleAccountDashboard:
|
|
1085
1085
|
|
1086
1086
|
metrics_panel = Panel(
|
1087
1087
|
metrics_content,
|
1088
|
-
title="[bold cyan]📊
|
1088
|
+
title="[bold cyan]📊 Phase 2 Performance Metrics[/bold cyan]",
|
1089
1089
|
border_style="cyan",
|
1090
1090
|
padding=(1, 2)
|
1091
1091
|
)
|
@@ -1099,13 +1099,13 @@ class SingleAccountDashboard:
|
|
1099
1099
|
f"Session operations: {audit_summary['total_operations']}"
|
1100
1100
|
)
|
1101
1101
|
self.context_logger.info(
|
1102
|
-
"
|
1102
|
+
"Phase 2 performance metrics displayed",
|
1103
1103
|
technical_detail=metrics_details
|
1104
1104
|
)
|
1105
1105
|
|
1106
1106
|
except Exception as e:
|
1107
1107
|
# Graceful degradation - don't fail the main dashboard
|
1108
|
-
print_warning(f"
|
1108
|
+
print_warning(f"Phase 2 metrics display failed: {str(e)[:50]}")
|
1109
1109
|
|
1110
1110
|
|
1111
1111
|
def create_single_dashboard(console: Optional[Console] = None) -> SingleAccountDashboard:
|
@@ -45,9 +45,9 @@ class TestFinOpsConfig:
|
|
45
45
|
config = FinOpsConfig()
|
46
46
|
|
47
47
|
# Test default profile values
|
48
|
-
assert config.billing_profile == "
|
49
|
-
assert config.management_profile == "
|
50
|
-
assert config.operational_profile == "
|
48
|
+
assert config.billing_profile == "${BILLING_PROFILE}"
|
49
|
+
assert config.management_profile == "${MANAGEMENT_PROFILE}"
|
50
|
+
assert config.operational_profile == "${CENTRALISED_OPS_PROFILE}"
|
51
51
|
|
52
52
|
# Test analysis parameters
|
53
53
|
assert config.time_range_days == 30
|
@@ -582,8 +582,8 @@ class TestReferenceImage5_ExportIntegration:
|
|
582
582
|
"status": "completed",
|
583
583
|
"available_profiles": ["profile1", "profile2"],
|
584
584
|
"configured_profiles": {
|
585
|
-
"billing": "
|
586
|
-
"management": "
|
585
|
+
"billing": "${BILLING_PROFILE}",
|
586
|
+
"management": "${MANAGEMENT_PROFILE}",
|
587
587
|
},
|
588
588
|
}
|
589
589
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
Single Account FinOps Features Test Suite - Definition of Done Validation.
|
4
4
|
|
5
5
|
This test suite validates the 5 key features for single account analysis
|
6
|
-
using REAL AWS data for account
|
6
|
+
using REAL AWS data for account ${ACCOUNT_ID} (ams-shared-services-non-prod).
|
7
7
|
|
8
8
|
Purpose: Ensure comprehensive functionality validation against manager requirements.
|
9
9
|
|
@@ -16,7 +16,7 @@ Test Cases:
|
|
16
16
|
|
17
17
|
Author: CloudOps Runbooks Team
|
18
18
|
Version: 0.7.8 - Single Account Focus
|
19
|
-
Target: Account
|
19
|
+
Target: Account ${ACCOUNT_ID} (ams-shared-services-non-prod-ReadOnlyAccess)
|
20
20
|
"""
|
21
21
|
|
22
22
|
import json
|
@@ -30,9 +30,9 @@ import boto3
|
|
30
30
|
import pytest
|
31
31
|
|
32
32
|
# Set environment for single account testing
|
33
|
-
os.environ["SINGLE_AWS_PROFILE"] = "
|
33
|
+
os.environ["SINGLE_AWS_PROFILE"] = "${SINGLE_AWS_PROFILE}"
|
34
34
|
os.environ["AWS_PROFILE"] = os.environ["SINGLE_AWS_PROFILE"]
|
35
|
-
os.environ["BILLING_PROFILE"] = "
|
35
|
+
os.environ["BILLING_PROFILE"] = "${BILLING_PROFILE}"
|
36
36
|
|
37
37
|
# Import FinOps components for testing
|
38
38
|
from runbooks.finops.finops_dashboard import (
|
@@ -53,10 +53,10 @@ class SingleAccountFinOpsConfig(FinOpsConfig):
|
|
53
53
|
super().__init__()
|
54
54
|
|
55
55
|
# Override for single account operation
|
56
|
-
self.target_account = "
|
56
|
+
self.target_account = "${SINGLE_AWS_PROFILE}"
|
57
57
|
|
58
58
|
# Single account configuration
|
59
|
-
self.billing_profile = os.environ.get("BILLING_PROFILE", "
|
59
|
+
self.billing_profile = os.environ.get("BILLING_PROFILE", "${BILLING_PROFILE}")
|
60
60
|
self.management_profile = self.target_account
|
61
61
|
self.operational_profile = self.target_account
|
62
62
|
|
@@ -67,7 +67,7 @@ class SingleAccountFinOpsConfig(FinOpsConfig):
|
|
67
67
|
|
68
68
|
# Single account specific settings
|
69
69
|
self.single_account_mode = True
|
70
|
-
self.account_id = "
|
70
|
+
self.account_id = "${ACCOUNT_ID}" # Extracted from profile name
|
71
71
|
|
72
72
|
|
73
73
|
class TestSingleAccountFeature1_CostTrendAnalysis:
|
@@ -75,7 +75,7 @@ class TestSingleAccountFeature1_CostTrendAnalysis:
|
|
75
75
|
Feature 1: Single Account Cost Trend Analysis with Real AWS Data.
|
76
76
|
|
77
77
|
Validates cost analysis functionality using real AWS Cost Explorer
|
78
|
-
for account
|
78
|
+
for account ${ACCOUNT_ID} with billing profile access.
|
79
79
|
"""
|
80
80
|
|
81
81
|
@pytest.fixture
|
@@ -211,7 +211,7 @@ class TestSingleAccountFeature2_ResourceUtilizationHeatmap:
|
|
211
211
|
Feature 2: Single Account Resource Utilization Heatmap with Real AWS Data.
|
212
212
|
|
213
213
|
Validates resource utilization analysis using real EC2, RDS, S3 data
|
214
|
-
for account
|
214
|
+
for account ${ACCOUNT_ID} with efficiency scoring and rightsizing.
|
215
215
|
"""
|
216
216
|
|
217
217
|
@pytest.fixture
|
@@ -374,7 +374,7 @@ class TestSingleAccountFeature3_ComplianceDashboard:
|
|
374
374
|
Feature 3: Single Account Compliance Dashboard with Real AWS Config Data.
|
375
375
|
|
376
376
|
Validates compliance audit functionality using real AWS Config
|
377
|
-
for account
|
377
|
+
for account ${ACCOUNT_ID} with risk assessment and findings.
|
378
378
|
"""
|
379
379
|
|
380
380
|
@pytest.fixture
|
@@ -527,7 +527,7 @@ class TestSingleAccountFeature4_RightsizingRecommendations:
|
|
527
527
|
Feature 4: Single Account Rightsizing Recommendations with Real CloudWatch Metrics.
|
528
528
|
|
529
529
|
Validates rightsizing functionality using real CloudWatch data
|
530
|
-
for account
|
530
|
+
for account ${ACCOUNT_ID} with cost optimization recommendations.
|
531
531
|
"""
|
532
532
|
|
533
533
|
def test_rightsizing_with_real_metrics(self):
|
@@ -565,7 +565,7 @@ class TestSingleAccountFeature5_ExecutiveSummary:
|
|
565
565
|
Feature 5: Single Account Executive Summary with Real Aggregated Data.
|
566
566
|
|
567
567
|
Validates executive dashboard functionality combining all real data sources
|
568
|
-
for account
|
568
|
+
for account ${ACCOUNT_ID} with C-suite presentation format.
|
569
569
|
"""
|
570
570
|
|
571
571
|
def test_executive_summary_with_real_data(self):
|
@@ -629,15 +629,15 @@ class TestSingleAccountNotebookIntegration:
|
|
629
629
|
def test_notebook_environment_setup(self):
|
630
630
|
"""Test notebook environment is properly configured."""
|
631
631
|
# Verify environment variables
|
632
|
-
assert os.environ.get("SINGLE_AWS_PROFILE") == "
|
633
|
-
assert os.environ.get("BILLING_PROFILE") == "
|
632
|
+
assert os.environ.get("SINGLE_AWS_PROFILE") == "${SINGLE_AWS_PROFILE}"
|
633
|
+
assert os.environ.get("BILLING_PROFILE") == "${BILLING_PROFILE}"
|
634
634
|
|
635
635
|
# Verify AWS connectivity
|
636
636
|
try:
|
637
637
|
session = boto3.Session(profile_name=os.environ["BILLING_PROFILE"])
|
638
638
|
sts = session.client("sts")
|
639
639
|
identity = sts.get_caller_identity()
|
640
|
-
assert identity["Account"] == "
|
640
|
+
assert identity["Account"] == "${BILLING_ACCOUNT_ID}" # Billing account
|
641
641
|
|
642
642
|
print("✅ Notebook environment properly configured")
|
643
643
|
|
@@ -650,8 +650,8 @@ class TestSingleAccountNotebookIntegration:
|
|
650
650
|
|
651
651
|
# Validate single account configuration
|
652
652
|
assert config.single_account_mode is True
|
653
|
-
assert config.account_id == "
|
654
|
-
assert config.target_account == "
|
653
|
+
assert config.account_id == "${ACCOUNT_ID}"
|
654
|
+
assert config.target_account == "${SINGLE_AWS_PROFILE}"
|
655
655
|
assert config.min_account_threshold == 1
|
656
656
|
assert config.enable_cross_account is False
|
657
657
|
|
@@ -64,7 +64,7 @@ def validate_functionality():
|
|
64
64
|
|
65
65
|
config = FinOpsConfig()
|
66
66
|
|
67
|
-
assert config.billing_profile == "
|
67
|
+
assert config.billing_profile == "${BILLING_PROFILE}"
|
68
68
|
assert config.dry_run is True
|
69
69
|
assert config.target_savings_percent == 40
|
70
70
|
print("✅ Configuration validation passed")
|
@@ -16,7 +16,7 @@ Key Features:
|
|
16
16
|
- Quality gates enforcement for enterprise operations
|
17
17
|
|
18
18
|
Author: Enterprise Agile Team (6-Agent Coordination)
|
19
|
-
Version:
|
19
|
+
Version: latest version - Distributed Architecture Framework
|
20
20
|
"""
|
21
21
|
|
22
22
|
import os
|
@@ -138,7 +138,7 @@ class MCPValidator:
|
|
138
138
|
Strategic Focus: Ensure cost calculations meet ≥99.5% accuracy for
|
139
139
|
enterprise financial decision making.
|
140
140
|
"""
|
141
|
-
print_header("MCP Cost Validation", "Accuracy Framework
|
141
|
+
print_header("MCP Cost Validation", "Accuracy Framework latest version")
|
142
142
|
|
143
143
|
validation_start = time.time()
|
144
144
|
validation_id = self._generate_validation_id("cost_analysis")
|
@@ -239,7 +239,7 @@ class MCPValidator:
|
|
239
239
|
|
240
240
|
Focus: Ensure resource counts and attributes match AWS reality.
|
241
241
|
"""
|
242
|
-
print_header("MCP Resource Validation", "Discovery Framework
|
242
|
+
print_header("MCP Resource Validation", "Discovery Framework latest version")
|
243
243
|
|
244
244
|
validation_start = time.time()
|
245
245
|
validation_id = self._generate_validation_id("resource_discovery")
|
@@ -310,7 +310,7 @@ class MCPValidator:
|
|
310
310
|
|
311
311
|
Focus: Ensure recommendations are based on accurate current state analysis.
|
312
312
|
"""
|
313
|
-
print_header("MCP Optimization Validation", "Recommendations Framework
|
313
|
+
print_header("MCP Optimization Validation", "Recommendations Framework latest version")
|
314
314
|
|
315
315
|
validation_start = time.time()
|
316
316
|
validation_id = self._generate_validation_id("optimization_recommendations")
|
@@ -734,7 +734,7 @@ def create_enterprise_validator(
|
|
734
734
|
def main():
|
735
735
|
"""Demo MCP validation framework."""
|
736
736
|
|
737
|
-
print_header("MCP Validation Framework Demo", "
|
737
|
+
print_header("MCP Validation Framework Demo", "latest version")
|
738
738
|
|
739
739
|
# Create validator
|
740
740
|
validator = create_enterprise_validator(accuracy_threshold=99.5)
|
@@ -6,7 +6,7 @@ This module provides export functionality for VPC cleanup analysis results,
|
|
6
6
|
leveraging the existing markdown_exporter infrastructure with VPC-specific formatting.
|
7
7
|
|
8
8
|
Author: CloudOps Runbooks Team
|
9
|
-
Version:
|
9
|
+
Version: latest version
|
10
10
|
"""
|
11
11
|
|
12
12
|
import csv
|
@@ -238,7 +238,7 @@ def _export_vpc_candidates_json(vpc_candidates: List[Any], output_dir: str) -> s
|
|
238
238
|
"metadata": {
|
239
239
|
"export_timestamp": datetime.now().isoformat(),
|
240
240
|
"total_candidates": len(candidates_data),
|
241
|
-
"generator": "CloudOps Runbooks VPC Module
|
241
|
+
"generator": "CloudOps Runbooks VPC Module latest version"
|
242
242
|
},
|
243
243
|
"vpc_candidates": candidates_data
|
244
244
|
}
|
@@ -273,7 +273,7 @@ def _export_vpc_candidates_pdf(vpc_candidates: List[Any], output_dir: str) -> st
|
|
273
273
|
summary_text = f"""
|
274
274
|
<b>Generated:</b> {datetime.now().strftime('%Y-%m-%d %H:%M:%S UTC')}<br/>
|
275
275
|
<b>Total VPC Candidates:</b> {len(vpc_candidates)}<br/>
|
276
|
-
<b>Analysis Source:</b> CloudOps Runbooks VPC Module
|
276
|
+
<b>Analysis Source:</b> CloudOps Runbooks VPC Module latest version
|
277
277
|
"""
|
278
278
|
summary = Paragraph(summary_text, styles['Normal'])
|
279
279
|
story.append(summary)
|
@@ -216,7 +216,7 @@ class VPCCleanupOptimizer:
|
|
216
216
|
|
217
217
|
Returns: Comprehensive cleanup analysis with validated savings
|
218
218
|
"""
|
219
|
-
print_header("VPC Cleanup Cost Optimization Engine", "
|
219
|
+
print_header("VPC Cleanup Cost Optimization Engine", "latest version")
|
220
220
|
print_info("AWSO-05 Implementation - Three-Bucket Strategy")
|
221
221
|
|
222
222
|
# Initialize MCP validator for accuracy validation
|
@@ -280,7 +280,7 @@ class VPCCleanupOptimizer:
|
|
280
280
|
|
281
281
|
Returns: Aggregated VPC cleanup analysis across accessible accounts
|
282
282
|
"""
|
283
|
-
print_header("Multi-Account VPC Cleanup Analysis", "
|
283
|
+
print_header("Multi-Account VPC Cleanup Analysis", "latest version")
|
284
284
|
print_info(f"🏢 Analyzing VPCs across {len(account_ids)} organization accounts")
|
285
285
|
print_info(f"🔐 Using profile: {self.profile} (scope: accessible accounts only)")
|
286
286
|
|
@@ -1323,7 +1323,7 @@ class VPCCleanupOptimizer:
|
|
1323
1323
|
monthly_vpc_endpoint_cost = endpoint_result.monthly_cost
|
1324
1324
|
|
1325
1325
|
# Data processing costs vary by usage - using conservative estimate per region
|
1326
|
-
regional_multiplier = pricing_engine.
|
1326
|
+
regional_multiplier = pricing_engine.get_regional_pricing_multiplier('vpc_endpoint', default_region, "us-east-1")
|
1327
1327
|
monthly_data_processing_cost = 50.0 * regional_multiplier # Base estimate adjusted for region
|
1328
1328
|
|
1329
1329
|
total_annual_savings = 0.0
|
@@ -75,7 +75,7 @@ class WorkSpacesCostAnalyzer:
|
|
75
75
|
"""
|
76
76
|
WorkSpaces cost optimization analyzer following enterprise patterns.
|
77
77
|
|
78
|
-
Implements
|
78
|
+
Implements WorkSpaces optimization requirements with proven profile management and Rich CLI standards.
|
79
79
|
"""
|
80
80
|
|
81
81
|
def __init__(self, profile: Optional[str] = None):
|
@@ -84,7 +84,7 @@ class WorkSpacesCostAnalyzer:
|
|
84
84
|
self.profile = get_profile_for_operation("operational", profile)
|
85
85
|
self.session = boto3.Session(profile_name=self.profile)
|
86
86
|
|
87
|
-
#
|
87
|
+
# WorkSpaces optimization business targets
|
88
88
|
self.target_annual_savings = 12518.0
|
89
89
|
self.unused_threshold_days = 90
|
90
90
|
self.analysis_period_days = 30
|
@@ -286,7 +286,7 @@ class WorkSpacesCostAnalyzer:
|
|
286
286
|
print_header("WorkSpaces Cost Analysis Summary")
|
287
287
|
|
288
288
|
summary_table = create_table(
|
289
|
-
title="
|
289
|
+
title="WorkSpaces Optimization Summary",
|
290
290
|
columns=[
|
291
291
|
{"header": "Metric", "style": "cyan"},
|
292
292
|
{"header": "Count", "style": "green bold"},
|
@@ -377,7 +377,7 @@ class WorkSpacesCostAnalyzer:
|
|
377
377
|
"analysis_timestamp": summary.analysis_timestamp,
|
378
378
|
"profile": self.profile,
|
379
379
|
"target_savings": self.target_annual_savings,
|
380
|
-
"version": "
|
380
|
+
"version": "latest version"
|
381
381
|
}
|
382
382
|
}
|
383
383
|
|
@@ -555,6 +555,11 @@ def analyze_workspaces(
|
|
555
555
|
Analysis results with cost optimization recommendations
|
556
556
|
"""
|
557
557
|
try:
|
558
|
+
# Initialize variables to prevent scope errors
|
559
|
+
results = []
|
560
|
+
summary = None
|
561
|
+
export_file = None
|
562
|
+
|
558
563
|
analyzer = WorkSpacesCostAnalyzer(profile=profile)
|
559
564
|
results, summary = analyzer.analyze_workspaces(
|
560
565
|
unused_days=unused_days,
|
@@ -573,19 +578,32 @@ def analyze_workspaces(
|
|
573
578
|
)
|
574
579
|
|
575
580
|
# Return comprehensive results
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
581
|
+
if summary is not None:
|
582
|
+
return {
|
583
|
+
"summary": summary.to_dict(),
|
584
|
+
"workspaces": [result.to_dict() for result in results],
|
585
|
+
"export_file": export_file,
|
586
|
+
"achievement_rate": summary.target_achievement_rate,
|
587
|
+
"status": "success"
|
588
|
+
}
|
589
|
+
else:
|
590
|
+
return {
|
591
|
+
"summary": {"error": "Analysis failed before completion"},
|
592
|
+
"workspaces": [],
|
593
|
+
"export_file": None,
|
594
|
+
"achievement_rate": 0,
|
595
|
+
"status": "partial_failure"
|
596
|
+
}
|
597
|
+
|
584
598
|
except Exception as e:
|
585
599
|
print_error(f"WorkSpaces analysis failed: {e}")
|
586
600
|
return {
|
587
601
|
"error": str(e),
|
588
|
-
"status": "failed"
|
602
|
+
"status": "failed",
|
603
|
+
"summary": {"error": str(e)},
|
604
|
+
"workspaces": [],
|
605
|
+
"export_file": None,
|
606
|
+
"achievement_rate": 0
|
589
607
|
}
|
590
608
|
|
591
609
|
|