runbooks 1.1.4__py3-none-any.whl → 1.1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. runbooks/__init__.py +31 -2
  2. runbooks/__init___optimized.py +18 -4
  3. runbooks/_platform/__init__.py +1 -5
  4. runbooks/_platform/core/runbooks_wrapper.py +141 -138
  5. runbooks/aws2/accuracy_validator.py +812 -0
  6. runbooks/base.py +7 -0
  7. runbooks/cfat/assessment/compliance.py +1 -1
  8. runbooks/cfat/assessment/runner.py +1 -0
  9. runbooks/cfat/cloud_foundations_assessment.py +227 -239
  10. runbooks/cli/__init__.py +1 -1
  11. runbooks/cli/commands/cfat.py +64 -23
  12. runbooks/cli/commands/finops.py +1005 -54
  13. runbooks/cli/commands/inventory.py +138 -35
  14. runbooks/cli/commands/operate.py +9 -36
  15. runbooks/cli/commands/security.py +42 -18
  16. runbooks/cli/commands/validation.py +432 -18
  17. runbooks/cli/commands/vpc.py +81 -17
  18. runbooks/cli/registry.py +22 -10
  19. runbooks/cloudops/__init__.py +20 -27
  20. runbooks/cloudops/base.py +96 -107
  21. runbooks/cloudops/cost_optimizer.py +544 -542
  22. runbooks/cloudops/infrastructure_optimizer.py +5 -4
  23. runbooks/cloudops/interfaces.py +224 -225
  24. runbooks/cloudops/lifecycle_manager.py +5 -4
  25. runbooks/cloudops/mcp_cost_validation.py +252 -235
  26. runbooks/cloudops/models.py +78 -53
  27. runbooks/cloudops/monitoring_automation.py +5 -4
  28. runbooks/cloudops/notebook_framework.py +177 -213
  29. runbooks/cloudops/security_enforcer.py +125 -159
  30. runbooks/common/accuracy_validator.py +11 -0
  31. runbooks/common/aws_pricing.py +349 -326
  32. runbooks/common/aws_pricing_api.py +211 -212
  33. runbooks/common/aws_profile_manager.py +40 -36
  34. runbooks/common/aws_utils.py +74 -79
  35. runbooks/common/business_logic.py +126 -104
  36. runbooks/common/cli_decorators.py +36 -60
  37. runbooks/common/comprehensive_cost_explorer_integration.py +455 -463
  38. runbooks/common/cross_account_manager.py +197 -204
  39. runbooks/common/date_utils.py +27 -39
  40. runbooks/common/decorators.py +29 -19
  41. runbooks/common/dry_run_examples.py +173 -208
  42. runbooks/common/dry_run_framework.py +157 -155
  43. runbooks/common/enhanced_exception_handler.py +15 -4
  44. runbooks/common/enhanced_logging_example.py +50 -64
  45. runbooks/common/enhanced_logging_integration_example.py +65 -37
  46. runbooks/common/env_utils.py +16 -16
  47. runbooks/common/error_handling.py +40 -38
  48. runbooks/common/lazy_loader.py +41 -23
  49. runbooks/common/logging_integration_helper.py +79 -86
  50. runbooks/common/mcp_cost_explorer_integration.py +476 -493
  51. runbooks/common/mcp_integration.py +63 -74
  52. runbooks/common/memory_optimization.py +140 -118
  53. runbooks/common/module_cli_base.py +37 -58
  54. runbooks/common/organizations_client.py +175 -193
  55. runbooks/common/patterns.py +23 -25
  56. runbooks/common/performance_monitoring.py +67 -71
  57. runbooks/common/performance_optimization_engine.py +283 -274
  58. runbooks/common/profile_utils.py +111 -37
  59. runbooks/common/rich_utils.py +201 -141
  60. runbooks/common/sre_performance_suite.py +177 -186
  61. runbooks/enterprise/__init__.py +1 -1
  62. runbooks/enterprise/logging.py +144 -106
  63. runbooks/enterprise/security.py +187 -204
  64. runbooks/enterprise/validation.py +43 -56
  65. runbooks/finops/__init__.py +26 -30
  66. runbooks/finops/account_resolver.py +1 -1
  67. runbooks/finops/advanced_optimization_engine.py +980 -0
  68. runbooks/finops/automation_core.py +268 -231
  69. runbooks/finops/business_case_config.py +184 -179
  70. runbooks/finops/cli.py +660 -139
  71. runbooks/finops/commvault_ec2_analysis.py +157 -164
  72. runbooks/finops/compute_cost_optimizer.py +336 -320
  73. runbooks/finops/config.py +20 -20
  74. runbooks/finops/cost_optimizer.py +484 -618
  75. runbooks/finops/cost_processor.py +332 -214
  76. runbooks/finops/dashboard_runner.py +1006 -172
  77. runbooks/finops/ebs_cost_optimizer.py +991 -657
  78. runbooks/finops/elastic_ip_optimizer.py +317 -257
  79. runbooks/finops/enhanced_mcp_integration.py +340 -0
  80. runbooks/finops/enhanced_progress.py +32 -29
  81. runbooks/finops/enhanced_trend_visualization.py +3 -2
  82. runbooks/finops/enterprise_wrappers.py +223 -285
  83. runbooks/finops/executive_export.py +203 -160
  84. runbooks/finops/helpers.py +130 -288
  85. runbooks/finops/iam_guidance.py +1 -1
  86. runbooks/finops/infrastructure/__init__.py +80 -0
  87. runbooks/finops/infrastructure/commands.py +506 -0
  88. runbooks/finops/infrastructure/load_balancer_optimizer.py +866 -0
  89. runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +832 -0
  90. runbooks/finops/markdown_exporter.py +337 -174
  91. runbooks/finops/mcp_validator.py +1952 -0
  92. runbooks/finops/nat_gateway_optimizer.py +1512 -481
  93. runbooks/finops/network_cost_optimizer.py +657 -587
  94. runbooks/finops/notebook_utils.py +226 -188
  95. runbooks/finops/optimization_engine.py +1136 -0
  96. runbooks/finops/optimizer.py +19 -23
  97. runbooks/finops/rds_snapshot_optimizer.py +367 -411
  98. runbooks/finops/reservation_optimizer.py +427 -363
  99. runbooks/finops/scenario_cli_integration.py +64 -65
  100. runbooks/finops/scenarios.py +1277 -438
  101. runbooks/finops/schemas.py +218 -182
  102. runbooks/finops/snapshot_manager.py +2289 -0
  103. runbooks/finops/types.py +3 -3
  104. runbooks/finops/validation_framework.py +259 -265
  105. runbooks/finops/vpc_cleanup_exporter.py +189 -144
  106. runbooks/finops/vpc_cleanup_optimizer.py +591 -573
  107. runbooks/finops/workspaces_analyzer.py +171 -182
  108. runbooks/integration/__init__.py +89 -0
  109. runbooks/integration/mcp_integration.py +1920 -0
  110. runbooks/inventory/CLAUDE.md +816 -0
  111. runbooks/inventory/__init__.py +2 -2
  112. runbooks/inventory/cloud_foundations_integration.py +144 -149
  113. runbooks/inventory/collectors/aws_comprehensive.py +1 -1
  114. runbooks/inventory/collectors/aws_networking.py +109 -99
  115. runbooks/inventory/collectors/base.py +4 -0
  116. runbooks/inventory/core/collector.py +495 -313
  117. runbooks/inventory/drift_detection_cli.py +69 -96
  118. runbooks/inventory/inventory_mcp_cli.py +48 -46
  119. runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
  120. runbooks/inventory/mcp_inventory_validator.py +549 -465
  121. runbooks/inventory/mcp_vpc_validator.py +359 -442
  122. runbooks/inventory/organizations_discovery.py +55 -51
  123. runbooks/inventory/rich_inventory_display.py +33 -32
  124. runbooks/inventory/unified_validation_engine.py +278 -251
  125. runbooks/inventory/vpc_analyzer.py +732 -695
  126. runbooks/inventory/vpc_architecture_validator.py +293 -348
  127. runbooks/inventory/vpc_dependency_analyzer.py +382 -378
  128. runbooks/inventory/vpc_flow_analyzer.py +1 -1
  129. runbooks/main.py +49 -34
  130. runbooks/main_final.py +91 -60
  131. runbooks/main_minimal.py +22 -10
  132. runbooks/main_optimized.py +131 -100
  133. runbooks/main_ultra_minimal.py +7 -2
  134. runbooks/mcp/__init__.py +36 -0
  135. runbooks/mcp/integration.py +679 -0
  136. runbooks/monitoring/performance_monitor.py +9 -4
  137. runbooks/operate/dynamodb_operations.py +3 -1
  138. runbooks/operate/ec2_operations.py +145 -137
  139. runbooks/operate/iam_operations.py +146 -152
  140. runbooks/operate/networking_cost_heatmap.py +29 -8
  141. runbooks/operate/rds_operations.py +223 -254
  142. runbooks/operate/s3_operations.py +107 -118
  143. runbooks/operate/vpc_operations.py +646 -616
  144. runbooks/remediation/base.py +1 -1
  145. runbooks/remediation/commons.py +10 -7
  146. runbooks/remediation/commvault_ec2_analysis.py +70 -66
  147. runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
  148. runbooks/remediation/multi_account.py +24 -21
  149. runbooks/remediation/rds_snapshot_list.py +86 -60
  150. runbooks/remediation/remediation_cli.py +92 -146
  151. runbooks/remediation/universal_account_discovery.py +83 -79
  152. runbooks/remediation/workspaces_list.py +46 -41
  153. runbooks/security/__init__.py +19 -0
  154. runbooks/security/assessment_runner.py +1150 -0
  155. runbooks/security/baseline_checker.py +812 -0
  156. runbooks/security/cloudops_automation_security_validator.py +509 -535
  157. runbooks/security/compliance_automation_engine.py +17 -17
  158. runbooks/security/config/__init__.py +2 -2
  159. runbooks/security/config/compliance_config.py +50 -50
  160. runbooks/security/config_template_generator.py +63 -76
  161. runbooks/security/enterprise_security_framework.py +1 -1
  162. runbooks/security/executive_security_dashboard.py +519 -508
  163. runbooks/security/multi_account_security_controls.py +959 -1210
  164. runbooks/security/real_time_security_monitor.py +422 -444
  165. runbooks/security/security_baseline_tester.py +1 -1
  166. runbooks/security/security_cli.py +143 -112
  167. runbooks/security/test_2way_validation.py +439 -0
  168. runbooks/security/two_way_validation_framework.py +852 -0
  169. runbooks/sre/production_monitoring_framework.py +167 -177
  170. runbooks/tdd/__init__.py +15 -0
  171. runbooks/tdd/cli.py +1071 -0
  172. runbooks/utils/__init__.py +14 -17
  173. runbooks/utils/logger.py +7 -2
  174. runbooks/utils/version_validator.py +50 -47
  175. runbooks/validation/__init__.py +6 -6
  176. runbooks/validation/cli.py +9 -3
  177. runbooks/validation/comprehensive_2way_validator.py +745 -704
  178. runbooks/validation/mcp_validator.py +906 -228
  179. runbooks/validation/terraform_citations_validator.py +104 -115
  180. runbooks/validation/terraform_drift_detector.py +447 -451
  181. runbooks/vpc/README.md +617 -0
  182. runbooks/vpc/__init__.py +8 -1
  183. runbooks/vpc/analyzer.py +577 -0
  184. runbooks/vpc/cleanup_wrapper.py +476 -413
  185. runbooks/vpc/cli_cloudtrail_commands.py +339 -0
  186. runbooks/vpc/cli_mcp_validation_commands.py +480 -0
  187. runbooks/vpc/cloudtrail_audit_integration.py +717 -0
  188. runbooks/vpc/config.py +92 -97
  189. runbooks/vpc/cost_engine.py +411 -148
  190. runbooks/vpc/cost_explorer_integration.py +553 -0
  191. runbooks/vpc/cross_account_session.py +101 -106
  192. runbooks/vpc/enhanced_mcp_validation.py +917 -0
  193. runbooks/vpc/eni_gate_validator.py +961 -0
  194. runbooks/vpc/heatmap_engine.py +185 -160
  195. runbooks/vpc/mcp_no_eni_validator.py +680 -639
  196. runbooks/vpc/nat_gateway_optimizer.py +358 -0
  197. runbooks/vpc/networking_wrapper.py +15 -8
  198. runbooks/vpc/pdca_remediation_planner.py +528 -0
  199. runbooks/vpc/performance_optimized_analyzer.py +219 -231
  200. runbooks/vpc/runbooks_adapter.py +1167 -241
  201. runbooks/vpc/tdd_red_phase_stubs.py +601 -0
  202. runbooks/vpc/test_data_loader.py +358 -0
  203. runbooks/vpc/tests/conftest.py +314 -4
  204. runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
  205. runbooks/vpc/tests/test_cost_engine.py +0 -2
  206. runbooks/vpc/topology_generator.py +326 -0
  207. runbooks/vpc/unified_scenarios.py +1297 -1124
  208. runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
  209. runbooks-1.1.5.dist-info/METADATA +328 -0
  210. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/RECORD +214 -193
  211. runbooks/finops/README.md +0 -414
  212. runbooks/finops/accuracy_cross_validator.py +0 -647
  213. runbooks/finops/business_cases.py +0 -950
  214. runbooks/finops/dashboard_router.py +0 -922
  215. runbooks/finops/ebs_optimizer.py +0 -973
  216. runbooks/finops/embedded_mcp_validator.py +0 -1629
  217. runbooks/finops/enhanced_dashboard_runner.py +0 -527
  218. runbooks/finops/finops_dashboard.py +0 -584
  219. runbooks/finops/finops_scenarios.py +0 -1218
  220. runbooks/finops/legacy_migration.py +0 -730
  221. runbooks/finops/multi_dashboard.py +0 -1519
  222. runbooks/finops/single_dashboard.py +0 -1113
  223. runbooks/finops/unlimited_scenarios.py +0 -393
  224. runbooks-1.1.4.dist-info/METADATA +0 -800
  225. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/WHEEL +0 -0
  226. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/entry_points.txt +0 -0
  227. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/licenses/LICENSE +0 -0
  228. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/top_level.txt +0 -0
