runbooks 1.1.4__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 (228) 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/assessment/compliance.py +1 -1
  8. runbooks/cfat/assessment/runner.py +1 -0
  9. runbooks/cfat/cloud_foundations_assessment.py +227 -239
  10. runbooks/cli/__init__.py +1 -1
  11. runbooks/cli/commands/cfat.py +64 -23
  12. runbooks/cli/commands/finops.py +1005 -54
  13. runbooks/cli/commands/inventory.py +138 -35
  14. runbooks/cli/commands/operate.py +9 -36
  15. runbooks/cli/commands/security.py +42 -18
  16. runbooks/cli/commands/validation.py +432 -18
  17. runbooks/cli/commands/vpc.py +81 -17
  18. runbooks/cli/registry.py +22 -10
  19. runbooks/cloudops/__init__.py +20 -27
  20. runbooks/cloudops/base.py +96 -107
  21. runbooks/cloudops/cost_optimizer.py +544 -542
  22. runbooks/cloudops/infrastructure_optimizer.py +5 -4
  23. runbooks/cloudops/interfaces.py +224 -225
  24. runbooks/cloudops/lifecycle_manager.py +5 -4
  25. runbooks/cloudops/mcp_cost_validation.py +252 -235
  26. runbooks/cloudops/models.py +78 -53
  27. runbooks/cloudops/monitoring_automation.py +5 -4
  28. runbooks/cloudops/notebook_framework.py +177 -213
  29. runbooks/cloudops/security_enforcer.py +125 -159
  30. runbooks/common/accuracy_validator.py +11 -0
  31. runbooks/common/aws_pricing.py +349 -326
  32. runbooks/common/aws_pricing_api.py +211 -212
  33. runbooks/common/aws_profile_manager.py +40 -36
  34. runbooks/common/aws_utils.py +74 -79
  35. runbooks/common/business_logic.py +126 -104
  36. runbooks/common/cli_decorators.py +36 -60
  37. runbooks/common/comprehensive_cost_explorer_integration.py +455 -463
  38. runbooks/common/cross_account_manager.py +197 -204
  39. runbooks/common/date_utils.py +27 -39
  40. runbooks/common/decorators.py +29 -19
  41. runbooks/common/dry_run_examples.py +173 -208
  42. runbooks/common/dry_run_framework.py +157 -155
  43. runbooks/common/enhanced_exception_handler.py +15 -4
  44. runbooks/common/enhanced_logging_example.py +50 -64
  45. runbooks/common/enhanced_logging_integration_example.py +65 -37
  46. runbooks/common/env_utils.py +16 -16
  47. runbooks/common/error_handling.py +40 -38
  48. runbooks/common/lazy_loader.py +41 -23
  49. runbooks/common/logging_integration_helper.py +79 -86
  50. runbooks/common/mcp_cost_explorer_integration.py +476 -493
  51. runbooks/common/mcp_integration.py +63 -74
  52. runbooks/common/memory_optimization.py +140 -118
  53. runbooks/common/module_cli_base.py +37 -58
  54. runbooks/common/organizations_client.py +175 -193
  55. runbooks/common/patterns.py +23 -25
  56. runbooks/common/performance_monitoring.py +67 -71
  57. runbooks/common/performance_optimization_engine.py +283 -274
  58. runbooks/common/profile_utils.py +111 -37
  59. runbooks/common/rich_utils.py +201 -141
  60. runbooks/common/sre_performance_suite.py +177 -186
  61. runbooks/enterprise/__init__.py +1 -1
  62. runbooks/enterprise/logging.py +144 -106
  63. runbooks/enterprise/security.py +187 -204
  64. runbooks/enterprise/validation.py +43 -56
  65. runbooks/finops/__init__.py +26 -30
  66. runbooks/finops/account_resolver.py +1 -1
  67. runbooks/finops/advanced_optimization_engine.py +980 -0
  68. runbooks/finops/automation_core.py +268 -231
  69. runbooks/finops/business_case_config.py +184 -179
  70. runbooks/finops/cli.py +660 -139
  71. runbooks/finops/commvault_ec2_analysis.py +157 -164
  72. runbooks/finops/compute_cost_optimizer.py +336 -320
  73. runbooks/finops/config.py +20 -20
  74. runbooks/finops/cost_optimizer.py +484 -618
  75. runbooks/finops/cost_processor.py +332 -214
  76. runbooks/finops/dashboard_runner.py +1006 -172
  77. runbooks/finops/ebs_cost_optimizer.py +991 -657
  78. runbooks/finops/elastic_ip_optimizer.py +317 -257
  79. runbooks/finops/enhanced_mcp_integration.py +340 -0
  80. runbooks/finops/enhanced_progress.py +32 -29
  81. runbooks/finops/enhanced_trend_visualization.py +3 -2
  82. runbooks/finops/enterprise_wrappers.py +223 -285
  83. runbooks/finops/executive_export.py +203 -160
  84. runbooks/finops/helpers.py +130 -288
  85. runbooks/finops/iam_guidance.py +1 -1
  86. runbooks/finops/infrastructure/__init__.py +80 -0
  87. runbooks/finops/infrastructure/commands.py +506 -0
  88. runbooks/finops/infrastructure/load_balancer_optimizer.py +866 -0
  89. runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +832 -0
  90. runbooks/finops/markdown_exporter.py +337 -174
  91. runbooks/finops/mcp_validator.py +1952 -0
  92. runbooks/finops/nat_gateway_optimizer.py +1512 -481
  93. runbooks/finops/network_cost_optimizer.py +657 -587
  94. runbooks/finops/notebook_utils.py +226 -188
  95. runbooks/finops/optimization_engine.py +1136 -0
  96. runbooks/finops/optimizer.py +19 -23
  97. runbooks/finops/rds_snapshot_optimizer.py +367 -411
  98. runbooks/finops/reservation_optimizer.py +427 -363
  99. runbooks/finops/scenario_cli_integration.py +64 -65
  100. runbooks/finops/scenarios.py +1277 -438
  101. runbooks/finops/schemas.py +218 -182
  102. runbooks/finops/snapshot_manager.py +2289 -0
  103. runbooks/finops/types.py +3 -3
  104. runbooks/finops/validation_framework.py +259 -265
  105. runbooks/finops/vpc_cleanup_exporter.py +189 -144
  106. runbooks/finops/vpc_cleanup_optimizer.py +591 -573
  107. runbooks/finops/workspaces_analyzer.py +171 -182
  108. runbooks/integration/__init__.py +89 -0
  109. runbooks/integration/mcp_integration.py +1920 -0
  110. runbooks/inventory/CLAUDE.md +816 -0
  111. runbooks/inventory/__init__.py +2 -2
  112. runbooks/inventory/cloud_foundations_integration.py +144 -149
  113. runbooks/inventory/collectors/aws_comprehensive.py +1 -1
  114. runbooks/inventory/collectors/aws_networking.py +109 -99
  115. runbooks/inventory/collectors/base.py +4 -0
  116. runbooks/inventory/core/collector.py +495 -313
  117. runbooks/inventory/drift_detection_cli.py +69 -96
  118. runbooks/inventory/inventory_mcp_cli.py +48 -46
  119. runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
  120. runbooks/inventory/mcp_inventory_validator.py +549 -465
  121. runbooks/inventory/mcp_vpc_validator.py +359 -442
  122. runbooks/inventory/organizations_discovery.py +55 -51
  123. runbooks/inventory/rich_inventory_display.py +33 -32
  124. runbooks/inventory/unified_validation_engine.py +278 -251
  125. runbooks/inventory/vpc_analyzer.py +732 -695
  126. runbooks/inventory/vpc_architecture_validator.py +293 -348
  127. runbooks/inventory/vpc_dependency_analyzer.py +382 -378
  128. runbooks/inventory/vpc_flow_analyzer.py +1 -1
  129. runbooks/main.py +49 -34
  130. runbooks/main_final.py +91 -60
  131. runbooks/main_minimal.py +22 -10
  132. runbooks/main_optimized.py +131 -100
  133. runbooks/main_ultra_minimal.py +7 -2
  134. runbooks/mcp/__init__.py +36 -0
  135. runbooks/mcp/integration.py +679 -0
  136. runbooks/monitoring/performance_monitor.py +9 -4
  137. runbooks/operate/dynamodb_operations.py +3 -1
  138. runbooks/operate/ec2_operations.py +145 -137
  139. runbooks/operate/iam_operations.py +146 -152
  140. runbooks/operate/networking_cost_heatmap.py +29 -8
  141. runbooks/operate/rds_operations.py +223 -254
  142. runbooks/operate/s3_operations.py +107 -118
  143. runbooks/operate/vpc_operations.py +646 -616
  144. runbooks/remediation/base.py +1 -1
  145. runbooks/remediation/commons.py +10 -7
  146. runbooks/remediation/commvault_ec2_analysis.py +70 -66
  147. runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
  148. runbooks/remediation/multi_account.py +24 -21
  149. runbooks/remediation/rds_snapshot_list.py +86 -60
  150. runbooks/remediation/remediation_cli.py +92 -146
  151. runbooks/remediation/universal_account_discovery.py +83 -79
  152. runbooks/remediation/workspaces_list.py +46 -41
  153. runbooks/security/__init__.py +19 -0
  154. runbooks/security/assessment_runner.py +1150 -0
  155. runbooks/security/baseline_checker.py +812 -0
  156. runbooks/security/cloudops_automation_security_validator.py +509 -535
  157. runbooks/security/compliance_automation_engine.py +17 -17
  158. runbooks/security/config/__init__.py +2 -2
  159. runbooks/security/config/compliance_config.py +50 -50
  160. runbooks/security/config_template_generator.py +63 -76
  161. runbooks/security/enterprise_security_framework.py +1 -1
  162. runbooks/security/executive_security_dashboard.py +519 -508
  163. runbooks/security/multi_account_security_controls.py +959 -1210
  164. runbooks/security/real_time_security_monitor.py +422 -444
  165. runbooks/security/security_baseline_tester.py +1 -1
  166. runbooks/security/security_cli.py +143 -112
  167. runbooks/security/test_2way_validation.py +439 -0
  168. runbooks/security/two_way_validation_framework.py +852 -0
  169. runbooks/sre/production_monitoring_framework.py +167 -177
  170. runbooks/tdd/__init__.py +15 -0
  171. runbooks/tdd/cli.py +1071 -0
  172. runbooks/utils/__init__.py +14 -17
  173. runbooks/utils/logger.py +7 -2
  174. runbooks/utils/version_validator.py +50 -47
  175. runbooks/validation/__init__.py +6 -6
  176. runbooks/validation/cli.py +9 -3
  177. runbooks/validation/comprehensive_2way_validator.py +745 -704
  178. runbooks/validation/mcp_validator.py +906 -228
  179. runbooks/validation/terraform_citations_validator.py +104 -115
  180. runbooks/validation/terraform_drift_detector.py +447 -451
  181. runbooks/vpc/README.md +617 -0
  182. runbooks/vpc/__init__.py +8 -1
  183. runbooks/vpc/analyzer.py +577 -0
  184. runbooks/vpc/cleanup_wrapper.py +476 -413
  185. runbooks/vpc/cli_cloudtrail_commands.py +339 -0
  186. runbooks/vpc/cli_mcp_validation_commands.py +480 -0
  187. runbooks/vpc/cloudtrail_audit_integration.py +717 -0
  188. runbooks/vpc/config.py +92 -97
  189. runbooks/vpc/cost_engine.py +411 -148
  190. runbooks/vpc/cost_explorer_integration.py +553 -0
  191. runbooks/vpc/cross_account_session.py +101 -106
  192. runbooks/vpc/enhanced_mcp_validation.py +917 -0
  193. runbooks/vpc/eni_gate_validator.py +961 -0
  194. runbooks/vpc/heatmap_engine.py +185 -160
  195. runbooks/vpc/mcp_no_eni_validator.py +680 -639
  196. runbooks/vpc/nat_gateway_optimizer.py +358 -0
  197. runbooks/vpc/networking_wrapper.py +15 -8
  198. runbooks/vpc/pdca_remediation_planner.py +528 -0
  199. runbooks/vpc/performance_optimized_analyzer.py +219 -231
  200. runbooks/vpc/runbooks_adapter.py +1167 -241
  201. runbooks/vpc/tdd_red_phase_stubs.py +601 -0
  202. runbooks/vpc/test_data_loader.py +358 -0
  203. runbooks/vpc/tests/conftest.py +314 -4
  204. runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
  205. runbooks/vpc/tests/test_cost_engine.py +0 -2
  206. runbooks/vpc/topology_generator.py +326 -0
  207. runbooks/vpc/unified_scenarios.py +1297 -1124
  208. runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
  209. runbooks-1.1.5.dist-info/METADATA +328 -0
  210. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/RECORD +214 -193
  211. runbooks/finops/README.md +0 -414
  212. runbooks/finops/accuracy_cross_validator.py +0 -647
  213. runbooks/finops/business_cases.py +0 -950
  214. runbooks/finops/dashboard_router.py +0 -922
  215. runbooks/finops/ebs_optimizer.py +0 -973
  216. runbooks/finops/embedded_mcp_validator.py +0 -1629
  217. runbooks/finops/enhanced_dashboard_runner.py +0 -527
  218. runbooks/finops/finops_dashboard.py +0 -584
  219. runbooks/finops/finops_scenarios.py +0 -1218
  220. runbooks/finops/legacy_migration.py +0 -730
  221. runbooks/finops/multi_dashboard.py +0 -1519
  222. runbooks/finops/single_dashboard.py +0 -1113
  223. runbooks/finops/unlimited_scenarios.py +0 -393
  224. runbooks-1.1.4.dist-info/METADATA +0 -800
  225. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/WHEEL +0 -0
  226. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/entry_points.txt +0 -0
  227. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/licenses/LICENSE +0 -0
  228. {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/top_level.txt +0 -0
@@ -17,14 +17,12 @@ _session_cache: Dict[str, boto3.Session] = {} # Cache AWS sessions
17
17
 
18
18
  # Timeout configuration for AWS API calls (prevents execution flow hangs)
19
19
  _AWS_CLIENT_CONFIG = Config(
20
- connect_timeout=30, # Connection timeout: 30 seconds
21
- read_timeout=60, # Read timeout: 60 seconds
22
- retries={
23
- 'max_attempts': 3,
24
- 'mode': 'adaptive'
25
- }
20
+ connect_timeout=30, # Connection timeout: 30 seconds
21
+ read_timeout=60, # Read timeout: 60 seconds
22
+ retries={"max_attempts": 3, "mode": "adaptive"},
26
23
  )
27
24
 
25
+
28
26
  def _get_session_id() -> str:
29
27
  """Generate consistent session ID for cache scoping"""
30
28
  global _session_id
@@ -32,10 +30,9 @@ def _get_session_id() -> str:
32
30
  _session_id = f"session_{int(time.time())}"
33
31
  return _session_id
34
32
 
33
+
35
34
  def get_profile_for_operation(
36
- operation_type: str,
37
- user_specified_profile: Optional[str] = None,
38
- profiles: Optional[List[str]] = None
35
+ operation_type: str, user_specified_profile: Optional[str] = None, profiles: Optional[List[str]] = None
39
36
  ) -> str:
40
37
  """
41
38
  Enhanced profile resolution with intelligent caching and enterprise logging optimization.
@@ -65,9 +62,7 @@ def get_profile_for_operation(
65
62
  profile_cache_key = f"{_get_session_id()}:{user_specified_profile or 'default'}"
66
63
 
67
64
  # Return cached result if still valid and within TTL
68
- if (profile_cache_key in _profile_cache and
69
- _cache_timestamp and
70
- current_time - _cache_timestamp < _cache_ttl):
65
+ if profile_cache_key in _profile_cache and _cache_timestamp and current_time - _cache_timestamp < _cache_ttl:
71
66
  return _profile_cache[profile_cache_key]
72
67
 
73
68
  # Update cache timestamp only when cache is actually refreshed
@@ -125,6 +120,7 @@ def get_profile_for_operation(
125
120
  console.log("[yellow]Please run: aws configure sso or aws configure[/]")
126
121
  raise SystemExit(1)
127
122
 
123
+
128
124
  def validate_profile_access(profile_name: str, operation_description: str = "") -> bool:
129
125
  """
130
126
  Validate that the specified profile has proper AWS access with caching.
@@ -141,14 +137,12 @@ def validate_profile_access(profile_name: str, operation_description: str = "")
141
137
  current_time = time.time()
142
138
  cache_key = f"validation:{profile_name}"
143
139
 
144
- if (cache_key in _validation_cache and
145
- _cache_timestamp and
146
- current_time - _cache_timestamp < _cache_ttl):
140
+ if cache_key in _validation_cache and _cache_timestamp and current_time - _cache_timestamp < _cache_ttl:
147
141
  return _validation_cache[cache_key]
148
142
 
149
143
  try:
150
144
  session = boto3.Session(profile_name=profile_name)
151
- sts_client = session.client('sts')
145
+ sts_client = session.client("sts")
152
146
  sts_client.get_caller_identity()
153
147
 
154
148
  # Cache successful validation
@@ -160,6 +154,7 @@ def validate_profile_access(profile_name: str, operation_description: str = "")
160
154
  console.log(f"[yellow]Profile {profile_name} validation failed: {e}[/]")
161
155
  return False
162
156
 
157
+
163
158
  def get_account_id_from_profile(profile_name: str) -> Optional[str]:
164
159
  """
165
160
  Extract account ID from AWS profile.
@@ -172,12 +167,87 @@ def get_account_id_from_profile(profile_name: str) -> Optional[str]:
172
167
  """
173
168
  try:
174
169
  session = boto3.Session(profile_name=profile_name)
175
- sts_client = session.client('sts')
170
+ sts_client = session.client("sts")
176
171
  response = sts_client.get_caller_identity()
177
- return response.get('Account')
172
+ return response.get("Account")
178
173
  except Exception:
179
174
  return None
180
175
 
176
+
177
+ def auto_discover_enterprise_profiles() -> Dict[str, Optional[str]]:
178
+ """
179
+ Auto-discover enterprise AWS SSO profiles for streamlined initialization.
180
+
181
+ Searches for profiles matching common enterprise naming patterns:
182
+ - *Billing* or *billing* for BILLING_PROFILE
183
+ - *Management* or *management* for MANAGEMENT_PROFILE
184
+ - *Ops* or *ops* for CENTRALISED_OPS_PROFILE
185
+ - Single account profiles for SINGLE_AWS_PROFILE
186
+
187
+ Returns:
188
+ Dict mapping profile types to discovered profile names
189
+ """
190
+ available_profiles = boto3.Session().available_profiles
191
+ discovered = {"billing": None, "management": None, "centralised_ops": None, "single_aws": None}
192
+
193
+ # Search patterns for enterprise profiles
194
+ for profile in available_profiles:
195
+ profile_lower = profile.lower()
196
+
197
+ # Billing profile detection
198
+ if ("billing" in profile_lower or "cost" in profile_lower) and not discovered["billing"]:
199
+ discovered["billing"] = profile
200
+
201
+ # Management profile detection
202
+ elif ("management" in profile_lower or "admin" in profile_lower) and not discovered["management"]:
203
+ discovered["management"] = profile
204
+
205
+ # Operations profile detection
206
+ elif (
207
+ "ops" in profile_lower or "operational" in profile_lower or "centralised" in profile_lower
208
+ ) and not discovered["centralised_ops"]:
209
+ discovered["centralised_ops"] = profile
210
+
211
+ # Single account detection (typically shorter names or containing 'single')
212
+ elif ("single" in profile_lower or len(profile) < 20) and not discovered["single_aws"]:
213
+ discovered["single_aws"] = profile
214
+
215
+ # Log discovered profiles for transparency
216
+ for profile_type, profile_name in discovered.items():
217
+ if profile_name:
218
+ console.log(f"[green]✅ Auto-discovered {profile_type}: {profile_name}[/green]")
219
+ else:
220
+ console.log(f"[yellow]⚠️ No profile found for {profile_type}[/yellow]")
221
+
222
+ return discovered
223
+
224
+
225
+ def setup_enterprise_environment_variables(discovered_profiles: Optional[Dict[str, Optional[str]]] = None) -> None:
226
+ """
227
+ Setup enterprise environment variables from discovered profiles.
228
+
229
+ Args:
230
+ discovered_profiles: Optional pre-discovered profiles dict
231
+ """
232
+ if not discovered_profiles:
233
+ discovered_profiles = auto_discover_enterprise_profiles()
234
+
235
+ # Set environment variables if not already set
236
+ env_mappings = {
237
+ "BILLING_PROFILE": discovered_profiles.get("billing"),
238
+ "MANAGEMENT_PROFILE": discovered_profiles.get("management"),
239
+ "CENTRALISED_OPS_PROFILE": discovered_profiles.get("centralised_ops"),
240
+ "SINGLE_AWS_PROFILE": discovered_profiles.get("single_aws"),
241
+ }
242
+
243
+ for env_var, profile_name in env_mappings.items():
244
+ if profile_name and not os.getenv(env_var):
245
+ os.environ[env_var] = profile_name
246
+ console.log(f"[blue]📋 Set {env_var}={profile_name}[/blue]")
247
+ elif os.getenv(env_var):
248
+ console.log(f"[dim]Using existing {env_var}={os.getenv(env_var)}[/dim]")
249
+
250
+
181
251
  def create_cost_session(profile_name: Optional[str] = None) -> boto3.Session:
182
252
  """
183
253
  Create AWS session optimized for cost operations (Cost Explorer) with token error handling.
@@ -203,7 +273,7 @@ def create_cost_session(profile_name: Optional[str] = None) -> boto3.Session:
203
273
  # Quick validation that the cached session still works
204
274
  try:
205
275
  # Test with a minimal STS call to check if credentials are valid (with timeout)
206
- sts_client = cached_session.client('sts', config=_AWS_CLIENT_CONFIG)
276
+ sts_client = cached_session.client("sts", config=_AWS_CLIENT_CONFIG)
207
277
  sts_client.get_caller_identity()
208
278
  return cached_session
209
279
  except (TokenRetrievalError, NoCredentialsError):
@@ -214,7 +284,7 @@ def create_cost_session(profile_name: Optional[str] = None) -> boto3.Session:
214
284
  try:
215
285
  session = boto3.Session(profile_name=cost_profile)
216
286
  # Test the session to ensure credentials are valid (with timeout)
217
- sts_client = session.client('sts', config=_AWS_CLIENT_CONFIG)
287
+ sts_client = session.client("sts", config=_AWS_CLIENT_CONFIG)
218
288
  sts_client.get_caller_identity()
219
289
 
220
290
  # Cache only if session works
@@ -250,6 +320,7 @@ def create_cost_session(profile_name: Optional[str] = None) -> boto3.Session:
250
320
  console.log(f"[dim]Error details: {str(e)}[/]")
251
321
  raise SystemExit(1)
252
322
 
323
+
253
324
  def create_management_session(profile_name: Optional[str] = None) -> boto3.Session:
254
325
  """
255
326
  Create AWS session optimized for management operations (Organizations) with token error handling.
@@ -275,7 +346,7 @@ def create_management_session(profile_name: Optional[str] = None) -> boto3.Sessi
275
346
  # Quick validation that the cached session still works
276
347
  try:
277
348
  # Test with a minimal STS call to check if credentials are valid (with timeout)
278
- sts_client = cached_session.client('sts', config=_AWS_CLIENT_CONFIG)
349
+ sts_client = cached_session.client("sts", config=_AWS_CLIENT_CONFIG)
279
350
  sts_client.get_caller_identity()
280
351
  return cached_session
281
352
  except (TokenRetrievalError, NoCredentialsError):
@@ -286,7 +357,7 @@ def create_management_session(profile_name: Optional[str] = None) -> boto3.Sessi
286
357
  try:
287
358
  session = boto3.Session(profile_name=mgmt_profile)
288
359
  # Test the session to ensure credentials are valid (with timeout)
289
- sts_client = session.client('sts', config=_AWS_CLIENT_CONFIG)
360
+ sts_client = session.client("sts", config=_AWS_CLIENT_CONFIG)
290
361
  sts_client.get_caller_identity()
291
362
 
292
363
  # Cache only if session works
@@ -322,6 +393,7 @@ def create_management_session(profile_name: Optional[str] = None) -> boto3.Sessi
322
393
  console.log(f"[dim]Error details: {str(e)}[/]")
323
394
  raise SystemExit(1)
324
395
 
396
+
325
397
  def create_operational_session(profile_name: Optional[str] = None) -> boto3.Session:
326
398
  """
327
399
  Create AWS session optimized for operational tasks (EC2, S3, etc).
@@ -343,6 +415,7 @@ def create_operational_session(profile_name: Optional[str] = None) -> boto3.Sess
343
415
  _session_cache[session_key] = session
344
416
  return session
345
417
 
418
+
346
419
  def get_current_profile_info(profile_name: Optional[str] = None) -> Dict[str, Any]:
347
420
  """
348
421
  Get current profile information including account ID and region.
@@ -355,28 +428,26 @@ def get_current_profile_info(profile_name: Optional[str] = None) -> Dict[str, An
355
428
  """
356
429
  try:
357
430
  session = boto3.Session(profile_name=profile_name)
358
- sts_client = session.client('sts', config=_AWS_CLIENT_CONFIG)
431
+ sts_client = session.client("sts", config=_AWS_CLIENT_CONFIG)
359
432
  identity = sts_client.get_caller_identity()
360
433
 
361
434
  return {
362
- 'profile_name': profile_name or 'default',
363
- 'account_id': identity.get('Account'),
364
- 'user_arn': identity.get('Arn'),
365
- 'region': session.region_name or 'us-east-1'
435
+ "profile_name": profile_name or "default",
436
+ "account_id": identity.get("Account"),
437
+ "user_arn": identity.get("Arn"),
438
+ "region": session.region_name or "us-east-1",
366
439
  }
367
440
  except Exception as e:
368
441
  return {
369
- 'profile_name': profile_name or 'default',
370
- 'error': str(e),
371
- 'account_id': None,
372
- 'user_arn': None,
373
- 'region': None
442
+ "profile_name": profile_name or "default",
443
+ "error": str(e),
444
+ "account_id": None,
445
+ "user_arn": None,
446
+ "region": None,
374
447
  }
375
448
 
376
- def resolve_profile_for_operation_silent(
377
- operation_type: str,
378
- user_specified_profile: Optional[str] = None
379
- ) -> str:
449
+
450
+ def resolve_profile_for_operation_silent(operation_type: str, user_specified_profile: Optional[str] = None) -> str:
380
451
  """
381
452
  Silent version of profile resolution without logging.
382
453
 
@@ -404,6 +475,7 @@ def resolve_profile_for_operation_silent(
404
475
 
405
476
  return user_specified_profile or "default"
406
477
 
478
+
407
479
  def list_available_profiles() -> List[str]:
408
480
  """
409
481
  Get list of all available AWS profiles.
@@ -413,6 +485,7 @@ def list_available_profiles() -> List[str]:
413
485
  """
414
486
  return boto3.Session().available_profiles
415
487
 
488
+
416
489
  def clear_profile_cache() -> None:
417
490
  """Clear the profile cache for testing or troubleshooting."""
418
491
  global _profile_cache, _validation_cache, _session_cache, _cache_timestamp, _session_id
@@ -422,6 +495,7 @@ def clear_profile_cache() -> None:
422
495
  _cache_timestamp = None
423
496
  _session_id = None
424
497
 
498
+
425
499
  def create_timeout_protected_client(session: boto3.Session, service_name: str, region_name: Optional[str] = None):
426
500
  """
427
501
  Create AWS service client with timeout protection to prevent execution flow hangs.
@@ -442,4 +516,4 @@ def create_timeout_protected_client(session: boto3.Session, service_name: str, r
442
516
  ce_client = create_timeout_protected_client(session, 'ce', 'us-east-1')
443
517
  ec2_client = create_timeout_protected_client(session, 'ec2', region_name)
444
518
  """
445
- return session.client(service_name, region_name=region_name, config=_AWS_CLIENT_CONFIG)
519
+ return session.client(service_name, region_name=region_name, config=_AWS_CLIENT_CONFIG)