9
9
EC2_HOST_NAME_URI = DEFAULT_EC2_METADATA_URI + "local-hostname"
10
10
EC2_HOST_INSTANCE_TYPE_URI = DEFAULT_EC2_METADATA_URI + "instance-type"
11
11
12
+ # Used for IMDSv2 to retrieve API token that will be used to call the EC2 METADATA service.
13
+ # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html
14
+ # Bandit marks the following line as risky because it contains the word "token",
15
+ # thought it doesn't contain any secret; ignoring with # nosec
16
+ # https://bandit.readthedocs.io/en/latest/plugins/b105_hardcoded_password_string.html
17
+ EC2_API_TOKEN_URI = "http://169.254.169.254/latest/api/token" # nosec
18
+ EC2_METADATA_TOKEN_HEADER_KEY = 'X-aws-ec2-metadata-token' # nosec
19
+ EC2_METADATA_TOKEN_TTL_HEADER_KEY = 'X-aws-ec2-metadata-token-ttl-seconds' # nosec
20
+ EC2_METADATA_TOKEN_TTL_HEADER_VALUE = '21600' # nosec
21
+
12
22
logger = logging .getLogger (__name__ )
13
23
24
+
14
25
class AWSEC2Instance (FleetInfo ):
15
26
"""
16
27
This class will get and parse the EC2 metadata if available.
@@ -26,29 +37,47 @@ def get_fleet_instance_id(self):
26
37
return self .host_name
27
38
28
39
@classmethod
29
- def __look_up_host_name (cls ):
30
- # The id of the fleet element. Eg. host name in ec2.
31
- return http_get (url = EC2_HOST_NAME_URI ).read ().decode ()
40
+ def __look_up_host_name (cls , token ):
41
+ """
42
+ The id of the fleet element. Eg. host name in ec2.
43
+ """
44
+ return cls .__look_up_with_IMDSv2 (EC2_HOST_NAME_URI , token )
45
+
46
+ @classmethod
47
+ def __look_up_instance_type (cls , token ):
48
+ """
49
+ The type of the instance. Eg. m5.2xlarge
50
+ """
51
+ return cls .__look_up_with_IMDSv2 (EC2_HOST_INSTANCE_TYPE_URI , token )
32
52
33
53
@classmethod
34
- def __look_up_instance_type (cls ):
35
- return http_get (url = EC2_HOST_INSTANCE_TYPE_URI ).read ().decode ()
54
+ def __look_up_with_IMDSv2 (cls , url , token ):
55
+ return http_get (url = url ,
56
+ headers = {EC2_METADATA_TOKEN_HEADER_KEY : token }) \
57
+ .read ().decode ()
58
+
59
+ @classmethod
60
+ def __look_up_ec2_api_token (cls ):
61
+ return http_get (url = EC2_API_TOKEN_URI ,
62
+ headers = {EC2_METADATA_TOKEN_TTL_HEADER_KEY : EC2_METADATA_TOKEN_TTL_HEADER_VALUE }) \
63
+ .read ().decode ()
36
64
37
65
@classmethod
38
66
def look_up_metadata (cls ):
39
67
try :
68
+ token = cls .__look_up_ec2_api_token ()
40
69
return cls (
41
- host_name = cls .__look_up_host_name (),
42
- host_type = cls .__look_up_instance_type ()
70
+ host_name = cls .__look_up_host_name (token ),
71
+ host_type = cls .__look_up_instance_type (token )
43
72
)
44
73
except Exception :
45
74
log_exception (logger , "Unable to get Ec2 instance metadata, this is normal when running in a different "
46
75
"environment (e.g. Fargate), profiler will still work" )
47
76
return None
48
-
77
+
49
78
def serialize_to_map (self ):
50
79
return {
51
- "computeType" : "aws_ec2_instance" ,
52
- "hostName" : self .host_name ,
80
+ "computeType" : "aws_ec2_instance" ,
81
+ "hostName" : self .host_name ,
53
82
"hostType" : self .host_type
54
83
}
0 commit comments