runbooks 1.1.3__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 (247) 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/WEIGHT_CONFIG_README.md +1 -1
  8. runbooks/cfat/assessment/compliance.py +8 -8
  9. runbooks/cfat/assessment/runner.py +1 -0
  10. runbooks/cfat/cloud_foundations_assessment.py +227 -239
  11. runbooks/cfat/models.py +6 -2
  12. runbooks/cfat/tests/__init__.py +6 -1
  13. runbooks/cli/__init__.py +13 -0
  14. runbooks/cli/commands/cfat.py +274 -0
  15. runbooks/cli/commands/finops.py +1164 -0
  16. runbooks/cli/commands/inventory.py +379 -0
  17. runbooks/cli/commands/operate.py +239 -0
  18. runbooks/cli/commands/security.py +248 -0
  19. runbooks/cli/commands/validation.py +825 -0
  20. runbooks/cli/commands/vpc.py +310 -0
  21. runbooks/cli/registry.py +107 -0
  22. runbooks/cloudops/__init__.py +23 -30
  23. runbooks/cloudops/base.py +96 -107
  24. runbooks/cloudops/cost_optimizer.py +549 -547
  25. runbooks/cloudops/infrastructure_optimizer.py +5 -4
  26. runbooks/cloudops/interfaces.py +226 -227
  27. runbooks/cloudops/lifecycle_manager.py +5 -4
  28. runbooks/cloudops/mcp_cost_validation.py +252 -235
  29. runbooks/cloudops/models.py +78 -53
  30. runbooks/cloudops/monitoring_automation.py +5 -4
  31. runbooks/cloudops/notebook_framework.py +179 -215
  32. runbooks/cloudops/security_enforcer.py +125 -159
  33. runbooks/common/accuracy_validator.py +11 -0
  34. runbooks/common/aws_pricing.py +349 -326
  35. runbooks/common/aws_pricing_api.py +211 -212
  36. runbooks/common/aws_profile_manager.py +341 -0
  37. runbooks/common/aws_utils.py +75 -80
  38. runbooks/common/business_logic.py +127 -105
  39. runbooks/common/cli_decorators.py +36 -60
  40. runbooks/common/comprehensive_cost_explorer_integration.py +456 -464
  41. runbooks/common/cross_account_manager.py +198 -205
  42. runbooks/common/date_utils.py +27 -39
  43. runbooks/common/decorators.py +235 -0
  44. runbooks/common/dry_run_examples.py +173 -208
  45. runbooks/common/dry_run_framework.py +157 -155
  46. runbooks/common/enhanced_exception_handler.py +15 -4
  47. runbooks/common/enhanced_logging_example.py +50 -64
  48. runbooks/common/enhanced_logging_integration_example.py +65 -37
  49. runbooks/common/env_utils.py +16 -16
  50. runbooks/common/error_handling.py +40 -38
  51. runbooks/common/lazy_loader.py +41 -23
  52. runbooks/common/logging_integration_helper.py +79 -86
  53. runbooks/common/mcp_cost_explorer_integration.py +478 -495
  54. runbooks/common/mcp_integration.py +63 -74
  55. runbooks/common/memory_optimization.py +140 -118
  56. runbooks/common/module_cli_base.py +37 -58
  57. runbooks/common/organizations_client.py +176 -194
  58. runbooks/common/patterns.py +204 -0
  59. runbooks/common/performance_monitoring.py +67 -71
  60. runbooks/common/performance_optimization_engine.py +283 -274
  61. runbooks/common/profile_utils.py +248 -39
  62. runbooks/common/rich_utils.py +643 -92
  63. runbooks/common/sre_performance_suite.py +177 -186
  64. runbooks/enterprise/__init__.py +1 -1
  65. runbooks/enterprise/logging.py +144 -106
  66. runbooks/enterprise/security.py +187 -204
  67. runbooks/enterprise/validation.py +43 -56
  68. runbooks/finops/__init__.py +29 -33
  69. runbooks/finops/account_resolver.py +1 -1
  70. runbooks/finops/advanced_optimization_engine.py +980 -0
  71. runbooks/finops/automation_core.py +268 -231
  72. runbooks/finops/business_case_config.py +184 -179
  73. runbooks/finops/cli.py +660 -139
  74. runbooks/finops/commvault_ec2_analysis.py +157 -164
  75. runbooks/finops/compute_cost_optimizer.py +336 -320
  76. runbooks/finops/config.py +20 -20
  77. runbooks/finops/cost_optimizer.py +488 -622
  78. runbooks/finops/cost_processor.py +332 -214
  79. runbooks/finops/dashboard_runner.py +1006 -172
  80. runbooks/finops/ebs_cost_optimizer.py +991 -657
  81. runbooks/finops/elastic_ip_optimizer.py +317 -257
  82. runbooks/finops/enhanced_mcp_integration.py +340 -0
  83. runbooks/finops/enhanced_progress.py +40 -37
  84. runbooks/finops/enhanced_trend_visualization.py +3 -2
  85. runbooks/finops/enterprise_wrappers.py +230 -292
  86. runbooks/finops/executive_export.py +203 -160
  87. runbooks/finops/helpers.py +130 -288
  88. runbooks/finops/iam_guidance.py +1 -1
  89. runbooks/finops/infrastructure/__init__.py +80 -0
  90. runbooks/finops/infrastructure/commands.py +506 -0
  91. runbooks/finops/infrastructure/load_balancer_optimizer.py +866 -0
  92. runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +832 -0
  93. runbooks/finops/markdown_exporter.py +338 -175
  94. runbooks/finops/mcp_validator.py +1952 -0
  95. runbooks/finops/nat_gateway_optimizer.py +1513 -482
  96. runbooks/finops/network_cost_optimizer.py +657 -587
  97. runbooks/finops/notebook_utils.py +226 -188
  98. runbooks/finops/optimization_engine.py +1136 -0
  99. runbooks/finops/optimizer.py +25 -29
  100. runbooks/finops/rds_snapshot_optimizer.py +367 -411
  101. runbooks/finops/reservation_optimizer.py +427 -363
  102. runbooks/finops/scenario_cli_integration.py +77 -78
  103. runbooks/finops/scenarios.py +1278 -439
  104. runbooks/finops/schemas.py +218 -182
  105. runbooks/finops/snapshot_manager.py +2289 -0
  106. runbooks/finops/tests/test_finops_dashboard.py +3 -3
  107. runbooks/finops/tests/test_reference_images_validation.py +2 -2
  108. runbooks/finops/tests/test_single_account_features.py +17 -17
  109. runbooks/finops/tests/validate_test_suite.py +1 -1
  110. runbooks/finops/types.py +3 -3
  111. runbooks/finops/validation_framework.py +263 -269
  112. runbooks/finops/vpc_cleanup_exporter.py +191 -146
  113. runbooks/finops/vpc_cleanup_optimizer.py +593 -575
  114. runbooks/finops/workspaces_analyzer.py +171 -182
  115. runbooks/hitl/enhanced_workflow_engine.py +1 -1
  116. runbooks/integration/__init__.py +89 -0
  117. runbooks/integration/mcp_integration.py +1920 -0
  118. runbooks/inventory/CLAUDE.md +816 -0
  119. runbooks/inventory/README.md +3 -3
  120. runbooks/inventory/Tests/common_test_data.py +30 -30
  121. runbooks/inventory/__init__.py +2 -2
  122. runbooks/inventory/cloud_foundations_integration.py +144 -149
  123. runbooks/inventory/collectors/aws_comprehensive.py +28 -11
  124. runbooks/inventory/collectors/aws_networking.py +111 -101
  125. runbooks/inventory/collectors/base.py +4 -0
  126. runbooks/inventory/core/collector.py +495 -313
  127. runbooks/inventory/discovery.md +2 -2
  128. runbooks/inventory/drift_detection_cli.py +69 -96
  129. runbooks/inventory/find_ec2_security_groups.py +1 -1
  130. runbooks/inventory/inventory_mcp_cli.py +48 -46
  131. runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
  132. runbooks/inventory/mcp_inventory_validator.py +549 -465
  133. runbooks/inventory/mcp_vpc_validator.py +359 -442
  134. runbooks/inventory/organizations_discovery.py +56 -52
  135. runbooks/inventory/rich_inventory_display.py +33 -32
  136. runbooks/inventory/unified_validation_engine.py +278 -251
  137. runbooks/inventory/vpc_analyzer.py +733 -696
  138. runbooks/inventory/vpc_architecture_validator.py +293 -348
  139. runbooks/inventory/vpc_dependency_analyzer.py +382 -378
  140. runbooks/inventory/vpc_flow_analyzer.py +3 -3
  141. runbooks/main.py +152 -9147
  142. runbooks/main_final.py +91 -60
  143. runbooks/main_minimal.py +22 -10
  144. runbooks/main_optimized.py +131 -100
  145. runbooks/main_ultra_minimal.py +7 -2
  146. runbooks/mcp/__init__.py +36 -0
  147. runbooks/mcp/integration.py +679 -0
  148. runbooks/metrics/dora_metrics_engine.py +2 -2
  149. runbooks/monitoring/performance_monitor.py +9 -4
  150. runbooks/operate/dynamodb_operations.py +3 -1
  151. runbooks/operate/ec2_operations.py +145 -137
  152. runbooks/operate/iam_operations.py +146 -152
  153. runbooks/operate/mcp_integration.py +1 -1
  154. runbooks/operate/networking_cost_heatmap.py +33 -10
  155. runbooks/operate/privatelink_operations.py +1 -1
  156. runbooks/operate/rds_operations.py +223 -254
  157. runbooks/operate/s3_operations.py +107 -118
  158. runbooks/operate/vpc_endpoints.py +1 -1
  159. runbooks/operate/vpc_operations.py +648 -618
  160. runbooks/remediation/base.py +1 -1
  161. runbooks/remediation/commons.py +10 -7
  162. runbooks/remediation/commvault_ec2_analysis.py +71 -67
  163. runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
  164. runbooks/remediation/multi_account.py +24 -21
  165. runbooks/remediation/rds_snapshot_list.py +91 -65
  166. runbooks/remediation/remediation_cli.py +92 -146
  167. runbooks/remediation/universal_account_discovery.py +83 -79
  168. runbooks/remediation/workspaces_list.py +49 -44
  169. runbooks/security/__init__.py +19 -0
  170. runbooks/security/assessment_runner.py +1150 -0
  171. runbooks/security/baseline_checker.py +812 -0
  172. runbooks/security/cloudops_automation_security_validator.py +509 -535
  173. runbooks/security/compliance_automation_engine.py +17 -17
  174. runbooks/security/config/__init__.py +2 -2
  175. runbooks/security/config/compliance_config.py +50 -50
  176. runbooks/security/config_template_generator.py +63 -76
  177. runbooks/security/enterprise_security_framework.py +1 -1
  178. runbooks/security/executive_security_dashboard.py +519 -508
  179. runbooks/security/integration_test_enterprise_security.py +5 -3
  180. runbooks/security/multi_account_security_controls.py +959 -1210
  181. runbooks/security/real_time_security_monitor.py +422 -444
  182. runbooks/security/run_script.py +1 -1
  183. runbooks/security/security_baseline_tester.py +1 -1
  184. runbooks/security/security_cli.py +143 -112
  185. runbooks/security/test_2way_validation.py +439 -0
  186. runbooks/security/two_way_validation_framework.py +852 -0
  187. runbooks/sre/mcp_reliability_engine.py +6 -6
  188. runbooks/sre/production_monitoring_framework.py +167 -177
  189. runbooks/tdd/__init__.py +15 -0
  190. runbooks/tdd/cli.py +1071 -0
  191. runbooks/utils/__init__.py +14 -17
  192. runbooks/utils/logger.py +7 -2
  193. runbooks/utils/version_validator.py +51 -48
  194. runbooks/validation/__init__.py +6 -6
  195. runbooks/validation/cli.py +9 -3
  196. runbooks/validation/comprehensive_2way_validator.py +754 -708
  197. runbooks/validation/mcp_validator.py +906 -228
  198. runbooks/validation/terraform_citations_validator.py +104 -115
  199. runbooks/validation/terraform_drift_detector.py +447 -451
  200. runbooks/vpc/README.md +617 -0
  201. runbooks/vpc/__init__.py +8 -1
  202. runbooks/vpc/analyzer.py +577 -0
  203. runbooks/vpc/cleanup_wrapper.py +476 -413
  204. runbooks/vpc/cli_cloudtrail_commands.py +339 -0
  205. runbooks/vpc/cli_mcp_validation_commands.py +480 -0
  206. runbooks/vpc/cloudtrail_audit_integration.py +717 -0
  207. runbooks/vpc/config.py +92 -97
  208. runbooks/vpc/cost_engine.py +411 -148
  209. runbooks/vpc/cost_explorer_integration.py +553 -0
  210. runbooks/vpc/cross_account_session.py +101 -106
  211. runbooks/vpc/enhanced_mcp_validation.py +917 -0
  212. runbooks/vpc/eni_gate_validator.py +961 -0
  213. runbooks/vpc/heatmap_engine.py +190 -162
  214. runbooks/vpc/mcp_no_eni_validator.py +681 -640
  215. runbooks/vpc/nat_gateway_optimizer.py +358 -0
  216. runbooks/vpc/networking_wrapper.py +15 -8
  217. runbooks/vpc/pdca_remediation_planner.py +528 -0
  218. runbooks/vpc/performance_optimized_analyzer.py +219 -231
  219. runbooks/vpc/runbooks_adapter.py +1167 -241
  220. runbooks/vpc/tdd_red_phase_stubs.py +601 -0
  221. runbooks/vpc/test_data_loader.py +358 -0
  222. runbooks/vpc/tests/conftest.py +314 -4
  223. runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
  224. runbooks/vpc/tests/test_cost_engine.py +0 -2
  225. runbooks/vpc/topology_generator.py +326 -0
  226. runbooks/vpc/unified_scenarios.py +1302 -1129
  227. runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
  228. runbooks-1.1.5.dist-info/METADATA +328 -0
  229. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/RECORD +233 -200
  230. runbooks/finops/README.md +0 -414
  231. runbooks/finops/accuracy_cross_validator.py +0 -647
  232. runbooks/finops/business_cases.py +0 -950
  233. runbooks/finops/dashboard_router.py +0 -922
  234. runbooks/finops/ebs_optimizer.py +0 -956
  235. runbooks/finops/embedded_mcp_validator.py +0 -1629
  236. runbooks/finops/enhanced_dashboard_runner.py +0 -527
  237. runbooks/finops/finops_dashboard.py +0 -584
  238. runbooks/finops/finops_scenarios.py +0 -1218
  239. runbooks/finops/legacy_migration.py +0 -730
  240. runbooks/finops/multi_dashboard.py +0 -1519
  241. runbooks/finops/single_dashboard.py +0 -1113
  242. runbooks/finops/unlimited_scenarios.py +0 -393
  243. runbooks-1.1.3.dist-info/METADATA +0 -799
  244. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/WHEEL +0 -0
  245. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/entry_points.txt +0 -0
  246. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/licenses/LICENSE +0 -0
  247. {runbooks-1.1.3.dist-info → runbooks-1.1.5.dist-info}/top_level.txt +0 -0