@@ -13,22 +13,31 @@ from dataclasses import dataclass, field
13
13
  from enum import Enum
14
14
 
15
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
16
+ create_table,
17
+ console,
18
+ print_header,
19
+ print_success,
20
+ print_info,
21
+ print_warning,
22
+ format_cost,
23
+ create_panel,
24
+ create_progress_bar,
18
25
  )
19
26
  from .profile_utils import get_profile_for_operation
20
27
 
21
28
 
22
29
  class BusinessImpactLevel(Enum):
23
30
  """Business impact classification for operations and optimizations."""
31
+
24
32
  CRITICAL = "CRITICAL" # >$100K annual impact
25
- HIGH = "HIGH" # measurable range annual impact
26
- MEDIUM = "MEDIUM" # measurable range annual impact
27
- LOW = "LOW" # <$5K annual impact
33
+ HIGH = "HIGH" # measurable range annual impact
34
+ MEDIUM = "MEDIUM" # measurable range annual impact
35
+ LOW = "LOW" # <$5K annual impact
28
36
 
29
37
 
30
38
  class OptimizationType(Enum):
31
39
  """Types of optimization operations supported."""
40
+
32
41
  COST_REDUCTION = "COST_REDUCTION"
33
42
  RESOURCE_EFFICIENCY = "RESOURCE_EFFICIENCY"
