runbooks 0.7.9__py3-none-any.whl → 0.9.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.
Files changed (122) hide show
  1. runbooks/__init__.py +1 -1
  2. runbooks/cfat/README.md +12 -1
  3. runbooks/cfat/__init__.py +1 -1
  4. runbooks/cfat/assessment/compliance.py +4 -1
  5. runbooks/cfat/assessment/runner.py +42 -34
  6. runbooks/cfat/models.py +1 -1
  7. runbooks/cloudops/__init__.py +123 -0
  8. runbooks/cloudops/base.py +385 -0
  9. runbooks/cloudops/cost_optimizer.py +811 -0
  10. runbooks/cloudops/infrastructure_optimizer.py +29 -0
  11. runbooks/cloudops/interfaces.py +828 -0
  12. runbooks/cloudops/lifecycle_manager.py +29 -0
  13. runbooks/cloudops/mcp_cost_validation.py +678 -0
  14. runbooks/cloudops/models.py +251 -0
  15. runbooks/cloudops/monitoring_automation.py +29 -0
  16. runbooks/cloudops/notebook_framework.py +676 -0
  17. runbooks/cloudops/security_enforcer.py +449 -0
  18. runbooks/common/__init__.py +152 -0
  19. runbooks/common/accuracy_validator.py +1039 -0
  20. runbooks/common/context_logger.py +440 -0
  21. runbooks/common/cross_module_integration.py +594 -0
  22. runbooks/common/enhanced_exception_handler.py +1108 -0
  23. runbooks/common/enterprise_audit_integration.py +634 -0
  24. runbooks/common/mcp_cost_explorer_integration.py +900 -0
  25. runbooks/common/mcp_integration.py +548 -0
  26. runbooks/common/performance_monitor.py +387 -0
  27. runbooks/common/profile_utils.py +216 -0
  28. runbooks/common/rich_utils.py +172 -1
  29. runbooks/feedback/user_feedback_collector.py +440 -0
  30. runbooks/finops/README.md +377 -458
  31. runbooks/finops/__init__.py +4 -21
  32. runbooks/finops/account_resolver.py +279 -0
  33. runbooks/finops/accuracy_cross_validator.py +638 -0
  34. runbooks/finops/aws_client.py +721 -36
  35. runbooks/finops/budget_integration.py +313 -0
  36. runbooks/finops/cli.py +59 -5
  37. runbooks/finops/cost_optimizer.py +1340 -0
  38. runbooks/finops/cost_processor.py +211 -37
  39. runbooks/finops/dashboard_router.py +900 -0
  40. runbooks/finops/dashboard_runner.py +990 -232
  41. runbooks/finops/embedded_mcp_validator.py +288 -0
  42. runbooks/finops/enhanced_dashboard_runner.py +8 -7
  43. runbooks/finops/enhanced_progress.py +327 -0
  44. runbooks/finops/enhanced_trend_visualization.py +423 -0
  45. runbooks/finops/finops_dashboard.py +184 -1829
  46. runbooks/finops/helpers.py +509 -196
  47. runbooks/finops/iam_guidance.py +400 -0
  48. runbooks/finops/markdown_exporter.py +466 -0
  49. runbooks/finops/multi_dashboard.py +1502 -0
  50. runbooks/finops/optimizer.py +15 -15
  51. runbooks/finops/profile_processor.py +2 -2
  52. runbooks/finops/runbooks.inventory.organizations_discovery.log +0 -0
  53. runbooks/finops/runbooks.security.report_generator.log +0 -0
  54. runbooks/finops/runbooks.security.run_script.log +0 -0
  55. runbooks/finops/runbooks.security.security_export.log +0 -0
  56. runbooks/finops/schemas.py +589 -0
  57. runbooks/finops/service_mapping.py +195 -0
  58. runbooks/finops/single_dashboard.py +710 -0
  59. runbooks/finops/tests/test_reference_images_validation.py +1 -1
  60. runbooks/inventory/README.md +12 -1
  61. runbooks/inventory/core/collector.py +157 -29
  62. runbooks/inventory/list_ec2_instances.py +9 -6
  63. runbooks/inventory/list_ssm_parameters.py +10 -10
  64. runbooks/inventory/organizations_discovery.py +210 -164
  65. runbooks/inventory/rich_inventory_display.py +74 -107
  66. runbooks/inventory/run_on_multi_accounts.py +13 -13
  67. runbooks/inventory/runbooks.inventory.organizations_discovery.log +0 -0
  68. runbooks/inventory/runbooks.security.security_export.log +0 -0
  69. runbooks/main.py +1371 -240
  70. runbooks/metrics/dora_metrics_engine.py +711 -17
  71. runbooks/monitoring/performance_monitor.py +433 -0
  72. runbooks/operate/README.md +394 -0
  73. runbooks/operate/base.py +215 -47
  74. runbooks/operate/ec2_operations.py +435 -5
  75. runbooks/operate/iam_operations.py +598 -3
  76. runbooks/operate/privatelink_operations.py +1 -1
  77. runbooks/operate/rds_operations.py +508 -0
  78. runbooks/operate/s3_operations.py +508 -0
  79. runbooks/operate/vpc_endpoints.py +1 -1
  80. runbooks/remediation/README.md +489 -13
  81. runbooks/remediation/base.py +5 -3
  82. runbooks/remediation/commons.py +8 -4
  83. runbooks/security/ENTERPRISE_SECURITY_FRAMEWORK.md +506 -0
  84. runbooks/security/README.md +12 -1
  85. runbooks/security/__init__.py +265 -33
  86. runbooks/security/cloudops_automation_security_validator.py +1164 -0
  87. runbooks/security/compliance_automation.py +12 -10
  88. runbooks/security/compliance_automation_engine.py +1021 -0
  89. runbooks/security/enterprise_security_framework.py +930 -0
  90. runbooks/security/enterprise_security_policies.json +293 -0
  91. runbooks/security/executive_security_dashboard.py +1247 -0
  92. runbooks/security/integration_test_enterprise_security.py +879 -0
  93. runbooks/security/module_security_integrator.py +641 -0
  94. runbooks/security/multi_account_security_controls.py +2254 -0
  95. runbooks/security/real_time_security_monitor.py +1196 -0
  96. runbooks/security/report_generator.py +1 -1
  97. runbooks/security/run_script.py +4 -8
  98. runbooks/security/security_baseline_tester.py +39 -52
  99. runbooks/security/security_export.py +99 -120
  100. runbooks/sre/README.md +472 -0
  101. runbooks/sre/__init__.py +33 -0
  102. runbooks/sre/mcp_reliability_engine.py +1049 -0
  103. runbooks/sre/performance_optimization_engine.py +1032 -0
  104. runbooks/sre/production_monitoring_framework.py +584 -0
  105. runbooks/sre/reliability_monitoring_framework.py +1011 -0
  106. runbooks/validation/__init__.py +2 -2
  107. runbooks/validation/benchmark.py +154 -149
  108. runbooks/validation/cli.py +159 -147
  109. runbooks/validation/mcp_validator.py +291 -248
  110. runbooks/vpc/README.md +478 -0
  111. runbooks/vpc/__init__.py +2 -2
  112. runbooks/vpc/manager_interface.py +366 -351
  113. runbooks/vpc/networking_wrapper.py +68 -36
  114. runbooks/vpc/rich_formatters.py +22 -8
  115. runbooks-0.9.1.dist-info/METADATA +308 -0
  116. {runbooks-0.7.9.dist-info → runbooks-0.9.1.dist-info}/RECORD +120 -59
  117. {runbooks-0.7.9.dist-info → runbooks-0.9.1.dist-info}/entry_points.txt +1 -1
  118. runbooks/finops/cross_validation.py +0 -375
  119. runbooks-0.7.9.dist-info/METADATA +0 -636
  120. {runbooks-0.7.9.dist-info → runbooks-0.9.1.dist-info}/WHEEL +0 -0
  121. {runbooks-0.7.9.dist-info → runbooks-0.9.1.dist-info}/licenses/LICENSE +0 -0
  122. {runbooks-0.7.9.dist-info → runbooks-0.9.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,400 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Enhanced Exception Handling with IAM/SSO Role Requirements
4
+ Enterprise-grade error messaging with actionable guidance for AWS permissions.
5
+ """
6
+
7
+ import re
8
+ from typing import Dict, List, Optional
9
+
10
+ from rich.console import Console
11
+ from rich.panel import Panel
12
+ from rich.table import Table
13
+
14
+ console = Console()
15
+
16
+
17
+ class EnterpriseIAMGuidance:
18
+ """Provides clear IAM/SSO role requirements and troubleshooting guidance."""
19
+
20
+ # AWS API Permission Requirements for Runbooks Operations
21
+ # ANY AWS profile needs these specific API permissions to run runbooks commands
22
+ RUNBOOKS_API_REQUIREMENTS = {
23
+ # FinOps Operations
24
+ "ce:GetCostAndUsage": {
25
+ "purpose": "Retrieve cost and usage data from Cost Explorer",
26
+ "functionality_impact": "Cost analysis, spending trends, budget reports",
27
+ "command_impact": "runbooks finops (dashboard, trend analysis)",
28
+ "aws_managed_policies": ["AWBillingReadOnlyAccess", "AWCostExplorerServiceRolePolicy"],
29
+ },
30
+ "budgets:ViewBudget": {
31
+ "purpose": "Access budget information and alerts",
32
+ "functionality_impact": "Budget status, alerts, spending limits",
33
+ "command_impact": "runbooks finops (budget dashboard)",
34
+ "aws_managed_policies": ["AWBillingReadOnlyAccess"],
35
+ },
36
+ # Resource Discovery Operations
37
+ "ec2:DescribeInstances": {
38
+ "purpose": "List and describe EC2 instances",
39
+ "functionality_impact": "Instance inventory, cost allocation, resource optimization",
40
+ "command_impact": "runbooks inventory, runbooks operate ec2",
41
+ "aws_managed_policies": ["ReadOnlyAccess", "EC2ReadOnlyAccess"],
42
+ },
43
+ "ec2:DescribeRegions": {
44
+ "purpose": "List available AWS regions",
45
+ "functionality_impact": "Multi-region resource discovery",
46
+ "command_impact": "runbooks inventory (region scanning)",
47
+ "aws_managed_policies": ["ReadOnlyAccess"],
48
+ },
49
+ "sts:GetCallerIdentity": {
50
+ "purpose": "Retrieve AWS account ID and user information",
51
+ "functionality_impact": "Account verification, audit trails",
52
+ "command_impact": "All runbooks commands (account identification)",
53
+ "aws_managed_policies": ["ReadOnlyAccess"],
54
+ },
55
+ "ec2:DescribeVolumes": {
56
+ "purpose": "List and describe EBS volumes",
57
+ "functionality_impact": "Storage cost analysis, orphaned volume detection",
58
+ "command_impact": "runbooks inventory, runbooks operate ebs",
59
+ "aws_managed_policies": ["ReadOnlyAccess", "EC2ReadOnlyAccess"],
60
+ },
61
+ "ec2:DescribeAddresses": {
62
+ "purpose": "List elastic IP addresses",
63
+ "functionality_impact": "IP cost optimization, unused resource detection",
64
+ "command_impact": "runbooks inventory, runbooks operate eip",
65
+ "aws_managed_policies": ["ReadOnlyAccess", "EC2ReadOnlyAccess"],
66
+ },
67
+ "rds:DescribeDBInstances": {
68
+ "purpose": "List and describe RDS database instances",
69
+ "functionality_impact": "Database cost analysis, resource optimization",
70
+ "command_impact": "runbooks inventory, runbooks operate rds",
71
+ "aws_managed_policies": ["ReadOnlyAccess", "RDSReadOnlyAccess"],
72
+ },
73
+ "rds:ListTagsForResource": {
74
+ "purpose": "Retrieve tags for RDS resources",
75
+ "functionality_impact": "Cost allocation, compliance tracking",
76
+ "command_impact": "runbooks inventory (tag-based filtering)",
77
+ "aws_managed_policies": ["ReadOnlyAccess", "RDSReadOnlyAccess"],
78
+ },
79
+ "lambda:ListFunctions": {
80
+ "purpose": "List Lambda functions",
81
+ "functionality_impact": "Serverless cost analysis, function inventory",
82
+ "command_impact": "runbooks inventory, runbooks operate lambda",
83
+ "aws_managed_policies": ["ReadOnlyAccess", "AWSLambda_ReadOnlyAccess"],
84
+ },
85
+ "lambda:ListTags": {
86
+ "purpose": "Retrieve tags for Lambda functions",
87
+ "functionality_impact": "Cost allocation, resource organization",
88
+ "command_impact": "runbooks inventory (Lambda tag analysis)",
89
+ "aws_managed_policies": ["ReadOnlyAccess", "AWSLambda_ReadOnlyAccess"],
90
+ },
91
+ "elbv2:DescribeLoadBalancers": {
92
+ "purpose": "List and describe Application Load Balancers",
93
+ "functionality_impact": "Load balancer cost analysis, traffic optimization",
94
+ "command_impact": "runbooks inventory, runbooks operate alb",
95
+ "aws_managed_policies": ["ReadOnlyAccess", "ElasticLoadBalancingReadOnly"],
96
+ },
97
+ "elbv2:DescribeTags": {
98
+ "purpose": "Retrieve tags for load balancers",
99
+ "functionality_impact": "Cost allocation, compliance tracking",
100
+ "command_impact": "runbooks inventory (ALB tag analysis)",
101
+ "aws_managed_policies": ["ReadOnlyAccess", "ElasticLoadBalancingReadOnly"],
102
+ },
103
+ }
104
+
105
+ @staticmethod
106
+ def parse_aws_error(error_message: str) -> Dict[str, str]:
107
+ """Parse AWS error message to extract key components."""
108
+
109
+ # Extract permission that was denied
110
+ permission_match = re.search(r"perform: ([a-zA-Z0-9:*]+)", str(error_message))
111
+ permission_denied = permission_match.group(1) if permission_match else "Unknown"
112
+
113
+ # Extract resource ARN
114
+ resource_match = re.search(r"resource: (arn:aws:[^)]+)", str(error_message))
115
+ resource_arn = resource_match.group(1) if resource_match else "Unknown"
116
+
117
+ # Extract user ARN
118
+ user_match = re.search(r"User: (arn:aws:sts::[^)]+)", str(error_message))
119
+ user_arn = user_match.group(1) if user_match else "Unknown"
120
+
121
+ # Determine error type
122
+ if "AccessDeniedException" in str(error_message):
123
+ error_type = "Access Denied"
124
+ elif "UnauthorizedOperation" in str(error_message):
125
+ error_type = "Unauthorized Operation"
126
+ elif "Token has expired" in str(error_message):
127
+ error_type = "SSO Token Expired"
128
+ else:
129
+ error_type = "Permission Error"
130
+
131
+ return {
132
+ "error_type": error_type,
133
+ "permission_denied": permission_denied,
134
+ "resource_arn": resource_arn,
135
+ "user_arn": user_arn,
136
+ }
137
+
138
+ @classmethod
139
+ def get_permission_guidance(cls, permission_denied: str) -> Optional[Dict]:
140
+ """Get specific guidance for the denied AWS API permission."""
141
+
142
+ # Direct permission match
143
+ if permission_denied in cls.RUNBOOKS_API_REQUIREMENTS:
144
+ return cls.RUNBOOKS_API_REQUIREMENTS[permission_denied]
145
+
146
+ # Pattern matching for wildcard permissions (e.g., ec2:Describe* matches ec2:DescribeInstances)
147
+ for api_permission, config in cls.RUNBOOKS_API_REQUIREMENTS.items():
148
+ permission_prefix = api_permission.split(":")[0]
149
+ denied_prefix = permission_denied.split(":")[0]
150
+
151
+ if permission_prefix == denied_prefix:
152
+ # Same service, likely related permission
153
+ return config
154
+
155
+ return None
156
+
157
+ @classmethod
158
+ def display_enhanced_error(cls, error: Exception, operation_context: str = "runbooks operation"):
159
+ """Display enterprise-grade error message with actionable guidance."""
160
+
161
+ error_details = cls.parse_aws_error(str(error))
162
+ permission_guidance = cls.get_permission_guidance(error_details["permission_denied"])
163
+
164
+ # Create main error panel
165
+ error_panel = Panel(
166
+ f"[red]❌ {error_details['error_type']}: {error_details['permission_denied']}[/red]\n\n"
167
+ f"[yellow]Operation:[/yellow] {operation_context}\n"
168
+ f"[yellow]Resource:[/yellow] {error_details['resource_arn']}\n"
169
+ f"[yellow]User:[/yellow] {error_details['user_arn']}",
170
+ title="🚨 AWS Permission Error",
171
+ border_style="red",
172
+ )
173
+ console.print(error_panel)
174
+
175
+ # Display specific guidance if available
176
+ if permission_guidance:
177
+ cls._display_permission_requirements(error_details["permission_denied"], permission_guidance)
178
+ else:
179
+ cls._display_general_guidance(error_details["permission_denied"])
180
+
181
+ # Display troubleshooting steps
182
+ cls._display_troubleshooting_steps(error_details["error_type"])
183
+
184
+ @classmethod
185
+ def _display_permission_requirements(cls, permission_denied: str, permission_config: Dict):
186
+ """Display specific AWS API permission requirements and impact."""
187
+
188
+ # Permission impact table
189
+ impact_table = Table(title=f"📋 AWS API Permission Analysis: {permission_denied}")
190
+ impact_table.add_column("Aspect", style="bold cyan")
191
+ impact_table.add_column("Details", style="white")
192
+
193
+ impact_table.add_row("Permission", permission_denied)
194
+ impact_table.add_row("Purpose", permission_config["purpose"])
195
+ impact_table.add_row("Functionality Impact", permission_config["functionality_impact"])
196
+ impact_table.add_row("Affected Commands", permission_config["command_impact"])
197
+
198
+ console.print(impact_table)
199
+
200
+ # Solution panel
201
+ solution_panel = Panel(
202
+ f"[green]✅ IAM/SSO Configuration Required:[/green]\n\n"
203
+ f"1. **Required Permission**: `{permission_denied}`\n"
204
+ f"2. **Add to IAM Policy**: Include this permission in your IAM role/policy\n"
205
+ f"3. **SSO Configuration**: Ensure your SSO role includes this permission\n"
206
+ f"4. **SCP Compliance**: Verify Service Control Policies don't deny this permission\n\n"
207
+ f"[bold]AWS Managed Policies (containing this permission):[/bold]\n"
208
+ + "\n".join([f"• {policy}" for policy in permission_config["aws_managed_policies"]]),
209
+ title="🔧 Permission Resolution Guidance",
210
+ border_style="green",
211
+ )
212
+ console.print(solution_panel)
213
+
214
+ @classmethod
215
+ def _display_general_guidance(cls, permission_denied: str):
216
+ """Display general IAM guidance for unknown permissions."""
217
+
218
+ guidance_panel = Panel(
219
+ f"[yellow]⚠️ Permission Required: {permission_denied}[/yellow]\n\n"
220
+ f"[bold]General Resolution Steps:[/bold]\n"
221
+ f"• **IAM Policy**: Add `{permission_denied}` to your IAM role/policy\n"
222
+ f"• **SSO Role**: Ensure your AWS SSO role includes this permission\n"
223
+ f"• **SCP Review**: Check Service Control Policies don't deny this permission\n"
224
+ f"• **Resource Policy**: Verify resource-based policies allow access\n"
225
+ f"• **Console Test**: Test this permission via AWS Console first\n\n"
226
+ f"[bold]Common Solutions:[/bold]\n"
227
+ f"• Attach AWS managed policy: `ReadOnlyAccess`\n"
228
+ f"• Create custom policy with this specific permission\n"
229
+ f"• Contact your AWS administrator for permission escalation",
230
+ title="📋 Permission Resolution Guidance",
231
+ border_style="yellow",
232
+ )
233
+ console.print(guidance_panel)
234
+
235
+ @classmethod
236
+ def _display_troubleshooting_steps(cls, error_type: str):
237
+ """Display troubleshooting steps based on error type."""
238
+
239
+ if error_type == "SSO Token Expired":
240
+ troubleshooting = (
241
+ "[bold]🔄 SSO Token Refresh Steps:[/bold]\n"
242
+ "1. Run: `aws sso login --profile your-profile-name`\n"
243
+ "2. Follow browser authentication flow\n"
244
+ "3. Retry the runbooks operation\n"
245
+ "4. Consider extending SSO session duration in AWS SSO settings"
246
+ )
247
+ else:
248
+ troubleshooting = (
249
+ "[bold]🛠️ Permission Resolution Steps:[/bold]\n"
250
+ "1. **Verify Profile**: Check `aws sts get-caller-identity --profile your-profile`\n"
251
+ "2. **Review IAM Policy**: Ensure your role has the required permission\n"
252
+ "3. **Check SCP**: Verify Service Control Policies allow this action\n"
253
+ "4. **Test Console Access**: Try the same operation in AWS Console\n"
254
+ "5. **Contact Administrator**: Request IAM policy update with required permission"
255
+ )
256
+
257
+ troubleshoot_panel = Panel(troubleshooting, title="🔧 Next Steps", border_style="blue")
258
+ console.print(troubleshoot_panel)
259
+
260
+ @classmethod
261
+ def display_runbooks_permission_requirements(cls):
262
+ """Display complete runbooks AWS API permission requirements."""
263
+
264
+ matrix_table = Table(title="🔧 Runbooks AWS API Permission Requirements")
265
+ matrix_table.add_column("AWS API Permission", style="bold cyan")
266
+ matrix_table.add_column("Purpose", style="white")
267
+ matrix_table.add_column("Affected Commands", style="green")
268
+ matrix_table.add_column("AWS Managed Policy", style="yellow")
269
+
270
+ for permission, config in cls.RUNBOOKS_API_REQUIREMENTS.items():
271
+ policies = ", ".join(config["aws_managed_policies"][:2]) + (
272
+ "..." if len(config["aws_managed_policies"]) > 2 else ""
273
+ )
274
+ matrix_table.add_row(permission, config["purpose"], config["command_impact"], policies)
275
+
276
+ console.print(matrix_table)
277
+
278
+ # Enterprise guidance
279
+ enterprise_panel = Panel(
280
+ "[bold]🎯 IAM Configuration Best Practices:[/bold]\n\n"
281
+ "• **Any AWS Profile**: Requires these specific API permissions to run runbooks\n"
282
+ "• **SSO Integration**: Configure SSO roles with required permissions\n"
283
+ "• **SCP Compliance**: Ensure Service Control Policies don't deny these permissions\n\n"
284
+ "[bold]🔒 Security Notes:[/bold]\n"
285
+ "• All permissions are ReadOnly - no destructive operations possible\n"
286
+ "• Permissions follow least-privilege principle\n"
287
+ "• IAM policies can be customized based on specific runbooks usage",
288
+ title="🔧 Runbooks Permission Configuration",
289
+ border_style="cyan",
290
+ )
291
+ console.print(enterprise_panel)
292
+
293
+
294
+ # Enhanced Cost Explorer Error Handling for Single Account Scenarios
295
+ def handle_cost_explorer_error(error: Exception, profile_name: Optional[str] = None):
296
+ """
297
+ Handle Cost Explorer specific errors with context-aware guidance for single accounts.
298
+
299
+ Provides enhanced error messaging that explains why single accounts typically
300
+ don't have Cost Explorer access and suggests practical solutions.
301
+ """
302
+ error_str = str(error)
303
+
304
+ # Check if this is a single account Cost Explorer access issue
305
+ if ("AccessDeniedException" in error_str or "explicitly denied" in error_str) and "ce:GetCostAndUsage" in error_str:
306
+ _display_single_account_cost_explorer_guidance(error, profile_name)
307
+ else:
308
+ # Fall back to general IAM guidance
309
+ EnterpriseIAMGuidance.display_enhanced_error(error, "runbooks finops operation (Cost Explorer API)")
310
+
311
+
312
+ def _display_single_account_cost_explorer_guidance(error: Exception, profile_name: Optional[str] = None):
313
+ """Display context-aware guidance for single account Cost Explorer limitations."""
314
+
315
+ # Main explanation panel
316
+ explanation_panel = Panel(
317
+ "[yellow]ℹ️ Cost Explorer Access Limitation[/yellow]\n\n"
318
+ "[bold]What's happening:[/bold]\n"
319
+ "• Individual AWS accounts often don't have Cost Explorer API permissions\n"
320
+ "• Cost Explorer is typically accessible through the billing/payer account\n"
321
+ "• This is expected behavior for member accounts in AWS Organizations\n\n"
322
+ "[bold]Why this occurs:[/bold]\n"
323
+ "• Cost Explorer requires specific billing permissions\n"
324
+ "• Member accounts may not have consolidated billing access\n"
325
+ "• Service Control Policies (SCPs) may restrict Cost Explorer access",
326
+ title="🔍 Single Account Cost Explorer Context",
327
+ border_style="yellow",
328
+ )
329
+ console.print(explanation_panel)
330
+
331
+ # Solution panel with actionable guidance
332
+ if profile_name:
333
+ profile_text = f"your current profile `{profile_name}`"
334
+ solution_commands = f"""[bold]Option 1: Use Billing Profile (Recommended)[/bold]
335
+ • Set environment variable: `export BILLING_PROFILE="your-billing-profile-name"`
336
+ • Run: `runbooks finops --profile your-billing-profile-name`
337
+
338
+ [bold]Option 2: Use Your Current Profile for Resource Analysis[/bold]
339
+ • Current profile: `{profile_name}`
340
+ • Resource discovery will work, but cost data will be limited
341
+ • Consider using: `runbooks inventory collect --profile {profile_name}`"""
342
+ else:
343
+ profile_text = "your current profile"
344
+ solution_commands = """[bold]Option 1: Use Billing Profile (Recommended)[/bold]
345
+ • Set environment variable: `export BILLING_PROFILE="your-billing-profile-name"`
346
+ • Run: `runbooks finops --profile your-billing-profile-name`
347
+
348
+ [bold]Option 2: Request Billing Account Access[/bold]
349
+ • Contact your AWS administrator
350
+ • Request access to the organization's billing account
351
+ • Use that profile for Cost Explorer operations"""
352
+
353
+ solution_panel = Panel(
354
+ f"[green]✅ Recommended Solutions:[/green]\n\n"
355
+ f"{solution_commands}\n\n"
356
+ f"[bold]🎯 Quick Test Commands:[/bold]\n"
357
+ f"• Test billing access: `aws ce get-cost-and-usage --time-period Start=2024-01-01,End=2024-01-02 --granularity MONTHLY --metrics UnblendedCost --profile your-billing-profile`\n"
358
+ f"• List available profiles: `aws configure list-profiles`\n"
359
+ f"• Check current identity: `aws sts get-caller-identity --profile {profile_name or 'your-profile'}`\n\n"
360
+ f"[bold]💡 Alternative Approach:[/bold]\n"
361
+ f"• Use resource-based analysis: `runbooks inventory collect`\n"
362
+ f"• Focus on resource optimization rather than cost analysis\n"
363
+ f"• Generate resource reports for cost discussions with billing team",
364
+ title="🔧 Cost Explorer Access Solutions",
365
+ border_style="green",
366
+ )
367
+ console.print(solution_panel)
368
+
369
+ # Enterprise context panel
370
+ enterprise_context = Panel(
371
+ "[bold]🏢 Enterprise Context:[/bold]\n\n"
372
+ "• **Single Account Limitations**: Member accounts typically lack billing permissions\n"
373
+ "• **Billing Account Access**: Contact your cloud team for billing profile access\n"
374
+ "• **Alternative Analysis**: Resource inventory can provide optimization insights\n"
375
+ "• **Cost Management**: Consider AWS Cost and Usage Reports (CUR) for detailed analysis\n\n"
376
+ "[bold]📊 What You Can Still Do:[/bold]\n"
377
+ "• Resource discovery and optimization recommendations\n"
378
+ "• Security compliance scanning and remediation\n"
379
+ "• Infrastructure inventory and tagging analysis\n"
380
+ "• Performance monitoring and optimization guidance",
381
+ title="🎯 Enterprise Guidance",
382
+ border_style="cyan",
383
+ )
384
+ console.print(enterprise_context)
385
+
386
+
387
+ # Original convenience functions maintained for compatibility
388
+ def handle_cost_explorer_error_simple(error: Exception):
389
+ """Handle Cost Explorer specific errors with guidance (legacy function)."""
390
+ EnterpriseIAMGuidance.display_enhanced_error(error, "runbooks finops operation (Cost Explorer API)")
391
+
392
+
393
+ def handle_organizations_error(error: Exception):
394
+ """Handle AWS Organizations specific errors with guidance."""
395
+ EnterpriseIAMGuidance.display_enhanced_error(error, "runbooks inventory operation (Organizations API)")
396
+
397
+
398
+ def handle_resource_discovery_error(error: Exception):
399
+ """Handle resource discovery specific errors with guidance."""
400
+ EnterpriseIAMGuidance.display_enhanced_error(error, "runbooks inventory operation (Resource Discovery APIs)")