runbooks/vpc/config.py CHANGED
@@ -13,6 +13,7 @@ from typing import Any, Dict, List, Optional
13
13
  # Import AWS Pricing API for zero hardcoded values
14
14
  try:
15
15
  from runbooks.common.aws_pricing_api import pricing_api
16
+
16
17
  AWS_PRICING_AVAILABLE = True
17
18
  except ImportError:
18
19
  AWS_PRICING_AVAILABLE = False
@@ -25,20 +26,12 @@ class AWSCostModel:
25
26
  # NAT Gateway Pricing - Real-time from AWS Pricing API (NO hardcoded defaults)
26
27
  nat_gateway_hourly: float = field(default_factory=lambda: AWSCostModel._get_nat_gateway_hourly())
27
28
  nat_gateway_monthly: float = field(default_factory=lambda: AWSCostModel._get_nat_gateway_monthly())
28
- nat_gateway_data_processing: float = field(
29
- default_factory=lambda: AWSCostModel._get_nat_gateway_data_processing()
30
- )
29
+ nat_gateway_data_processing: float = field(default_factory=lambda: AWSCostModel._get_nat_gateway_data_processing())
31
30
 
32
31
  # Transit Gateway Pricing - Real-time from AWS Pricing API (NO hardcoded defaults)
33
- transit_gateway_hourly: float = field(
34
- default_factory=lambda: AWSCostModel._get_transit_gateway_hourly()
35
- )
36
- transit_gateway_monthly: float = field(
37
- default_factory=lambda: AWSCostModel._get_transit_gateway_monthly()
38
- )
39
- transit_gateway_attachment: float = field(
40
- default_factory=lambda: AWSCostModel._get_transit_gateway_attachment()
41
- )
32
+ transit_gateway_hourly: float = field(default_factory=lambda: AWSCostModel._get_transit_gateway_hourly())
33
+ transit_gateway_monthly: float = field(default_factory=lambda: AWSCostModel._get_transit_gateway_monthly())
34
+ transit_gateway_attachment: float = field(default_factory=lambda: AWSCostModel._get_transit_gateway_attachment())
42
35
  transit_gateway_data_processing: float = field(
43
36
  default_factory=lambda: AWSCostModel._get_transit_gateway_data_processing()
44
37
  )