34
43
  SECURITY_COMPLIANCE = "SECURITY_COMPLIANCE"
@@ -39,6 +48,7 @@ class OptimizationType(Enum):
39
48
  @dataclass
40
49
  class BusinessMetrics:
41
50
  """Universal business metrics for operations and optimizations."""
51
+
42
52
  annual_savings: float = 0.0
43
53
  monthly_cost_current: float = 0.0
44
54
  monthly_cost_optimized: float = 0.0
@@ -70,6 +80,7 @@ class BusinessMetrics:
70
80
  @dataclass
71
81
  class OptimizationResult:
72
82
  """Universal optimization result structure."""
83
+
73
84
  resource_type: str
74
85
  operation_type: OptimizationType
75
86
  business_metrics: BusinessMetrics
@@ -101,8 +112,9 @@ class UniversalBusinessLogic:
101
112
  self.module_name = module_name
102
113
  self.session_metrics = []
103
114
 
104
- def create_cost_analysis_table(self, cost_data: Dict[str, Any], title: str,
105
- include_quarterly: bool = False) -> None:
115
+ def create_cost_analysis_table(
116
+ self, cost_data: Dict[str, Any], title: str, include_quarterly: bool = False
117
+ ) -> None:
106
118
  """
107
119
  Standardized cost analysis table creation following FinOps patterns.
108
120
 
@@ -111,10 +123,7 @@ class UniversalBusinessLogic:
111
123
  title: Table title for display
112
124
  include_quarterly: Include quarterly intelligence columns
113
125
  """
