runbooks 0.7.7__py3-none-any.whl → 0.9.0__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 (157) hide show
  1. runbooks/__init__.py +1 -1
  2. runbooks/base.py +2 -2
  3. runbooks/cfat/README.md +12 -1
  4. runbooks/cfat/__init__.py +8 -4
  5. runbooks/cfat/assessment/collectors.py +171 -14
  6. runbooks/cfat/assessment/compliance.py +546 -522
  7. runbooks/cfat/assessment/runner.py +129 -10
  8. runbooks/cfat/models.py +6 -2
  9. runbooks/common/__init__.py +152 -0
  10. runbooks/common/accuracy_validator.py +1039 -0
  11. runbooks/common/context_logger.py +440 -0
  12. runbooks/common/cross_module_integration.py +594 -0
  13. runbooks/common/enhanced_exception_handler.py +1108 -0
  14. runbooks/common/enterprise_audit_integration.py +634 -0
  15. runbooks/common/logger.py +14 -0
  16. runbooks/common/mcp_integration.py +539 -0
  17. runbooks/common/performance_monitor.py +387 -0
  18. runbooks/common/profile_utils.py +216 -0
  19. runbooks/common/rich_utils.py +622 -0
  20. runbooks/enterprise/__init__.py +68 -0
  21. runbooks/enterprise/error_handling.py +411 -0
  22. runbooks/enterprise/logging.py +439 -0
  23. runbooks/enterprise/multi_tenant.py +583 -0
  24. runbooks/feedback/user_feedback_collector.py +440 -0
  25. runbooks/finops/README.md +129 -14
  26. runbooks/finops/__init__.py +22 -3
  27. runbooks/finops/account_resolver.py +279 -0
  28. runbooks/finops/accuracy_cross_validator.py +638 -0
  29. runbooks/finops/aws_client.py +721 -36
  30. runbooks/finops/budget_integration.py +313 -0
  31. runbooks/finops/cli.py +90 -33
  32. runbooks/finops/cost_processor.py +211 -37
  33. runbooks/finops/dashboard_router.py +900 -0
  34. runbooks/finops/dashboard_runner.py +1334 -399
  35. runbooks/finops/embedded_mcp_validator.py +288 -0
  36. runbooks/finops/enhanced_dashboard_runner.py +526 -0
  37. runbooks/finops/enhanced_progress.py +327 -0
  38. runbooks/finops/enhanced_trend_visualization.py +423 -0
  39. runbooks/finops/finops_dashboard.py +41 -0
  40. runbooks/finops/helpers.py +639 -323
  41. runbooks/finops/iam_guidance.py +400 -0
  42. runbooks/finops/markdown_exporter.py +466 -0
  43. runbooks/finops/multi_dashboard.py +1502 -0
  44. runbooks/finops/optimizer.py +396 -395
  45. runbooks/finops/profile_processor.py +2 -2
  46. runbooks/finops/runbooks.inventory.organizations_discovery.log +0 -0
  47. runbooks/finops/runbooks.security.report_generator.log +0 -0
  48. runbooks/finops/runbooks.security.run_script.log +0 -0
  49. runbooks/finops/runbooks.security.security_export.log +0 -0
  50. runbooks/finops/service_mapping.py +195 -0
  51. runbooks/finops/single_dashboard.py +710 -0
  52. runbooks/finops/tests/__init__.py +19 -0
  53. runbooks/finops/tests/results_test_finops_dashboard.xml +1 -0
  54. runbooks/finops/tests/run_comprehensive_tests.py +421 -0
  55. runbooks/finops/tests/run_tests.py +305 -0
  56. runbooks/finops/tests/test_finops_dashboard.py +705 -0
  57. runbooks/finops/tests/test_integration.py +477 -0
  58. runbooks/finops/tests/test_performance.py +380 -0
  59. runbooks/finops/tests/test_performance_benchmarks.py +500 -0
  60. runbooks/finops/tests/test_reference_images_validation.py +867 -0
  61. runbooks/finops/tests/test_single_account_features.py +715 -0
  62. runbooks/finops/tests/validate_test_suite.py +220 -0
  63. runbooks/finops/types.py +1 -1
  64. runbooks/hitl/enhanced_workflow_engine.py +725 -0
  65. runbooks/inventory/README.md +12 -1
  66. runbooks/inventory/artifacts/scale-optimize-status.txt +12 -0
  67. runbooks/inventory/collectors/aws_comprehensive.py +192 -185
  68. runbooks/inventory/collectors/enterprise_scale.py +281 -0
  69. runbooks/inventory/core/collector.py +299 -12
  70. runbooks/inventory/list_ec2_instances.py +21 -20
  71. runbooks/inventory/list_ssm_parameters.py +31 -3
  72. runbooks/inventory/organizations_discovery.py +1315 -0
  73. runbooks/inventory/rich_inventory_display.py +360 -0
  74. runbooks/inventory/run_on_multi_accounts.py +32 -16
  75. runbooks/inventory/runbooks.security.report_generator.log +0 -0
  76. runbooks/inventory/runbooks.security.run_script.log +0 -0
  77. runbooks/inventory/vpc_flow_analyzer.py +1030 -0
  78. runbooks/main.py +4171 -1615
  79. runbooks/metrics/dora_metrics_engine.py +1293 -0
  80. runbooks/monitoring/performance_monitor.py +433 -0
  81. runbooks/operate/README.md +394 -0
  82. runbooks/operate/__init__.py +2 -2
  83. runbooks/operate/base.py +291 -11
  84. runbooks/operate/deployment_framework.py +1032 -0
  85. runbooks/operate/deployment_validator.py +853 -0
  86. runbooks/operate/dynamodb_operations.py +10 -6
  87. runbooks/operate/ec2_operations.py +321 -11
  88. runbooks/operate/executive_dashboard.py +779 -0
  89. runbooks/operate/mcp_integration.py +750 -0
  90. runbooks/operate/nat_gateway_operations.py +1120 -0
  91. runbooks/operate/networking_cost_heatmap.py +685 -0
  92. runbooks/operate/privatelink_operations.py +940 -0
  93. runbooks/operate/s3_operations.py +10 -6
  94. runbooks/operate/vpc_endpoints.py +644 -0
  95. runbooks/operate/vpc_operations.py +1038 -0
  96. runbooks/remediation/README.md +489 -13
  97. runbooks/remediation/__init__.py +2 -2
  98. runbooks/remediation/acm_remediation.py +1 -1
  99. runbooks/remediation/base.py +1 -1
  100. runbooks/remediation/cloudtrail_remediation.py +1 -1
  101. runbooks/remediation/cognito_remediation.py +1 -1
  102. runbooks/remediation/commons.py +8 -4
  103. runbooks/remediation/dynamodb_remediation.py +1 -1
  104. runbooks/remediation/ec2_remediation.py +1 -1
  105. runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -1
  106. runbooks/remediation/kms_enable_key_rotation.py +1 -1
  107. runbooks/remediation/kms_remediation.py +1 -1
  108. runbooks/remediation/lambda_remediation.py +1 -1
  109. runbooks/remediation/multi_account.py +1 -1
  110. runbooks/remediation/rds_remediation.py +1 -1
  111. runbooks/remediation/s3_block_public_access.py +1 -1
  112. runbooks/remediation/s3_enable_access_logging.py +1 -1
  113. runbooks/remediation/s3_encryption.py +1 -1
  114. runbooks/remediation/s3_remediation.py +1 -1
  115. runbooks/remediation/vpc_remediation.py +475 -0
  116. runbooks/security/ENTERPRISE_SECURITY_FRAMEWORK.md +506 -0
  117. runbooks/security/README.md +12 -1
  118. runbooks/security/__init__.py +166 -33
  119. runbooks/security/compliance_automation.py +634 -0
  120. runbooks/security/compliance_automation_engine.py +1021 -0
  121. runbooks/security/enterprise_security_framework.py +931 -0
  122. runbooks/security/enterprise_security_policies.json +293 -0
  123. runbooks/security/integration_test_enterprise_security.py +879 -0
  124. runbooks/security/module_security_integrator.py +641 -0
  125. runbooks/security/report_generator.py +10 -0
  126. runbooks/security/run_script.py +27 -5
  127. runbooks/security/security_baseline_tester.py +153 -27
  128. runbooks/security/security_export.py +456 -0
  129. runbooks/sre/README.md +472 -0
  130. runbooks/sre/__init__.py +33 -0
  131. runbooks/sre/mcp_reliability_engine.py +1049 -0
  132. runbooks/sre/performance_optimization_engine.py +1032 -0
  133. runbooks/sre/reliability_monitoring_framework.py +1011 -0
  134. runbooks/validation/__init__.py +10 -0
  135. runbooks/validation/benchmark.py +489 -0
  136. runbooks/validation/cli.py +368 -0
  137. runbooks/validation/mcp_validator.py +797 -0
  138. runbooks/vpc/README.md +478 -0
  139. runbooks/vpc/__init__.py +38 -0
  140. runbooks/vpc/config.py +212 -0
  141. runbooks/vpc/cost_engine.py +347 -0
  142. runbooks/vpc/heatmap_engine.py +605 -0
  143. runbooks/vpc/manager_interface.py +649 -0
  144. runbooks/vpc/networking_wrapper.py +1289 -0
  145. runbooks/vpc/rich_formatters.py +693 -0
  146. runbooks/vpc/tests/__init__.py +5 -0
  147. runbooks/vpc/tests/conftest.py +356 -0
  148. runbooks/vpc/tests/test_cli_integration.py +530 -0
  149. runbooks/vpc/tests/test_config.py +458 -0
  150. runbooks/vpc/tests/test_cost_engine.py +479 -0
  151. runbooks/vpc/tests/test_networking_wrapper.py +512 -0
  152. {runbooks-0.7.7.dist-info → runbooks-0.9.0.dist-info}/METADATA +175 -65
  153. {runbooks-0.7.7.dist-info → runbooks-0.9.0.dist-info}/RECORD +157 -60
  154. {runbooks-0.7.7.dist-info → runbooks-0.9.0.dist-info}/entry_points.txt +1 -1
  155. {runbooks-0.7.7.dist-info → runbooks-0.9.0.dist-info}/WHEEL +0 -0
  156. {runbooks-0.7.7.dist-info → runbooks-0.9.0.dist-info}/licenses/LICENSE +0 -0
  157. {runbooks-0.7.7.dist-info → runbooks-0.9.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,288 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Embedded MCP Validator - Internal AWS API Validation for Enterprise Accuracy
4
+
5
+ This module provides self-contained MCP-style validation without external dependencies.
6
+ Direct AWS API integration ensures >=99.5% financial accuracy for enterprise compliance.
7
+
8
+ User Innovation: "MCP inside runbooks API may be a good feature"
9
+ Implementation: Embedded validation eliminates external MCP server requirements
10
+ """
11
+
12
+ import asyncio
13
+ import time
14
+ from datetime import datetime, timedelta
15
+ from typing import Any, Dict, List, Optional, Tuple
16
+
17
+ import boto3
18
+ from rich.console import Console
19
+ from rich.progress import BarColumn, Progress, SpinnerColumn, TaskProgressColumn, TextColumn, TimeElapsedColumn
20
+
21
+ from ..common.rich_utils import (
22
+ console as rich_console,
23
+ )
24
+ from ..common.rich_utils import (
25
+ format_cost,
26
+ print_error,
27
+ print_info,
28
+ print_success,
29
+ print_warning,
30
+ )
31
+
32
+
33
+ class EmbeddedMCPValidator:
34
+ """
35
+ Internal MCP-style validator with direct AWS API integration.
36
+
37
+ Provides real-time cost validation without external MCP server dependencies.
38
+ Ensures >=99.5% accuracy for enterprise financial compliance.
39
+ """
40
+
41
+ def __init__(self, profiles: List[str], console: Optional[Console] = None):
42
+ """Initialize embedded MCP validator with AWS profiles."""
43
+ self.profiles = profiles
44
+ self.console = console or rich_console
45
+ self.aws_sessions = {}
46
+ self.validation_threshold = 99.5 # Enterprise accuracy requirement
47
+ self.tolerance_percent = 5.0 # ±5% tolerance for validation
48
+
49
+ # Initialize AWS sessions for each profile
50
+ self._initialize_aws_sessions()
51
+
52
+ def _initialize_aws_sessions(self) -> None:
53
+ """Initialize AWS sessions for all profiles with error handling."""
54
+ for profile in self.profiles:
55
+ try:
56
+ session = boto3.Session(profile_name=profile)
57
+ # Test session validity
58
+ session.client("sts").get_caller_identity()
59
+ self.aws_sessions[profile] = session
60
+ print_info(f"MCP session initialized for profile: {profile[:30]}...")
61
+ except Exception as e:
62
+ print_warning(f"MCP session failed for {profile[:20]}...: {str(e)[:30]}")
63
+
64
+ async def validate_cost_data_async(self, runbooks_data: Dict[str, Any]) -> Dict[str, Any]:
65
+ """
66
+ Asynchronously validate runbooks cost data against direct AWS API calls.
67
+
68
+ Args:
69
+ runbooks_data: Cost data from runbooks FinOps analysis
70
+
71
+ Returns:
72
+ Validation results with accuracy metrics
73
+ """
74
+ validation_results = {
75
+ "validation_timestamp": datetime.now().isoformat(),
76
+ "profiles_validated": 0,
77
+ "total_accuracy": 0.0,
78
+ "passed_validation": False,
79
+ "profile_results": [],
80
+ "validation_method": "embedded_mcp_direct_aws_api",
81
+ }
82
+
83
+ with Progress(
84
+ SpinnerColumn(),
85
+ TextColumn("[progress.description]{task.description}"),
86
+ BarColumn(),
87
+ TaskProgressColumn(),
88
+ TimeElapsedColumn(),
89
+ console=self.console,
90
+ ) as progress:
91
+ task = progress.add_task("Validating financial data with embedded MCP...", total=len(self.aws_sessions))
92
+
93
+ for profile, session in self.aws_sessions.items():
94
+ try:
95
+ # Get independent cost data from AWS API
96
+ aws_cost_data = await self._get_independent_cost_data(session, profile)
97
+
98
+ # Find corresponding runbooks data
99
+ runbooks_cost_data = self._extract_runbooks_cost_data(runbooks_data, profile)
100
+
101
+ # Calculate accuracy
102
+ accuracy_result = self._calculate_accuracy(runbooks_cost_data, aws_cost_data, profile)
103
+ validation_results["profile_results"].append(accuracy_result)
104
+
105
+ progress.advance(task)
106
+
107
+ except Exception as e:
108
+ print_warning(f"Validation failed for {profile[:20]}...: {str(e)[:40]}")
109
+ progress.advance(task)
110
+
111
+ # Calculate overall validation metrics
112
+ self._finalize_validation_results(validation_results)
113
+ return validation_results
114
+
115
+ async def _get_independent_cost_data(self, session: boto3.Session, profile: str) -> Dict[str, Any]:
116
+ """Get independent cost data directly from AWS Cost Explorer API."""
117
+ try:
118
+ ce_client = session.client("ce", region_name="us-east-1")
119
+
120
+ # Calculate date range (current month)
121
+ end_date = datetime.now().date()
122
+ start_date = end_date.replace(day=1)
123
+
124
+ # Get cost and usage data (independent from runbooks)
125
+ response = ce_client.get_cost_and_usage(
126
+ TimePeriod={"Start": start_date.isoformat(), "End": end_date.isoformat()},
127
+ Granularity="MONTHLY",
128
+ Metrics=["BlendedCost"],
129
+ GroupBy=[{"Type": "DIMENSION", "Key": "SERVICE"}],
130
+ )
131
+
132
+ # Process AWS response into comparable format
133
+ total_cost = 0.0
134
+ services_cost = {}
135
+
136
+ if response.get("ResultsByTime"):
137
+ for result in response["ResultsByTime"]:
138
+ for group in result.get("Groups", []):
139
+ service = group.get("Keys", ["Unknown"])[0]
140
+ cost = float(group.get("Metrics", {}).get("BlendedCost", {}).get("Amount", 0))
141
+ services_cost[service] = cost
142
+ total_cost += cost
143
+
144
+ return {
145
+ "profile": profile,
146
+ "total_cost": total_cost,
147
+ "services": services_cost,
148
+ "data_source": "direct_aws_cost_explorer",
149
+ "timestamp": datetime.now().isoformat(),
150
+ }
151
+
152
+ except Exception as e:
153
+ return {
154
+ "profile": profile,
155
+ "error": str(e),
156
+ "total_cost": 0.0,
157
+ "services": {},
158
+ "data_source": "error_fallback",
159
+ }
160
+
161
+ def _extract_runbooks_cost_data(self, runbooks_data: Dict[str, Any], profile: str) -> Dict[str, Any]:
162
+ """Extract cost data from runbooks results for comparison."""
163
+ # This method adapts to the actual runbooks data structure
164
+ # Implementation depends on the runbooks data format
165
+ return {
166
+ "profile": profile,
167
+ "total_cost": runbooks_data.get("total_cost", 0.0),
168
+ "services": runbooks_data.get("services", {}),
169
+ "data_source": "runbooks_finops_analysis",
170
+ }
171
+
172
+ def _calculate_accuracy(self, runbooks_data: Dict, aws_data: Dict, profile: str) -> Dict[str, Any]:
173
+ """Calculate accuracy between runbooks and AWS API data."""
174
+ try:
175
+ runbooks_cost = float(runbooks_data.get("total_cost", 0))
176
+ aws_cost = float(aws_data.get("total_cost", 0))
177
+
178
+ if runbooks_cost > 0:
179
+ accuracy_percent = (1 - abs(runbooks_cost - aws_cost) / runbooks_cost) * 100
180
+ else:
181
+ accuracy_percent = 100.0 if aws_cost == 0 else 0.0
182
+
183
+ # Determine validation status
184
+ passed = accuracy_percent >= self.validation_threshold
185
+
186
+ return {
187
+ "profile": profile,
188
+ "runbooks_cost": runbooks_cost,
189
+ "aws_api_cost": aws_cost,
190
+ "accuracy_percent": accuracy_percent,
191
+ "passed_validation": passed,
192
+ "tolerance_met": abs(runbooks_cost - aws_cost) / max(runbooks_cost, 1) * 100 <= self.tolerance_percent,
193
+ "cost_difference": abs(runbooks_cost - aws_cost),
194
+ "validation_status": "PASSED" if passed else "FAILED",
195
+ }
196
+
197
+ except Exception as e:
198
+ return {
199
+ "profile": profile,
200
+ "accuracy_percent": 0.0,
201
+ "passed_validation": False,
202
+ "error": str(e),
203
+ "validation_status": "ERROR",
204
+ }
205
+
206
+ def _finalize_validation_results(self, validation_results: Dict[str, Any]) -> None:
207
+ """Calculate overall validation metrics and status."""
208
+ profile_results = validation_results["profile_results"]
209
+
210
+ if not profile_results:
211
+ validation_results["total_accuracy"] = 0.0
212
+ validation_results["passed_validation"] = False
213
+ return
214
+
215
+ # Calculate overall accuracy
216
+ valid_results = [r for r in profile_results if r.get("accuracy_percent", 0) > 0]
217
+ if valid_results:
218
+ total_accuracy = sum(r["accuracy_percent"] for r in valid_results) / len(valid_results)
219
+ validation_results["total_accuracy"] = total_accuracy
220
+ validation_results["profiles_validated"] = len(valid_results)
221
+ validation_results["passed_validation"] = total_accuracy >= self.validation_threshold
222
+
223
+ # Display results
224
+ self._display_validation_results(validation_results)
225
+
226
+ def _display_validation_results(self, results: Dict[str, Any]) -> None:
227
+ """Display validation results with Rich CLI formatting."""
228
+ overall_accuracy = results.get("total_accuracy", 0)
229
+ passed = results.get("passed_validation", False)
230
+
231
+ self.console.print(f"\n[bright_cyan]🔍 Embedded MCP Validation Results[/]")
232
+
233
+ # Display per-profile results
234
+ for profile_result in results.get("profile_results", []):
235
+ accuracy = profile_result.get("accuracy_percent", 0)
236
+ status = profile_result.get("validation_status", "UNKNOWN")
237
+ profile = profile_result.get("profile", "Unknown")
238
+
239
+ if status == "PASSED":
240
+ icon = "✅"
241
+ color = "green"
242
+ elif status == "FAILED":
243
+ icon = "⚠️"
244
+ color = "yellow"
245
+ else:
246
+ icon = "❌"
247
+ color = "red"
248
+
249
+ self.console.print(f"[dim] {profile[:30]}: {icon} [{color}]{accuracy:.1f}% accuracy[/][/]")
250
+
251
+ # Overall summary
252
+ if passed:
253
+ print_success(f"✅ MCP Validation PASSED: {overall_accuracy:.1f}% accuracy achieved")
254
+ print_info(f"Enterprise compliance: {results['profiles_validated']} profiles validated")
255
+ else:
256
+ print_warning(f"⚠️ MCP Validation: {overall_accuracy:.1f}% accuracy (≥99.5% required)")
257
+ print_info("Consider reviewing data sources for accuracy improvements")
258
+
259
+ def validate_cost_data(self, runbooks_data: Dict[str, Any]) -> Dict[str, Any]:
260
+ """Synchronous wrapper for async validation."""
261
+ try:
262
+ loop = asyncio.get_event_loop()
263
+ except RuntimeError:
264
+ loop = asyncio.new_event_loop()
265
+ asyncio.set_event_loop(loop)
266
+
267
+ return loop.run_until_complete(self.validate_cost_data_async(runbooks_data))
268
+
269
+
270
+ def create_embedded_mcp_validator(profiles: List[str], console: Optional[Console] = None) -> EmbeddedMCPValidator:
271
+ """Factory function to create embedded MCP validator."""
272
+ return EmbeddedMCPValidator(profiles=profiles, console=console)
273
+
274
+
275
+ # Integration with existing FinOps dashboard
276
+ def validate_finops_results_with_embedded_mcp(profiles: List[str], runbooks_results: Dict[str, Any]) -> Dict[str, Any]:
277
+ """
278
+ Convenience function to validate FinOps results with embedded MCP.
279
+
280
+ Args:
281
+ profiles: List of AWS profiles to validate
282
+ runbooks_results: Results from runbooks FinOps analysis
283
+
284
+ Returns:
285
+ Validation results with accuracy metrics
286
+ """
287
+ validator = create_embedded_mcp_validator(profiles)
288
+ return validator.validate_cost_data(runbooks_results)