@@ -21,8 +21,8 @@ import (
2121 "context"
2222 "encoding/json"
2323 "fmt"
24- "io"
2524 "net/http"
25+ "path"
2626 "strings"
2727 "time"
2828
@@ -32,7 +32,9 @@ import (
3232)
3333
3434const (
35- IMDSURL = "http://169.254.169.254/latest/meta-data/"
35+ IMDS = "http://169.254.169.254"
36+ IMDS_TOKEN_URL = IMDS + "/latest/api/token"
37+ IMDS_URL = IMDS + "/latest/meta-data"
3638
3739 tokenTimeDelay = 15 * time .Second
3840)
@@ -45,20 +47,59 @@ type Creds struct {
4547 Expiration string `json:"Expiration"`
4648}
4749
48- func getMetadata (path string ) ([]byte , error ) {
49- url := IMDSURL + path
50+ func getToken () (string , error ) {
51+ req , err := http .NewRequest ("PUT" , IMDS_TOKEN_URL , nil )
52+ if err != nil {
53+ return "" , fmt .Errorf ("failed to create HTTP request: %v" , err )
54+ }
55+
56+ req .Header .Add ("X-aws-ec2-metadata-token-ttl-seconds" , "21600" )
57+
58+ _ , data , err := utils .HttpRequest (req )
59+ if err != nil {
60+ return "" , fmt .Errorf ("failed to send HTTP request: %v" , err )
61+ }
5062
51- resp , err := http .Get (url )
63+ return string (data ), nil
64+ }
65+
66+ func addToken (req * http.Request ) error {
67+ token , err := getToken ()
68+ if err != nil {
69+ return err
70+ }
71+
72+ if len (token ) != 0 {
73+ req .Header .Add ("X-aws-ec2-metadata-token" , token )
74+ }
75+
76+ return nil
77+ }
78+
79+ func getMetadata (route string ) ([]byte , error ) {
80+ url := path .Join (IMDS_URL , route )
81+ klog .V (4 ).Infof ("Requesting URL %s" , url )
82+
83+ req , err := http .NewRequest ("GET" , url , nil )
84+ if err != nil {
85+ return nil , fmt .Errorf ("failed to create HTTP request: %v" , err )
86+ }
87+
88+ err = addToken (req )
5289 if err != nil {
5390 return nil , err
5491 }
55- defer func () { _ = resp .Body .Close () }()
92+
93+ resp , data , err := utils .HttpRequest (req )
94+ if err != nil {
95+ return nil , fmt .Errorf ("failed to send HTTP request: %v" , err )
96+ }
5697
5798 if resp .StatusCode != http .StatusOK {
5899 return nil , fmt .Errorf ("HTTP status: %s" , resp .Status )
59100 }
60101
61- return io . ReadAll ( resp . Body )
102+ return data , nil
62103}
63104
64105func GetRegion () (string , error ) {
@@ -71,22 +112,22 @@ func GetRegion() (string, error) {
71112}
72113
73114func GetCredentials () (* Creds , error ) {
74- path := "iam/security-credentials"
75- data , err := getMetadata (path )
115+ route := "iam/security-credentials"
116+ data , err := getMetadata (route )
76117 if err != nil {
77118 return nil , err
78119 }
79120
80121 lines := strings .Split (string (data ), "\n " )
81122 for _ , line := range lines {
82- path = fmt . Sprintf ( "%s/%s" , path , line )
123+ route = path . Join ( route , line )
83124 break
84125 }
85126
86127 // ensure the credentials remain valid for at least the next tokenTimeDelay
87128 for {
88- klog .V (4 ).Infof ("Getting credentials from path %s" , path )
89- data , err = getMetadata (path )
129+ klog .V (4 ).Infof ("Getting credentials from %s" , route )
130+ data , err = getMetadata (route )
90131 if err != nil {
91132 return nil , err
92133 }
@@ -114,7 +155,8 @@ func GetCredentials() (*Creds, error) {
114155}
115156
116157func Instance2NodeMap (ctx context.Context , nodes []string ) (map [string ]string , error ) {
117- args := []string {"-w" , strings .Join (nodes , "," ), fmt .Sprintf ("echo $(curl -s %s/instance-id)" , IMDSURL )}
158+ args := []string {"-w" , strings .Join (nodes , "," ),
159+ fmt .Sprintf ("TOKEN=$(curl -s -X PUT -H \" X-aws-ec2-metadata-token-ttl-seconds: 21600\" %s); echo $(curl -s -H \" X-aws-ec2-metadata-token: $TOKEN\" %s)" , IMDS_TOKEN_URL , path .Join (IMDS_URL , "instance-id" ))}
118160
119161 stdout , err := utils .Exec (ctx , "pdsh" , args , nil )
120162 if err != nil {
0 commit comments