114
- table = create_table(
115
- title=title,
116
- caption="Enterprise cost analysis with MCP validation"
117
- )
126
+ table = create_table(title=title, caption="Enterprise cost analysis with MCP validation")
118
127
 
119
128
  # Standard columns based on successful FinOps patterns
120
129
  table.add_column("Resource", style="cyan", no_wrap=True)
@@ -129,21 +138,16 @@ class UniversalBusinessLogic:
129
138
  # Add rows with consistent formatting
130
139
  total_savings = 0.0
131
140
  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)
141
+ current_cost = data.get("current", 0.0)
142
+ optimization_pct = data.get("optimization_percentage", 0.0)
143
+ annual_savings = data.get("annual_savings", 0.0)
135
144
  total_savings += annual_savings
136
145
 
137
- row_data = [
138
- resource,
139
- format_cost(current_cost),
140
- f"{optimization_pct:.1f}%",
141
- format_cost(annual_savings)
142
- ]
146
+ row_data = [resource, format_cost(current_cost), f"{optimization_pct:.1f}%", format_cost(annual_savings)]
143
147
 
144
148
  if include_quarterly:
145
- quarterly_trend = data.get('quarterly_trend', 'Stable')
146
- strategic_context = data.get('strategic_context', 'Monitor')
149
+ quarterly_trend = data.get("quarterly_trend", "Stable")
150
+ strategic_context = data.get("strategic_context", "Monitor")
147
151
  row_data.extend([quarterly_trend, strategic_context])
