runbooks 0.7.6__py3-none-any.whl → 0.7.9__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/base.py +5 -1
  3. runbooks/cfat/__init__.py +8 -4
  4. runbooks/cfat/assessment/collectors.py +171 -14
  5. runbooks/cfat/assessment/compliance.py +871 -0
  6. runbooks/cfat/assessment/runner.py +122 -11
  7. runbooks/cfat/models.py +6 -2
  8. runbooks/common/logger.py +14 -0
  9. runbooks/common/rich_utils.py +451 -0
  10. runbooks/enterprise/__init__.py +68 -0
  11. runbooks/enterprise/error_handling.py +411 -0
  12. runbooks/enterprise/logging.py +439 -0
  13. runbooks/enterprise/multi_tenant.py +583 -0
  14. runbooks/finops/README.md +468 -241
  15. runbooks/finops/__init__.py +39 -3
  16. runbooks/finops/cli.py +83 -18
  17. runbooks/finops/cross_validation.py +375 -0
  18. runbooks/finops/dashboard_runner.py +812 -164
  19. runbooks/finops/enhanced_dashboard_runner.py +525 -0
  20. runbooks/finops/finops_dashboard.py +1892 -0
  21. runbooks/finops/helpers.py +485 -51
  22. runbooks/finops/optimizer.py +823 -0
  23. runbooks/finops/tests/__init__.py +19 -0
  24. runbooks/finops/tests/results_test_finops_dashboard.xml +1 -0
  25. runbooks/finops/tests/run_comprehensive_tests.py +421 -0
  26. runbooks/finops/tests/run_tests.py +305 -0
  27. runbooks/finops/tests/test_finops_dashboard.py +705 -0
  28. runbooks/finops/tests/test_integration.py +477 -0
  29. runbooks/finops/tests/test_performance.py +380 -0
  30. runbooks/finops/tests/test_performance_benchmarks.py +500 -0
  31. runbooks/finops/tests/test_reference_images_validation.py +867 -0
  32. runbooks/finops/tests/test_single_account_features.py +715 -0
  33. runbooks/finops/tests/validate_test_suite.py +220 -0
  34. runbooks/finops/types.py +1 -1
  35. runbooks/hitl/enhanced_workflow_engine.py +725 -0
  36. runbooks/inventory/artifacts/scale-optimize-status.txt +12 -0
  37. runbooks/inventory/collectors/aws_comprehensive.py +442 -0
  38. runbooks/inventory/collectors/enterprise_scale.py +281 -0
  39. runbooks/inventory/core/collector.py +172 -13
  40. runbooks/inventory/discovery.md +1 -1
  41. runbooks/inventory/list_ec2_instances.py +18 -20
  42. runbooks/inventory/list_ssm_parameters.py +31 -3
  43. runbooks/inventory/organizations_discovery.py +1269 -0
  44. runbooks/inventory/rich_inventory_display.py +393 -0
  45. runbooks/inventory/run_on_multi_accounts.py +35 -19
  46. runbooks/inventory/runbooks.security.report_generator.log +0 -0
  47. runbooks/inventory/runbooks.security.run_script.log +0 -0
  48. runbooks/inventory/vpc_flow_analyzer.py +1030 -0
  49. runbooks/main.py +2215 -119
  50. runbooks/metrics/dora_metrics_engine.py +599 -0
  51. runbooks/operate/__init__.py +2 -2
  52. runbooks/operate/base.py +122 -10
  53. runbooks/operate/deployment_framework.py +1032 -0
  54. runbooks/operate/deployment_validator.py +853 -0
  55. runbooks/operate/dynamodb_operations.py +10 -6
  56. runbooks/operate/ec2_operations.py +319 -11
  57. runbooks/operate/executive_dashboard.py +779 -0
  58. runbooks/operate/mcp_integration.py +750 -0
  59. runbooks/operate/nat_gateway_operations.py +1120 -0
  60. runbooks/operate/networking_cost_heatmap.py +685 -0
  61. runbooks/operate/privatelink_operations.py +940 -0
  62. runbooks/operate/s3_operations.py +10 -6
  63. runbooks/operate/vpc_endpoints.py +644 -0
  64. runbooks/operate/vpc_operations.py +1038 -0
  65. runbooks/remediation/__init__.py +2 -2
  66. runbooks/remediation/acm_remediation.py +1 -1
  67. runbooks/remediation/base.py +1 -1
  68. runbooks/remediation/cloudtrail_remediation.py +1 -1
  69. runbooks/remediation/cognito_remediation.py +1 -1
  70. runbooks/remediation/dynamodb_remediation.py +1 -1
  71. runbooks/remediation/ec2_remediation.py +1 -1
  72. runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -1
  73. runbooks/remediation/kms_enable_key_rotation.py +1 -1
  74. runbooks/remediation/kms_remediation.py +1 -1
  75. runbooks/remediation/lambda_remediation.py +1 -1
  76. runbooks/remediation/multi_account.py +1 -1
  77. runbooks/remediation/rds_remediation.py +1 -1
  78. runbooks/remediation/s3_block_public_access.py +1 -1
  79. runbooks/remediation/s3_enable_access_logging.py +1 -1
  80. runbooks/remediation/s3_encryption.py +1 -1
  81. runbooks/remediation/s3_remediation.py +1 -1
  82. runbooks/remediation/vpc_remediation.py +475 -0
  83. runbooks/security/__init__.py +3 -1
  84. runbooks/security/compliance_automation.py +632 -0
  85. runbooks/security/report_generator.py +10 -0
  86. runbooks/security/run_script.py +31 -5
  87. runbooks/security/security_baseline_tester.py +169 -30
  88. runbooks/security/security_export.py +477 -0
  89. runbooks/validation/__init__.py +10 -0
  90. runbooks/validation/benchmark.py +484 -0
  91. runbooks/validation/cli.py +356 -0
  92. runbooks/validation/mcp_validator.py +768 -0
  93. runbooks/vpc/__init__.py +38 -0
  94. runbooks/vpc/config.py +212 -0
  95. runbooks/vpc/cost_engine.py +347 -0
  96. runbooks/vpc/heatmap_engine.py +605 -0
  97. runbooks/vpc/manager_interface.py +634 -0
  98. runbooks/vpc/networking_wrapper.py +1260 -0
  99. runbooks/vpc/rich_formatters.py +679 -0
  100. runbooks/vpc/tests/__init__.py +5 -0
  101. runbooks/vpc/tests/conftest.py +356 -0
  102. runbooks/vpc/tests/test_cli_integration.py +530 -0
  103. runbooks/vpc/tests/test_config.py +458 -0
  104. runbooks/vpc/tests/test_cost_engine.py +479 -0
  105. runbooks/vpc/tests/test_networking_wrapper.py +512 -0
  106. {runbooks-0.7.6.dist-info → runbooks-0.7.9.dist-info}/METADATA +40 -12
  107. {runbooks-0.7.6.dist-info → runbooks-0.7.9.dist-info}/RECORD +111 -50
  108. {runbooks-0.7.6.dist-info → runbooks-0.7.9.dist-info}/WHEEL +0 -0
  109. {runbooks-0.7.6.dist-info → runbooks-0.7.9.dist-info}/entry_points.txt +0 -0
  110. {runbooks-0.7.6.dist-info → runbooks-0.7.9.dist-info}/licenses/LICENSE +0 -0
  111. {runbooks-0.7.6.dist-info → runbooks-0.7.9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,356 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ MCP Validation CLI - Enterprise Command Line Interface
4
+
5
+ Provides command-line access to MCP validation framework with enterprise features:
6
+ - Comprehensive validation across all critical operations
7
+ - Real-time progress monitoring with Rich UI
8
+ - Detailed reporting and recommendations
9
+ - Performance benchmarking with <30s target
10
+ - Multi-profile AWS integration
11
+
12
+ Usage:
13
+ python -m runbooks.validation.cli validate-all
14
+ python -m runbooks.validation.cli validate-costs --profile billing
15
+ python -m runbooks.validation.cli benchmark --target-accuracy 99.5
16
+ """
17
+
18
+ import asyncio
19
+ import sys
20
+ from pathlib import Path
21
+ from typing import Optional, List
22
+ import click
23
+ from rich.console import Console
24
+ from rich.panel import Panel
25
+ from rich.table import Table
26
+ from rich import box
27
+
28
+ from .mcp_validator import MCPValidator, ValidationStatus
29
+
30
+ console = Console()
31
+
32
+ @click.group()
33
+ @click.version_option(version="1.0.0", prog_name="MCP Validator")
34
+ def cli():
35
+ """Enterprise MCP Validation Framework - 99.5% Accuracy Target"""
36
+ pass
37
+
38
+ @cli.command()
39
+ @click.option('--tolerance', default=5.0, help='Tolerance percentage for variance detection')
40
+ @click.option('--performance-target', default=30.0, help='Performance target in seconds')
41
+ @click.option('--save-report', is_flag=True, help='Save detailed report to artifacts')
42
+ @click.option('--profile', help='AWS profile override')
43
+ def validate_all(tolerance: float, performance_target: float, save_report: bool, profile: Optional[str]):
44
+ """Run comprehensive validation across all critical operations."""
45
+
46
+ console.print(Panel(
47
+ "[bold blue]Enterprise MCP Validation Framework[/bold blue]\n"
48
+ f"Target Accuracy: 99.5% | Tolerance: ±{tolerance}% | Performance: <{performance_target}s",
49
+ title="MCP Validator"
50
+ ))
51
+
52
+ # Initialize validator
53
+ profiles = None
54
+ if profile:
55
+ profiles = {
56
+ 'billing': profile,
57
+ 'management': profile,
58
+ 'centralised_ops': profile,
59
+ 'single_aws': profile
60
+ }
61
+
62
+ validator = MCPValidator(
63
+ profiles=profiles,
64
+ tolerance_percentage=tolerance,
65
+ performance_target_seconds=performance_target
66
+ )
67
+
68
+ # Run validation
69
+ try:
70
+ report = asyncio.run(validator.validate_all_operations())
71
+
72
+ # Display results
73
+ validator.display_validation_report(report)
74
+
75
+ # Exit code based on results
76
+ if report.overall_accuracy >= 99.5:
77
+ console.print("[bold green]✅ Validation PASSED - Deploy with confidence[/bold green]")
78
+ sys.exit(0)
79
+ elif report.overall_accuracy >= 95.0:
80
+ console.print("[bold yellow]⚠️ Validation WARNING - Review before deployment[/bold yellow]")
81
+ sys.exit(1)
82
+ else:
83
+ console.print("[bold red]❌ Validation FAILED - Address issues before deployment[/bold red]")
84
+ sys.exit(2)
85
+
86
+ except Exception as e:
87
+ console.print(f"[bold red]Error running validation: {e}[/bold red]")
88
+ sys.exit(3)
89
+
90
+ @cli.command()
91
+ @click.option('--profile', default='ams-admin-Billing-ReadOnlyAccess-909135376185', help='AWS billing profile')
92
+ @click.option('--tolerance', default=5.0, help='Cost variance tolerance percentage')
93
+ def validate_costs(profile: str, tolerance: float):
94
+ """Validate Cost Explorer data accuracy."""
95
+
96
+ console.print(Panel(
97
+ f"[bold cyan]Cost Explorer Validation[/bold cyan]\n"
98
+ f"Profile: {profile}\nTolerance: ±{tolerance}%",
99
+ title="Cost Validation"
100
+ ))
101
+
102
+ validator = MCPValidator(
103
+ profiles={'billing': profile},
104
+ tolerance_percentage=tolerance
105
+ )
106
+
107
+ try:
108
+ result = asyncio.run(validator.validate_cost_explorer())
109
+
110
+ # Display result
111
+ status_color = "green" if result.status == ValidationStatus.PASSED else "red"
112
+
113
+ table = Table(title="Cost Validation Result", box=box.ROUNDED)
114
+ table.add_column("Metric", style="cyan")
115
+ table.add_column("Value", style="bold")
116
+
117
+ table.add_row("Status", f"[{status_color}]{result.status.value}[/{status_color}]")
118
+ table.add_row("Accuracy", f"{result.accuracy_percentage:.2f}%")
119
+ table.add_row("Execution Time", f"{result.execution_time:.2f}s")
120
+ table.add_row("Timestamp", result.timestamp.strftime("%Y-%m-%d %H:%M:%S"))
121
+
122
+ if result.error_message:
123
+ table.add_row("Error", f"[red]{result.error_message}[/red]")
124
+
125
+ console.print(table)
126
+
127
+ # Variance details
128
+ if result.variance_details:
129
+ console.print(Panel(
130
+ f"Runbooks Total: {result.variance_details.get('details', {}).get('runbooks_total', 'N/A')}\n"
131
+ f"MCP Available: {result.variance_details.get('details', {}).get('mcp_available', 'N/A')}",
132
+ title="Variance Analysis"
133
+ ))
134
+
135
+ sys.exit(0 if result.status == ValidationStatus.PASSED else 1)
136
+
137
+ except Exception as e:
138
+ console.print(f"[bold red]Error validating costs: {e}[/bold red]")
139
+ sys.exit(3)
140
+
141
+ @cli.command()
142
+ @click.option('--profile', default='ams-admin-ReadOnlyAccess-909135376185', help='AWS management profile')
143
+ def validate_organizations(profile: str):
144
+ """Validate Organizations API data accuracy."""
145
+
146
+ console.print(Panel(
147
+ f"[bold cyan]Organizations Validation[/bold cyan]\n"
148
+ f"Profile: {profile}",
149
+ title="Organizations Validation"
150
+ ))
151
+
152
+ validator = MCPValidator(profiles={'management': profile})
153
+
154
+ try:
155
+ result = asyncio.run(validator.validate_organizations_data())
156
+
157
+ # Display result
158
+ status_color = "green" if result.status == ValidationStatus.PASSED else "red"
159
+
160
+ table = Table(title="Organizations Validation Result", box=box.ROUNDED)
161
+ table.add_column("Metric", style="cyan")
162
+ table.add_column("Value", style="bold")
163
+
164
+ table.add_row("Status", f"[{status_color}]{result.status.value}[/{status_color}]")
165
+ table.add_row("Accuracy", f"{result.accuracy_percentage:.2f}%")
166
+ table.add_row("Execution Time", f"{result.execution_time:.2f}s")
167
+
168
+ if result.variance_details:
169
+ details = result.variance_details.get('details', {})
170
+ table.add_row("Runbooks Accounts", str(details.get('runbooks_accounts', 'N/A')))
171
+ table.add_row("MCP Accounts", str(details.get('mcp_accounts', 'N/A')))
172
+
173
+ console.print(table)
174
+
175
+ sys.exit(0 if result.status == ValidationStatus.PASSED else 1)
176
+
177
+ except Exception as e:
178
+ console.print(f"[bold red]Error validating organizations: {e}[/bold red]")
179
+ sys.exit(3)
180
+
181
+ @cli.command()
182
+ @click.option('--target-accuracy', default=99.5, help='Target accuracy percentage')
183
+ @click.option('--iterations', default=5, help='Number of benchmark iterations')
184
+ @click.option('--performance-target', default=30.0, help='Performance target in seconds')
185
+ def benchmark(target_accuracy: float, iterations: int, performance_target: float):
186
+ """Run performance benchmark for MCP validation framework."""
187
+
188
+ console.print(Panel(
189
+ f"[bold magenta]MCP Validation Benchmark[/bold magenta]\n"
190
+ f"Target Accuracy: {target_accuracy}%\n"
191
+ f"Iterations: {iterations}\n"
192
+ f"Performance Target: <{performance_target}s",
193
+ title="Benchmark Suite"
194
+ ))
195
+
196
+ validator = MCPValidator(performance_target_seconds=performance_target)
197
+
198
+ results = []
199
+
200
+ try:
201
+ for i in range(iterations):
202
+ console.print(f"\n[bold cyan]Iteration {i+1}/{iterations}[/bold cyan]")
203
+
204
+ report = asyncio.run(validator.validate_all_operations())
205
+ results.append(report)
206
+
207
+ console.print(f"Accuracy: {report.overall_accuracy:.1f}% | "
208
+ f"Time: {report.execution_time:.1f}s | "
209
+ f"Passed: {report.passed_validations}/{report.total_validations}")
210
+
211
+ # Benchmark summary
212
+ avg_accuracy = sum(r.overall_accuracy for r in results) / len(results)
213
+ avg_time = sum(r.execution_time for r in results) / len(results)
214
+ success_rate = len([r for r in results if r.overall_accuracy >= target_accuracy]) / len(results) * 100
215
+
216
+ summary_table = Table(title="Benchmark Summary", box=box.ROUNDED)
217
+ summary_table.add_column("Metric", style="cyan")
218
+ summary_table.add_column("Value", style="bold")
219
+
220
+ summary_table.add_row("Average Accuracy", f"{avg_accuracy:.2f}%")
221
+ summary_table.add_row("Average Time", f"{avg_time:.2f}s")
222
+ summary_table.add_row("Success Rate", f"{success_rate:.1f}%")
223
+ summary_table.add_row("Target Met", "✅ YES" if avg_accuracy >= target_accuracy else "❌ NO")
224
+ summary_table.add_row("Performance Met", "✅ YES" if avg_time <= performance_target else "❌ NO")
225
+
226
+ console.print(summary_table)
227
+
228
+ # Performance analysis
229
+ if avg_accuracy >= target_accuracy and avg_time <= performance_target:
230
+ console.print("[bold green]🎯 Benchmark PASSED - Production ready[/bold green]")
231
+ sys.exit(0)
232
+ else:
233
+ console.print("[bold red]⚠️ Benchmark FAILED - Optimization needed[/bold red]")
234
+ sys.exit(1)
235
+
236
+ except Exception as e:
237
+ console.print(f"[bold red]Benchmark error: {e}[/bold red]")
238
+ sys.exit(3)
239
+
240
+ @cli.command()
241
+ @click.option('--operation',
242
+ type=click.Choice(['costs', 'organizations', 'ec2', 'security', 'vpc']),
243
+ help='Specific operation to validate')
244
+ @click.option('--profile', help='AWS profile to use')
245
+ @click.option('--tolerance', default=5.0, help='Tolerance percentage')
246
+ def validate_single(operation: str, profile: Optional[str], tolerance: float):
247
+ """Validate a single operation."""
248
+
249
+ console.print(Panel(
250
+ f"[bold cyan]Single Operation Validation[/bold cyan]\n"
251
+ f"Operation: {operation.title()}\n"
252
+ f"Profile: {profile or 'default'}\n"
253
+ f"Tolerance: ±{tolerance}%",
254
+ title="Single Validation"
255
+ ))
256
+
257
+ validator = MCPValidator(tolerance_percentage=tolerance)
258
+
259
+ try:
260
+ # Map operations to methods
261
+ operation_map = {
262
+ 'costs': validator.validate_cost_explorer,
263
+ 'organizations': validator.validate_organizations_data,
264
+ 'ec2': validator.validate_ec2_inventory,
265
+ 'security': validator.validate_security_baseline,
266
+ 'vpc': validator.validate_vpc_analysis
267
+ }
268
+
269
+ if operation not in operation_map:
270
+ console.print(f"[red]Unknown operation: {operation}[/red]")
271
+ sys.exit(1)
272
+
273
+ result = asyncio.run(operation_map[operation]())
274
+
275
+ # Display result
276
+ status_color = {
277
+ ValidationStatus.PASSED: "green",
278
+ ValidationStatus.WARNING: "yellow",
279
+ ValidationStatus.FAILED: "red",
280
+ ValidationStatus.ERROR: "red",
281
+ ValidationStatus.TIMEOUT: "red"
282
+ }[result.status]
283
+
284
+ table = Table(title=f"{operation.title()} Validation Result", box=box.ROUNDED)
285
+ table.add_column("Metric", style="cyan")
286
+ table.add_column("Value", style="bold")
287
+
288
+ table.add_row("Status", f"[{status_color}]{result.status.value}[/{status_color}]")
289
+ table.add_row("Accuracy", f"{result.accuracy_percentage:.2f}%")
290
+ table.add_row("Execution Time", f"{result.execution_time:.2f}s")
291
+ table.add_row("Timestamp", result.timestamp.strftime("%Y-%m-%d %H:%M:%S"))
292
+
293
+ if result.error_message:
294
+ table.add_row("Error", f"[red]{result.error_message}[/red]")
295
+
296
+ console.print(table)
297
+
298
+ sys.exit(0 if result.status == ValidationStatus.PASSED else 1)
299
+
300
+ except Exception as e:
301
+ console.print(f"[bold red]Error validating {operation}: {e}[/bold red]")
302
+ sys.exit(3)
303
+
304
+ @cli.command()
305
+ def status():
306
+ """Show MCP validation framework status."""
307
+
308
+ table = Table(title="MCP Validation Framework Status", box=box.ROUNDED)
309
+ table.add_column("Component", style="cyan")
310
+ table.add_column("Status", style="bold")
311
+ table.add_column("Details")
312
+
313
+ # Check MCP integration
314
+ try:
315
+ from notebooks.mcp_integration import MCPIntegrationManager
316
+ table.add_row("MCP Integration", "[green]✅ Available[/green]", "Ready for validation")
317
+ except ImportError:
318
+ table.add_row("MCP Integration", "[red]❌ Unavailable[/red]", "Install MCP dependencies")
319
+
320
+ # Check AWS profiles
321
+ profiles = [
322
+ 'ams-admin-Billing-ReadOnlyAccess-909135376185',
323
+ 'ams-admin-ReadOnlyAccess-909135376185',
324
+ 'ams-centralised-ops-ReadOnlyAccess-335083429030',
325
+ 'ams-shared-services-non-prod-ReadOnlyAccess-499201730520'
326
+ ]
327
+
328
+ for profile in profiles:
329
+ try:
330
+ import boto3
331
+ session = boto3.Session(profile_name=profile)
332
+ sts = session.client('sts')
333
+ identity = sts.get_caller_identity()
334
+ table.add_row(f"Profile: {profile[:20]}...", "[green]✅ Valid[/green]", f"Account: {identity['Account']}")
335
+ except Exception as e:
336
+ table.add_row(f"Profile: {profile[:20]}...", "[red]❌ Invalid[/red]", str(e)[:50])
337
+
338
+ # Check validation components
339
+ components = [
340
+ ('Cost Explorer', 'runbooks.finops'),
341
+ ('Organizations', 'runbooks.inventory'),
342
+ ('Security', 'runbooks.security'),
343
+ ('VPC Analysis', 'runbooks.vpc')
344
+ ]
345
+
346
+ for name, module in components:
347
+ try:
348
+ __import__(module)
349
+ table.add_row(f"Component: {name}", "[green]✅ Ready[/green]", "Module loaded")
350
+ except ImportError:
351
+ table.add_row(f"Component: {name}", "[red]❌ Missing[/red]", "Module not available")
352
+
353
+ console.print(table)
354
+
355
+ if __name__ == '__main__':
356
+ cli()