11import functools
2+ import json
23import os
4+ import urllib .request as req
5+ import time
6+ import random
37
48import airline
59
610
7- def airline_wrapper (_handler = None , * , env_vars = None ):
11+ def airline_wrapper (_handler = None , * , env_vars = None , add_role_info = True ):
812 '''airline decorator for a function in a AWS Batch job
913 ```
1014 @airline_wrapper
@@ -35,6 +39,9 @@ def _airline_wrapper(*args, **kwargs):
3539 for name , var in env_vars .items ():
3640 airline .add_environment_variable (name , var )
3741
42+ if add_role_info :
43+ _add_role_info ()
44+
3845 resp = handler (* args , ** kwargs )
3946
4047 return resp
@@ -44,3 +51,35 @@ def _airline_wrapper(*args, **kwargs):
4451 return decorator_airline
4552 else :
4653 return decorator_airline (_handler )
54+
55+
56+ def _add_role_info ():
57+ uri = os .getenv ("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" )
58+ if not uri :
59+ return
60+
61+ full_uri = f"169.254.170.2{ uri } "
62+ data = _fetch_parse_uri (full_uri )
63+
64+ airline .add_context_field ('aws.role_arn' , data .get ('RoleArn' ))
65+ airline .add_context_field ('aws.access_key_id' , data .get ('AccessKeyId' ))
66+
67+
68+ def _fetch_parse_uri (uri , attempts = 5 ):
69+ attempt = 0
70+ while True :
71+ try :
72+ attempt += 1
73+ with req .urlopen (uri , timeout = 1 ) as f :
74+ response = json .load (f )
75+ return response
76+ except req .URLError :
77+ if attempt < attempts :
78+ _sleep (attempt )
79+ else :
80+ raise
81+
82+
83+ def _sleep (attempt , cap = 60 , base = 1 ):
84+ sleep_time = random .uniform (0 , min (cap , base * 2 ** attempt ))
85+ time .sleep (sleep_time )
0 commit comments