148
152
 
149
153
  table.add_row(*row_data)
@@ -163,17 +167,14 @@ class UniversalBusinessLogic:
163
167
  [bold bright_green]Total Annual Savings: {format_cost(total_savings)}[/]
164
168
  [yellow]Business Impact: {impact_level.value}[/]
165
169
  [cyan]Resources Analyzed: {len(cost_data)}[/]
166
- [dim]Analysis Timestamp: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}[/]
170
+ [dim]Analysis Timestamp: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}[/]
167
171
  """
168
- summary_panel = create_panel(
169
- summary_text.strip(),
170
- title="💰 Executive Summary",
171
- border_style="green"
172
- )
172
+ summary_panel = create_panel(summary_text.strip(), title="💰 Executive Summary", border_style="green")
173
173
  console.print(summary_panel)
174
174
 
175
- def standardize_resource_operations(self, resource_type: str, operation: str,
176
- profile: Optional[str] = None, **kwargs) -> Dict[str, Any]:
175
+ def standardize_resource_operations(
176
+ self, resource_type: str, operation: str, profile: Optional[str] = None, **kwargs
177
+ ) -> Dict[str, Any]:
177
178
  """
178
179
  Standardized resource operation pattern following proven CLI patterns.
179
180
 
@@ -197,19 +198,16 @@ class UniversalBusinessLogic:
197
198
 
198
199
  # Standard result format following successful patterns
199
200
  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
- }
201
+ "module": self.module_name,
202
+ "resource_type": resource_type,
203
+ "operation": operation,
204
+ "profile_used": selected_profile,
205
+ "timestamp": operation_start.isoformat(),
206
+ "success": True,
207
+ "results": {},
208
+ "business_metrics": BusinessMetrics(),
209
+ "recommendations": [],
210
+ "performance_data": {"start_time": operation_start.isoformat(), "execution_time_seconds": 0.0},
213
211
  }
214
212
 
215
213
  return result
@@ -230,30 +228,38 @@ class UniversalBusinessLogic:
230
228
 
231
229
  # Impact-based recommendations
232
230
  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
- ])
231
+ recommendations.extend(
232
+ [
233
+ f"🚨 CRITICAL: Immediate action required - ${metrics.annual_savings:,.0f} annual savings opportunity",
234
+ "📋 Executive approval recommended for implementation",
235
+ " Target implementation: Within 30 days",
236
+ "📊 Monthly progress tracking recommended",
237
+ ]
238
+ )
239
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
- ])
240
+ recommendations.extend(
241
+ [
242
+ f"🔴 HIGH PRIORITY: ${metrics.annual_savings:,.0f} annual savings available",
243
+ "📋 Business case development recommended",
244
+ " Target implementation: Within 90 days",
245
+ "📊 Quarterly progress review recommended",
246
+ ]
247
+ )
246
248
  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
- ])
249
+ recommendations.extend(
250
+ [
251
+ f"🟡 MEDIUM PRIORITY: ${metrics.annual_savings:,.0f} annual savings potential",
252
+ "📋 Consider in next planning cycle",
253
+ "⏰ Target implementation: Within 6 months",
254
+ ]
255
+ )
252
256
  else:
253
- recommendations.extend([
254
- f"🟢 LOW PRIORITY: ${metrics.annual_savings:,.0f} annual savings",
255
- "📋 Include in routine optimization reviews"
256
- ])
257
+ recommendations.extend(
258
+ [
259
+ f"🟢 LOW PRIORITY: ${metrics.annual_savings:,.0f} annual savings",
260
+ "📋 Include in routine optimization reviews",
261
+ ]
262
+ )
257
263
 
258
264
  # ROI-based recommendations
259
265
  if metrics.roi_percentage > 200:
@@ -271,8 +277,9 @@ class UniversalBusinessLogic:
271
277
 
272
278
  return recommendations
273
279
 
