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
@@ -2,6 +2,7 @@
2
2
  Enterprise FinOps Platform - RunbooksWrapper
3
3
  Provides unified access to all runbooks CLI commands with MCP validation and Rich output
4
4
  """
5
+
5
6
  import subprocess
6
7
  import json
7
8
  import yaml
@@ -18,32 +19,33 @@ from rich import box
18
19
 
19
20
  console = Console()
20
21
 
22
+
21
23
  class RunbooksWrapper:
22
24
  """
23
25
  Enterprise wrapper for runbooks CLI commands with MCP validation and Rich output.
24
-
26
+
25
27
  Provides Jupyter-friendly interface to all runbooks functionality:
26
28
  - Inventory collection and analysis
27
- - FinOps cost analysis and optimization
29
+ - FinOps cost analysis and optimization
28
30
  - Security assessments and remediation
29
31
  - CFAT well-architected evaluations
30
32
  - Operations automation
31
33
  - Organization management
32
34
  """
33
-
35
+
34
36
  def __init__(self, default_profile: Optional[str] = None):
35
37
  """Initialize wrapper with optional default AWS profile."""
36
38
  self.default_profile = default_profile
37
39
  self.console = Console()
38
-
40
+
39
41
  def _execute_command(self, command: str, capture_output: bool = True) -> Dict[str, Any]:
40
42
  """
41
43
  Execute runbooks command with error handling and rich output.
42
-
44
+
43
45
  Args:
44
46
  command: Full runbooks command to execute
45
47
  capture_output: Whether to capture command output
46
-
48
+
47
49
  Returns:
48
50
  Dictionary with command result, output, and metadata
49
51
  """
@@ -55,74 +57,71 @@ class RunbooksWrapper:
55
57
  transient=True,
56
58
  ) as progress:
57
59
  progress.add_task(description="Executing command...", total=None)
58
-
60
+
59
61
  result = subprocess.run(
60
62
  command.split(),
61
63
  capture_output=capture_output,
62
64
  text=True,
63
- timeout=300 # 5 minute timeout
65
+ timeout=300, # 5 minute timeout
64
66
  )
65
-
67
+
66
68
  return {
67
69
  "success": result.returncode == 0,
68
70
  "returncode": result.returncode,
69
71
  "stdout": result.stdout,
70
72
  "stderr": result.stderr,
71
73
  "command": command,
72
- "timestamp": datetime.now().isoformat()
74
+ "timestamp": datetime.now().isoformat(),
73
75
  }
74
-
76
+
75
77
  except subprocess.TimeoutExpired:
76
78
  return {
77
79
  "success": False,
78
80
  "error": "Command timed out after 5 minutes",
79
81
  "command": command,
80
- "timestamp": datetime.now().isoformat()
82
+ "timestamp": datetime.now().isoformat(),
81
83
  }
82
84
  except Exception as e:
83
- return {
84
- "success": False,
85
- "error": str(e),
86
- "command": command,
87
- "timestamp": datetime.now().isoformat()
88
- }
89
-
85
+ return {"success": False, "error": str(e), "command": command, "timestamp": datetime.now().isoformat()}
86
+
90
87
  # Inventory Operations
91
- def inventory_collect(self,
92
- resources: List[str] = None,
93
- profile: str = None,
94
- all_accounts: bool = False,
95
- include_costs: bool = False,
96
- regions: List[str] = None) -> pd.DataFrame:
88
+ def inventory_collect(
89
+ self,
90
+ resources: List[str] = None,
91
+ profile: str = None,
92
+ all_accounts: bool = False,
93
+ include_costs: bool = False,
94
+ regions: List[str] = None,
95
+ ) -> pd.DataFrame:
97
96
  """
98
97
  Collect inventory across AWS accounts and services.
99
-
98
+
100
99
  Args:
101
100
  resources: List of AWS resources (ec2, s3, rds, lambda, etc.)
102
101
  profile: AWS profile to use
103
102
  all_accounts: Scan all accounts in organization
104
103
  include_costs: Include cost analysis
105
104
  regions: Specific regions to scan
106
-
105
+
107
106
  Returns:
108
107
  DataFrame with inventory results
