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.
Files changed (94) hide show
  1. runbooks/__init__.py +1 -1
  2. runbooks/cfat/WEIGHT_CONFIG_README.md +1 -1
  3. runbooks/cfat/assessment/compliance.py +7 -7
  4. runbooks/cfat/models.py +6 -2
  5. runbooks/cfat/tests/__init__.py +6 -1
  6. runbooks/cli/__init__.py +13 -0
  7. runbooks/cli/commands/cfat.py +233 -0
  8. runbooks/cli/commands/finops.py +213 -0
  9. runbooks/cli/commands/inventory.py +276 -0
  10. runbooks/cli/commands/operate.py +266 -0
  11. runbooks/cli/commands/security.py +224 -0
  12. runbooks/cli/commands/validation.py +411 -0
  13. runbooks/cli/commands/vpc.py +246 -0
  14. runbooks/cli/registry.py +95 -0
  15. runbooks/cloudops/__init__.py +3 -3
  16. runbooks/cloudops/cost_optimizer.py +164 -28
  17. runbooks/cloudops/interfaces.py +2 -2
  18. runbooks/cloudops/mcp_cost_validation.py +3 -3
  19. runbooks/cloudops/notebook_framework.py +2 -2
  20. runbooks/common/aws_profile_manager.py +337 -0
  21. runbooks/common/aws_utils.py +1 -1
  22. runbooks/common/business_logic.py +3 -3
  23. runbooks/common/comprehensive_cost_explorer_integration.py +1 -1
  24. runbooks/common/cross_account_manager.py +1 -1
  25. runbooks/common/decorators.py +225 -0
  26. runbooks/common/mcp_cost_explorer_integration.py +2 -2
  27. runbooks/common/organizations_client.py +1 -1
  28. runbooks/common/patterns.py +206 -0
  29. runbooks/common/profile_utils.py +149 -14
  30. runbooks/common/rich_utils.py +507 -16
  31. runbooks/finops/README.md +11 -11
  32. runbooks/finops/__init__.py +4 -4
  33. runbooks/finops/business_cases.py +3 -3
  34. runbooks/finops/cli.py +169 -103
  35. runbooks/finops/cost_optimizer.py +4 -4
  36. runbooks/finops/dashboard_router.py +2 -2
  37. runbooks/finops/ebs_cost_optimizer.py +4 -4
  38. runbooks/finops/ebs_optimizer.py +19 -2
  39. runbooks/finops/embedded_mcp_validator.py +101 -23
  40. runbooks/finops/enhanced_progress.py +8 -8
  41. runbooks/finops/enterprise_wrappers.py +7 -7
  42. runbooks/finops/finops_scenarios.py +101 -27
  43. runbooks/finops/legacy_migration.py +8 -8
  44. runbooks/finops/markdown_exporter.py +2 -2
  45. runbooks/finops/multi_dashboard.py +1 -1
  46. runbooks/finops/nat_gateway_optimizer.py +1 -1
  47. runbooks/finops/optimizer.py +6 -6
  48. runbooks/finops/rds_snapshot_optimizer.py +1389 -0
  49. runbooks/finops/scenario_cli_integration.py +13 -13
  50. runbooks/finops/scenarios.py +16 -16
  51. runbooks/finops/single_dashboard.py +10 -10
  52. runbooks/finops/tests/test_finops_dashboard.py +3 -3
  53. runbooks/finops/tests/test_reference_images_validation.py +2 -2
  54. runbooks/finops/tests/test_single_account_features.py +17 -17
  55. runbooks/finops/tests/validate_test_suite.py +1 -1
  56. runbooks/finops/validation_framework.py +5 -5
  57. runbooks/finops/vpc_cleanup_exporter.py +3 -3
  58. runbooks/finops/vpc_cleanup_optimizer.py +3 -3
  59. runbooks/finops/workspaces_analyzer.py +31 -13
  60. runbooks/hitl/enhanced_workflow_engine.py +1 -1
  61. runbooks/inventory/README.md +3 -3
  62. runbooks/inventory/Tests/common_test_data.py +30 -30
  63. runbooks/inventory/collectors/aws_comprehensive.py +28 -11
  64. runbooks/inventory/collectors/aws_networking.py +2 -2
  65. runbooks/inventory/discovery.md +2 -2
  66. runbooks/inventory/find_ec2_security_groups.py +1 -1
  67. runbooks/inventory/list_rds_snapshots_aggregator.py +745 -0
  68. runbooks/inventory/organizations_discovery.py +1 -1
  69. runbooks/inventory/vpc_analyzer.py +1 -1
  70. runbooks/inventory/vpc_flow_analyzer.py +2 -2
  71. runbooks/main.py +143 -8882
  72. runbooks/metrics/dora_metrics_engine.py +2 -2
  73. runbooks/operate/mcp_integration.py +1 -1
  74. runbooks/operate/networking_cost_heatmap.py +4 -2
  75. runbooks/operate/privatelink_operations.py +1 -1
  76. runbooks/operate/vpc_endpoints.py +1 -1
  77. runbooks/operate/vpc_operations.py +2 -2
  78. runbooks/remediation/commvault_ec2_analysis.py +1 -1
  79. runbooks/remediation/rds_snapshot_list.py +5 -5
  80. runbooks/remediation/workspaces_list.py +5 -5
  81. runbooks/security/integration_test_enterprise_security.py +5 -3
  82. runbooks/security/run_script.py +1 -1
  83. runbooks/sre/mcp_reliability_engine.py +6 -6
  84. runbooks/utils/version_validator.py +1 -1
  85. runbooks/validation/comprehensive_2way_validator.py +9 -4
  86. runbooks/vpc/heatmap_engine.py +7 -4
  87. runbooks/vpc/mcp_no_eni_validator.py +1 -1
  88. runbooks/vpc/unified_scenarios.py +7 -7
  89. {runbooks-1.1.2.dist-info → runbooks-1.1.4.dist-info}/METADATA +53 -52
  90. {runbooks-1.1.2.dist-info → runbooks-1.1.4.dist-info}/RECORD +94 -80
  91. {runbooks-1.1.2.dist-info → runbooks-1.1.4.dist-info}/WHEEL +0 -0
  92. {runbooks-1.1.2.dist-info → runbooks-1.1.4.dist-info}/entry_points.txt +0 -0
  93. {runbooks-1.1.2.dist-info → runbooks-1.1.4.dist-info}/licenses/LICENSE +0 -0
  94. {runbooks-1.1.2.dist-info → runbooks-1.1.4.dist-info}/top_level.txt +0 -0
