@@ -9,27 +9,26 @@ class InstanceMetadata
99 PORT = 80
1010 HTTP_TIMEOUT = 30
1111
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+
1217 def self . host_identifier
1318 "arn:#{ partition } :ec2:#{ doc [ 'region' ] } :#{ doc [ 'accountId' ] } :instance/#{ doc [ 'instanceId' ] } "
1419 end
1520
1621 def self . partition
17- http_get ( '/latest/meta-data/services/partition' ) . strip
22+ get_metadata_wrapper ( PARTITION_PATH ) . strip
1823 end
1924
2025 def self . region
21- doc [ 'region' ]
26+ doc [ 'region' ] . strip
2227 end
2328
2429 def self . instance_id
2530 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 )
3332 rescue
3433 return nil
3534 end
@@ -39,19 +38,48 @@ class InstanceMetadataError < StandardError
3938 end
4039
4140 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 )
4555 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 } "
4857 end
4958 return response . body
5059 end
5160 end
5261
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+
5476 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
5684 end
5785end
0 commit comments