109
108
  """
110
109
  cmd_parts = ["runbooks", "inventory", "collect"]
111
-
110
+
112
111
  if resources:
113
112
  cmd_parts.extend(["-r", ",".join(resources)])
114
113
  if profile or self.default_profile:
115
114
  cmd_parts.extend(["--profile", profile or self.default_profile])
116
115
  if all_accounts:
117
- cmd_parts.append("--all-accounts")
116
+ cmd_parts.append("--all-profiles")
118
117
  if include_costs:
119
118
  cmd_parts.append("--include-costs")
120
119
  if regions:
121
120
  cmd_parts.extend(["--regions", ",".join(regions)])
122
-
121
+
123
122
  command = " ".join(cmd_parts)
124
123
  result = self._execute_command(command)
125
-
124
+
126
125
  if result["success"]:
127
126
  try:
128
127
  # Parse JSON output to DataFrame
@@ -134,45 +133,49 @@ class RunbooksWrapper:
134
133
  console.print("[yellow]Warning: Could not parse JSON output, returning raw text[/yellow]")
135
134
  return pd.DataFrame({"output": [result["stdout"]]})
136
135
  else:
137
- console.print(f"[red]Error executing inventory command: {result.get('error', result.get('stderr', 'Unknown error'))}[/red]")
136
+ console.print(
137
+ f"[red]Error executing inventory command: {result.get('error', result.get('stderr', 'Unknown error'))}[/red]"
138
+ )
138
139
  return pd.DataFrame()
139
-
140
- # FinOps Operations
141
- def finops_analyze(self,
142
- profile: str = None,
143
- all_accounts: bool = False,
144
- target_reduction: str = "20-40%",
145
- breakdown_by: List[str] = None,
146
- export_format: str = "json") -> Dict[str, Any]:
140
+
141
+ # FinOps Operations
142
+ def finops_analyze(
143
+ self,
144
+ profile: str = None,
145
+ all_accounts: bool = False,
146
+ target_reduction: str = "20-40%",
147
+ breakdown_by: List[str] = None,
148
+ export_format: str = "json",
149
+ ) -> Dict[str, Any]:
147
150
  """
148
151
  Perform FinOps cost analysis and optimization recommendations.
149
-
152
+
150
153
  Args:
151
- profile: AWS billing profile
154
+ profile: AWS billing profile
152
155
  all_accounts: Analyze all accounts
153
156
  target_reduction: Target cost reduction percentage
154
157
  breakdown_by: Breakdown by service, account, region
155
158
  export_format: Export format (json, csv, html)
156
-
159
+
157
160
  Returns:
158
161
  Dictionary with cost analysis results
159
162
  """
160
163
  cmd_parts = ["runbooks", "finops", "--analyze"]
161
-
164
+
162
165
  if profile or self.default_profile:
163
166
  cmd_parts.extend(["--profile", profile or self.default_profile])
164
167
  if all_accounts:
165
- cmd_parts.append("--all-accounts")
168
+ cmd_parts.append("--all-profiles")
166
169
  if target_reduction:
167
170
  cmd_parts.extend(["--target-reduction", target_reduction])
168
171
  if breakdown_by:
169
172
  cmd_parts.extend(["--breakdown-by", ",".join(breakdown_by)])
170
173
  if export_format:
171
174
  cmd_parts.extend(["--export", export_format])
172
-
175
+
173
176
  command = " ".join(cmd_parts)
174
177
  result = self._execute_command(command)
175
-
178
+
176
179
  if result["success"]:
177
180
  try:
178
181
  data = json.loads(result["stdout"])
@@ -182,45 +185,49 @@ class RunbooksWrapper:
182
185
  console.print("[yellow]Warning: Could not parse JSON output[/yellow]")
183
186
  return {"raw_output": result["stdout"]}
184
187
  else:
185
- console.print(f"[red]Error executing FinOps analysis: {result.get('error', result.get('stderr', 'Unknown error'))}[/red]")
188
+ console.print(
189
+ f"[red]Error executing FinOps analysis: {result.get('error', result.get('stderr', 'Unknown error'))}[/red]"
190
+ )
186
191
  return {}
187
-
192
+
188
193
  # Security Operations
189
- def security_assess(self,
190
- profile: str = None,
191
- all_accounts: bool = False,
192
- checks: str = "all",
193
- language: str = "EN",
194
- format: str = "json") -> Dict[str, Any]:
194
+ def security_assess(
195
+ self,
196
+ profile: str = None,
197
+ all_accounts: bool = False,
198
+ checks: str = "all",
199
+ language: str = "EN",
200
+ format: str = "json",
201
+ ) -> Dict[str, Any]:
195
202
  """
196
203
  Perform security assessment across accounts.
197
-
204
+
198
205
  Args:
199
206
  profile: AWS profile to use
200
207
  all_accounts: Assess all accounts
201
208
  checks: Specific security checks or "all"
202
209
  language: Report language (EN, JP, KR, VN)