@@ -56,60 +49,48 @@ class AWSCostModel:
56
49
  )
57
50
 
58
51
  # Elastic IP Pricing - ENTERPRISE COMPLIANCE: Real-time AWS Pricing API ONLY
59
- elastic_ip_idle_hourly: float = field(
60
- default_factory=lambda: AWSCostModel._get_elastic_ip_idle_hourly()
61
- )
62
- elastic_ip_idle_monthly: float = field(
63
- default_factory=lambda: AWSCostModel._get_elastic_ip_idle_monthly()
64
- )
52
+ elastic_ip_idle_hourly: float = field(default_factory=lambda: AWSCostModel._get_elastic_ip_idle_hourly())
53
+ elastic_ip_idle_monthly: float = field(default_factory=lambda: AWSCostModel._get_elastic_ip_idle_monthly())
65
54
  elastic_ip_attached: float = 0.0 # Always free when attached (AWS confirmed)
66
- elastic_ip_remap: float = field(
67
- default_factory=lambda: AWSCostModel._get_elastic_ip_remap()
68
- )
55
+ elastic_ip_remap: float = field(default_factory=lambda: AWSCostModel._get_elastic_ip_remap())
69
56
 
70
57
  # Data Transfer Pricing - ENTERPRISE COMPLIANCE: Real-time AWS Pricing API ONLY
