runbooks 1.1.1__py3-none-any.whl → 1.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- runbooks/__init__.py +1 -1
- runbooks/cfat/assessment/collectors.py +3 -2
- runbooks/cloudops/cost_optimizer.py +235 -83
- runbooks/cloudops/models.py +8 -2
- runbooks/common/aws_pricing.py +12 -0
- runbooks/common/business_logic.py +1 -1
- runbooks/common/profile_utils.py +213 -310
- runbooks/common/rich_utils.py +15 -21
- runbooks/finops/README.md +3 -3
- runbooks/finops/__init__.py +13 -5
- runbooks/finops/business_case_config.py +5 -5
- runbooks/finops/cli.py +170 -95
- runbooks/finops/cost_optimizer.py +2 -1
- runbooks/finops/cost_processor.py +69 -22
- runbooks/finops/dashboard_router.py +3 -3
- runbooks/finops/dashboard_runner.py +3 -4
- runbooks/finops/embedded_mcp_validator.py +101 -23
- runbooks/finops/enhanced_progress.py +213 -0
- runbooks/finops/finops_scenarios.py +90 -16
- runbooks/finops/markdown_exporter.py +4 -2
- runbooks/finops/multi_dashboard.py +1 -1
- runbooks/finops/nat_gateway_optimizer.py +85 -57
- runbooks/finops/rds_snapshot_optimizer.py +1389 -0
- runbooks/finops/scenario_cli_integration.py +212 -22
- runbooks/finops/scenarios.py +41 -25
- runbooks/finops/single_dashboard.py +68 -9
- runbooks/finops/tests/run_tests.py +5 -3
- runbooks/finops/vpc_cleanup_optimizer.py +1 -1
- runbooks/finops/workspaces_analyzer.py +40 -16
- runbooks/inventory/list_rds_snapshots_aggregator.py +745 -0
- runbooks/main.py +393 -61
- runbooks/operate/executive_dashboard.py +4 -3
- runbooks/remediation/rds_snapshot_list.py +13 -0
- {runbooks-1.1.1.dist-info → runbooks-1.1.3.dist-info}/METADATA +234 -40
- {runbooks-1.1.1.dist-info → runbooks-1.1.3.dist-info}/RECORD +39 -37
- {runbooks-1.1.1.dist-info → runbooks-1.1.3.dist-info}/WHEEL +0 -0
- {runbooks-1.1.1.dist-info → runbooks-1.1.3.dist-info}/entry_points.txt +0 -0
- {runbooks-1.1.1.dist-info → runbooks-1.1.3.dist-info}/licenses/LICENSE +0 -0
- {runbooks-1.1.1.dist-info → runbooks-1.1.3.dist-info}/top_level.txt +0 -0
@@ -134,30 +134,69 @@ class NATGatewayOptimizer:
|
|
134
134
|
"""Initialize NAT Gateway optimizer with enterprise profile support."""
|
135
135
|
self.profile_name = profile_name
|
136
136
|
self.regions = regions or ['us-east-1', 'us-west-2', 'eu-west-1']
|
137
|
-
|
137
|
+
|
138
138
|
# Initialize AWS session with profile priority system
|
139
139
|
self.session = boto3.Session(
|
140
140
|
profile_name=get_profile_for_operation("operational", profile_name)
|
141
141
|
)
|
142
|
-
|
143
|
-
#
|
142
|
+
|
143
|
+
# Get billing profile for pricing operations (CRITICAL FIX)
|
144
|
+
self.billing_profile = get_profile_for_operation("billing", profile_name)
|
145
|
+
|
146
|
+
# NAT Gateway pricing - using dynamic pricing engine with billing profile
|
144
147
|
# Base monthly cost calculation (will be applied per region)
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
+
try:
|
149
|
+
self._base_monthly_cost_us_east_1 = get_service_monthly_cost("nat_gateway", "us-east-1", self.billing_profile)
|
150
|
+
except Exception as e:
|
151
|
+
print_warning(f"Failed to get NAT Gateway pricing from AWS API: {e}")
|
152
|
+
# Use a fallback mechanism to calculate pricing
|
153
|
+
self._base_monthly_cost_us_east_1 = self._get_fallback_nat_gateway_pricing("us-east-1")
|
154
|
+
|
155
|
+
# Data transfer pricing - handle gracefully since not supported by AWS Pricing API
|
156
|
+
try:
|
157
|
+
self.nat_gateway_data_processing_cost = get_service_monthly_cost("data_transfer", "us-east-1", self.billing_profile)
|
158
|
+
except Exception as e:
|
159
|
+
print_warning(f"Data transfer pricing not available from AWS API: {e}")
|
160
|
+
# Use standard AWS data transfer pricing as fallback
|
161
|
+
self.nat_gateway_data_processing_cost = 0.045 # $0.045/GB for NAT Gateway data processing (standard AWS rate)
|
162
|
+
|
148
163
|
# Enterprise thresholds for optimization recommendations
|
149
164
|
self.low_usage_threshold_connections = 10 # Active connections per day
|
150
165
|
self.low_usage_threshold_bytes = 1_000_000 # 1MB per day
|
151
166
|
self.analysis_period_days = 7 # CloudWatch analysis period
|
152
|
-
|
167
|
+
|
168
|
+
def _get_fallback_nat_gateway_pricing(self, region: str) -> float:
|
169
|
+
"""
|
170
|
+
Fallback NAT Gateway pricing when AWS Pricing API is unavailable.
|
171
|
+
|
172
|
+
Uses standard AWS NAT Gateway pricing with regional multipliers.
|
173
|
+
This maintains enterprise compliance by using AWS published rates.
|
174
|
+
"""
|
175
|
+
# Standard AWS NAT Gateway pricing (as of 2024)
|
176
|
+
base_pricing = {
|
177
|
+
"us-east-1": 32.85, # $32.85/month
|
178
|
+
"us-west-2": 32.85, # Same as us-east-1
|
179
|
+
"eu-west-1": 36.14, # EU pricing slightly higher
|
180
|
+
"ap-southeast-1": 39.42, # APAC pricing
|
181
|
+
}
|
182
|
+
|
183
|
+
# Use region-specific pricing if available, otherwise use us-east-1 as base
|
184
|
+
if region in base_pricing:
|
185
|
+
return base_pricing[region]
|
186
|
+
else:
|
187
|
+
# For unknown regions, use us-east-1 pricing (conservative estimate)
|
188
|
+
print_warning(f"Using us-east-1 pricing for unknown region {region}")
|
189
|
+
return base_pricing["us-east-1"]
|
190
|
+
|
153
191
|
def _get_regional_monthly_cost(self, region: str) -> float:
|
154
192
|
"""Get dynamic monthly NAT Gateway cost for specified region."""
|
155
193
|
try:
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
194
|
+
# Use billing profile for pricing operations
|
195
|
+
return get_service_monthly_cost("nat_gateway", region, self.billing_profile)
|
196
|
+
except Exception as e:
|
197
|
+
print_warning(f"AWS Pricing API unavailable for region {region}: {e}")
|
198
|
+
# Fallback to our built-in pricing table
|
199
|
+
return self._get_fallback_nat_gateway_pricing(region)
|
161
200
|
|
162
201
|
async def analyze_nat_gateways(self, dry_run: bool = True) -> NATGatewayOptimizerResults:
|
163
202
|
"""
|
@@ -776,60 +815,49 @@ class EnhancedVPCCostOptimizer:
|
|
776
815
|
|
777
816
|
# Dynamic cost model using AWS pricing engine
|
778
817
|
self.cost_model = self._initialize_dynamic_cost_model()
|
779
|
-
|
818
|
+
|
819
|
+
def _get_fallback_data_transfer_cost(self) -> float:
|
820
|
+
"""
|
821
|
+
Fallback data transfer pricing when AWS Pricing API doesn't support data_transfer service.
|
822
|
+
|
823
|
+
Returns standard AWS data transfer pricing for NAT Gateway processing.
|
824
|
+
"""
|
825
|
+
# Standard AWS NAT Gateway data processing pricing: $0.045/GB
|
826
|
+
return 0.045
|
827
|
+
|
780
828
|
def _initialize_dynamic_cost_model(self) -> Dict[str, float]:
|
781
829
|
"""Initialize dynamic cost model using AWS pricing engine with universal compatibility."""
|
830
|
+
# Get billing profile for pricing operations
|
831
|
+
billing_profile = get_profile_for_operation("billing", self.profile)
|
832
|
+
|
782
833
|
try:
|
783
834
|
# Get base pricing for us-east-1, then apply regional multipliers as needed
|
784
835
|
base_region = "us-east-1"
|
785
|
-
|
836
|
+
|
786
837
|
return {
|
787
|
-
"nat_gateway_monthly": get_service_monthly_cost("nat_gateway", base_region,
|
788
|
-
"nat_gateway_data_processing":
|
789
|
-
"transit_gateway_monthly": get_service_monthly_cost("transit_gateway", base_region,
|
790
|
-
"vpc_endpoint_monthly": get_service_monthly_cost("vpc_endpoint", base_region,
|
791
|
-
"vpc_endpoint_interface_hourly":
|
792
|
-
"transit_gateway_attachment_hourly":
|
793
|
-
"data_transfer_regional":
|
794
|
-
"data_transfer_internet":
|
838
|
+
"nat_gateway_monthly": get_service_monthly_cost("nat_gateway", base_region, billing_profile),
|
839
|
+
"nat_gateway_data_processing": self._get_fallback_data_transfer_cost(), # Use fallback for data_transfer
|
840
|
+
"transit_gateway_monthly": get_service_monthly_cost("transit_gateway", base_region, billing_profile),
|
841
|
+
"vpc_endpoint_monthly": get_service_monthly_cost("vpc_endpoint", base_region, billing_profile),
|
842
|
+
"vpc_endpoint_interface_hourly": 0.01, # $0.01/hour standard AWS rate
|
843
|
+
"transit_gateway_attachment_hourly": 0.05, # $0.05/hour standard AWS rate
|
844
|
+
"data_transfer_regional": self._get_fallback_data_transfer_cost() * 0.1, # Regional is ~10% of internet
|
845
|
+
"data_transfer_internet": self._get_fallback_data_transfer_cost(),
|
795
846
|
}
|
796
847
|
except Exception as e:
|
797
848
|
print_warning(f"Dynamic pricing initialization failed: {e}")
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
#
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
data_transfer_pricing = pricing_engine.get_data_transfer_pricing("us-east-1", "internet")
|
811
|
-
|
812
|
-
return {
|
813
|
-
"nat_gateway_monthly": nat_gateway_pricing.monthly_cost,
|
814
|
-
"nat_gateway_data_processing": data_transfer_pricing.cost_per_gb,
|
815
|
-
"transit_gateway_monthly": transit_gateway_pricing.monthly_cost,
|
816
|
-
"transit_gateway_attachment_hourly": transit_gateway_pricing.attachment_hourly_cost,
|
817
|
-
"vpc_endpoint_interface_hourly": vpc_endpoint_pricing.interface_hourly_cost,
|
818
|
-
"data_transfer_regional": data_transfer_pricing.cost_per_gb * 0.1, # Regional is ~10% of internet cost
|
819
|
-
"data_transfer_cross_region": data_transfer_pricing.cost_per_gb * 0.2, # Cross-region is ~20% of internet cost
|
820
|
-
"data_transfer_internet": data_transfer_pricing.cost_per_gb
|
821
|
-
}
|
822
|
-
|
823
|
-
except Exception as pricing_error:
|
824
|
-
print_error(f"ENTERPRISE COMPLIANCE VIOLATION: Cannot determine pricing without AWS API access: {pricing_error}")
|
825
|
-
print_warning("Universal compatibility requires dynamic pricing - hardcoded values not permitted")
|
826
|
-
|
827
|
-
# Return error state instead of hardcoded values to maintain enterprise compliance
|
828
|
-
raise RuntimeError(
|
829
|
-
"Universal compatibility mode requires dynamic AWS pricing API access. "
|
830
|
-
"Please ensure your AWS profile has pricing:GetProducts permissions or configure "
|
831
|
-
"appropriate billing/management profile access."
|
832
|
-
)
|
849
|
+
print_info("Using fallback pricing based on standard AWS rates")
|
850
|
+
|
851
|
+
# Graceful fallback with standard AWS pricing (maintains enterprise compliance)
|
852
|
+
return {
|
853
|
+
"nat_gateway_monthly": 32.85, # Standard AWS NAT Gateway pricing for us-east-1
|
854
|
+
"nat_gateway_data_processing": self._get_fallback_data_transfer_cost(),
|
855
|
+
"transit_gateway_monthly": 36.50, # Standard AWS Transit Gateway pricing
|
856
|
+
"transit_gateway_attachment_hourly": 0.05, # Standard AWS attachment pricing
|
857
|
+
"vpc_endpoint_interface_hourly": 0.01, # Standard AWS Interface endpoint pricing
|
858
|
+
"data_transfer_regional": self._get_fallback_data_transfer_cost() * 0.1, # Regional is 10% of internet
|
859
|
+
"data_transfer_internet": self._get_fallback_data_transfer_cost(),
|
860
|
+
}
|
833
861
|
|
834
862
|
async def analyze_comprehensive_vpc_costs(self, profile: Optional[str] = None,
|
835
863
|
regions: Optional[List[str]] = None) -> Dict[str, Any]:
|