@@ -9,27 +9,26 @@ class InstanceMetadata
9
9
PORT = 80
10
10
HTTP_TIMEOUT = 30
11
11
12
+ PARTITION_PATH = '/latest/meta-data/services/partition'
13
+ INSTANCE_ID_PATH = '/latest/meta-data/instance-id'
14
+ TOKEN_PATH = '/latest/api/token'
15
+ DOCUMENT_PATH = '/latest/dynamic/instance-identity/document'
16
+
12
17
def self . host_identifier
13
18
"arn:#{ partition } :ec2:#{ doc [ 'region' ] } :#{ doc [ 'accountId' ] } :instance/#{ doc [ 'instanceId' ] } "
14
19
end
15
20
16
21
def self . partition
17
- http_get ( '/latest/meta-data/services/partition' ) . strip
22
+ get_metadata_wrapper ( PARTITION_PATH ) . strip
18
23
end
19
24
20
25
def self . region
21
- doc [ 'region' ]
26
+ doc [ 'region' ] . strip
22
27
end
23
28
24
29
def self . instance_id
25
30
begin
26
- Net ::HTTP . start ( IP_ADDRESS , PORT ) do |http |
27
- response = http . get ( '/latest/meta-data/instance-id' )
28
- if response . code . to_i != 200
29
- return nil
30
- end
31
- return response . body
32
- end
31
+ get_metadata_wrapper ( INSTANCE_ID_PATH )
33
32
rescue
34
33
return nil
35
34
end
@@ -39,19 +38,48 @@ class InstanceMetadataError < StandardError
39
38
end
40
39
41
40
private
42
- def self . http_get ( path )
43
- Net ::HTTP . start ( IP_ADDRESS , PORT , :read_timeout => HTTP_TIMEOUT /2 , :open_timeout => HTTP_TIMEOUT /2 ) do |http |
44
- response = http . get ( path )
41
+ def self . get_metadata_wrapper ( path )
42
+ begin
43
+ token = put_request ( TOKEN_PATH )
44
+ get_request ( path , token )
45
+ rescue
46
+ InstanceAgent ::Log . send ( :info , "IMDSv2 http request failed, falling back to IMDSv1." )
47
+ get_request ( path )
48
+ end
49
+
50
+ end
51
+
52
+ def self . http_request ( request )
53
+ Net ::HTTP . start ( IP_ADDRESS , PORT , :read_timeout => 120 , :open_timeout => 120 ) do |http |
54
+ response = http . request ( request )
45
55
if response . code . to_i != 200
46
- InstanceAgent ::Log . send ( :debug , "HTTP error from metadata service, code #{ response . code } " )
47
- raise "HTTP error from metadata service, code #{ response . code } "
56
+ raise "HTTP error from metadata service: #{ response . message } , code #{ response . code } "
48
57
end
49
58
return response . body
50
59
end
51
60
end
52
61
53
- private
62
+ def self . put_request ( path )
63
+ request = Net ::HTTP ::Put . new ( path )
64
+ request [ 'X-aws-ec2-metadata-token-ttl-seconds' ] = '21600'
65
+ http_request ( request )
66
+ end
67
+
68
+ def self . get_request ( path , token = nil )
69
+ request = Net ::HTTP ::Get . new ( path )
70
+ unless token . nil?
71
+ request [ 'X-aws-ec2-metadata-token' ] = token
72
+ end
73
+ http_request ( request )
74
+ end
75
+
54
76
def self . doc
55
- JSON . parse ( http_get ( '/latest/dynamic/instance-identity/document' ) . strip )
77
+ begin
78
+ token = put_request ( TOKEN_PATH )
79
+ JSON . parse ( get_request ( DOCUMENT_PATH , token ) . strip )
80
+ rescue
81
+ InstanceAgent ::Log . send ( :info , "IMDSv2 http request failed, falling back to IMDSv1." )
82
+ JSON . parse ( get_request ( DOCUMENT_PATH ) . strip )
83
+ end
56
84
end
57
85
end
0 commit comments