@@ -67,7 +67,7 @@ from runbooks.finops.finops_scenarios import (
67
67
  FinOpsBusinessScenarios,
68
68
  )
69
69
 
70
- # NEW v0.9.5: Clean API wrapper for notebook consumption
70
+ # NEW latest version: Clean API wrapper for notebook consumption
71
71
  from runbooks.finops.scenarios import (
72
72
  finops_workspaces,
73
73
  finops_snapshots,
@@ -99,12 +99,12 @@ __all__ = [
99
99
  "_run_executive_dashboard",
100
100
  # Enterprise Dashboard Classes - backward compatibility
101
101
  "FinOpsConfig",
102
- # Business scenarios with notebook integration (v0.9.5)
102
+ # Business scenarios with notebook integration (latest version)
103
103
  "create_business_scenarios_validated",
104
104
  "format_for_business_audience",
105
105
  "format_for_technical_audience",
106
106
  "FinOpsBusinessScenarios",
107
- # NEW v0.9.5: Clean API wrapper functions (cleaned naming)
107
+ # NEW latest version: Clean API wrapper functions (cleaned naming)
108
108
  "finops_workspaces",
109
109
  "finops_snapshots",
110
110
  "finops_commvault",
@@ -140,7 +140,7 @@ __all__ = [
140
140
  "export_audit_report_to_json",
141
141
  "export_trend_data_to_json",
142
142
  "load_config_file",
143
- # NOTEBOOK INTEGRATION FUNCTIONS (v0.9.5)
143
+ # NOTEBOOK INTEGRATION FUNCTIONS (latest version)
144
144
  "format_currency",
145
145
  "create_business_summary_table",
146
146
  "export_scenarios_to_notebook_html",
@@ -1,5 +1,5 @@
1
1
  """
2
- 🏢 CloudOps-Automation Business Cases Module (Enhanced v0.9.6)
2
+ 🏢 CloudOps-Automation Business Cases Module (Enhanced latest version)
3
3
  Enterprise Business Logic Extraction from 67+ Notebooks
4
4
 
5
5
  Strategic Achievement: Business logic consolidation enabling $78,500+ annual savings
@@ -17,7 +17,7 @@ Enhanced Features:
17
17
  - Executive dashboard integration
18
18
 
19
19
  Author: Enterprise Agile Team (6-Agent Coordination)
20
- Version: 0.9.6 - Distributed Architecture Framework
20
+ Version: latest version - Distributed Architecture Framework
21
21
  """
22
22
 
23
23
  import os
@@ -758,7 +758,7 @@ class EnhancedBusinessCaseDashboard:
758
758
 
759
759
  Strategic Output: Complete business case portfolio for C-suite presentation
760
760
  """
761
- print_header("Enterprise Business Case Portfolio Analysis", "v0.9.6")
761
+ print_header("Enterprise Business Case Portfolio Analysis", "latest version")
762
762
 
763
763
  # Get FinOps business cases (Universal $132K methodology)
764
764
  finops_cases = self.finops_analyzer.get_all_business_cases()
runbooks/finops/cli.py CHANGED
@@ -228,7 +228,7 @@ def main() -> int:
228
228
  parser.add_argument(
229
229
  "--scenario",
230
230
  type=str,
231
- help="Business scenario analysis (workspaces, snapshots, commvault, nat-gateway, elastic-ip, ebs, vpc-cleanup)",
231
+ help="Business scenario analysis (workspaces, rds-snapshots, backup-investigation, nat-gateway, elastic-ip, ebs-optimization, vpc-cleanup)",
232
232
  )
233
233
  parser.add_argument(
234
234
  "--help-scenario",
@@ -272,93 +272,58 @@ def main() -> int:
272
272
 
273
273
  console.print(f"[bold cyan]🎯 Executing Business Scenario: {args.scenario}[/bold cyan]")
274
274
 
275
- # Define scenario execution functions with proper parameters
276
- # CRITICAL FIX: Use enterprise profile management for proper BILLING_PROFILE fallback
277
- from runbooks.common.profile_utils import get_profile_for_operation
278
-
279
- def execute_workspaces_scenario():
280
- from runbooks.finops.scenarios import finops_workspaces
281
- # Use enterprise profile resolution: User > Environment > Default
282
- profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
283
- return finops_workspaces(profile=profile_param)
284
-
285
- def execute_snapshots_scenario():
286
- from runbooks.finops.scenarios import finops_snapshots
287
- # Use enterprise profile resolution: User > Environment > Default
288
- profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
289
- return finops_snapshots(profile=profile_param)
290
-
291
- def execute_commvault_scenario():
292
- from runbooks.finops.scenarios import finops_commvault
293
- # Use enterprise profile resolution: User > Environment > Default
294
- profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
295
- return finops_commvault(profile=profile_param)
296
-
297
- def execute_nat_gateway_scenario():
298
- from runbooks.finops.nat_gateway_optimizer import nat_gateway_optimizer
299
- # Use enterprise profile resolution: User > Environment > Default
300
- profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
301
- regions = args.regions if args.regions else ['us-east-1']
302
- # Call the CLI function with default parameters
303
- nat_gateway_optimizer(
304
- profile=profile_param,
305
- regions=regions,
306
- dry_run=True,
307
- export_format='json',
308
- output_file=None,
309
- usage_threshold_days=7
310
- )
311
- return {"scenario": "nat-gateway", "status": "completed", "profile": profile_param}
312
-
313
- def execute_ebs_scenario():
314
- # Create a simplified EBS scenario execution
315
- print_info("EBS optimization scenario analysis")
316
- # Use enterprise profile resolution: User > Environment > Default
317
- profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
318
- return {"scenario": "ebs", "status": "completed", "profile": profile_param}
319
-
320
- def execute_vpc_cleanup_scenario():
321
- # Create a simplified VPC cleanup scenario execution
322
- print_info("VPC cleanup scenario analysis")
323
- # Use enterprise profile resolution: User > Environment > Default
324
- profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
325
- return {"scenario": "vpc-cleanup", "status": "completed", "profile": profile_param}
326
-
327
- def execute_elastic_ip_scenario():
328
- # Create a simplified elastic IP scenario execution
329
- print_info("Elastic IP optimization scenario analysis")
330
- # Use enterprise profile resolution: User > Environment > Default
331
- profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
332
- return {"scenario": "elastic-ip", "status": "completed", "profile": profile_param}
333
-
334
- # Map scenarios to execution functions
335
- scenario_map = {
336
- 'workspaces': execute_workspaces_scenario,
337
- 'snapshots': execute_snapshots_scenario,
338
- 'commvault': execute_commvault_scenario,
339
- 'nat-gateway': execute_nat_gateway_scenario,
340
- 'ebs': execute_ebs_scenario,
341
- 'vpc-cleanup': execute_vpc_cleanup_scenario,
342
- 'elastic-ip': execute_elastic_ip_scenario,
343
- }
344
-
345
- if args.scenario not in scenario_map:
346
- print_error(f"Unknown scenario: '{args.scenario}'")
347
- print_info("Available scenarios: " + ", ".join(scenario_map.keys()))
348
- return 1
349
-
350
- # Execute scenario
351
- scenario_func = scenario_map[args.scenario]
352
- result = scenario_func()
353
-
354
- print_success(f"✅ Scenario '{args.scenario}' completed successfully")
355
-
356
- # Export results if requested
357
- if args.report_type and result:
358
- from runbooks.finops.helpers import export_scenario_results
359
- export_scenario_results(result, args.scenario, args.report_type, args.dir)
360
-
361
- return 0
275
+ # CRITICAL FIX: Handle --all flag for scenarios by using dashboard router logic
276
+ if hasattr(args, "all") and args.all:
277
+ print_info("🔍 --all flag detected: Integrating with dashboard router for organization discovery")
278
+
279
+ # Use dashboard router to handle --all flag and get profiles
280
+ from runbooks.finops.dashboard_router import create_dashboard_router
281
+ router = create_dashboard_router()
282
+ use_case, routing_config = router.detect_use_case(args)
283
+
284
+ # Extract profiles from routing config
285
+ profiles_to_use = routing_config.get("profiles_to_analyze", [])
286
+ if not profiles_to_use:
287
+ print_error("--all flag failed to discover any profiles")
288
+ return 1
289
+
290
+ print_success(f"Discovered {len(profiles_to_use)} profiles for scenario execution")
291
+
292
+ # Execute scenario across all discovered profiles
293
+ all_results = []
294
+ for profile in profiles_to_use:
295
+ print_info(f"Executing scenario '{args.scenario}' for profile: {profile}")
296
+
297
+ # Create a copy of args with single profile for execution
298
+ single_profile_args = argparse.Namespace(**vars(args))
299
+ single_profile_args.profiles = [profile]
300
+ single_profile_args.all = False # Disable --all for individual execution
301
+
302
+ # Execute scenario with single profile (recursive call but with all=False)
303
+ result = _execute_single_scenario(single_profile_args)
304
+ if result:
305
+ all_results.append(result)
306
+
307
+ # Combine results and export if requested
308
+ combined_result = {
309
+ "scenario": args.scenario,
310
+ "status": "completed",
311
+ "profiles_analyzed": len(profiles_to_use),
312
+ "individual_results": all_results,
313
+ "organization_scope": use_case == "organization_wide"
314
+ }
315
+
316
+ print_success(f"✅ Scenario '{args.scenario}' completed for {len(profiles_to_use)} profiles")
317
+
318
+ # Export results if requested
319
+ if args.report_type and combined_result:
320
+ from runbooks.finops.helpers import export_scenario_results
321
+ export_scenario_results(combined_result, args.scenario, args.report_type, args.dir)
322
+
323
+ return 0
324
+ else:
325
+ # Handle single profile execution (existing logic)
326
+ return _execute_single_scenario(args)
362
327
 
363
328
  except ImportError as e:
364
329
  console.print(f"[red]❌ Scenario '{args.scenario}' not available: {e}[/red]")
@@ -367,26 +332,127 @@ def main() -> int:
367
332
  console.print(f"[red]❌ Scenario execution failed: {e}[/red]")
368
333
  return 1
369
334
 
335
+
336
+ def _execute_single_scenario(args: argparse.Namespace) -> int:
337
+ """Execute a scenario for a single profile (internal helper function)."""
338
+ import argparse
339
+ from runbooks.common.rich_utils import print_header, print_success, print_error, print_info
340
+ from runbooks.common.profile_utils import get_profile_for_operation
341
+
342
+ def execute_workspaces_scenario():
343
+ from runbooks.finops.scenarios import finops_workspaces
344
+ # Use enterprise profile resolution: User > Environment > Default
345
+ profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
346
+ return finops_workspaces(profile=profile_param)
347
+
348
+ def execute_snapshots_scenario():
349
+ from runbooks.finops.scenarios import finops_snapshots
350
+ # Use enterprise profile resolution: User > Environment > Default
351
+ profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
352
+ return finops_snapshots(profile=profile_param)
353
+
354
+ def execute_commvault_scenario():
355
+ from runbooks.finops.scenarios import finops_commvault
356
+ # Use enterprise profile resolution: User > Environment > Default
357
+ profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
358
+ return finops_commvault(profile=profile_param)
359
+
360
+ def execute_nat_gateway_scenario():
361
+ from runbooks.finops.nat_gateway_optimizer import nat_gateway_optimizer
362
+ # Use enterprise profile resolution: User > Environment > Default
363
+ profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
364
+ regions = args.regions if args.regions else ['us-east-1']
365
+ # Call the CLI function with default parameters
366
+ nat_gateway_optimizer(
367
+ profile=profile_param,
368
+ regions=regions,
369
+ dry_run=True,
370
+ export_format='json',
371
+ output_file=None,
372
+ usage_threshold_days=7
373
+ )
374
+ return {"scenario": "nat-gateway", "status": "completed", "profile": profile_param}
375
+
376
+ def execute_ebs_scenario():
377
+ # Create a simplified EBS scenario execution
378
+ print_info("EBS optimization scenario analysis")
379
+ # Use enterprise profile resolution: User > Environment > Default
380
+ profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
381
+ return {"scenario": "ebs", "status": "completed", "profile": profile_param}
382
+
383
+ def execute_vpc_cleanup_scenario():
384
+ # Create a simplified VPC cleanup scenario execution
385
+ print_info("VPC cleanup scenario analysis")
386
+ # Use enterprise profile resolution: User > Environment > Default
387
+ profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
388
+ return {"scenario": "vpc-cleanup", "status": "completed", "profile": profile_param}
389
+
390
+ def execute_elastic_ip_scenario():
391
+ # Create a simplified elastic IP scenario execution
392
+ print_info("Elastic IP optimization scenario analysis")
393
+ # Use enterprise profile resolution: User > Environment > Default
394
+ profile_param = get_profile_for_operation("billing", args.profiles[0] if args.profiles else None)
395
+ return {"scenario": "elastic-ip", "status": "completed", "profile": profile_param}
396
+
397
+ # Map scenarios to execution functions
398
+ scenario_map = {
399
+ 'workspaces': execute_workspaces_scenario,
400
+ 'rds-snapshots': execute_snapshots_scenario,
401
+ 'backup-investigation': execute_commvault_scenario,
402
+ 'nat-gateway': execute_nat_gateway_scenario,
403
+ 'ebs-optimization': execute_ebs_scenario,
404
+ 'vpc-cleanup': execute_vpc_cleanup_scenario,
405
+ 'elastic-ip': execute_elastic_ip_scenario,
406
+ }
407
+
408
+ if args.scenario not in scenario_map:
409
+ print_error(f"Unknown scenario: '{args.scenario}'")
410
+ print_info("Available scenarios: " + ", ".join(scenario_map.keys()))
411
+ return 1
412
+
413
+ # Execute scenario
414
+ scenario_func = scenario_map[args.scenario]
415
+ result = scenario_func()
416
+
417
+ print_success(f"✅ Scenario '{args.scenario}' completed successfully")
418
+
419
+ # Export results if requested
420
+ if args.report_type and result:
421
+ from runbooks.finops.helpers import export_scenario_results
422
+ export_scenario_results(result, args.scenario, args.report_type, args.dir)
423
+
424
+ return 0
425
+
426
+
370
427
  # Handle PDCA mode
371
428
  if args.pdca or args.pdca_continuous:
372
- import asyncio
373
-
374
- from runbooks.finops.pdca_engine import AutonomousPDCAEngine, PDCAThresholds
429
+ try:
430
+ import asyncio
431
+ from runbooks.finops.pdca_engine import AutonomousPDCAEngine, PDCAThresholds
432
+
433
+ console.print("[bold bright_cyan]🤖 Launching Autonomous PDCA Engine...[/]")
434
+
435
+ # Configure PDCA thresholds
436
+ thresholds = PDCAThresholds(
437
+ max_risk_score=25,
438
+ max_cost_increase=10.0,
439
+ max_untagged_resources=50,
440
+ max_unused_eips=5,
441
+ max_budget_overruns=1,
442
+ )
375
443
 
376
- console.print("[bold bright_cyan]🤖 Launching Autonomous PDCA Engine...[/]")
444
+ # Initialize PDCA engine
445
+ artifacts_dir = args.dir or "artifacts"
377
446
 
378
- # Configure PDCA thresholds
379
- thresholds = PDCAThresholds(
380
- max_risk_score=25,
381
- max_cost_increase=10.0,
382
- max_untagged_resources=50,
383
- max_unused_eips=5,
384
- max_budget_overruns=1,
385
- )
447
+ # Ensure artifacts directory exists
448
+ import os
449
+ os.makedirs(artifacts_dir, exist_ok=True)
386
450
 
387
- # Initialize PDCA engine
388
- artifacts_dir = args.dir or "artifacts"
389
- engine = AutonomousPDCAEngine(thresholds=thresholds, artifacts_dir=artifacts_dir)
451
+ engine = AutonomousPDCAEngine(thresholds=thresholds, artifacts_dir=artifacts_dir)
452
+ except ImportError as e:
453
+ console.print(f"[red]❌ PDCA Engine not available: {e}[/]")
454
+ console.print("[yellow]💡 PDCA functionality requires additional setup[/]")
455
+ return 1
390
456
 
391
457
  try:
392
458
  # Determine execution mode
@@ -100,7 +100,7 @@ class AWSCostOptimizer:
100
100
  Returns:
101
101
  Tuple (success, list_of_idle_instances)
102
102
  """
103
- print_header("Cost Optimizer - Idle Instance Detection", "v0.9.1")
103
+ print_header("Cost Optimizer - Idle Instance Detection", "latest version")
104
104
 
105
105
  result = []
106
106
  regions_to_check = [region] if region else self._get_all_regions()
@@ -409,7 +409,7 @@ class AWSCostOptimizer:
409
409
  Returns:
410
410
  Tuple (success, list_of_low_usage_volumes)
411
411
  """
412
- print_header("Cost Optimizer - Low Usage EBS Volume Detection", "v0.9.1")
412
+ print_header("Cost Optimizer - Low Usage EBS Volume Detection", "latest version")
413
413
 
414
414
  result = []
415
415
  regions_to_check = [region] if region else self._get_all_regions()
@@ -739,7 +739,7 @@ class AWSCostOptimizer:
739
739
  Returns:
740
740
  Tuple (success, list_of_unused_nat_gateways)
741
741
  """
742
- print_header("Cost Optimizer - Unused NAT Gateway Detection", "v0.9.1")
742
+ print_header("Cost Optimizer - Unused NAT Gateway Detection", "latest version")
743
743
 
744
744
  result = []
745
745
  regions_to_check = [region] if region else self._get_all_regions()
@@ -1206,7 +1206,7 @@ def comprehensive_cost_optimization(
1206
1206
  - AWS_Delete_EBS_Volumes_With_Low_Usage.ipynb
1207
1207
  """
1208
1208
 
1209
- print_header("Comprehensive AWS Cost Optimization", "v0.9.1")
1209
+ print_header("Comprehensive AWS Cost Optimization", "latest version")
1210
1210
 
1211
1211
  total_monthly_savings = 0.0
1212
1212
  total_annual_savings = 0.0
@@ -283,7 +283,7 @@ class DashboardRouter:
283
283
  int: Exit code (0 for success, 1 for failure)
284
284
  """
285
285
  try:
286
- print_header("FinOps Dashboard Router", "1.1.1")
286
+ print_header("FinOps Dashboard Router", "latest version")
287
287
 
288
288
  # Detect use-case and route appropriately
289
289
  use_case, routing_config = self.detect_use_case(args)
@@ -551,7 +551,7 @@ class DashboardRouter:
551
551
  - Smooth progress tracking (no 0%→100% jumps)
552
552
  """
553
553
  try:
554
- print_header("Service-Per-Row Dashboard", "1.1.1")
554
+ print_header("Service-Per-Row Dashboard", "latest version")
555
555
  print_info("🎯 Focus: TOP 10 Services with optimization insights")
556
556
 
557
557
  # Get profile for analysis
@@ -16,7 +16,7 @@ Business Focus: CFO/Financial stakeholder optimization with quantified ROI analy
16
16
  and enterprise-grade safety controls for multi-account EBS portfolio management.
17
17
 
18
18
  Author: Enterprise Agile Team (6-Agent Coordination)
19
- Version: 0.9.6 - Cost Optimization Portfolio
19
+ Version: latest version - Cost Optimization Portfolio
20
20
  """
21
21
 
22
22
  import os
@@ -154,7 +154,7 @@ class EBSCostOptimizer:
154
154
  Strategic Focus: Complete EBS portfolio analysis with quantified business impact
155
155
  for enterprise financial decision making.
156
156
  """
157
- print_header("EBS Volume Cost Optimization Engine", "Comprehensive Analysis v0.9.6")
157
+ print_header("EBS Volume Cost Optimization Engine", "Comprehensive Analysis latest version")
158
158
 
159
159
  regions = regions or ["us-east-1", "us-west-2", "eu-west-1"]
160
160
 
@@ -254,7 +254,7 @@ class EBSCostOptimizer:
254
254
  Business Focus: 20% cost reduction with enhanced performance for GP2 volumes
255
255
  Enterprise Value: $1.5M-$9.3M savings potential across large environments
256
256
  """
257
- print_header("GP2 to GP3 Conversion Analysis", "Cost Optimization Engine v0.9.6")
257
+ print_header("GP2 to GP3 Conversion Analysis", "Cost Optimization Engine latest version")
258
258
 
259
259
  regions = regions or ["us-east-1", "us-west-2"]
260
260
 
@@ -329,7 +329,7 @@ EBS GP2 to GP3 Conversion Analysis Summary:
329
329
  Business Focus: Eliminate ongoing costs for unused storage resources
330
330
  Safety Focus: Comprehensive safety checks before cleanup recommendations
331
331
  """
332
- print_header("Unattached EBS Volume Cleanup Analysis", "Resource Cleanup v0.9.6")
332
+ print_header("Unattached EBS Volume Cleanup Analysis", "Resource Cleanup latest version")
333
333
 
334
334
  regions = regions or ["us-east-1", "us-west-2"]
335
335
 
@@ -513,8 +513,25 @@ class EBSOptimizer:
513
513
  metrics = usage_metrics.get(volume.volume_id)
514
514
  instance_state = getattr(volume, 'instance_state', None)
515
515
 
516
- # Calculate current monthly cost
517
- monthly_cost = volume.size * self.ebs_pricing.get(volume.volume_type, 0.10)
516
+ # Calculate current monthly cost using dynamic pricing (enterprise compliance)
517
+ volume_pricing = self.ebs_pricing.get(volume.volume_type)
518
+ if volume_pricing is None:
519
+ # Dynamic fallback for unknown volume types - no hardcoded values
520
+ try:
521
+ from ..common.aws_pricing import get_aws_pricing_engine
522
+ pricing_engine = get_aws_pricing_engine(profile=self.profile_name, enable_fallback=True)
523
+ volume_pricing_result = pricing_engine.get_ebs_pricing(volume.volume_type, "us-east-1")
524
+ volume_pricing = volume_pricing_result.monthly_cost_per_gb
525
+ print_info(f"Dynamic pricing resolved for {volume.volume_type}: ${volume_pricing:.4f}/GB/month")
526
+ except Exception as e:
527
+ print_error(f"ENTERPRISE COMPLIANCE VIOLATION: Cannot determine pricing for {volume.volume_type}: {e}")
528
+ print_warning("Universal compatibility requires dynamic pricing - hardcoded values not permitted")
529
+ raise RuntimeError(
530
+ f"Universal compatibility mode requires dynamic AWS pricing for volume type '{volume.volume_type}'. "
531
+ f"Please ensure your AWS profile has pricing:GetProducts permissions."
532
+ )
533
+
534
+ monthly_cost = volume.size * volume_pricing
518
535
  annual_cost = monthly_cost * 12
519
536
 
520
537
  # Initialize optimization analysis