27
27
from mypy_boto3_sagemaker import SageMakerClient
28
28
from mypy_boto3_sts import STSClient
29
29
30
+
30
31
class AwsEnvironment (Enum ):
31
32
EC2 = "EC2"
32
33
ECS = "ECS"
@@ -37,6 +38,7 @@ class AwsEnvironment(Enum):
37
38
CLOUD_FORMATION = "CLOUD_FORMATION"
38
39
UNKNOWN = "UNKNOWN"
39
40
41
+
40
42
class AwsAssumeRoleConfig (PermissiveConfigModel ):
41
43
# Using the PermissiveConfigModel to allow the user to pass additional arguments.
42
44
@@ -55,7 +57,7 @@ def get_instance_metadata_token() -> Optional[str]:
55
57
response = requests .put (
56
58
"http://169.254.169.254/latest/api/token" ,
57
59
headers = {"X-aws-ec2-metadata-token-ttl-seconds" : "21600" },
58
- timeout = 1
60
+ timeout = 1 ,
59
61
)
60
62
if response .status_code == 200 :
61
63
return response .text
@@ -74,7 +76,7 @@ def is_running_on_ec2() -> bool:
74
76
response = requests .get (
75
77
"http://169.254.169.254/latest/meta-data/instance-id" ,
76
78
headers = {"X-aws-ec2-metadata-token" : token },
77
- timeout = 1
79
+ timeout = 1 ,
78
80
)
79
81
return response .status_code == 200
80
82
except requests .exceptions .RequestException :
@@ -87,25 +89,27 @@ def detect_aws_environment() -> AwsEnvironment:
87
89
Order matters as some environments may have multiple indicators.
88
90
"""
89
91
# Check Lambda first as it's most specific
90
- if os .getenv (' AWS_LAMBDA_FUNCTION_NAME' ):
91
- if os .getenv (' AWS_EXECUTION_ENV' , '' ).startswith (' CloudFormation' ):
92
+ if os .getenv (" AWS_LAMBDA_FUNCTION_NAME" ):
93
+ if os .getenv (" AWS_EXECUTION_ENV" , "" ).startswith (" CloudFormation" ):
92
94
return AwsEnvironment .CLOUD_FORMATION
93
95
return AwsEnvironment .LAMBDA
94
96
95
97
# Check EKS (IRSA)
96
- if os .getenv (' AWS_WEB_IDENTITY_TOKEN_FILE' ) and os .getenv (' AWS_ROLE_ARN' ):
98
+ if os .getenv (" AWS_WEB_IDENTITY_TOKEN_FILE" ) and os .getenv (" AWS_ROLE_ARN" ):
97
99
return AwsEnvironment .EKS
98
100
99
101
# Check App Runner
100
- if os .getenv (' AWS_APP_RUNNER_SERVICE_ID' ):
102
+ if os .getenv (" AWS_APP_RUNNER_SERVICE_ID" ):
101
103
return AwsEnvironment .APP_RUNNER
102
104
103
105
# Check ECS
104
- if os .getenv ('ECS_CONTAINER_METADATA_URI_V4' ) or os .getenv ('ECS_CONTAINER_METADATA_URI' ):
106
+ if os .getenv ("ECS_CONTAINER_METADATA_URI_V4" ) or os .getenv (
107
+ "ECS_CONTAINER_METADATA_URI"
108
+ ):
105
109
return AwsEnvironment .ECS
106
110
107
111
# Check Elastic Beanstalk
108
- if os .getenv (' ELASTIC_BEANSTALK_ENVIRONMENT_NAME' ):
112
+ if os .getenv (" ELASTIC_BEANSTALK_ENVIRONMENT_NAME" ):
109
113
return AwsEnvironment .BEANSTALK
110
114
111
115
if is_running_on_ec2 ():
@@ -124,14 +128,14 @@ def get_instance_role_arn() -> Optional[str]:
124
128
response = requests .get (
125
129
"http://169.254.169.254/latest/meta-data/iam/security-credentials/" ,
126
130
headers = {"X-aws-ec2-metadata-token" : token },
127
- timeout = 1
131
+ timeout = 1 ,
128
132
)
129
133
if response .status_code == 200 :
130
134
role_name = response .text .strip ()
131
135
if role_name :
132
- sts = boto3 .client (' sts' )
136
+ sts = boto3 .client (" sts" )
133
137
identity = sts .get_caller_identity ()
134
- return identity [ ' Arn' ]
138
+ return identity . get ( " Arn" )
135
139
except Exception as e :
136
140
logger .debug (f"Failed to get instance role ARN: { e } " )
137
141
return None
@@ -140,15 +144,15 @@ def get_instance_role_arn() -> Optional[str]:
140
144
def get_lambda_role_arn () -> Optional [str ]:
141
145
"""Get the Lambda function's role ARN"""
142
146
try :
143
- function_name = os .getenv (' AWS_LAMBDA_FUNCTION_NAME' )
147
+ function_name = os .getenv (" AWS_LAMBDA_FUNCTION_NAME" )
144
148
if not function_name :
145
149
return None
146
150
147
- lambda_client = boto3 .client (' lambda' )
151
+ lambda_client = boto3 .client (" lambda" )
148
152
function_config = lambda_client .get_function_configuration (
149
153
FunctionName = function_name
150
154
)
151
- return function_config .get (' Role' )
155
+ return function_config .get (" Role" )
152
156
except Exception as e :
153
157
logger .debug (f"Failed to get Lambda role ARN: { e } " )
154
158
return None
@@ -166,26 +170,28 @@ def get_current_identity() -> Tuple[Optional[str], Optional[str]]:
166
170
return role_arn , "lambda.amazonaws.com"
167
171
168
172
elif env == AwsEnvironment .EKS :
169
- role_arn = os .getenv (' AWS_ROLE_ARN' )
173
+ role_arn = os .getenv (" AWS_ROLE_ARN" )
170
174
return role_arn , "eks.amazonaws.com"
171
175
172
176
elif env == AwsEnvironment .APP_RUNNER :
173
177
try :
174
- sts = boto3 .client (' sts' )
178
+ sts = boto3 .client (" sts" )
175
179
identity = sts .get_caller_identity ()
176
- return identity [ ' Arn' ] , "apprunner.amazonaws.com"
180
+ return identity . get ( " Arn" ) , "apprunner.amazonaws.com"
177
181
except Exception as e :
178
182
logger .debug (f"Failed to get App Runner role: { e } " )
179
183
180
184
elif env == AwsEnvironment .ECS :
181
185
try :
182
- metadata_uri = os .getenv ('ECS_CONTAINER_METADATA_URI_V4' ) or os .getenv ('ECS_CONTAINER_METADATA_URI' )
186
+ metadata_uri = os .getenv ("ECS_CONTAINER_METADATA_URI_V4" ) or os .getenv (
187
+ "ECS_CONTAINER_METADATA_URI"
188
+ )
183
189
if metadata_uri :
184
190
response = requests .get (f"{ metadata_uri } /task" , timeout = 1 )
185
191
if response .status_code == 200 :
186
192
task_metadata = response .json ()
187
- if ' TaskARN' in task_metadata :
188
- return task_metadata .get (' TaskARN' ), "ecs.amazonaws.com"
193
+ if " TaskARN" in task_metadata :
194
+ return task_metadata .get (" TaskARN" ), "ecs.amazonaws.com"
189
195
except Exception as e :
190
196
logger .debug (f"Failed to get ECS task role: { e } " )
191
197
@@ -320,8 +326,7 @@ def get_session(self) -> Session:
320
326
elif self .aws_profile :
321
327
# Named profile is second priority
322
328
session = Session (
323
- region_name = self .aws_region ,
324
- profile_name = self .aws_profile
329
+ region_name = self .aws_region , profile_name = self .aws_profile
325
330
)
326
331
else :
327
332
# Use boto3's credential autodetection
@@ -334,9 +339,8 @@ def get_session(self) -> Session:
334
339
# Only assume role if:
335
340
# 1. We're not in a known AWS environment with a role, or
336
341
# 2. We need to assume a different role than our current one
337
- should_assume_role = (
338
- current_role_arn is None or
339
- any (role .RoleArn != current_role_arn for role in target_roles )
342
+ should_assume_role = current_role_arn is None or any (
343
+ role .RoleArn != current_role_arn for role in target_roles
340
344
)
341
345
342
346
if should_assume_role :
0 commit comments