274
- def create_executive_dashboard(self, results: List[OptimizationResult],
275
- dashboard_title: str = "Executive Dashboard") -> None:
280
+ def create_executive_dashboard(
281
+ self, results: List[OptimizationResult], dashboard_title: str = "Executive Dashboard"
282
+ ) -> None:
276
283
  """
277
284
  Create executive dashboard following successful FinOps patterns.
278
285
 
@@ -288,7 +295,14 @@ class UniversalBusinessLogic:
288
295
 
289
296
  # Summary metrics
290
297
  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]])
298
+ high_impact_count = len(
299
+ [
300
+ r
301
+ for r in results
302
+ if r.business_metrics.determine_impact_level()
303
+ in [BusinessImpactLevel.CRITICAL, BusinessImpactLevel.HIGH]
304
+ ]
305
+ )
292
306
 
293
307
  # Executive summary table
294
308
  summary_table = create_table(
@@ -296,13 +310,17 @@ class UniversalBusinessLogic:
296
310
  columns=[
297
311
  {"name": "Metric", "style": "cyan", "justify": "left"},
298
312
  {"name": "Value", "style": "bright_green", "justify": "right"},
299
- {"name": "Impact", "style": "yellow", "justify": "left"}
300
- ]
313
+ {"name": "Impact", "style": "yellow", "justify": "left"},
314
+ ],
301
315
  )
302
316
 
303
317
  summary_table.add_row("Total Annual Savings", format_cost(total_savings), f"{len(results)} opportunities")
304
318
  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")
319
+ summary_table.add_row(
320
+ "Average Confidence",
321
+ f"{sum(r.business_metrics.confidence_level for r in results) / len(results):.1f}%",
322
+ "Validation accuracy",
323
+ )
306
324
 
307
325
  console.print(summary_table)
308
326
 
@@ -318,8 +336,8 @@ class UniversalBusinessLogic:
318
336
  {"name": "Annual Savings", "style": "bright_green", "justify": "right"},
319
337
  {"name": "Impact", "style": "yellow", "justify": "center"},
320
338
  {"name": "Confidence", "style": "blue", "justify": "right"},
321
- {"name": "Next Action", "style": "white", "justify": "left"}
322
- ]
339
+ {"name": "Next Action", "style": "white", "justify": "left"},
340
+ ],
323
341
  )
324
342
 
325
343
  for result in top_results:
@@ -331,7 +349,7 @@ class UniversalBusinessLogic:
331
349
  format_cost(result.business_metrics.annual_savings),
332
350
  impact.value,
333
351
  f"{result.business_metrics.confidence_level:.1f}%",
334
- next_action
352
+ next_action,
335
353
  )
336
354
 
337
355
  console.print(opportunities_table)
@@ -350,8 +368,8 @@ class UniversalBusinessLogic:
350
368
  metrics = BusinessMetrics()
351
369
 
352
370
  # 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
371
+ current_monthly = usage_data.get("monthly_cost_current", 0.0)
372
+ optimized_monthly = usage_data.get("monthly_cost_optimized", current_monthly * 0.7) # Default 30% optimization
355
373
 
356
374
  metrics.monthly_cost_current = current_monthly
357
375
  metrics.monthly_cost_optimized = optimized_monthly
@@ -362,12 +380,12 @@ class UniversalBusinessLogic:
362
380
 
363
381
  # Set confidence based on resource type (following successful patterns)
364
382
  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
383
+ "NAT Gateway": 95.0, # High confidence from proven results
384
+ "Elastic IP": 90.0,
385
+ "EBS Volume": 85.0,
386
+ "EC2 Instance": 80.0,
387
+ "RDS Instance": 75.0,
388
+ "Generic": 70.0,
371
389
  }
372
390
  metrics.confidence_level = confidence_levels.get(resource_type, 70.0)
373
391
 
@@ -384,8 +402,9 @@ class UniversalBusinessLogic:
384
402
 
385
403
  return metrics
386
404
 
387
- def export_business_results(self, results: List[OptimizationResult],
388
- export_formats: List[str] = None) -> Dict[str, str]:
405
+ def export_business_results(
406
+ self, results: List[OptimizationResult], export_formats: List[str] = None
407
+ ) -> Dict[str, str]:
389
408
  """
390
409
  Export business results in multiple formats following successful patterns.
391
410
 
@@ -397,9 +416,9 @@ class UniversalBusinessLogic:
397
416
  Dictionary with export file paths