71
- data_transfer_inter_az: float = field(
72
- default_factory=lambda: AWSCostModel._get_data_transfer_inter_az()
73
- )
74
- data_transfer_inter_region: float = field(
75
- default_factory=lambda: AWSCostModel._get_data_transfer_inter_region()
76
- )
77
- data_transfer_internet_out: float = field(
78
- default_factory=lambda: AWSCostModel._get_data_transfer_internet_out()
79
- )
58
+ data_transfer_inter_az: float = field(default_factory=lambda: AWSCostModel._get_data_transfer_inter_az())
59
+ data_transfer_inter_region: float = field(default_factory=lambda: AWSCostModel._get_data_transfer_inter_region())
60
+ data_transfer_internet_out: float = field(default_factory=lambda: AWSCostModel._get_data_transfer_internet_out())
80
61
  data_transfer_s3_same_region: float = 0.0 # Always free
81
-
62
+
82
63
  @staticmethod
83
64
  def _get_nat_gateway_hourly() -> float:
84
65
  """Get NAT Gateway hourly cost from AWS Pricing API with enhanced enterprise fallback."""
85
66
  if AWS_PRICING_AVAILABLE:
86
67
  try:
87
68
  # Use enhanced pricing API with regional fallback and graceful degradation
88
- current_region = os.getenv('AWS_DEFAULT_REGION', 'us-east-1')
69
+ current_region = os.getenv("AWS_DEFAULT_REGION", "us-east-1")
89
70
  monthly_cost = pricing_api.get_nat_gateway_monthly_cost(current_region)