203
210
  format: Output format (json, html, csv)
204
-
211
+
205
212
  Returns:
206
213
  Dictionary with security assessment results
207
214
  """
208
215
  cmd_parts = ["runbooks", "security", "assess"]
209
-
216
+
210
217
  if profile or self.default_profile:
211
218
  cmd_parts.extend(["--profile", profile or self.default_profile])
212
219
  if all_accounts:
213
- cmd_parts.append("--all-accounts")
220
+ cmd_parts.append("--all-profiles")
214
221
  if checks:
215
222
  cmd_parts.extend(["--checks", checks])
216
223
  if language:
217
224
  cmd_parts.extend(["--language", language])
218
225
  if format:
219
226
  cmd_parts.extend(["--format", format])
220
-
227
+
221
228
  command = " ".join(cmd_parts)
222
229
  result = self._execute_command(command)
223
-
230
+
224
231
  if result["success"]:
225
232
  try:
226
233
  data = json.loads(result["stdout"])
@@ -229,31 +236,35 @@ class RunbooksWrapper:
229
236
  except json.JSONDecodeError:
230
237
  return {"raw_output": result["stdout"]}
231
238
  else:
232
- console.print(f"[red]Error executing security assessment: {result.get('error', result.get('stderr', 'Unknown error'))}[/red]")
239
+ console.print(
240
+ f"[red]Error executing security assessment: {result.get('error', result.get('stderr', 'Unknown error'))}[/red]"
241
+ )
233
242
  return {}
234
-
243
+
235
244
  # CFAT Operations
236
- def cfat_assess(self,
237
- profile: str = None,
238
- compliance_framework: str = "AWS Well-Architected",
239
- output_format: str = "json",
240
- serve_web: bool = False,
241
- port: int = 8080) -> Dict[str, Any]:
245
+ def cfat_assess(
246
+ self,
247
+ profile: str = None,
248
+ compliance_framework: str = "AWS Well-Architected",
249
+ output_format: str = "json",
250
+ serve_web: bool = False,
251
+ port: int = 8080,
252
+ ) -> Dict[str, Any]:
242
253
  """
243
254
  Perform Cloud Foundation Assessment Tool evaluation.
244
-
255
+
245
256
  Args:
246
257
  profile: AWS profile to use
247
258
  compliance_framework: Framework to assess against
248
259
  output_format: Output format
249
260
  serve_web: Start web server for results
250
261
  port: Web server port
251
-
262
+
252
263
  Returns:
253
264
  Dictionary with CFAT assessment results
254
265
  """
255
266
  cmd_parts = ["runbooks", "cfat", "assess"]
256
-
267
+
257
268
  if profile or self.default_profile:
258
269
  cmd_parts.extend(["--profile", profile or self.default_profile])
259
270
  if compliance_framework:
@@ -262,10 +273,10 @@ class RunbooksWrapper:
262
273
  cmd_parts.extend(["--output", output_format])
263
274
  if serve_web:
264
275
  cmd_parts.extend(["--serve-web", "--port", str(port)])
265
-
276
+
266
277
  command = " ".join(cmd_parts)
267
278
  result = self._execute_command(command)
268
-
279
+
269
280
  if result["success"]:
270
281
  try:
271
282
  data = json.loads(result["stdout"])
@@ -274,63 +285,69 @@ class RunbooksWrapper:
274
285
  except json.JSONDecodeError:
275
286
  return {"raw_output": result["stdout"]}
276
287
  else:
277
- console.print(f"[red]Error executing CFAT assessment: {result.get('error', result.get('stderr', 'Unknown error'))}[/red]")
288
+ console.print(
289
+ f"[red]Error executing CFAT assessment: {result.get('error', result.get('stderr', 'Unknown error'))}[/red]"
290
+ )
278
291
  return {}
279
-
292
+
280
293
  # Operations
281
- def operate_ec2(self, action: str, instance_ids: List[str], profile: str = None, dry_run: bool = True) -> Dict[str, Any]:
294
+ def operate_ec2(
295
+ self, action: str, instance_ids: List[str], profile: str = None, dry_run: bool = True
296
+ ) -> Dict[str, Any]:
282
297
  """
283
298
  Perform EC2 operations (start, stop, terminate).
284
-
299
+
285
300
  Args:
286
301
  action: Action to perform (start, stop, terminate)
287
302
  instance_ids: List of instance IDs
288
303
  profile: AWS profile to use
289
304
  dry_run: Perform dry run only
290
-
305
+
291
306
  Returns:
292
307
  Dictionary with operation results
