chore: send useIMDSv2 bool from fetchIMDSToken method

Instead of using the errors to figure out whether IMDSv2 needs to be used,
we return a boolean value for useIMDSv2 from the function itself, and
propagate the error to upstream function calls in the library.

IMDSv2 tokens can be used in all cases, even when IMDSv2 is set to `Optional`
in the EC2 Instance configuration. As such, calls with token will not fail and
we should be able to send IMDSv2 requests with token even when using IMDSv1.

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
This commit is contained in:
Chinmay D. Pai
2024-07-03 13:29:48 +05:30
parent 547dfa8756
commit 430bffb2e2
+14 -12
View File
@@ -25,6 +25,7 @@ import (
const (
imdsTokenURL = "http://169.254.169.254/latest/api/token"
imdsTokenHeader = "X-aws-ec2-metadata-token"
imdsTokenTtlHeader = "X-aws-ec2-metadata-token-ttl-seconds"
securityCredentialsURL = "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
// AMZMetaPrefix to prefix metadata key.
@@ -153,32 +154,32 @@ func NewUsingIAM(region string) (*S3, error) {
}
// fetchIMDSToken retrieves an IMDSv2 token from the
// EC2 instance metadata service. It returns a token
// EC2 instance metadata service. It returns a token and boolean,
// only if IMDSv2 is enabled in the EC2 instance metadata
// configuration, otherwise returns an error.
func fetchIMDSToken(cl *http.Client) (string, error) {
func fetchIMDSToken(cl *http.Client) (string, bool, error) {
req, err := http.NewRequest(http.MethodPut, imdsTokenURL, nil)
if err != nil {
return "", err
return "", false, err
}
req.Header.Set("X-aws-ec2-metadata-token-ttl-seconds", "21600")
req.Header.Set(imdsTokenTtlHeader, "21600")
resp, err := cl.Do(req)
if err != nil {
return "", err
return "", false, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("failed to fetch IMDSv2 token: %s", resp.Status)
return "", false, fmt.Errorf("failed to request IMDSv2 token: %s", resp.Status)
}
token, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
return "", false, err
}
return string(token), nil
return string(token), true, nil
}
// fetchIAMData fetches the IAM data from the given URL.
@@ -187,10 +188,11 @@ func fetchIMDSToken(cl *http.Client) (string, error) {
// endpoint and pass it to SetIAMData.
func fetchIAMData(cl *http.Client, baseURL string) (IAMResponse, error) {
var token string
token, err := fetchIMDSToken(cl)
// useIMDSv2 if no errors were returned from
// the fetchIMDSToken method call.
useIMDSv2 := err == nil
var useIMDSv2 bool
token, useIMDSv2, err := fetchIMDSToken(cl)
if err != nil {
return IAMResponse{}, fmt.Errorf("Error fetching IMDSv2 token: %w", err)
}
req, err := http.NewRequest(http.MethodGet, baseURL, nil)
if err != nil {