90
71
  return monthly_cost / (24 * 30)
91
72
  except Exception as e:
92
73
  print(f"⚠️ NAT Gateway pricing API fallback: {e}")
93
-
74
+
94
75
  # Universal compatibility: standard AWS pricing when API unavailable
95
76
  print("ℹ️ Using universal compatibility NAT Gateway rate")
96
77
  return 0.045 # AWS standard NAT Gateway hourly rate
97
-
78
+
98
79
  @staticmethod
99
80
  def _get_nat_gateway_monthly() -> float:
100
81
  """Get NAT Gateway monthly cost from AWS Pricing API with enhanced enterprise fallback."""
101
82
  if AWS_PRICING_AVAILABLE:
102
83
  try:
103
84
  # Use enhanced pricing API with regional fallback and graceful degradation
104
- current_region = os.getenv('AWS_DEFAULT_REGION', 'us-east-1')
85
+ current_region = os.getenv("AWS_DEFAULT_REGION", "us-east-1")
105
86
  return pricing_api.get_nat_gateway_monthly_cost(current_region)
106
87
  except Exception as e:
107
88
  print(f"⚠️ NAT Gateway monthly pricing API fallback: {e}")
108
-
89
+
109
90
  # Universal compatibility: calculate from hourly rate
110
91
  print("ℹ️ Calculating monthly cost from universal compatibility hourly rate")
111
92
  return AWSCostModel._get_nat_gateway_hourly() * 24 * 30
112
-
93
+
113
94
  @staticmethod
114
95
  def _get_nat_gateway_data_processing() -> float:
115
96
  """Get NAT Gateway data processing cost from AWS Pricing API."""
@@ -121,7 +102,7 @@ class AWSCostModel:
121
102
  pass
122
103
  # Universal compatibility: standard AWS pricing
123
104
  return 0.045 # AWS standard NAT Gateway data processing rate
124
-
105
+
125
106
  @staticmethod
126
107
  def _get_transit_gateway_hourly() -> float:
127
108
  """Get Transit Gateway hourly cost from AWS Pricing API."""
@@ -133,12 +114,12 @@ class AWSCostModel:
133
114
  pass
134
115
  # Universal compatibility: standard AWS pricing
135
116
  return 0.05 # AWS standard Transit Gateway hourly rate
136
-
117
+
137
118
  @staticmethod
138
119
  def _get_transit_gateway_monthly() -> float:
139
120
  """Get Transit Gateway monthly cost from AWS Pricing API."""
140
121
  return AWSCostModel._get_transit_gateway_hourly() * 24 * 30
141
-
122
+
142
123
  @staticmethod
143
124
  def _get_transit_gateway_attachment() -> float:
144
125
  """Get Transit Gateway attachment cost from AWS Pricing API."""
@@ -150,7 +131,7 @@ class AWSCostModel:
150
131
  pass
151
132
  # Universal compatibility: standard AWS pricing
152
133
  return 0.05 # AWS standard TGW attachment rate
153
-
134
+
154
135
  @staticmethod
155
136
  def _get_transit_gateway_data_processing() -> float:
156
137
  """Get Transit Gateway data processing cost from AWS Pricing API."""
@@ -162,7 +143,7 @@ class AWSCostModel:
162
143
  pass
163
144
  # Universal compatibility: standard AWS pricing
164
145
  return 0.02 # AWS standard TGW data processing rate
165
-
146
+
166
147
  # VPC Endpoint Pricing Methods
167
148
  @staticmethod