293
308
  """
294
309
  cmd_parts = ["runbooks", "operate", "ec2", action]
295
310
  cmd_parts.extend(["--instance-ids"] + instance_ids)
296
-
311
+
297
312
  if profile or self.default_profile:
298
313
  cmd_parts.extend(["--profile", profile or self.default_profile])
299
314
  if dry_run:
300
315
  cmd_parts.append("--dry-run")
301
-
316
+
302
317
  command = " ".join(cmd_parts)
303
318
  result = self._execute_command(command)
304
-
319
+
305
320
  if result["success"]:
306
321
  console.print(f"[green]✅ EC2 {action} operation completed successfully[/green]")
307
322
  return {"success": True, "output": result["stdout"]}
308
323
  else:
309
- console.print(f"[red]❌ EC2 {action} operation failed: {result.get('error', result.get('stderr', 'Unknown error'))}[/red]")
324
+ console.print(
325
+ f"[red]❌ EC2 {action} operation failed: {result.get('error', result.get('stderr', 'Unknown error'))}[/red]"
326
+ )
310
327
  return {"success": False, "error": result.get("error", result.get("stderr"))}
311
-
328
+
312
329
  # Organization Management
313
330
  def org_list_ous(self, profile: str = None, output_format: str = "table") -> pd.DataFrame:
314
331
  """
315
332
  List organizational units in AWS Organizations.
316
-
333
+
317
334
  Args:
318
335
  profile: AWS management profile
319
336
  output_format: Output format (table, json)
320
-
337
+
321
338
  Returns:
322
339
  DataFrame with OU information
323
340
  """
324
341
  cmd_parts = ["runbooks", "org", "list-ous"]
325
-
342
+
326
343
  if profile or self.default_profile:
327
344
  cmd_parts.extend(["--profile", profile or self.default_profile])
328
345
  if output_format:
329
346
  cmd_parts.extend(["--output", output_format])
330
-
347
+
331
348
  command = " ".join(cmd_parts)
332
349
  result = self._execute_command(command)
333
-
350
+
334
351
  if result["success"]:
335
352
  try:
336
353
  if output_format == "json":
@@ -345,26 +362,26 @@ class RunbooksWrapper:
345
362
  else:
346
363
  console.print(f"[red]Error listing OUs: {result.get('error', result.get('stderr', 'Unknown error'))}[/red]")
347
364
  return pd.DataFrame()
348
-
365
+
349
366
  # MCP Validation
350
367
  def validate_mcp_servers(self, billing_profile: str = None) -> Dict[str, Any]:
351
368
  """
352
369
  Validate MCP servers connectivity and accuracy.
353
-
370
+
354
371
  Args:
355
372
  billing_profile: Billing profile for validation
356
-
373
+
357
374
  Returns:
358
375
  Dictionary with validation results