398
417
  """
399
418
  if export_formats is None:
400
- export_formats = ['csv', 'json', 'markdown']
419
+ export_formats = ["csv", "json", "markdown"]
401
420
 
402
- timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
421
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
403
422
  base_filename = f"{self.module_name}_optimization_results_{timestamp}"
404
423
 
405
424
  exported_files = {}
@@ -409,41 +428,44 @@ class UniversalBusinessLogic:
409
428
  for fmt in export_formats:
410
429
  filename = f"./awso_evidence/{base_filename}.{fmt}"
411
430
 
412
- if fmt == 'csv':
431
+ if fmt == "csv":
413
432
  # CSV export for analysis
414
433
  csv_content = "Resource,Annual_Savings,Impact_Level,Confidence,ROI_Percentage\n"
415
434
  for result in results:
416
435
  csv_content += f"{result.resource_type},{result.business_metrics.annual_savings},"
417
436
  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"
437
+ csv_content += (
438
+ f"{result.business_metrics.confidence_level},{result.business_metrics.roi_percentage}\n"
439
+ )
419
440
 
420
- with open(filename, 'w') as f:
441
+ with open(filename, "w") as f:
421
442
  f.write(csv_content)
422
443
 
423
- elif fmt == 'json':
444
+ elif fmt == "json":
424
445
  # JSON export for systems integration
425
446
  import json
447
+
426
448
  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': [
449
+ "module": self.module_name,
450
+ "timestamp": timestamp,
451
+ "total_results": len(results),
452
+ "total_annual_savings": sum(r.business_metrics.annual_savings for r in results),
453
+ "results": [
432
454
  {
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()
455
+ "resource_type": r.resource_type,
456
+ "annual_savings": r.business_metrics.annual_savings,
457
+ "impact_level": r.business_metrics.determine_impact_level().value,
458
+ "confidence_level": r.business_metrics.confidence_level,
459
+ "executive_summary": r.get_executive_summary(),
438
460
  }
439
461
  for r in results
440
- ]
462
+ ],
441
463
  }
442
464
 
443
- with open(filename, 'w') as f:
465
+ with open(filename, "w") as f:
444
466
  json.dump(json_data, f, indent=2)
445
467
 
446
- elif fmt == 'markdown':
468
+ elif fmt == "markdown":
447
469
  # Markdown export for documentation and reports
448
470
  md_content = f"# {self.module_name.title()} Optimization Results\n\n"
449
471
  md_content += f"**Generated**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
@@ -462,7 +484,7 @@ class UniversalBusinessLogic:
462
484
  md_content += f"- **Confidence**: {result.business_metrics.confidence_level:.1f}%\n"
463
485
  md_content += f"- **ROI**: {result.business_metrics.roi_percentage:.1f}%\n\n"
464
486
 
465
- with open(filename, 'w') as f:
487
+ with open(filename, "w") as f:
466
488
  f.write(md_content)
467
489
 
468
490
  exported_files[fmt] = filename
@@ -482,4 +504,4 @@ def create_business_logic_handler(module_name: str) -> UniversalBusinessLogic:
482
504
  Returns:
483
505
  UniversalBusinessLogic instance configured for the module
484
506
  """
485
- return UniversalBusinessLogic(module_name)
507
+ return UniversalBusinessLogic(module_name)
@@ -27,26 +27,19 @@ def common_aws_options(f: Callable) -> Callable:
27
27
  def my_command(profile, region, dry_run, **kwargs):
28
28
  # Your command logic here
29
29
  """
30
+
31
+ @click.option("--profile", help="AWS profile override (highest priority over environment variables)", type=str)
32
+ @click.option("--region", help="AWS region override (default: us-east-1)", type=str, default="us-east-1")
30
33
  @click.option(
31
- '--profile',
32
- help='AWS profile override (highest priority over environment variables)',
33
- type=str
34
- )
35
- @click.option(
36
- '--region',
37
- help='AWS region override (default: us-east-1)',
38
- type=str,
39
- default='us-east-1'
40
- )
41
- @click.option(
42
- '--dry-run',
34
+ "--dry-run",
43
35
  is_flag=True,
44
36
  default=True,
45
- help='Safe analysis mode - no resource modifications (enterprise default)'
37
+ help="Safe analysis mode - no resource modifications (enterprise default)",
46
38
  )
47
39
  @wraps(f)
48
40
  def wrapper(*args, **kwargs):
49
41
  return f(*args, **kwargs)
42
+
50
43
  return wrapper
51
44
 
52
45
 
@@ -65,26 +58,24 @@ def common_output_options(f: Callable) -> Callable:
65
58
  def my_command(output_format, output_dir, export, **kwargs):
66
59
  # Your command logic here
67
60
  """
61
+
68
62
  @click.option(
69
- '--output-format',
70
- type=click.Choice(['json', 'csv', 'table', 'pdf', 'markdown'], case_sensitive=False),
71
- default='table',
72
- help='Output format for results display'
73
- )
74
- @click.option(
75
- '--output-dir',
76
- default='./awso_evidence',
77
- help='Directory for generated files and evidence packages',
78
- type=click.Path()
63
+ "--output-format",
64
+ type=click.Choice(["json", "csv", "table", "pdf", "markdown"], case_sensitive=False),
65
+ default="table",
66
+ help="Output format for results display",
79
67
  )
80
68
  @click.option(
81
- '--export',
82
- is_flag=True,
83
- help='Enable multi-format export (CSV, JSON, PDF, HTML)'
69
+ "--output-dir",
70
+ default="./awso_evidence",
71
+ help="Directory for generated files and evidence packages",
72
+ type=click.Path(),
84
73
  )
