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
@@ -0,0 +1,341 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ AWS Profile Manager - Universal v1.1.x Compatibility
4
+
5
+ Centralized AWS profile and account management for CloudOps Runbooks platform.
6
+ Eliminates ALL hardcoded account IDs and provides universal --profile support.
7
+
8
+ Features:
9
+ - 3-tier profile priority: User > Environment > Default
10
+ - Dynamic account ID resolution
11
+ - Multi-account discovery and validation
12
+ - Profile existence validation with helpful error messages
13
+ - Integration with Rich CLI for beautiful output
14
+
15
+ Author: CloudOps Runbooks Team
16
+ Version: 1.1.0
17
+ """
18
+
19
+ import os
20
+ import boto3
21
+ from typing import Dict, List, Optional, Any
22
+ from botocore.exceptions import ClientError, ProfileNotFound, NoCredentialsError
23
+ from rich.console import Console
24
+
25
+ from runbooks.common.rich_utils import console, print_error, print_success, print_warning, print_info
26
+
27
+
28
+ class AWSProfileManager:
29
+ """
30
+ Universal AWS Profile Manager for CloudOps v1.1.x compatibility.
31
+
32
+ Provides centralized profile management, account resolution, and
33
+ multi-account discovery for all CloudOps modules.
34
+ """
35
+
36
+ def __init__(self, profile: Optional[str] = None):
37
+ """
38
+ Initialize ProfileManager with 3-tier priority.
39
+
40
+ Args:
41
+ profile: User-specified profile (highest priority)
42
+ """
43
+ self.profile = self._resolve_profile(profile)
44
+ self.session = None
45
+ self._account_cache: Dict[str, str] = {}
46
+
47
+ def _resolve_profile(self, user_profile: Optional[str]) -> Optional[str]:
48
+ """
49
+ Resolve profile using 3-tier priority: User > Environment > Default
50
+
51
+ Args:
52
+ user_profile: User-specified profile
53
+
54
+ Returns:
55
+ Resolved profile name or None for default
56
+ """
57
+ # Tier 1: User-specified profile (highest priority)
58
+ if user_profile:
59
+ return user_profile
60
+
61
+ # Tier 2: Environment variable
62
+ env_profile = os.getenv("AWS_PROFILE")
63
+ if env_profile:
64
+ return env_profile
65
+
66
+ # Tier 3: Default (no explicit profile)
67
+ return None
68
+
69
+ def get_session(self, region: str = "us-east-1") -> boto3.Session:
70
+ """
71
+ Get boto3 session with resolved profile.
72
+
73
+ Args:
74
+ region: AWS region (default: us-east-1)
75
+
76
+ Returns:
77
+ Configured boto3 session
78
+
79
+ Raises:
80
+ ProfileNotFound: If specified profile doesn't exist
81
+ NoCredentialsError: If no valid credentials found
82
+ """
83
+ if not self.session:
84
+ try:
85
+ if self.profile:
86
+ self.session = boto3.Session(profile_name=self.profile, region_name=region)
87
+ print_info(f"Using AWS profile: {self.profile}")
88
+ else:
89
+ self.session = boto3.Session(region_name=region)
90
+ print_info("Using default AWS credentials")
91
+
92
+ # Validate credentials by getting caller identity
93
+ sts = self.session.client("sts")
94
+ identity = sts.get_caller_identity()
95
+ print_success(f"✅ Authenticated as: {identity.get('Arn', 'Unknown')}")
96
+
97
+ except ProfileNotFound as e:
98
+ print_error(f"❌ AWS profile '{self.profile}' not found")
99
+ print_info("Available profiles:")
100
+ self._list_available_profiles()
101
+ raise e
102
+ except NoCredentialsError as e:
103
+ print_error("❌ No AWS credentials found")
104
+ print_info("Setup options:")
105
+ print_info("1. Configure AWS CLI: aws configure")
106
+ print_info("2. Set AWS_PROFILE environment variable")
107
+ print_info("3. Use --profile flag with valid profile name")
108
+ raise e
109
+
110
+ return self.session
111
+
112
+ def get_account_id(self, region: str = "us-east-1") -> str:
113
+ """
114
+ Get current AWS account ID dynamically.
115
+
116
+ Args:
117
+ region: AWS region
118
+
119
+ Returns:
120
+ Current AWS account ID
121
+ """
122
+ cache_key = f"{self.profile or 'default'}:{region}"
123
+
124
+ if cache_key not in self._account_cache:
125
+ try:
126
+ session = self.get_session(region)
127
+ sts = session.client("sts")
128
+ identity = sts.get_caller_identity()
129
+ account_id = identity["Account"]
130
+ self._account_cache[cache_key] = account_id
131
+ print_info(f"Current account ID: {account_id}")
132
+
133
+ except ClientError as e:
134
+ print_error(f"❌ Failed to get account ID: {e}")
135
+ # Return generic account ID for testing/mock scenarios
136
+ return "123456789012"
137
+
138
+ return self._account_cache[cache_key]
139
+
140
+ def discover_organization_accounts(self, region: str = "us-east-1") -> List[Dict[str, Any]]:
141
+ """
142
+ Discover all accounts in AWS Organizations (if available).
143
+
144
+ Args:
145
+ region: AWS region
146
+
147
+ Returns:
148
+ List of organization accounts with metadata
149
+ """
150
+ try:
151
+ session = self.get_session(region)
152
+ org_client = session.client("organizations")
153
+
154
+ # Get organization information
155
+ try:
156
+ org_info = org_client.describe_organization()
157
+ print_success(f"✅ Organization: {org_info['Organization']['Id']}")
158
+ except ClientError:
159
+ print_warning("⚠️ Not connected to AWS Organizations")
160
+ return []
161
+
162
+ # List all accounts
163
+ accounts = []
164
+ paginator = org_client.get_paginator("list_accounts")
165
+
166
+ for page in paginator.paginate():
167
+ for account in page["Accounts"]:
168
+ accounts.append(
169
+ {
170
+ "Id": account["Id"],
171
+ "Name": account["Name"],
172
+ "Email": account["Email"],
173
+ "Status": account["Status"],
174
+ "JoinedMethod": account.get("JoinedMethod", "UNKNOWN"),
175
+ }
176
+ )
177
+
178
+ print_success(f"✅ Discovered {len(accounts)} organization accounts")
179
+ return accounts
180
+
181
+ except ClientError as e:
182
+ print_warning(f"⚠️ Unable to discover organization accounts: {e}")
183
+ return []
184
+
185
+ def validate_profile_access(self, required_services: List[str] = None) -> Dict[str, bool]:
186
+ """
187
+ Validate profile has access to required AWS services.
188
+
189
+ Args:
190
+ required_services: List of AWS service names to validate
191
+
192
+ Returns:
193
+ Dict mapping service names to access status
194
+ """
195
+ if not required_services:
196
+ required_services = ["sts", "ce", "ec2", "s3"]
197
+
198
+ access_status = {}
199
+ session = self.get_session()
200
+
201
+ for service in required_services:
202
+ try:
203
+ client = session.client(service)
204
+
205
+ # Service-specific health checks
206
+ if service == "sts":
207
+ client.get_caller_identity()
208
+ elif service == "ce":
209
+ # Test Cost Explorer access
210
+ from datetime import datetime, timedelta
211
+
212
+ end_date = datetime.now().strftime("%Y-%m-%d")
213
+ start_date = (datetime.now() - timedelta(days=7)).strftime("%Y-%m-%d")
214
+ client.get_cost_and_usage(
215
+ TimePeriod={"Start": start_date, "End": end_date},
216
+ Granularity="MONTHLY",
217
+ Metrics=["UnblendedCost"],
218
+ )
219
+ elif service == "ec2":
220
+ client.describe_regions(MaxResults=1)
221
+ elif service == "s3":
222
+ client.list_buckets()
223
+
224
+ access_status[service] = True
225
+ print_success(f"✅ {service.upper()} access validated")
226
+
227
+ except ClientError as e:
228
+ access_status[service] = False
229
+ print_warning(f"⚠️ {service.upper()} access limited: {e}")
230
+
231
+ return access_status
232
+
233
+ def _list_available_profiles(self) -> None:
234
+ """List available AWS profiles from credentials file."""
235
+ try:
236
+ import configparser
237
+ import os.path
238
+
239
+ credentials_path = os.path.expanduser("~/.aws/credentials")
240
+ config_path = os.path.expanduser("~/.aws/config")
241
+
242
+ profiles = set()
243
+
244
+ # Check credentials file
245
+ if os.path.exists(credentials_path):
246
+ cred_config = configparser.ConfigParser()
247
+ cred_config.read(credentials_path)
248
+ profiles.update(cred_config.sections())
249
+
250
+ # Check config file (profiles prefixed with 'profile ')
251
+ if os.path.exists(config_path):
252
+ config_config = configparser.ConfigParser()
253
+ config_config.read(config_path)
254
+ for section in config_config.sections():
255
+ if section.startswith("profile "):
256
+ profiles.add(section[8:]) # Remove 'profile ' prefix
257
+ elif section == "default":
258
+ profiles.add("default")
259
+
260
+ if profiles:
261
+ for profile in sorted(profiles):
262
+ print_info(f" - {profile}")
263
+ else:
264
+ print_info(" No profiles found in ~/.aws/credentials or ~/.aws/config")
265
+
266
+ except Exception as e:
267
+ print_warning(f"⚠️ Could not list profiles: {e}")
268
+
269
+ @classmethod
270
+ def create_mock_account_context(cls, mock_account_id: str = "123456789012") -> "AWSProfileManager":
271
+ """
272
+ Create mock profile manager for testing scenarios.
273
+
274
+ Args:
275
+ mock_account_id: Mock account ID to use
276
+
277
+ Returns:
278
+ ProfileManager configured for testing
279
+ """
280
+ manager = cls()
281
+ manager._account_cache["mock"] = mock_account_id
282
+ return manager
283
+
284
+ def get_profile_display_name(self) -> str:
285
+ """
286
+ Get human-friendly profile display name.
287
+
288
+ Returns:
289
+ Profile display name for CLI output
290
+ """
291
+ if self.profile:
292
+ return f"Profile: {self.profile}"
293
+ else:
294
+ return "Profile: default"
295
+
296
+ def __repr__(self) -> str:
297
+ return f"AWSProfileManager(profile={self.profile})"
298
+
299
+
300
+ # Global convenience functions for backward compatibility
301
+ def get_current_account_id(profile: Optional[str] = None, region: str = "us-east-1") -> str:
302
+ """
303
+ Convenience function to get current account ID.
304
+
305
+ Args:
306
+ profile: AWS profile name
307
+ region: AWS region
308
+
309
+ Returns:
310
+ Current AWS account ID
311
+ """
312
+ manager = AWSProfileManager(profile)
313
+ return manager.get_account_id(region)
314
+
315
+
316
+ def validate_profile_or_exit(profile: Optional[str] = None, required_services: List[str] = None) -> AWSProfileManager:
317
+ """
318
+ Validate profile exists and has required access, exit gracefully if not.
319
+
320
+ Args:
321
+ profile: AWS profile name
322
+ required_services: Required AWS services for validation
323
+
324
+ Returns:
325
+ Validated AWSProfileManager instance
326
+ """
327
+ try:
328
+ manager = AWSProfileManager(profile)
329
+ access_status = manager.validate_profile_access(required_services)
330
+
331
+ failed_services = [svc for svc, status in access_status.items() if not status]
332
+ if failed_services:
333
+ print_warning(f"⚠️ Limited access to services: {', '.join(failed_services)}")
334
+ print_info("Continuing with available services...")
335
+
336
+ return manager
337
+
338
+ except (ProfileNotFound, NoCredentialsError):
339
+ print_error("❌ Cannot proceed without valid AWS credentials")
340
+ print_info("Please configure AWS credentials and try again.")
341
+ exit(1)