359
376
  """
360
377
  cmd_parts = ["runbooks", "validate", "mcp-servers"]
361
-
378
+
362
379
  if billing_profile or self.default_profile:
363
380
  cmd_parts.extend(["--billing-profile", billing_profile or self.default_profile])
364
-
381
+
365
382
  command = " ".join(cmd_parts)
366
383
  result = self._execute_command(command)
367
-
384
+
368
385
  if result["success"]:
369
386
  try:
370
387
  data = json.loads(result["stdout"])
@@ -373,53 +390,51 @@ class RunbooksWrapper:
373
390
  except json.JSONDecodeError:
374
391
  return {"raw_output": result["stdout"]}
375
392
  else:
376
- console.print(f"[red]Error validating MCP servers: {result.get('error', result.get('stderr', 'Unknown error'))}[/red]")
393
+ console.print(
394
+ f"[red]Error validating MCP servers: {result.get('error', result.get('stderr', 'Unknown error'))}[/red]"
395
+ )
377
396
  return {}
378
-
397
+
379
398
  # Rich Display Methods
380
399
  def _display_inventory_summary(self, df: pd.DataFrame):
381
400
  """Display inventory results summary with Rich formatting."""
382
401
  if df.empty:
383
402
  console.print("[yellow]No inventory data to display[/yellow]")
384
403
  return
385
-
404
+
386
405
  table = Table(title="📊 Inventory Summary", box=box.ROUNDED)
387
406
  table.add_column("Metric", style="cyan")
388
407
  table.add_column("Count", justify="right", style="green")
389
-
408
+
390
409
  total_resources = len(df)
391
410
  resource_types = df.get("ResourceType", pd.Series()).nunique() if "ResourceType" in df.columns else 0
392
411
  accounts = df.get("AccountId", pd.Series()).nunique() if "AccountId" in df.columns else 0
393
-
412
+
394
413
  table.add_row("Total Resources", str(total_resources))
395
414
  table.add_row("Resource Types", str(resource_types))
396
415
  table.add_row("AWS Accounts", str(accounts))
397
-
416
+
398
417
  console.print(table)
399
-
418
+
400
419
  def _display_finops_summary(self, data: Dict[str, Any]):
401
420
  """Display FinOps analysis summary with Rich formatting."""
402
421
  panel_content = []
403
-
422
+
404
423
  if "total_cost" in data:
405
424
  panel_content.append(f"💰 Total Monthly Cost: ${data['total_cost']:,.2f}")
406
425
  if "potential_savings" in data:
407
426
  panel_content.append(f"💸 Potential Savings: ${data['potential_savings']:,.2f}")
408
427
  if "optimization_recommendations" in data:
409
428
  panel_content.append(f"📋 Recommendations: {len(data['optimization_recommendations'])}")
410
-
429
+
411
430
  content = "\n".join(panel_content) if panel_content else "FinOps analysis completed"
412
-
413
- console.print(Panel(
414
- content,
415
- title="💰 FinOps Analysis Summary",
416
- border_style="green"
417
- ))
418
-
431
+
432
+ console.print(Panel(content, title="💰 FinOps Analysis Summary", border_style="green"))
433
+
419
434
  def _display_security_summary(self, data: Dict[str, Any]):
420
435
  """Display security assessment summary with Rich formatting."""
421
436
  panel_content = []
422
-
437
+
423
438
  if "total_checks" in data:
424
439
  panel_content.append(f"🔍 Total Checks: {data['total_checks']}")
425
440
  if "passed_checks" in data:
@@ -428,51 +443,39 @@ class RunbooksWrapper:
428
443
  panel_content.append(f"❌ Failed: {data['failed_checks']}")
429
444
  if "compliance_score" in data:
430
445
  panel_content.append(f"📊 Compliance Score: {data['compliance_score']}%")
431
-
446
+
432
447
  content = "\n".join(panel_content) if panel_content else "Security assessment completed"
433
-
434
- console.print(Panel(
435
- content,
436
- title="🔒 Security Assessment Summary",
437
- border_style="red"
438
- ))
439
-
448
+
449
+ console.print(Panel(content, title="🔒 Security Assessment Summary", border_style="red"))
450
+
440
451
  def _display_cfat_summary(self, data: Dict[str, Any]):
441
452
  """Display CFAT assessment summary with Rich formatting."""
442
453
  panel_content = []
443
-
454
+
444
455
  if "well_architected_score" in data:
445
456
  panel_content.append(f"🏗️ Well-Architected Score: {data['well_architected_score']}%")
446
457
  if "pillars_assessed" in data:
447
458
  panel_content.append(f"📋 Pillars Assessed: {len(data['pillars_assessed'])}")
448
459
  if "high_risk_findings" in data:
449
460
  panel_content.append(f"⚠️ High Risk Findings: {data['high_risk_findings']}")
450
-
461
+
451
462
  content = "\n".join(panel_content) if panel_content else "CFAT assessment completed"
452
-
453
- console.print(Panel(
454
- content,
455
- title="🏗️ CFAT Assessment Summary",
456
- border_style="blue"
457
- ))
458
-
463
+
464
+ console.print(Panel(content, title="🏗️ CFAT Assessment Summary", border_style="blue"))
465
+
459
466
  def _display_mcp_validation_summary(self, data: Dict[str, Any]):
460
467
  """Display MCP validation summary with Rich formatting."""
461
468
  panel_content = []
462
-
469
+
463
470
  if "accuracy_rate" in data:
464
471
  panel_content.append(f"🎯 Accuracy Rate: {data['accuracy_rate']}%")
465
472
  if "servers_validated" in data:
466
473
  panel_content.append(f"🖥️ Servers Validated: {data['servers_validated']}")
467
474
  if "validation_time" in data:
468
475
  panel_content.append(f"⏱️ Validation Time: {data['validation_time']}s")
469
-
476
+
470
477
  content = "\n".join(panel_content) if panel_content else "MCP validation completed"
471
-
478
+
472
479
  color = "green" if data.get("accuracy_rate", 0) >= 99.5 else "yellow"
473
-
474
- console.print(Panel(
475
- content,
476
- title="🔍 MCP Validation Summary",
477
- border_style=color
478
- ))
480
+
481
+ console.print(Panel(content, title="🔍 MCP Validation Summary", border_style=color))