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.
- runbooks/__init__.py +31 -2
- runbooks/__init___optimized.py +18 -4
- runbooks/_platform/__init__.py +1 -5
- runbooks/_platform/core/runbooks_wrapper.py +141 -138
- runbooks/aws2/accuracy_validator.py +812 -0
- runbooks/base.py +7 -0
- runbooks/cfat/assessment/compliance.py +1 -1
- runbooks/cfat/assessment/runner.py +1 -0
- runbooks/cfat/cloud_foundations_assessment.py +227 -239
- runbooks/cli/__init__.py +1 -1
- runbooks/cli/commands/cfat.py +64 -23
- runbooks/cli/commands/finops.py +1005 -54
- runbooks/cli/commands/inventory.py +138 -35
- runbooks/cli/commands/operate.py +9 -36
- runbooks/cli/commands/security.py +42 -18
- runbooks/cli/commands/validation.py +432 -18
- runbooks/cli/commands/vpc.py +81 -17
- runbooks/cli/registry.py +22 -10
- runbooks/cloudops/__init__.py +20 -27
- runbooks/cloudops/base.py +96 -107
- runbooks/cloudops/cost_optimizer.py +544 -542
- runbooks/cloudops/infrastructure_optimizer.py +5 -4
- runbooks/cloudops/interfaces.py +224 -225
- runbooks/cloudops/lifecycle_manager.py +5 -4
- runbooks/cloudops/mcp_cost_validation.py +252 -235
- runbooks/cloudops/models.py +78 -53
- runbooks/cloudops/monitoring_automation.py +5 -4
- runbooks/cloudops/notebook_framework.py +177 -213
- runbooks/cloudops/security_enforcer.py +125 -159
- runbooks/common/accuracy_validator.py +11 -0
- runbooks/common/aws_pricing.py +349 -326
- runbooks/common/aws_pricing_api.py +211 -212
- runbooks/common/aws_profile_manager.py +40 -36
- runbooks/common/aws_utils.py +74 -79
- runbooks/common/business_logic.py +126 -104
- runbooks/common/cli_decorators.py +36 -60
- runbooks/common/comprehensive_cost_explorer_integration.py +455 -463
- runbooks/common/cross_account_manager.py +197 -204
- runbooks/common/date_utils.py +27 -39
- runbooks/common/decorators.py +29 -19
- runbooks/common/dry_run_examples.py +173 -208
- runbooks/common/dry_run_framework.py +157 -155
- runbooks/common/enhanced_exception_handler.py +15 -4
- runbooks/common/enhanced_logging_example.py +50 -64
- runbooks/common/enhanced_logging_integration_example.py +65 -37
- runbooks/common/env_utils.py +16 -16
- runbooks/common/error_handling.py +40 -38
- runbooks/common/lazy_loader.py +41 -23
- runbooks/common/logging_integration_helper.py +79 -86
- runbooks/common/mcp_cost_explorer_integration.py +476 -493
- runbooks/common/mcp_integration.py +63 -74
- runbooks/common/memory_optimization.py +140 -118
- runbooks/common/module_cli_base.py +37 -58
- runbooks/common/organizations_client.py +175 -193
- runbooks/common/patterns.py +23 -25
- runbooks/common/performance_monitoring.py +67 -71
- runbooks/common/performance_optimization_engine.py +283 -274
- runbooks/common/profile_utils.py +111 -37
- runbooks/common/rich_utils.py +201 -141
- runbooks/common/sre_performance_suite.py +177 -186
- runbooks/enterprise/__init__.py +1 -1
- runbooks/enterprise/logging.py +144 -106
- runbooks/enterprise/security.py +187 -204
- runbooks/enterprise/validation.py +43 -56
- runbooks/finops/__init__.py +26 -30
- runbooks/finops/account_resolver.py +1 -1
- runbooks/finops/advanced_optimization_engine.py +980 -0
- runbooks/finops/automation_core.py +268 -231
- runbooks/finops/business_case_config.py +184 -179
- runbooks/finops/cli.py +660 -139
- runbooks/finops/commvault_ec2_analysis.py +157 -164
- runbooks/finops/compute_cost_optimizer.py +336 -320
- runbooks/finops/config.py +20 -20
- runbooks/finops/cost_optimizer.py +484 -618
- runbooks/finops/cost_processor.py +332 -214
- runbooks/finops/dashboard_runner.py +1006 -172
- runbooks/finops/ebs_cost_optimizer.py +991 -657
- runbooks/finops/elastic_ip_optimizer.py +317 -257
- runbooks/finops/enhanced_mcp_integration.py +340 -0
- runbooks/finops/enhanced_progress.py +32 -29
- runbooks/finops/enhanced_trend_visualization.py +3 -2
- runbooks/finops/enterprise_wrappers.py +223 -285
- runbooks/finops/executive_export.py +203 -160
- runbooks/finops/helpers.py +130 -288
- runbooks/finops/iam_guidance.py +1 -1
- runbooks/finops/infrastructure/__init__.py +80 -0
- runbooks/finops/infrastructure/commands.py +506 -0
- runbooks/finops/infrastructure/load_balancer_optimizer.py +866 -0
- runbooks/finops/infrastructure/vpc_endpoint_optimizer.py +832 -0
- runbooks/finops/markdown_exporter.py +337 -174
- runbooks/finops/mcp_validator.py +1952 -0
- runbooks/finops/nat_gateway_optimizer.py +1512 -481
- runbooks/finops/network_cost_optimizer.py +657 -587
- runbooks/finops/notebook_utils.py +226 -188
- runbooks/finops/optimization_engine.py +1136 -0
- runbooks/finops/optimizer.py +19 -23
- runbooks/finops/rds_snapshot_optimizer.py +367 -411
- runbooks/finops/reservation_optimizer.py +427 -363
- runbooks/finops/scenario_cli_integration.py +64 -65
- runbooks/finops/scenarios.py +1277 -438
- runbooks/finops/schemas.py +218 -182
- runbooks/finops/snapshot_manager.py +2289 -0
- runbooks/finops/types.py +3 -3
- runbooks/finops/validation_framework.py +259 -265
- runbooks/finops/vpc_cleanup_exporter.py +189 -144
- runbooks/finops/vpc_cleanup_optimizer.py +591 -573
- runbooks/finops/workspaces_analyzer.py +171 -182
- runbooks/integration/__init__.py +89 -0
- runbooks/integration/mcp_integration.py +1920 -0
- runbooks/inventory/CLAUDE.md +816 -0
- runbooks/inventory/__init__.py +2 -2
- runbooks/inventory/cloud_foundations_integration.py +144 -149
- runbooks/inventory/collectors/aws_comprehensive.py +1 -1
- runbooks/inventory/collectors/aws_networking.py +109 -99
- runbooks/inventory/collectors/base.py +4 -0
- runbooks/inventory/core/collector.py +495 -313
- runbooks/inventory/drift_detection_cli.py +69 -96
- runbooks/inventory/inventory_mcp_cli.py +48 -46
- runbooks/inventory/list_rds_snapshots_aggregator.py +192 -208
- runbooks/inventory/mcp_inventory_validator.py +549 -465
- runbooks/inventory/mcp_vpc_validator.py +359 -442
- runbooks/inventory/organizations_discovery.py +55 -51
- runbooks/inventory/rich_inventory_display.py +33 -32
- runbooks/inventory/unified_validation_engine.py +278 -251
- runbooks/inventory/vpc_analyzer.py +732 -695
- runbooks/inventory/vpc_architecture_validator.py +293 -348
- runbooks/inventory/vpc_dependency_analyzer.py +382 -378
- runbooks/inventory/vpc_flow_analyzer.py +1 -1
- runbooks/main.py +49 -34
- runbooks/main_final.py +91 -60
- runbooks/main_minimal.py +22 -10
- runbooks/main_optimized.py +131 -100
- runbooks/main_ultra_minimal.py +7 -2
- runbooks/mcp/__init__.py +36 -0
- runbooks/mcp/integration.py +679 -0
- runbooks/monitoring/performance_monitor.py +9 -4
- runbooks/operate/dynamodb_operations.py +3 -1
- runbooks/operate/ec2_operations.py +145 -137
- runbooks/operate/iam_operations.py +146 -152
- runbooks/operate/networking_cost_heatmap.py +29 -8
- runbooks/operate/rds_operations.py +223 -254
- runbooks/operate/s3_operations.py +107 -118
- runbooks/operate/vpc_operations.py +646 -616
- runbooks/remediation/base.py +1 -1
- runbooks/remediation/commons.py +10 -7
- runbooks/remediation/commvault_ec2_analysis.py +70 -66
- runbooks/remediation/ec2_unattached_ebs_volumes.py +1 -0
- runbooks/remediation/multi_account.py +24 -21
- runbooks/remediation/rds_snapshot_list.py +86 -60
- runbooks/remediation/remediation_cli.py +92 -146
- runbooks/remediation/universal_account_discovery.py +83 -79
- runbooks/remediation/workspaces_list.py +46 -41
- runbooks/security/__init__.py +19 -0
- runbooks/security/assessment_runner.py +1150 -0
- runbooks/security/baseline_checker.py +812 -0
- runbooks/security/cloudops_automation_security_validator.py +509 -535
- runbooks/security/compliance_automation_engine.py +17 -17
- runbooks/security/config/__init__.py +2 -2
- runbooks/security/config/compliance_config.py +50 -50
- runbooks/security/config_template_generator.py +63 -76
- runbooks/security/enterprise_security_framework.py +1 -1
- runbooks/security/executive_security_dashboard.py +519 -508
- runbooks/security/multi_account_security_controls.py +959 -1210
- runbooks/security/real_time_security_monitor.py +422 -444
- runbooks/security/security_baseline_tester.py +1 -1
- runbooks/security/security_cli.py +143 -112
- runbooks/security/test_2way_validation.py +439 -0
- runbooks/security/two_way_validation_framework.py +852 -0
- runbooks/sre/production_monitoring_framework.py +167 -177
- runbooks/tdd/__init__.py +15 -0
- runbooks/tdd/cli.py +1071 -0
- runbooks/utils/__init__.py +14 -17
- runbooks/utils/logger.py +7 -2
- runbooks/utils/version_validator.py +50 -47
- runbooks/validation/__init__.py +6 -6
- runbooks/validation/cli.py +9 -3
- runbooks/validation/comprehensive_2way_validator.py +745 -704
- runbooks/validation/mcp_validator.py +906 -228
- runbooks/validation/terraform_citations_validator.py +104 -115
- runbooks/validation/terraform_drift_detector.py +447 -451
- runbooks/vpc/README.md +617 -0
- runbooks/vpc/__init__.py +8 -1
- runbooks/vpc/analyzer.py +577 -0
- runbooks/vpc/cleanup_wrapper.py +476 -413
- runbooks/vpc/cli_cloudtrail_commands.py +339 -0
- runbooks/vpc/cli_mcp_validation_commands.py +480 -0
- runbooks/vpc/cloudtrail_audit_integration.py +717 -0
- runbooks/vpc/config.py +92 -97
- runbooks/vpc/cost_engine.py +411 -148
- runbooks/vpc/cost_explorer_integration.py +553 -0
- runbooks/vpc/cross_account_session.py +101 -106
- runbooks/vpc/enhanced_mcp_validation.py +917 -0
- runbooks/vpc/eni_gate_validator.py +961 -0
- runbooks/vpc/heatmap_engine.py +185 -160
- runbooks/vpc/mcp_no_eni_validator.py +680 -639
- runbooks/vpc/nat_gateway_optimizer.py +358 -0
- runbooks/vpc/networking_wrapper.py +15 -8
- runbooks/vpc/pdca_remediation_planner.py +528 -0
- runbooks/vpc/performance_optimized_analyzer.py +219 -231
- runbooks/vpc/runbooks_adapter.py +1167 -241
- runbooks/vpc/tdd_red_phase_stubs.py +601 -0
- runbooks/vpc/test_data_loader.py +358 -0
- runbooks/vpc/tests/conftest.py +314 -4
- runbooks/vpc/tests/test_cleanup_framework.py +1022 -0
- runbooks/vpc/tests/test_cost_engine.py +0 -2
- runbooks/vpc/topology_generator.py +326 -0
- runbooks/vpc/unified_scenarios.py +1297 -1124
- runbooks/vpc/vpc_cleanup_integration.py +1943 -1115
- runbooks-1.1.5.dist-info/METADATA +328 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/RECORD +214 -193
- runbooks/finops/README.md +0 -414
- runbooks/finops/accuracy_cross_validator.py +0 -647
- runbooks/finops/business_cases.py +0 -950
- runbooks/finops/dashboard_router.py +0 -922
- runbooks/finops/ebs_optimizer.py +0 -973
- runbooks/finops/embedded_mcp_validator.py +0 -1629
- runbooks/finops/enhanced_dashboard_runner.py +0 -527
- runbooks/finops/finops_dashboard.py +0 -584
- runbooks/finops/finops_scenarios.py +0 -1218
- runbooks/finops/legacy_migration.py +0 -730
- runbooks/finops/multi_dashboard.py +0 -1519
- runbooks/finops/single_dashboard.py +0 -1113
- runbooks/finops/unlimited_scenarios.py +0 -393
- runbooks-1.1.4.dist-info/METADATA +0 -800
- {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/WHEEL +0 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/entry_points.txt +0 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/licenses/LICENSE +0 -0
- {runbooks-1.1.4.dist-info → runbooks-1.1.5.dist-info}/top_level.txt +0 -0
runbooks/common/profile_utils.py
CHANGED
@@ -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,
|
21
|
-
read_timeout=60,
|
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
|
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
|
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(
|
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(
|
170
|
+
sts_client = session.client("sts")
|
176
171
|
response = sts_client.get_caller_identity()
|
177
|
-
return response.get(
|
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(
|
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(
|
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(
|
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(
|
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(
|
431
|
+
sts_client = session.client("sts", config=_AWS_CLIENT_CONFIG)
|
359
432
|
identity = sts_client.get_caller_identity()
|
360
433
|
|
361
434
|
return {
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
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
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
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
|
-
|
377
|
-
|
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)
|