168
149
  def _get_vpc_endpoint_interface_hourly() -> float:
@@ -172,7 +153,7 @@ class AWSCostModel:
172
153
  # Universal compatibility: standard AWS pricing
173
154
  return 0.01 # AWS standard VPC Interface Endpoint hourly rate
174
155
  return float(value)
175
-
156
+
176
157
  @staticmethod
177
158
  def _get_vpc_endpoint_interface_monthly() -> float:
178
159
  """Get VPC Endpoint Interface monthly cost from AWS Pricing API."""
@@ -181,7 +162,7 @@ class AWSCostModel:
181
162
  # Universal compatibility: calculate from hourly rate
182
163
  return AWSCostModel._get_vpc_endpoint_interface_hourly() * 24 * 30
183
164
  return float(value)
184
-
165
+
185
166
  @staticmethod
186
167
  def _get_vpc_endpoint_data_processing() -> float:
187
168
  """Get VPC Endpoint data processing cost from AWS Pricing API."""
@@ -190,7 +171,7 @@ class AWSCostModel:
190
171
  # Universal compatibility: standard AWS pricing
191
172
  return 0.01 # AWS standard VPC Endpoint data processing rate
192
173
  return float(value)
193
-
174
+
194
175
  # Elastic IP Pricing Methods
195
176
  @staticmethod
196
177
  def _get_elastic_ip_idle_hourly() -> float:
@@ -200,7 +181,7 @@ class AWSCostModel:
200
181
  # Universal compatibility: standard AWS pricing
201
182
  return 0.005 # AWS standard Elastic IP idle hourly rate
202
183
  return float(value)
203
-
184
+
204
185
  @staticmethod
205
186
  def _get_elastic_ip_idle_monthly() -> float:
206
187
  """Get Elastic IP idle monthly cost from AWS Pricing API."""
@@ -209,7 +190,7 @@ class AWSCostModel:
209
190
  # Universal compatibility: calculate from hourly rate
210
191
  return AWSCostModel._get_elastic_ip_idle_hourly() * 24 * 30
211
192
  return float(value)
212
-
193
+
213
194
  @staticmethod
214
195
  def _get_elastic_ip_remap() -> float:
215
196
  """Get Elastic IP remap cost from AWS Pricing API."""
@@ -218,7 +199,7 @@ class AWSCostModel:
218
199
  # Universal compatibility: standard AWS pricing
219
200
  return 0.10 # AWS standard Elastic IP remap cost
220
201
  return float(value)
221
-
202
+
222
203
  # Data Transfer Pricing Methods
223
204
  @staticmethod
224
205
  def _get_data_transfer_inter_az() -> float:
@@ -228,7 +209,7 @@ class AWSCostModel:
228
209
  # Universal compatibility: standard AWS pricing
229
210
  return 0.01 # AWS standard Inter-AZ data transfer rate per GB
230
211
  return float(value)
231
-
212
+
232
213
  @staticmethod
233
214
  def _get_data_transfer_inter_region() -> float:
234
215
  """Get Inter-region data transfer cost from AWS Pricing API."""
@@ -237,7 +218,7 @@ class AWSCostModel:
237
218
  # Universal compatibility: standard AWS pricing
238
219
  return 0.02 # AWS standard Inter-region data transfer rate per GB
239
220
  return float(value)
240
-
221
+
241
222
  @staticmethod
242
223
  def _get_data_transfer_internet_out() -> float:
243
224
  """Get Internet outbound data transfer cost from AWS Pricing API."""
@@ -253,13 +234,23 @@ class OptimizationThresholds:
253
234
  """Configurable thresholds for optimization recommendations - NO hardcoded defaults"""
254
235
 
255
236
  # Usage thresholds - Dynamic from environment or raise error
256
- idle_connection_threshold: int = field(default_factory=lambda: OptimizationThresholds._get_env_int("IDLE_CONNECTION_THRESHOLD"))
257
- low_usage_gb_threshold: float = field(default_factory=lambda: OptimizationThresholds._get_env_float("LOW_USAGE_GB_THRESHOLD"))
258
- low_connection_threshold: int = field(default_factory=lambda: OptimizationThresholds._get_env_int("LOW_CONNECTION_THRESHOLD"))
237
+ idle_connection_threshold: int = field(
238
+ default_factory=lambda: OptimizationThresholds._get_env_int("IDLE_CONNECTION_THRESHOLD")
239
+ )
240
+ low_usage_gb_threshold: float = field(
241
+ default_factory=lambda: OptimizationThresholds._get_env_float("LOW_USAGE_GB_THRESHOLD")
242
+ )
243
+ low_connection_threshold: int = field(
244
+ default_factory=lambda: OptimizationThresholds._get_env_int("LOW_CONNECTION_THRESHOLD")
245
+ )
259
246
 
260
247
  # Cost thresholds - Dynamic from environment or raise error
