Skip to content

Commit

Permalink
aws/ec2metadata: Add support for EC2Metadata client secure token (#2958)
Browse files Browse the repository at this point in the history
aws/ec2metadata: Adds support for EC2Metadata client to use secure tokens provided by the IMDS. Modifies and adds tests to verify the behavior of the EC2Metadata client.
  • Loading branch information
skotambkar authored Nov 19, 2019
1 parent f103b8d commit 1b7071c
Show file tree
Hide file tree
Showing 6 changed files with 1,146 additions and 161 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG_PENDING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
### SDK Features

### SDK Enhancements

* `aws/ec2metadata`: Adds support for EC2Metadata client to use secure tokens provided by the IMDS ([#2958](https://github.com/aws/aws-sdk-go/pull/2958))
* Modifies and adds tests to verify the behavior of the EC2Metadata client.

### SDK Bugs
2 changes: 1 addition & 1 deletion aws/credentials/ec2rolecreds/ec2_role_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func initTestServer(expireOn string, failAssume bool) *httptest.Server {
fmt.Fprintf(w, credsRespTmpl, expireOn)
}
} else {
http.Error(w, "bad request", http.StatusBadRequest)
http.Error(w, "Not found", http.StatusNotFound)
}
}))

Expand Down
49 changes: 39 additions & 10 deletions aws/ec2metadata/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
"time"

Expand All @@ -12,20 +13,53 @@ import (
"github.com/aws/aws-sdk-go/internal/sdkuri"
)

// getToken uses the duration to return a token for EC2 metadata service,
// or an error if the request failed.
func (c *EC2Metadata) getToken(duration time.Duration) (tokenOutput, error) {
op := &request.Operation{
Name: "GetToken",
HTTPMethod: "PUT",
HTTPPath: "/api/token",
}

var output tokenOutput
req := c.NewRequest(op, nil, &output)

// remove the fetch token handler from the request handlers to avoid infinite recursion
req.Handlers.Sign.RemoveByName(fetchTokenHandlerName)

// Swap the unmarshalMetadataHandler with unmarshalTokenHandler on this request.
req.Handlers.Unmarshal.Swap(unmarshalMetadataHandlerName, unmarshalTokenHandler)

ttl := strconv.FormatInt(int64(duration / time.Second),10)
req.HTTPRequest.Header.Set(ttlHeader, ttl)

err := req.Send()

// Errors with bad request status should be returned.
if err != nil {
err = awserr.NewRequestFailure(
awserr.New(req.HTTPResponse.Status, http.StatusText(req.HTTPResponse.StatusCode), err),
req.HTTPResponse.StatusCode, req.RequestID)
}

return output, err
}

// GetMetadata uses the path provided to request information from the EC2
// instance metdata service. The content will be returned as a string, or
// instance metadata service. The content will be returned as a string, or
// error if the request failed.
func (c *EC2Metadata) GetMetadata(p string) (string, error) {
op := &request.Operation{
Name: "GetMetadata",
HTTPMethod: "GET",
HTTPPath: sdkuri.PathJoin("/meta-data", p),
}

output := &metadataOutput{}

req := c.NewRequest(op, nil, output)
err := req.Send()

err := req.Send()
return output.Content, err
}

Expand All @@ -41,13 +75,8 @@ func (c *EC2Metadata) GetUserData() (string, error) {

output := &metadataOutput{}
req := c.NewRequest(op, nil, output)
req.Handlers.UnmarshalError.PushBack(func(r *request.Request) {
if r.HTTPResponse.StatusCode == http.StatusNotFound {
r.Error = awserr.New("NotFoundError", "user-data not found", r.Error)
}
})
err := req.Send()

err := req.Send()
return output.Content, err
}

Expand All @@ -63,8 +92,8 @@ func (c *EC2Metadata) GetDynamicData(p string) (string, error) {

output := &metadataOutput{}
req := c.NewRequest(op, nil, output)
err := req.Send()

err := req.Send()
return output.Content, err
}

Expand Down
Loading

0 comments on commit 1b7071c

Please sign in to comment.