runbooks 0.9.9__py3-none-any.whl → 1.0.1__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 (111) hide show
  1. runbooks/__init__.py +1 -1
  2. runbooks/cfat/WEIGHT_CONFIG_README.md +368 -0
  3. runbooks/cfat/app.ts +27 -19
  4. runbooks/cfat/assessment/runner.py +6 -5
  5. runbooks/cfat/cloud_foundations_assessment.py +626 -0
  6. runbooks/cfat/tests/test_weight_configuration.ts +449 -0
  7. runbooks/cfat/weight_config.ts +574 -0
  8. runbooks/cloudops/cost_optimizer.py +95 -33
  9. runbooks/common/__init__.py +26 -9
  10. runbooks/common/aws_pricing.py +1353 -0
  11. runbooks/common/aws_pricing_api.py +205 -0
  12. runbooks/common/aws_utils.py +2 -2
  13. runbooks/common/comprehensive_cost_explorer_integration.py +979 -0
  14. runbooks/common/cross_account_manager.py +606 -0
  15. runbooks/common/date_utils.py +115 -0
  16. runbooks/common/enhanced_exception_handler.py +14 -7
  17. runbooks/common/env_utils.py +96 -0
  18. runbooks/common/mcp_cost_explorer_integration.py +5 -4
  19. runbooks/common/mcp_integration.py +49 -2
  20. runbooks/common/organizations_client.py +579 -0
  21. runbooks/common/profile_utils.py +127 -72
  22. runbooks/common/rich_utils.py +3 -3
  23. runbooks/finops/cost_optimizer.py +2 -1
  24. runbooks/finops/dashboard_runner.py +47 -28
  25. runbooks/finops/ebs_optimizer.py +56 -9
  26. runbooks/finops/elastic_ip_optimizer.py +13 -9
  27. runbooks/finops/embedded_mcp_validator.py +31 -0
  28. runbooks/finops/enhanced_trend_visualization.py +10 -4
  29. runbooks/finops/finops_dashboard.py +6 -5
  30. runbooks/finops/iam_guidance.py +6 -1
  31. runbooks/finops/markdown_exporter.py +217 -2
  32. runbooks/finops/nat_gateway_optimizer.py +76 -20
  33. runbooks/finops/tests/test_integration.py +3 -1
  34. runbooks/finops/vpc_cleanup_exporter.py +28 -26
  35. runbooks/finops/vpc_cleanup_optimizer.py +363 -16
  36. runbooks/inventory/__init__.py +10 -1
  37. runbooks/inventory/cloud_foundations_integration.py +409 -0
  38. runbooks/inventory/core/collector.py +1177 -94
  39. runbooks/inventory/discovery.md +339 -0
  40. runbooks/inventory/drift_detection_cli.py +327 -0
  41. runbooks/inventory/inventory_mcp_cli.py +171 -0
  42. runbooks/inventory/inventory_modules.py +6 -9
  43. runbooks/inventory/list_ec2_instances.py +3 -3
  44. runbooks/inventory/mcp_inventory_validator.py +2149 -0
  45. runbooks/inventory/mcp_vpc_validator.py +23 -6
  46. runbooks/inventory/organizations_discovery.py +104 -9
  47. runbooks/inventory/rich_inventory_display.py +129 -1
  48. runbooks/inventory/unified_validation_engine.py +1279 -0
  49. runbooks/inventory/verify_ec2_security_groups.py +3 -1
  50. runbooks/inventory/vpc_analyzer.py +825 -7
  51. runbooks/inventory/vpc_flow_analyzer.py +36 -42
  52. runbooks/main.py +708 -47
  53. runbooks/monitoring/performance_monitor.py +11 -7
  54. runbooks/operate/base.py +9 -6
  55. runbooks/operate/deployment_framework.py +5 -4
  56. runbooks/operate/deployment_validator.py +6 -5
  57. runbooks/operate/dynamodb_operations.py +6 -5
  58. runbooks/operate/ec2_operations.py +3 -2
  59. runbooks/operate/mcp_integration.py +6 -5
  60. runbooks/operate/networking_cost_heatmap.py +21 -16
  61. runbooks/operate/s3_operations.py +13 -12
  62. runbooks/operate/vpc_operations.py +100 -12
  63. runbooks/remediation/base.py +4 -2
  64. runbooks/remediation/commons.py +5 -5
  65. runbooks/remediation/commvault_ec2_analysis.py +68 -15
  66. runbooks/remediation/config/accounts_example.json +31 -0
  67. runbooks/remediation/ec2_unattached_ebs_volumes.py +6 -3
  68. runbooks/remediation/multi_account.py +120 -7
  69. runbooks/remediation/rds_snapshot_list.py +5 -3
  70. runbooks/remediation/remediation_cli.py +710 -0
  71. runbooks/remediation/universal_account_discovery.py +377 -0
  72. runbooks/security/compliance_automation_engine.py +99 -20
  73. runbooks/security/config/__init__.py +24 -0
  74. runbooks/security/config/compliance_config.py +255 -0
  75. runbooks/security/config/compliance_weights_example.json +22 -0
  76. runbooks/security/config_template_generator.py +500 -0
  77. runbooks/security/security_cli.py +377 -0
  78. runbooks/validation/__init__.py +21 -1
  79. runbooks/validation/cli.py +8 -7
  80. runbooks/validation/comprehensive_2way_validator.py +2007 -0
  81. runbooks/validation/mcp_validator.py +965 -101
  82. runbooks/validation/terraform_citations_validator.py +363 -0
  83. runbooks/validation/terraform_drift_detector.py +1098 -0
  84. runbooks/vpc/cleanup_wrapper.py +231 -10
  85. runbooks/vpc/config.py +346 -73
  86. runbooks/vpc/cross_account_session.py +312 -0
  87. runbooks/vpc/heatmap_engine.py +115 -41
  88. runbooks/vpc/manager_interface.py +9 -9
  89. runbooks/vpc/mcp_no_eni_validator.py +1630 -0
  90. runbooks/vpc/networking_wrapper.py +14 -8
  91. runbooks/vpc/runbooks_adapter.py +33 -12
  92. runbooks/vpc/tests/conftest.py +4 -2
  93. runbooks/vpc/tests/test_cost_engine.py +4 -2
  94. runbooks/vpc/unified_scenarios.py +73 -3
  95. runbooks/vpc/vpc_cleanup_integration.py +512 -78
  96. {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/METADATA +94 -52
  97. {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/RECORD +101 -81
  98. runbooks/finops/runbooks.inventory.organizations_discovery.log +0 -0
  99. runbooks/finops/runbooks.security.report_generator.log +0 -0
  100. runbooks/finops/runbooks.security.run_script.log +0 -0
  101. runbooks/finops/runbooks.security.security_export.log +0 -0
  102. runbooks/finops/tests/results_test_finops_dashboard.xml +0 -1
  103. runbooks/inventory/artifacts/scale-optimize-status.txt +0 -12
  104. runbooks/inventory/runbooks.inventory.organizations_discovery.log +0 -0
  105. runbooks/inventory/runbooks.security.report_generator.log +0 -0
  106. runbooks/inventory/runbooks.security.run_script.log +0 -0
  107. runbooks/inventory/runbooks.security.security_export.log +0 -0
  108. {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/WHEEL +0 -0
  109. {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/entry_points.txt +0 -0
  110. {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/licenses/LICENSE +0 -0
  111. {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/top_level.txt +0 -0
@@ -31,6 +31,8 @@ from runbooks.common.rich_utils import (
31
31
  console, print_header, print_success, print_error, print_warning, print_info,
32
32
  create_table, create_progress_bar, format_cost, create_panel
33
33
  )
34
+ from runbooks.common.aws_pricing import get_service_monthly_cost, calculate_annual_cost, calculate_regional_cost
35
+ from runbooks.common.env_utils import get_required_env_float
34
36
  from .base import CloudOpsBase
35
37
  from .models import (
36
38
  CostOptimizationResult, BusinessScenario, ExecutionMode, RiskLevel,
@@ -84,6 +86,7 @@ class CostOptimizer(CloudOpsBase):
84
86
  if dry_run:
85
87
  print_warning("🛡️ DRY RUN MODE: No resources will be modified")
86
88
 
89
+
87
90
  async def discover_infrastructure(
88
91
  self,
89
92
  regions: Optional[List[str]] = None,
@@ -180,9 +183,9 @@ class CostOptimizer(CloudOpsBase):
180
183
  for instance in reservation['Instances']:
181
184
  if instance['State']['Name'] in ['running', 'stopped']:
182
185
  total_instances += 1
183
- # Rough cost estimation
186
+ # Dynamic cost estimation
184
187
  instance_type = instance.get('InstanceType', 't3.micro')
185
- estimated_cost += self._estimate_ec2_cost(instance_type)
188
+ estimated_cost += self._estimate_ec2_cost(instance_type, region)
186
189
 
187
190
  except Exception as e:
188
191
  print_warning(f"EC2 discovery failed in {region}: {str(e)}")
@@ -208,7 +211,7 @@ class CostOptimizer(CloudOpsBase):
208
211
  total_volumes += 1
209
212
  volume_size = volume.get('Size', 0)
210
213
  volume_type = volume.get('VolumeType', 'gp2')
211
- estimated_cost += self._estimate_ebs_cost(volume_size, volume_type)
214
+ estimated_cost += self._estimate_ebs_cost(volume_size, volume_type, region)
212
215
 
213
216
  except Exception as e:
214
217
  print_warning(f"EBS discovery failed in {region}: {str(e)}")
@@ -227,8 +230,8 @@ class CostOptimizer(CloudOpsBase):
227
230
  response = s3.list_buckets()
228
231
 
229
232
  bucket_count = len(response['Buckets'])
230
- # S3 cost estimation is complex, using placeholder
231
- estimated_cost = bucket_count * 10.0 # Rough estimate
233
+ # S3 cost estimation - using standard storage baseline per bucket
234
+ estimated_cost = bucket_count * get_service_monthly_cost("s3_standard", "us-east-1")
232
235
 
233
236
  return {
234
237
  'service': 'S3',
@@ -254,7 +257,7 @@ class CostOptimizer(CloudOpsBase):
254
257
  for instance in response['DBInstances']:
255
258
  total_instances += 1
256
259
  instance_class = instance.get('DBInstanceClass', 'db.t3.micro')
257
- estimated_cost += self._estimate_rds_cost(instance_class)
260
+ estimated_cost += self._estimate_rds_cost(instance_class, region)
258
261
 
259
262
  except Exception as e:
260
263
  print_warning(f"RDS discovery failed in {region}: {str(e)}")
@@ -279,13 +282,13 @@ class CostOptimizer(CloudOpsBase):
279
282
  nat_response = ec2.describe_nat_gateways()
280
283
  nat_count = len(nat_response['NatGateways'])
281
284
  total_resources += nat_count
282
- estimated_cost += nat_count * 45.0 # $45/month per NAT gateway
285
+ estimated_cost += nat_count * get_service_monthly_cost("nat_gateway", region)
283
286
 
284
287
  # Elastic IPs
285
288
  eip_response = ec2.describe_addresses()
286
289
  eip_count = len(eip_response['Addresses'])
287
290
  total_resources += eip_count
288
- estimated_cost += eip_count * 3.6 # $3.60/month per unused EIP
291
+ estimated_cost += eip_count * get_service_monthly_cost("elastic_ip", region)
289
292
 
290
293
  except Exception as e:
291
294
  print_warning(f"VPC discovery failed in {region}: {str(e)}")
@@ -297,30 +300,84 @@ class CostOptimizer(CloudOpsBase):
297
300
  'optimization_opportunities': ['unused_nat_gateways', 'unused_eips', 'load_balancer_optimization']
298
301
  }
299
302
 
300
- def _estimate_ec2_cost(self, instance_type: str) -> float:
301
- """Rough EC2 cost estimation per month."""
302
- cost_map = {
303
- 't3.nano': 3.8, 't3.micro': 7.6, 't3.small': 15.2,
304
- 't3.medium': 30.4, 't3.large': 60.8, 't3.xlarge': 121.6,
305
- 'm5.large': 70.1, 'm5.xlarge': 140.2, 'm5.2xlarge': 280.3,
306
- 'c5.large': 62.1, 'c5.xlarge': 124.2, 'c5.2xlarge': 248.4
307
- }
308
- return cost_map.get(instance_type, 50.0) # Default estimate
303
+ def _estimate_ec2_cost(self, instance_type: str, region: str = "us-east-1") -> float:
304
+ """EC2 cost estimation using dynamic pricing with fallback."""
305
+ try:
306
+ # Map instance types to AWS pricing service keys
307
+ # For simplicity, using a base cost multiplier approach
308
+ base_cost = get_service_monthly_cost("ec2_instance", region)
309
+
310
+ # Instance type multipliers based on AWS pricing patterns
311
+ type_multipliers = {
312
+ 't3.nano': 0.1, 't3.micro': 0.2, 't3.small': 0.4,
313
+ 't3.medium': 0.8, 't3.large': 1.6, 't3.xlarge': 3.2,
314
+ 'm5.large': 1.8, 'm5.xlarge': 3.6, 'm5.2xlarge': 7.2,
315
+ 'c5.large': 1.6, 'c5.xlarge': 3.2, 'c5.2xlarge': 6.4
316
+ }
317
+
318
+ multiplier = type_multipliers.get(instance_type, 1.0)
319
+ return base_cost * multiplier
320
+
321
+ except Exception:
322
+ # Fallback to regional cost calculation if service key not available
323
+ base_costs = {
324
+ 't3.nano': 3.8, 't3.micro': 7.6, 't3.small': 15.2,
325
+ 't3.medium': 30.4, 't3.large': 60.8, 't3.xlarge': 121.6,
326
+ 'm5.large': 70.1, 'm5.xlarge': 140.2, 'm5.2xlarge': 280.3,
327
+ 'c5.large': 62.1, 'c5.xlarge': 124.2, 'c5.2xlarge': 248.4
328
+ }
329
+ base_cost = base_costs.get(instance_type, 50.0)
330
+ return calculate_regional_cost(base_cost, region)
309
331
 
310
- def _estimate_ebs_cost(self, size_gb: int, volume_type: str) -> float:
311
- """Rough EBS cost estimation per month."""
312
- cost_per_gb = {
313
- 'gp2': 0.10, 'gp3': 0.08, 'io1': 0.125, 'io2': 0.125, 'sc1': 0.025, 'st1': 0.045
314
- }
315
- return size_gb * cost_per_gb.get(volume_type, 0.10)
332
+ def _estimate_ebs_cost(self, size_gb: int, volume_type: str, region: str = "us-east-1") -> float:
333
+ """EBS cost estimation using dynamic pricing."""
334
+ try:
335
+ # Map volume types to service keys in our pricing engine
336
+ volume_service_map = {
337
+ 'gp2': 'ebs_gp2',
338
+ 'gp3': 'ebs_gp3',
339
+ 'io1': 'ebs_io1',
340
+ 'io2': 'ebs_io2',
341
+ 'sc1': 'ebs_sc1',
342
+ 'st1': 'ebs_st1'
343
+ }
344
+
345
+ service_key = volume_service_map.get(volume_type, 'ebs_gp2') # Default to gp2
346
+ cost_per_gb = get_service_monthly_cost(service_key, region)
347
+ return size_gb * cost_per_gb
348
+
349
+ except Exception:
350
+ # Fallback to regional cost calculation
351
+ cost_per_gb_base = {
352
+ 'gp2': 0.10, 'gp3': 0.08, 'io1': 0.125, 'io2': 0.125, 'sc1': 0.025, 'st1': 0.045
353
+ }
354
+ base_cost_per_gb = cost_per_gb_base.get(volume_type, 0.10)
355
+ regional_cost_per_gb = calculate_regional_cost(base_cost_per_gb, region)
356
+ return size_gb * regional_cost_per_gb
316
357
 
317
- def _estimate_rds_cost(self, instance_class: str) -> float:
318
- """Rough RDS cost estimation per month."""
319
- cost_map = {
320
- 'db.t3.micro': 14.6, 'db.t3.small': 29.2, 'db.t3.medium': 58.4,
321
- 'db.m5.large': 140.2, 'db.m5.xlarge': 280.3, 'db.m5.2xlarge': 560.6
322
- }
323
- return cost_map.get(instance_class, 100.0) # Default estimate
358
+ def _estimate_rds_cost(self, instance_class: str, region: str = "us-east-1") -> float:
359
+ """RDS cost estimation using dynamic pricing with fallback."""
360
+ try:
361
+ # Use RDS snapshot pricing as a baseline, then apply instance multipliers
362
+ base_cost = get_service_monthly_cost("rds_snapshot", region)
363
+
364
+ # Instance class multipliers based on AWS RDS pricing patterns
365
+ class_multipliers = {
366
+ 'db.t3.micro': 1.0, 'db.t3.small': 2.0, 'db.t3.medium': 4.0,
367
+ 'db.m5.large': 9.6, 'db.m5.xlarge': 19.2, 'db.m5.2xlarge': 38.4
368
+ }
369
+
370
+ multiplier = class_multipliers.get(instance_class, 6.8) # Reasonable default multiplier
371
+ return base_cost * multiplier
372
+
373
+ except Exception:
374
+ # Fallback to regional cost calculation
375
+ base_costs = {
376
+ 'db.t3.micro': 14.6, 'db.t3.small': 29.2, 'db.t3.medium': 58.4,
377
+ 'db.m5.large': 140.2, 'db.m5.xlarge': 280.3, 'db.m5.2xlarge': 560.6
378
+ }
379
+ base_cost = base_costs.get(instance_class, 100.0)
380
+ return calculate_regional_cost(base_cost, region)
324
381
 
325
382
  async def analyze_ec2_rightsizing(self) -> Dict[str, Any]:
326
383
  """Analyze EC2 instances for rightsizing opportunities."""
@@ -563,8 +620,8 @@ class CostOptimizer(CloudOpsBase):
563
620
  )
564
621
 
565
622
  if is_unused:
566
- # Estimate cost (approximately $45/month base cost)
567
- estimated_cost = 45.0 # Base NAT Gateway cost
623
+ # Estimate cost using dynamic pricing
624
+ estimated_cost = get_service_monthly_cost("nat_gateway", region)
568
625
 
569
626
  # Add data processing costs if available
570
627
  # (This would require more detailed Cost Explorer integration)
@@ -680,7 +737,7 @@ class CostOptimizer(CloudOpsBase):
680
737
  regions: Optional[List[str]] = None,
681
738
  cpu_threshold: float = 5.0,
682
739
  duration_hours: int = 168, # 7 days
683
- cost_threshold: float = 10.0
740
+ cost_threshold: float = None
684
741
  ) -> CostOptimizationResult:
685
742
  """
686
743
  Business Scenario: Stop idle EC2 instances
@@ -706,8 +763,13 @@ class CostOptimizer(CloudOpsBase):
706
763
  # Implementation follows similar pattern to NAT Gateway optimization
707
764
  # This would integrate the logic from AWS_Stop_Idle_EC2_Instances.ipynb
708
765
 
766
+ # Set dynamic cost threshold if not provided - NO hardcoded defaults
767
+ if cost_threshold is None:
768
+ cost_threshold = get_required_env_float('EC2_COST_THRESHOLD')
769
+
709
770
  print_info(f"Analyzing EC2 instances with <{cpu_threshold}% CPU utilization")
710
771
  print_info(f"Analysis period: {duration_hours} hours")
772
+ print_info(f"Minimum cost threshold: ${cost_threshold}/month")
711
773
 
712
774
  # Placeholder for detailed implementation
713
775
  # In production, this would:
@@ -1,23 +1,33 @@
1
1
  """
2
- CloudOps Runbooks Common Framework - Enterprise Foundation
2
+ CloudOps Runbooks Common Framework - Universal Foundation
3
3
 
4
- This module provides the foundational enterprise framework components
5
- extracted from proven FinOps success patterns achieving 99.9996% accuracy,
6
- 280% ROI, and $630K annual value creation.
4
+ This module provides the foundational universal framework components
5
+ that work with ANY AWS setup without hardcoded assumptions.
7
6
 
8
7
  Components:
9
8
  - rich_utils: Beautiful CLI formatting with CloudOps theme
10
- - profile_utils: Three-tier AWS profile management system
9
+ - profile_utils: Universal AWS profile management (User → AWS_PROFILE → default)
10
+ - date_utils: Dynamic date generation utilities (No hardcoded dates)
11
11
  - performance_monitor: Enterprise-grade performance benchmarking
12
12
  - context_logger: Context-aware logging for CLI and Jupyter
13
13
  - mcp_integration: Phase 4 MCP Integration Framework (NEW)
14
14
  - cross_module_integration: Phase 4 Cross-Module Data Flow (NEW)
15
15
  - enterprise_audit_integration: Phase 4 Enterprise Audit Framework (NEW)
16
16
 
17
- Version: 0.8.0 - Phase 4 Multi-Module Integration Complete
17
+ Version: 1.0.0 - Universal Compatibility Update
18
18
  """
19
19
 
20
20
  # Rich CLI utilities (CloudOps theme, console, formatting)
21
+ # Dynamic date utilities (No hardcoded dates)
22
+ from .date_utils import (
23
+ get_aws_cli_example_period,
24
+ get_collection_timestamp,
25
+ get_current_month_period,
26
+ get_current_year,
27
+ get_previous_month_period,
28
+ get_test_date_period,
29
+ )
30
+
21
31
  # Phase 4: Cross-Module Integration (Data Flow Architecture)
22
32
  from .cross_module_integration import (
23
33
  DataFlowContext,
@@ -51,12 +61,12 @@ from .performance_monitor import (
51
61
  get_performance_benchmark,
52
62
  )
53
63
 
54
- # Profile management utilities (Three-tier enterprise system)
64
+ # Profile management utilities (Universal AWS profile system)
55
65
  from .profile_utils import (
56
66
  create_cost_session,
57
67
  create_management_session,
58
68
  create_operational_session,
59
- get_enterprise_profile_mapping,
69
+ get_current_profile_info,
60
70
  get_profile_for_operation,
61
71
  resolve_profile_for_operation_silent,
62
72
  validate_profile_access,
@@ -120,13 +130,20 @@ __all__ = [
120
130
  "print_markdown",
121
131
  "confirm_action",
122
132
  "create_columns",
133
+ # Dynamic date utilities
134
+ "get_current_year",
135
+ "get_current_month_period",
136
+ "get_previous_month_period",
137
+ "get_test_date_period",
138
+ "get_aws_cli_example_period",
139
+ "get_collection_timestamp",
123
140
  # Profile management utilities
124
141
  "get_profile_for_operation",
125
142
  "resolve_profile_for_operation_silent",
126
143
  "create_cost_session",
127
144
  "create_management_session",
128
145
  "create_operational_session",
129
- "get_enterprise_profile_mapping",
146
+ "get_current_profile_info",
130
147
  "validate_profile_access",
131
148
  # Performance monitoring framework
132
149
  "PerformanceMetrics",