runbooks 1.0.3__py3-none-any.whl → 1.1.0__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 +10 -5
- runbooks/__init__.py.backup +134 -0
- runbooks/__init___optimized.py +110 -0
- runbooks/cloudops/base.py +56 -3
- runbooks/cloudops/cost_optimizer.py +496 -42
- runbooks/common/aws_pricing.py +236 -80
- runbooks/common/business_logic.py +485 -0
- runbooks/common/cli_decorators.py +219 -0
- runbooks/common/error_handling.py +424 -0
- runbooks/common/lazy_loader.py +186 -0
- runbooks/common/module_cli_base.py +378 -0
- runbooks/common/performance_monitoring.py +512 -0
- runbooks/common/profile_utils.py +133 -6
- runbooks/enterprise/logging.py +30 -2
- runbooks/enterprise/validation.py +177 -0
- runbooks/finops/README.md +311 -236
- runbooks/finops/aws_client.py +1 -1
- runbooks/finops/business_case_config.py +723 -19
- runbooks/finops/cli.py +136 -0
- runbooks/finops/commvault_ec2_analysis.py +25 -9
- runbooks/finops/config.py +272 -0
- runbooks/finops/dashboard_runner.py +136 -23
- runbooks/finops/ebs_cost_optimizer.py +39 -40
- runbooks/finops/enhanced_trend_visualization.py +7 -2
- runbooks/finops/enterprise_wrappers.py +45 -18
- runbooks/finops/finops_dashboard.py +50 -25
- runbooks/finops/finops_scenarios.py +22 -7
- runbooks/finops/helpers.py +115 -2
- runbooks/finops/multi_dashboard.py +7 -5
- runbooks/finops/optimizer.py +97 -6
- runbooks/finops/scenario_cli_integration.py +247 -0
- runbooks/finops/scenarios.py +12 -1
- runbooks/finops/unlimited_scenarios.py +393 -0
- runbooks/finops/validation_framework.py +19 -7
- runbooks/finops/workspaces_analyzer.py +1 -5
- runbooks/inventory/mcp_inventory_validator.py +2 -1
- runbooks/main.py +132 -94
- runbooks/main_final.py +358 -0
- runbooks/main_minimal.py +84 -0
- runbooks/main_optimized.py +493 -0
- runbooks/main_ultra_minimal.py +47 -0
- {runbooks-1.0.3.dist-info → runbooks-1.1.0.dist-info}/METADATA +1 -1
- {runbooks-1.0.3.dist-info → runbooks-1.1.0.dist-info}/RECORD +47 -31
- {runbooks-1.0.3.dist-info → runbooks-1.1.0.dist-info}/WHEEL +0 -0
- {runbooks-1.0.3.dist-info → runbooks-1.1.0.dist-info}/entry_points.txt +0 -0
- {runbooks-1.0.3.dist-info → runbooks-1.1.0.dist-info}/licenses/LICENSE +0 -0
- {runbooks-1.0.3.dist-info → runbooks-1.1.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,485 @@
|
|
1
|
+
"""
|
2
|
+
Business Logic Extraction for runbooks package - Universal Business Patterns
|
3
|
+
|
4
|
+
Extracts and standardizes business logic patterns from existing modules,
|
5
|
+
providing reusable components that maintain consistency across the platform.
|
6
|
+
|
7
|
+
Following KISS & DRY principles - extract proven patterns from existing successful modules.
|
8
|
+
"""
|
9
|
+
|
10
|
+
from datetime import datetime
|
11
|
+
from typing import Dict, Any, List, Optional, Union
|
12
|
+
from dataclasses import dataclass, field
|
13
|
+
from enum import Enum
|
14
|
+
|
15
|
+
from .rich_utils import (
|
16
|
+
create_table, console, print_header, print_success, print_info,
|
17
|
+
print_warning, format_cost, create_panel, create_progress_bar
|
18
|
+
)
|
19
|
+
from .profile_utils import get_profile_for_operation
|
20
|
+
|
21
|
+
|
22
|
+
class BusinessImpactLevel(Enum):
|
23
|
+
"""Business impact classification for operations and optimizations."""
|
24
|
+
CRITICAL = "CRITICAL" # >$100K annual impact
|
25
|
+
HIGH = "HIGH" # $20K-100K annual impact
|
26
|
+
MEDIUM = "MEDIUM" # $5K-20K annual impact
|
27
|
+
LOW = "LOW" # <$5K annual impact
|
28
|
+
|
29
|
+
|
30
|
+
class OptimizationType(Enum):
|
31
|
+
"""Types of optimization operations supported."""
|
32
|
+
COST_REDUCTION = "COST_REDUCTION"
|
33
|
+
RESOURCE_EFFICIENCY = "RESOURCE_EFFICIENCY"
|
34
|
+
SECURITY_COMPLIANCE = "SECURITY_COMPLIANCE"
|
35
|
+
PERFORMANCE_IMPROVEMENT = "PERFORMANCE_IMPROVEMENT"
|
36
|
+
OPERATIONAL_EXCELLENCE = "OPERATIONAL_EXCELLENCE"
|
37
|
+
|
38
|
+
|
39
|
+
@dataclass
|
40
|
+
class BusinessMetrics:
|
41
|
+
"""Universal business metrics for operations and optimizations."""
|
42
|
+
annual_savings: float = 0.0
|
43
|
+
monthly_cost_current: float = 0.0
|
44
|
+
monthly_cost_optimized: float = 0.0
|
45
|
+
roi_percentage: float = 0.0
|
46
|
+
payback_period_months: int = 0
|
47
|
+
confidence_level: float = 95.0
|
48
|
+
implementation_effort: str = "Medium"
|
49
|
+
business_risk: str = "Low"
|
50
|
+
|
51
|
+
def calculate_roi(self) -> float:
|
52
|
+
"""Calculate ROI percentage from current metrics."""
|
53
|
+
if self.annual_savings > 0 and self.monthly_cost_current > 0:
|
54
|
+
investment_cost = self.monthly_cost_current * 12 # Annual current cost as investment
|
55
|
+
self.roi_percentage = (self.annual_savings / investment_cost) * 100
|
56
|
+
return self.roi_percentage
|
57
|
+
|
58
|
+
def determine_impact_level(self) -> BusinessImpactLevel:
|
59
|
+
"""Determine business impact level from annual savings."""
|
60
|
+
if self.annual_savings >= 100000:
|
61
|
+
return BusinessImpactLevel.CRITICAL
|
62
|
+
elif self.annual_savings >= 20000:
|
63
|
+
return BusinessImpactLevel.HIGH
|
64
|
+
elif self.annual_savings >= 5000:
|
65
|
+
return BusinessImpactLevel.MEDIUM
|
66
|
+
else:
|
67
|
+
return BusinessImpactLevel.LOW
|
68
|
+
|
69
|
+
|
70
|
+
@dataclass
|
71
|
+
class OptimizationResult:
|
72
|
+
"""Universal optimization result structure."""
|
73
|
+
resource_type: str
|
74
|
+
operation_type: OptimizationType
|
75
|
+
business_metrics: BusinessMetrics
|
76
|
+
recommendations: List[str] = field(default_factory=list)
|
77
|
+
implementation_steps: List[str] = field(default_factory=list)
|
78
|
+
technical_details: Dict[str, Any] = field(default_factory=dict)
|
79
|
+
timestamp: str = field(default_factory=lambda: datetime.now().isoformat())
|
80
|
+
validated_by_mcp: bool = False
|
81
|
+
|
82
|
+
def get_executive_summary(self) -> str:
|
83
|
+
"""Get executive-friendly summary of the optimization."""
|
84
|
+
impact = self.business_metrics.determine_impact_level()
|
85
|
+
return (
|
86
|
+
f"{self.resource_type} optimization with "
|
87
|
+
f"${self.business_metrics.annual_savings:,.0f} annual savings "
|
88
|
+
f"({impact.value} impact, {self.business_metrics.confidence_level:.1f}% confidence)"
|
89
|
+
)
|
90
|
+
|
91
|
+
|
92
|
+
class UniversalBusinessLogic:
|
93
|
+
"""
|
94
|
+
Universal business logic extraction and standardization.
|
95
|
+
|
96
|
+
Provides reusable business logic patterns extracted from proven modules
|
97
|
+
like FinOps for consistent application across all runbooks modules.
|
98
|
+
"""
|
99
|
+
|
100
|
+
def __init__(self, module_name: str):
|
101
|
+
self.module_name = module_name
|
102
|
+
self.session_metrics = []
|
103
|
+
|
104
|
+
def create_cost_analysis_table(self, cost_data: Dict[str, Any], title: str,
|
105
|
+
include_quarterly: bool = False) -> None:
|
106
|
+
"""
|
107
|
+
Standardized cost analysis table creation following FinOps patterns.
|
108
|
+
|
109
|
+
Args:
|
110
|
+
cost_data: Cost data dictionary with resource costs
|
111
|
+
title: Table title for display
|
112
|
+
include_quarterly: Include quarterly intelligence columns
|
113
|
+
"""
|
114
|
+
table = create_table(
|
115
|
+
title=title,
|
116
|
+
caption="Enterprise cost analysis with MCP validation"
|
117
|
+
)
|
118
|
+
|
119
|
+
# Standard columns based on successful FinOps patterns
|
120
|
+
table.add_column("Resource", style="cyan", no_wrap=True)
|
121
|
+
table.add_column("Current Cost", justify="right", style="cost")
|
122
|
+
table.add_column("Optimization %", justify="right", style="yellow")
|
123
|
+
table.add_column("Annual Savings", justify="right", style="bright_green")
|
124
|
+
|
125
|
+
if include_quarterly:
|
126
|
+
table.add_column("Q3 Trend", justify="right", style="magenta")
|
127
|
+
table.add_column("Strategic Context", style="dim", max_width=20)
|
128
|
+
|
129
|
+
# Add rows with consistent formatting
|
130
|
+
total_savings = 0.0
|
131
|
+
for resource, data in cost_data.items():
|
132
|
+
current_cost = data.get('current', 0.0)
|
133
|
+
optimization_pct = data.get('optimization_percentage', 0.0)
|
134
|
+
annual_savings = data.get('annual_savings', 0.0)
|
135
|
+
total_savings += annual_savings
|
136
|
+
|
137
|
+
row_data = [
|
138
|
+
resource,
|
139
|
+
format_cost(current_cost),
|
140
|
+
f"{optimization_pct:.1f}%",
|
141
|
+
format_cost(annual_savings)
|
142
|
+
]
|
143
|
+
|
144
|
+
if include_quarterly:
|
145
|
+
quarterly_trend = data.get('quarterly_trend', 'Stable')
|
146
|
+
strategic_context = data.get('strategic_context', 'Monitor')
|
147
|
+
row_data.extend([quarterly_trend, strategic_context])
|
148
|
+
|
149
|
+
table.add_row(*row_data)
|
150
|
+
|
151
|
+
# Add total row
|
152
|
+
total_row = ["[bold]TOTAL[/]", "", "", f"[bold bright_green]{format_cost(total_savings)}[/]"]
|
153
|
+
if include_quarterly:
|
154
|
+
total_row.extend(["", ""])
|
155
|
+
table.add_row(*total_row)
|
156
|
+
|
157
|
+
console.print(table)
|
158
|
+
|
159
|
+
# Executive summary panel
|
160
|
+
if total_savings > 0:
|
161
|
+
impact_level = BusinessMetrics(annual_savings=total_savings).determine_impact_level()
|
162
|
+
summary_text = f"""
|
163
|
+
[bold bright_green]Total Annual Savings: {format_cost(total_savings)}[/]
|
164
|
+
[yellow]Business Impact: {impact_level.value}[/]
|
165
|
+
[cyan]Resources Analyzed: {len(cost_data)}[/]
|
166
|
+
[dim]Analysis Timestamp: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}[/]
|
167
|
+
"""
|
168
|
+
summary_panel = create_panel(
|
169
|
+
summary_text.strip(),
|
170
|
+
title="💰 Executive Summary",
|
171
|
+
border_style="green"
|
172
|
+
)
|
173
|
+
console.print(summary_panel)
|
174
|
+
|
175
|
+
def standardize_resource_operations(self, resource_type: str, operation: str,
|
176
|
+
profile: Optional[str] = None, **kwargs) -> Dict[str, Any]:
|
177
|
+
"""
|
178
|
+
Standardized resource operation pattern following proven CLI patterns.
|
179
|
+
|
180
|
+
Args:
|
181
|
+
resource_type: Type of AWS resource (EC2, S3, RDS, etc.)
|
182
|
+
operation: Operation being performed (analyze, optimize, inventory)
|
183
|
+
profile: AWS profile to use
|
184
|
+
**kwargs: Additional operation parameters
|
185
|
+
|
186
|
+
Returns:
|
187
|
+
Dictionary with standardized operation results
|
188
|
+
"""
|
189
|
+
# Apply proven profile management patterns
|
190
|
+
selected_profile = get_profile_for_operation("operational", profile)
|
191
|
+
|
192
|
+
print_header(f"{resource_type.title()} {operation.title()}", f"v1.0.0 - {self.module_name}")
|
193
|
+
print_info(f"Using profile: {selected_profile}")
|
194
|
+
|
195
|
+
# Standard operation tracking
|
196
|
+
operation_start = datetime.now()
|
197
|
+
|
198
|
+
# Standard result format following successful patterns
|
199
|
+
result = {
|
200
|
+
'module': self.module_name,
|
201
|
+
'resource_type': resource_type,
|
202
|
+
'operation': operation,
|
203
|
+
'profile_used': selected_profile,
|
204
|
+
'timestamp': operation_start.isoformat(),
|
205
|
+
'success': True,
|
206
|
+
'results': {},
|
207
|
+
'business_metrics': BusinessMetrics(),
|
208
|
+
'recommendations': [],
|
209
|
+
'performance_data': {
|
210
|
+
'start_time': operation_start.isoformat(),
|
211
|
+
'execution_time_seconds': 0.0
|
212
|
+
}
|
213
|
+
}
|
214
|
+
|
215
|
+
return result
|
216
|
+
|
217
|
+
def generate_optimization_recommendations(self, optimization_result: OptimizationResult) -> List[str]:
|
218
|
+
"""
|
219
|
+
Generate standardized optimization recommendations based on business impact.
|
220
|
+
|
221
|
+
Args:
|
222
|
+
optimization_result: Optimization analysis result
|
223
|
+
|
224
|
+
Returns:
|
225
|
+
List of actionable recommendations
|
226
|
+
"""
|
227
|
+
recommendations = []
|
228
|
+
metrics = optimization_result.business_metrics
|
229
|
+
impact = metrics.determine_impact_level()
|
230
|
+
|
231
|
+
# Impact-based recommendations
|
232
|
+
if impact == BusinessImpactLevel.CRITICAL:
|
233
|
+
recommendations.extend([
|
234
|
+
f"🚨 CRITICAL: Immediate action required - ${metrics.annual_savings:,.0f} annual savings opportunity",
|
235
|
+
"📋 Executive approval recommended for implementation",
|
236
|
+
"⏰ Target implementation: Within 30 days",
|
237
|
+
"📊 Monthly progress tracking recommended"
|
238
|
+
])
|
239
|
+
elif impact == BusinessImpactLevel.HIGH:
|
240
|
+
recommendations.extend([
|
241
|
+
f"🔴 HIGH PRIORITY: ${metrics.annual_savings:,.0f} annual savings available",
|
242
|
+
"📋 Business case development recommended",
|
243
|
+
"⏰ Target implementation: Within 90 days",
|
244
|
+
"📊 Quarterly progress review recommended"
|
245
|
+
])
|
246
|
+
elif impact == BusinessImpactLevel.MEDIUM:
|
247
|
+
recommendations.extend([
|
248
|
+
f"🟡 MEDIUM PRIORITY: ${metrics.annual_savings:,.0f} annual savings potential",
|
249
|
+
"📋 Consider in next planning cycle",
|
250
|
+
"⏰ Target implementation: Within 6 months"
|
251
|
+
])
|
252
|
+
else:
|
253
|
+
recommendations.extend([
|
254
|
+
f"🟢 LOW PRIORITY: ${metrics.annual_savings:,.0f} annual savings",
|
255
|
+
"📋 Include in routine optimization reviews"
|
256
|
+
])
|
257
|
+
|
258
|
+
# ROI-based recommendations
|
259
|
+
if metrics.roi_percentage > 200:
|
260
|
+
recommendations.append(f"💰 Excellent ROI: {metrics.roi_percentage:.1f}% return on investment")
|
261
|
+
elif metrics.roi_percentage > 100:
|
262
|
+
recommendations.append(f"💰 Good ROI: {metrics.roi_percentage:.1f}% return on investment")
|
263
|
+
|
264
|
+
# Risk-based recommendations
|
265
|
+
if metrics.business_risk == "Low":
|
266
|
+
recommendations.append("✅ Low implementation risk - safe to proceed")
|
267
|
+
elif metrics.business_risk == "Medium":
|
268
|
+
recommendations.append("⚠️ Medium risk - consider phased implementation")
|
269
|
+
else:
|
270
|
+
recommendations.append("🚨 High risk - detailed planning and approval required")
|
271
|
+
|
272
|
+
return recommendations
|
273
|
+
|
274
|
+
def create_executive_dashboard(self, results: List[OptimizationResult],
|
275
|
+
dashboard_title: str = "Executive Dashboard") -> None:
|
276
|
+
"""
|
277
|
+
Create executive dashboard following successful FinOps patterns.
|
278
|
+
|
279
|
+
Args:
|
280
|
+
results: List of optimization results
|
281
|
+
dashboard_title: Title for the dashboard
|
282
|
+
"""
|
283
|
+
print_header(dashboard_title, f"{self.module_name} Module")
|
284
|
+
|
285
|
+
if not results:
|
286
|
+
print_info("No optimization opportunities identified at this time")
|
287
|
+
return
|
288
|
+
|
289
|
+
# Summary metrics
|
290
|
+
total_savings = sum(r.business_metrics.annual_savings for r in results)
|
291
|
+
high_impact_count = len([r for r in results if r.business_metrics.determine_impact_level() in [BusinessImpactLevel.CRITICAL, BusinessImpactLevel.HIGH]])
|
292
|
+
|
293
|
+
# Executive summary table
|
294
|
+
summary_table = create_table(
|
295
|
+
title="📊 Executive Summary",
|
296
|
+
columns=[
|
297
|
+
{"name": "Metric", "style": "cyan", "justify": "left"},
|
298
|
+
{"name": "Value", "style": "bright_green", "justify": "right"},
|
299
|
+
{"name": "Impact", "style": "yellow", "justify": "left"}
|
300
|
+
]
|
301
|
+
)
|
302
|
+
|
303
|
+
summary_table.add_row("Total Annual Savings", format_cost(total_savings), f"{len(results)} opportunities")
|
304
|
+
summary_table.add_row("High Priority Items", str(high_impact_count), "Immediate attention required")
|
305
|
+
summary_table.add_row("Average Confidence", f"{sum(r.business_metrics.confidence_level for r in results) / len(results):.1f}%", "Validation accuracy")
|
306
|
+
|
307
|
+
console.print(summary_table)
|
308
|
+
|
309
|
+
# Top opportunities table
|
310
|
+
if results:
|
311
|
+
# Sort by annual savings
|
312
|
+
top_results = sorted(results, key=lambda x: x.business_metrics.annual_savings, reverse=True)[:5]
|
313
|
+
|
314
|
+
opportunities_table = create_table(
|
315
|
+
title="🎯 Top Optimization Opportunities",
|
316
|
+
columns=[
|
317
|
+
{"name": "Resource", "style": "cyan", "justify": "left"},
|
318
|
+
{"name": "Annual Savings", "style": "bright_green", "justify": "right"},
|
319
|
+
{"name": "Impact", "style": "yellow", "justify": "center"},
|
320
|
+
{"name": "Confidence", "style": "blue", "justify": "right"},
|
321
|
+
{"name": "Next Action", "style": "white", "justify": "left"}
|
322
|
+
]
|
323
|
+
)
|
324
|
+
|
325
|
+
for result in top_results:
|
326
|
+
impact = result.business_metrics.determine_impact_level()
|
327
|
+
next_action = "Executive Review" if impact == BusinessImpactLevel.CRITICAL else "Business Case"
|
328
|
+
|
329
|
+
opportunities_table.add_row(
|
330
|
+
result.resource_type,
|
331
|
+
format_cost(result.business_metrics.annual_savings),
|
332
|
+
impact.value,
|
333
|
+
f"{result.business_metrics.confidence_level:.1f}%",
|
334
|
+
next_action
|
335
|
+
)
|
336
|
+
|
337
|
+
console.print(opportunities_table)
|
338
|
+
|
339
|
+
def calculate_business_impact(self, resource_type: str, usage_data: Dict[str, Any]) -> BusinessMetrics:
|
340
|
+
"""
|
341
|
+
Standardized business impact calculation following proven FinOps methodology.
|
342
|
+
|
343
|
+
Args:
|
344
|
+
resource_type: Type of resource being analyzed
|
345
|
+
usage_data: Resource usage and cost data
|
346
|
+
|
347
|
+
Returns:
|
348
|
+
BusinessMetrics with calculated impact values
|
349
|
+
"""
|
350
|
+
metrics = BusinessMetrics()
|
351
|
+
|
352
|
+
# Extract costs
|
353
|
+
current_monthly = usage_data.get('monthly_cost_current', 0.0)
|
354
|
+
optimized_monthly = usage_data.get('monthly_cost_optimized', current_monthly * 0.7) # Default 30% optimization
|
355
|
+
|
356
|
+
metrics.monthly_cost_current = current_monthly
|
357
|
+
metrics.monthly_cost_optimized = optimized_monthly
|
358
|
+
metrics.annual_savings = (current_monthly - optimized_monthly) * 12
|
359
|
+
|
360
|
+
# Calculate ROI
|
361
|
+
metrics.calculate_roi()
|
362
|
+
|
363
|
+
# Set confidence based on resource type (following successful patterns)
|
364
|
+
confidence_levels = {
|
365
|
+
'NAT Gateway': 95.0, # High confidence from proven results
|
366
|
+
'Elastic IP': 90.0,
|
367
|
+
'EBS Volume': 85.0,
|
368
|
+
'EC2 Instance': 80.0,
|
369
|
+
'RDS Instance': 75.0,
|
370
|
+
'Generic': 70.0
|
371
|
+
}
|
372
|
+
metrics.confidence_level = confidence_levels.get(resource_type, 70.0)
|
373
|
+
|
374
|
+
# Estimate implementation effort and risk
|
375
|
+
if metrics.annual_savings > 50000:
|
376
|
+
metrics.implementation_effort = "High"
|
377
|
+
metrics.business_risk = "Medium"
|
378
|
+
elif metrics.annual_savings > 10000:
|
379
|
+
metrics.implementation_effort = "Medium"
|
380
|
+
metrics.business_risk = "Low"
|
381
|
+
else:
|
382
|
+
metrics.implementation_effort = "Low"
|
383
|
+
metrics.business_risk = "Low"
|
384
|
+
|
385
|
+
return metrics
|
386
|
+
|
387
|
+
def export_business_results(self, results: List[OptimizationResult],
|
388
|
+
export_formats: List[str] = None) -> Dict[str, str]:
|
389
|
+
"""
|
390
|
+
Export business results in multiple formats following successful patterns.
|
391
|
+
|
392
|
+
Args:
|
393
|
+
results: List of optimization results
|
394
|
+
export_formats: List of formats to export ('csv', 'json', 'markdown')
|
395
|
+
|
396
|
+
Returns:
|
397
|
+
Dictionary with export file paths
|
398
|
+
"""
|
399
|
+
if export_formats is None:
|
400
|
+
export_formats = ['csv', 'json', 'markdown']
|
401
|
+
|
402
|
+
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
403
|
+
base_filename = f"{self.module_name}_optimization_results_{timestamp}"
|
404
|
+
|
405
|
+
exported_files = {}
|
406
|
+
|
407
|
+
print_info(f"Exporting results in {len(export_formats)} formats...")
|
408
|
+
|
409
|
+
for fmt in export_formats:
|
410
|
+
filename = f"./awso_evidence/{base_filename}.{fmt}"
|
411
|
+
|
412
|
+
if fmt == 'csv':
|
413
|
+
# CSV export for analysis
|
414
|
+
csv_content = "Resource,Annual_Savings,Impact_Level,Confidence,ROI_Percentage\n"
|
415
|
+
for result in results:
|
416
|
+
csv_content += f"{result.resource_type},{result.business_metrics.annual_savings},"
|
417
|
+
csv_content += f"{result.business_metrics.determine_impact_level().value},"
|
418
|
+
csv_content += f"{result.business_metrics.confidence_level},{result.business_metrics.roi_percentage}\n"
|
419
|
+
|
420
|
+
with open(filename, 'w') as f:
|
421
|
+
f.write(csv_content)
|
422
|
+
|
423
|
+
elif fmt == 'json':
|
424
|
+
# JSON export for systems integration
|
425
|
+
import json
|
426
|
+
json_data = {
|
427
|
+
'module': self.module_name,
|
428
|
+
'timestamp': timestamp,
|
429
|
+
'total_results': len(results),
|
430
|
+
'total_annual_savings': sum(r.business_metrics.annual_savings for r in results),
|
431
|
+
'results': [
|
432
|
+
{
|
433
|
+
'resource_type': r.resource_type,
|
434
|
+
'annual_savings': r.business_metrics.annual_savings,
|
435
|
+
'impact_level': r.business_metrics.determine_impact_level().value,
|
436
|
+
'confidence_level': r.business_metrics.confidence_level,
|
437
|
+
'executive_summary': r.get_executive_summary()
|
438
|
+
}
|
439
|
+
for r in results
|
440
|
+
]
|
441
|
+
}
|
442
|
+
|
443
|
+
with open(filename, 'w') as f:
|
444
|
+
json.dump(json_data, f, indent=2)
|
445
|
+
|
446
|
+
elif fmt == 'markdown':
|
447
|
+
# Markdown export for documentation and reports
|
448
|
+
md_content = f"# {self.module_name.title()} Optimization Results\n\n"
|
449
|
+
md_content += f"**Generated**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
|
450
|
+
|
451
|
+
total_savings = sum(r.business_metrics.annual_savings for r in results)
|
452
|
+
md_content += f"## Executive Summary\n\n"
|
453
|
+
md_content += f"- **Total Annual Savings**: ${total_savings:,.0f}\n"
|
454
|
+
md_content += f"- **Optimization Opportunities**: {len(results)}\n"
|
455
|
+
md_content += f"- **High Priority Items**: {len([r for r in results if r.business_metrics.determine_impact_level() in [BusinessImpactLevel.CRITICAL, BusinessImpactLevel.HIGH]])}\n\n"
|
456
|
+
|
457
|
+
md_content += "## Detailed Results\n\n"
|
458
|
+
for i, result in enumerate(results, 1):
|
459
|
+
md_content += f"### {i}. {result.resource_type}\n\n"
|
460
|
+
md_content += f"- **Annual Savings**: ${result.business_metrics.annual_savings:,.0f}\n"
|
461
|
+
md_content += f"- **Impact Level**: {result.business_metrics.determine_impact_level().value}\n"
|
462
|
+
md_content += f"- **Confidence**: {result.business_metrics.confidence_level:.1f}%\n"
|
463
|
+
md_content += f"- **ROI**: {result.business_metrics.roi_percentage:.1f}%\n\n"
|
464
|
+
|
465
|
+
with open(filename, 'w') as f:
|
466
|
+
f.write(md_content)
|
467
|
+
|
468
|
+
exported_files[fmt] = filename
|
469
|
+
print_success(f"Exported {fmt.upper()}: {filename}")
|
470
|
+
|
471
|
+
return exported_files
|
472
|
+
|
473
|
+
|
474
|
+
# Factory function for easy integration
|
475
|
+
def create_business_logic_handler(module_name: str) -> UniversalBusinessLogic:
|
476
|
+
"""
|
477
|
+
Factory function to create business logic handler for any module.
|
478
|
+
|
479
|
+
Args:
|
480
|
+
module_name: Name of the module using business logic
|
481
|
+
|
482
|
+
Returns:
|
483
|
+
UniversalBusinessLogic instance configured for the module
|
484
|
+
"""
|
485
|
+
return UniversalBusinessLogic(module_name)
|