261
- high_cost_threshold: float = field(default_factory=lambda: OptimizationThresholds._get_env_float("HIGH_COST_THRESHOLD"))
262
- critical_cost_threshold: float = field(default_factory=lambda: OptimizationThresholds._get_env_float("CRITICAL_COST_THRESHOLD"))
248
+ high_cost_threshold: float = field(
249
+ default_factory=lambda: OptimizationThresholds._get_env_float("HIGH_COST_THRESHOLD")
250
+ )
251
+ critical_cost_threshold: float = field(
252
+ default_factory=lambda: OptimizationThresholds._get_env_float("CRITICAL_COST_THRESHOLD")
253
+ )
263
254
 
264
255
  # Optimization targets - Dynamic from environment or raise error
265
256
  target_reduction_percent: float = field(
@@ -270,23 +261,20 @@ class OptimizationThresholds:
270
261
  cost_approval_threshold: float = field(
271
262
  default_factory=lambda: OptimizationThresholds._get_env_float("COST_APPROVAL_THRESHOLD")
272
263
  )
273
-
264
+
274
265
  @staticmethod
275
266
  def _get_env_int(var_name: str) -> int:
276
267
  """Get integer from environment with universal compatibility defaults."""
277
268
  value = os.getenv(var_name)
278
269
  if value is None:
279
270
  # Universal compatibility defaults for optimization thresholds
280
- defaults = {
281
- "IDLE_CONNECTION_THRESHOLD": 1,
282
- "LOW_CONNECTION_THRESHOLD": 5
283
- }
271
+ defaults = {"IDLE_CONNECTION_THRESHOLD": 1, "LOW_CONNECTION_THRESHOLD": 5}
284
272
  default_value = defaults.get(var_name)
285
273
  if default_value is None:
286
274
  raise ValueError(f"Environment variable {var_name} required and no universal default available")
287
275
  return default_value
288
276
  return int(value)
289
-
277
+
290
278
  @staticmethod
291
279
  def _get_env_float(var_name: str) -> float:
292
280
  """Get float from environment with universal compatibility defaults."""
@@ -299,13 +287,14 @@ class OptimizationThresholds:
299
287
  "CRITICAL_COST_THRESHOLD": 1000.0,
300
288
  "TARGET_REDUCTION_PERCENT": 0.30,
301
289
  "COST_APPROVAL_THRESHOLD": 500.0,
302
- "PERFORMANCE_BASELINE_THRESHOLD": 30.0
290
+ "PERFORMANCE_BASELINE_THRESHOLD": 30.0,
303
291
  }
304
292
  default_value = defaults.get(var_name)
305
293
  if default_value is None:
306
294
  raise ValueError(f"Environment variable {var_name} required and no universal default available")
307
295
  return default_value
308
296
  return float(value)
297
+
309
298
  performance_baseline_threshold: float = field(
310
299
  default_factory=lambda: OptimizationThresholds._get_env_float("PERFORMANCE_BASELINE_THRESHOLD")
311
300
  )
@@ -334,14 +323,20 @@ class RegionalConfiguration:
334
323
  regional_multipliers: Dict[str, float] = field(
335
324
  default_factory=lambda: RegionalConfiguration._get_regional_multipliers()
336
325
  )
337
-
326
+
338
327
  @staticmethod
339
328
  def _get_regional_multipliers() -> Dict[str, float]:
340
329
  """Get regional cost multipliers - NO hardcoded defaults."""
341
330
  regions = [
342
- "us-east-1", "us-west-2", "us-west-1",
343
- "eu-west-1", "eu-central-1", "eu-west-2",
344
- "ap-southeast-1", "ap-southeast-2", "ap-northeast-1"
331
+ "us-east-1",
332
+ "us-west-2",
333
+ "us-west-1",
334
+ "eu-west-1",
335
+ "eu-central-1",
336
+ "eu-west-2",
337
+ "ap-southeast-1",
338
+ "ap-southeast-2",
339
+ "ap-northeast-1",
345
340
  ]
346
341
  multipliers = {}
347
342
  for region in regions:
@@ -361,7 +356,7 @@ class VPCNetworkingConfig:
361
356
 
362
357
  # AWS Configuration - NO hardcoded defaults
363
358
  default_region: str = field(default_factory=lambda: VPCNetworkingConfig._get_required_env("AWS_DEFAULT_REGION"))
364
-
359
+
365
360
  @staticmethod
366
361
  def _get_required_env(var_name: str) -> str:
367
362
  """Get environment variable with universal compatibility defaults."""
@@ -373,24 +368,21 @@ class VPCNetworkingConfig:
373
368
  "OUTPUT_FORMAT": "json",
374
369
  "OUTPUT_DIR": "./tmp",
375
370
  "ENABLE_COST_APPROVAL_WORKFLOW": "false",
