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.
- runbooks/__init__.py +1 -1
- runbooks/cfat/WEIGHT_CONFIG_README.md +368 -0
- runbooks/cfat/app.ts +27 -19
- runbooks/cfat/assessment/runner.py +6 -5
- runbooks/cfat/cloud_foundations_assessment.py +626 -0
- runbooks/cfat/tests/test_weight_configuration.ts +449 -0
- runbooks/cfat/weight_config.ts +574 -0
- runbooks/cloudops/cost_optimizer.py +95 -33
- runbooks/common/__init__.py +26 -9
- runbooks/common/aws_pricing.py +1353 -0
- runbooks/common/aws_pricing_api.py +205 -0
- runbooks/common/aws_utils.py +2 -2
- runbooks/common/comprehensive_cost_explorer_integration.py +979 -0
- runbooks/common/cross_account_manager.py +606 -0
- runbooks/common/date_utils.py +115 -0
- runbooks/common/enhanced_exception_handler.py +14 -7
- runbooks/common/env_utils.py +96 -0
- runbooks/common/mcp_cost_explorer_integration.py +5 -4
- runbooks/common/mcp_integration.py +49 -2
- runbooks/common/organizations_client.py +579 -0
- runbooks/common/profile_utils.py +127 -72
- runbooks/common/rich_utils.py +3 -3
- runbooks/finops/cost_optimizer.py +2 -1
- runbooks/finops/dashboard_runner.py +47 -28
- runbooks/finops/ebs_optimizer.py +56 -9
- runbooks/finops/elastic_ip_optimizer.py +13 -9
- runbooks/finops/embedded_mcp_validator.py +31 -0
- runbooks/finops/enhanced_trend_visualization.py +10 -4
- runbooks/finops/finops_dashboard.py +6 -5
- runbooks/finops/iam_guidance.py +6 -1
- runbooks/finops/markdown_exporter.py +217 -2
- runbooks/finops/nat_gateway_optimizer.py +76 -20
- runbooks/finops/tests/test_integration.py +3 -1
- runbooks/finops/vpc_cleanup_exporter.py +28 -26
- runbooks/finops/vpc_cleanup_optimizer.py +363 -16
- runbooks/inventory/__init__.py +10 -1
- runbooks/inventory/cloud_foundations_integration.py +409 -0
- runbooks/inventory/core/collector.py +1177 -94
- runbooks/inventory/discovery.md +339 -0
- runbooks/inventory/drift_detection_cli.py +327 -0
- runbooks/inventory/inventory_mcp_cli.py +171 -0
- runbooks/inventory/inventory_modules.py +6 -9
- runbooks/inventory/list_ec2_instances.py +3 -3
- runbooks/inventory/mcp_inventory_validator.py +2149 -0
- runbooks/inventory/mcp_vpc_validator.py +23 -6
- runbooks/inventory/organizations_discovery.py +104 -9
- runbooks/inventory/rich_inventory_display.py +129 -1
- runbooks/inventory/unified_validation_engine.py +1279 -0
- runbooks/inventory/verify_ec2_security_groups.py +3 -1
- runbooks/inventory/vpc_analyzer.py +825 -7
- runbooks/inventory/vpc_flow_analyzer.py +36 -42
- runbooks/main.py +708 -47
- runbooks/monitoring/performance_monitor.py +11 -7
- runbooks/operate/base.py +9 -6
- runbooks/operate/deployment_framework.py +5 -4
- runbooks/operate/deployment_validator.py +6 -5
- runbooks/operate/dynamodb_operations.py +6 -5
- runbooks/operate/ec2_operations.py +3 -2
- runbooks/operate/mcp_integration.py +6 -5
- runbooks/operate/networking_cost_heatmap.py +21 -16
- runbooks/operate/s3_operations.py +13 -12
- runbooks/operate/vpc_operations.py +100 -12
- runbooks/remediation/base.py +4 -2
- runbooks/remediation/commons.py +5 -5
- runbooks/remediation/commvault_ec2_analysis.py +68 -15
- runbooks/remediation/config/accounts_example.json +31 -0
- runbooks/remediation/ec2_unattached_ebs_volumes.py +6 -3
- runbooks/remediation/multi_account.py +120 -7
- runbooks/remediation/rds_snapshot_list.py +5 -3
- runbooks/remediation/remediation_cli.py +710 -0
- runbooks/remediation/universal_account_discovery.py +377 -0
- runbooks/security/compliance_automation_engine.py +99 -20
- runbooks/security/config/__init__.py +24 -0
- runbooks/security/config/compliance_config.py +255 -0
- runbooks/security/config/compliance_weights_example.json +22 -0
- runbooks/security/config_template_generator.py +500 -0
- runbooks/security/security_cli.py +377 -0
- runbooks/validation/__init__.py +21 -1
- runbooks/validation/cli.py +8 -7
- runbooks/validation/comprehensive_2way_validator.py +2007 -0
- runbooks/validation/mcp_validator.py +965 -101
- runbooks/validation/terraform_citations_validator.py +363 -0
- runbooks/validation/terraform_drift_detector.py +1098 -0
- runbooks/vpc/cleanup_wrapper.py +231 -10
- runbooks/vpc/config.py +346 -73
- runbooks/vpc/cross_account_session.py +312 -0
- runbooks/vpc/heatmap_engine.py +115 -41
- runbooks/vpc/manager_interface.py +9 -9
- runbooks/vpc/mcp_no_eni_validator.py +1630 -0
- runbooks/vpc/networking_wrapper.py +14 -8
- runbooks/vpc/runbooks_adapter.py +33 -12
- runbooks/vpc/tests/conftest.py +4 -2
- runbooks/vpc/tests/test_cost_engine.py +4 -2
- runbooks/vpc/unified_scenarios.py +73 -3
- runbooks/vpc/vpc_cleanup_integration.py +512 -78
- {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/METADATA +94 -52
- {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/RECORD +101 -81
- runbooks/finops/runbooks.inventory.organizations_discovery.log +0 -0
- runbooks/finops/runbooks.security.report_generator.log +0 -0
- runbooks/finops/runbooks.security.run_script.log +0 -0
- runbooks/finops/runbooks.security.security_export.log +0 -0
- runbooks/finops/tests/results_test_finops_dashboard.xml +0 -1
- runbooks/inventory/artifacts/scale-optimize-status.txt +0 -12
- runbooks/inventory/runbooks.inventory.organizations_discovery.log +0 -0
- runbooks/inventory/runbooks.security.report_generator.log +0 -0
- runbooks/inventory/runbooks.security.run_script.log +0 -0
- runbooks/inventory/runbooks.security.security_export.log +0 -0
- {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/WHEEL +0 -0
- {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/entry_points.txt +0 -0
- {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/licenses/LICENSE +0 -0
- {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
|
-
#
|
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
|
231
|
-
estimated_cost = bucket_count *
|
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 *
|
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 *
|
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
|
-
"""
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
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
|
-
"""
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
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
|
-
"""
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
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
|
567
|
-
estimated_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 =
|
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:
|
runbooks/common/__init__.py
CHANGED
@@ -1,23 +1,33 @@
|
|
1
1
|
"""
|
2
|
-
CloudOps Runbooks Common Framework -
|
2
|
+
CloudOps Runbooks Common Framework - Universal Foundation
|
3
3
|
|
4
|
-
This module provides the foundational
|
5
|
-
|
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:
|
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.
|
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 (
|
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
|
-
|
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
|
-
"
|
146
|
+
"get_current_profile_info",
|
130
147
|
"validate_profile_access",
|
131
148
|
# Performance monitoring framework
|
132
149
|
"PerformanceMetrics",
|