74
+ @click.option("--export", is_flag=True, help="Enable multi-format export (CSV, JSON, PDF, HTML)")
85
75
  @wraps(f)
86
76
  def wrapper(*args, **kwargs):
87
77
  return f(*args, **kwargs)
78
+
88
79
  return wrapper
89
80
 
90
81
 
@@ -102,20 +93,18 @@ def mcp_validation_option(f: Callable) -> Callable:
102
93
  def my_command(validate, confidence_threshold, **kwargs):
103
94
  # Your command logic with MCP validation
104
95
  """
96
+
97
+ @click.option("--validate", is_flag=True, help="Enable MCP validation for enhanced accuracy (≥99.5% target)")
105
98
  @click.option(
106
- '--validate',
107
- is_flag=True,
108
- help='Enable MCP validation for enhanced accuracy (≥99.5% target)'
109
- )
110
- @click.option(
111
- '--confidence-threshold',
99
+ "--confidence-threshold",
112
100
  type=float,
113
101
  default=99.5,
114
- help='Minimum confidence threshold for validation (default: 99.5%%)'
102
+ help="Minimum confidence threshold for validation (default: 99.5%%)",
115
103
  )
116
104
  @wraps(f)
117
105
  def wrapper(*args, **kwargs):
118
106
  return f(*args, **kwargs)
107
+
119
108
  return wrapper
120
109
 
121
110
 
@@ -134,26 +123,21 @@ def enterprise_options(f: Callable) -> Callable:
134
123
  def my_command(all_profiles, combine, approval_required, **kwargs):
135
124
  # Your enterprise command logic
136
125
  """
126
+
137
127
  @click.option(
138
- '--all',
139
- 'all_profiles',
140
- is_flag=True,
141
- help='Use all available AWS profiles for multi-account operations'
142
- )
143
- @click.option(
144
- '--combine',
145
- is_flag=True,
146
- help='Combine profiles from the same AWS account for unified reporting'
128
+ "--all", "all_profiles", is_flag=True, help="Use all available AWS profiles for multi-account operations"
147
129
  )
130
+ @click.option("--combine", is_flag=True, help="Combine profiles from the same AWS account for unified reporting")
148
131
  @click.option(
149
- '--approval-required',
132
+ "--approval-required",
150
133
  is_flag=True,
151
134
  default=True,
152
- help='Require human approval for state-changing operations (enterprise default)'
135
+ help="Require human approval for state-changing operations (enterprise default)",
153
136
  )
154
137
  @wraps(f)
155
138
  def wrapper(*args, **kwargs):
156
139
  return f(*args, **kwargs)
140
+
157
141
  return wrapper
158
142
 
159
143
 
@@ -172,26 +156,16 @@ def performance_options(f: Callable) -> Callable:
172
156
  def my_command(performance_target, timeout, parallel, **kwargs):
173
157
  # Your performance-monitored command
174
158
  """
159
+
175
160
  @click.option(
176
- '--performance-target',
177
- type=int,
178
- default=30,
179
- help='Target execution time in seconds (enterprise default: 30s)'
180
- )
181
- @click.option(
182
- '--timeout',
183
- type=int,
184
- default=300,
185
- help='Maximum execution timeout in seconds (default: 5 minutes)'
186
- )
187
- @click.option(
188
- '--parallel',
189
- is_flag=True,
190
- help='Enable parallel processing for multi-resource operations'
161
+ "--performance-target", type=int, default=30, help="Target execution time in seconds (enterprise default: 30s)"
191
162
  )
163
+ @click.option("--timeout", type=int, default=300, help="Maximum execution timeout in seconds (default: 5 minutes)")
164
+ @click.option("--parallel", is_flag=True, help="Enable parallel processing for multi-resource operations")
192
165
  @wraps(f)
193
166
  def wrapper(*args, **kwargs):
194
167
  return f(*args, **kwargs)
168
+
195
169
  return wrapper
196
170
 
197
171
 
@@ -208,6 +182,7 @@ def all_standard_options(f: Callable) -> Callable:
208
182
  def comprehensive_command(**kwargs):
209
183
  # Command with all standard options available
210
184
  """
185
+
211
186
  @performance_options
212
187
  @enterprise_options
213
188
  @mcp_validation_option
@@ -216,4 +191,5 @@ def all_standard_options(f: Callable) -> Callable:
216
191
  @wraps(f)
217
192
  def wrapper(*args, **kwargs):
218
193
  return f(*args, **kwargs)
219
- return wrapper
194
+
195
+ return wrapper