376
- "ENABLE_MCP_VALIDATION": "false"
371
+ "ENABLE_MCP_VALIDATION": "false",
377
372
  }
378
373
  default_value = defaults.get(var_name)
379
374
  if default_value is None:
380
375
  raise ValueError(f"Environment variable {var_name} required and no universal default available")
381
376
  return default_value
382
377
  return value
383
-
378
+
384
379
  @staticmethod
385
380
  def _get_required_env_int(var_name: str) -> int:
386
381
  """Get integer environment variable with universal compatibility defaults."""
387
382
  value = os.getenv(var_name)
388
383
  if value is None:
389
384
  # Universal compatibility defaults for any AWS environment
390
- defaults = {
391
- "DEFAULT_ANALYSIS_DAYS": 30,
392
- "FORECAST_DAYS": 30
393
- }
385
+ defaults = {"DEFAULT_ANALYSIS_DAYS": 30, "FORECAST_DAYS": 30}
394
386
  default_value = defaults.get(var_name)
395
387
  if default_value is None:
396
388
  raise ValueError(f"Environment variable {var_name} required and no universal default available")
@@ -398,31 +390,33 @@ class VPCNetworkingConfig:
398
390
  return int(value)
399
391
 
400
392
  # AWS Profiles - Universal compatibility with fallback to AWS_PROFILE or 'default'
401
- billing_profile: Optional[str] = field(default_factory=lambda: (
402
- os.getenv("BILLING_PROFILE") or
403
- os.getenv("AWS_PROFILE") or
404
- "default"
405
- ))
406
- centralized_ops_profile: Optional[str] = field(default_factory=lambda: (
407
- os.getenv("CENTRALIZED_OPS_PROFILE") or
408
- os.getenv("CENTRALISED_OPS_PROFILE") or # Alternative spelling
409
- os.getenv("AWS_PROFILE") or
410
- "default"
411
- ))
412
- single_account_profile: Optional[str] = field(default_factory=lambda: (
413
- os.getenv("SINGLE_ACCOUNT_PROFILE") or
414
- os.getenv("SINGLE_AWS_PROFILE") or # Alternative naming
415
- os.getenv("AWS_PROFILE") or
416
- "default"
417
- ))
418
- management_profile: Optional[str] = field(default_factory=lambda: (
419
- os.getenv("MANAGEMENT_PROFILE") or
420
- os.getenv("AWS_PROFILE") or
421
- "default"
422
- ))
393
+ billing_profile: Optional[str] = field(
394
+ default_factory=lambda: (os.getenv("BILLING_PROFILE") or os.getenv("AWS_PROFILE") or "default")
395
+ )
396
+ centralized_ops_profile: Optional[str] = field(
397
+ default_factory=lambda: (
398
+ os.getenv("CENTRALIZED_OPS_PROFILE")
399
+ or os.getenv("CENTRALISED_OPS_PROFILE") # Alternative spelling
400
+ or os.getenv("AWS_PROFILE")
401
+ or "default"
402
+ )
403
+ )
404
+ single_account_profile: Optional[str] = field(
405
+ default_factory=lambda: (
406
+ os.getenv("SINGLE_ACCOUNT_PROFILE")
407
+ or os.getenv("SINGLE_AWS_PROFILE") # Alternative naming
408
+ or os.getenv("AWS_PROFILE")
409
+ or "default"
410
+ )
411
+ )
412
+ management_profile: Optional[str] = field(
413
+ default_factory=lambda: (os.getenv("MANAGEMENT_PROFILE") or os.getenv("AWS_PROFILE") or "default")
414
+ )
423
415
 
424
416
  # Analysis Configuration - ENTERPRISE COMPLIANCE: No hardcoded defaults
425
- default_analysis_days: int = field(default_factory=lambda: VPCNetworkingConfig._get_required_env_int("DEFAULT_ANALYSIS_DAYS"))
417
+ default_analysis_days: int = field(
418
+ default_factory=lambda: VPCNetworkingConfig._get_required_env_int("DEFAULT_ANALYSIS_DAYS")
419
+ )
426
420
  forecast_days: int = field(default_factory=lambda: VPCNetworkingConfig._get_required_env_int("FORECAST_DAYS"))
427
421
 
428
422
  # Output Configuration - ENTERPRISE COMPLIANCE: No hardcoded defaults
@@ -476,10 +470,11 @@ def load_config(config_file: Optional[str] = None) -> VPCNetworkingConfig:
476
470
  # Universal compatibility - warn instead of failing
477
471
  if not config.billing_profile or config.billing_profile == "default":
478
472
  import warnings
473
+
479
474
  warnings.warn(
480
475
  "Cost approval workflow enabled but no specific BILLING_PROFILE set. "
481
476
  "Using default profile. Set BILLING_PROFILE for enterprise multi-account setup.",
482
- UserWarning
477
+ UserWarning,
483
478
  )
484
479
 
485
480
  return config