Skip to content

Commit 8d7fdba

Browse files
authored
aws/ec2rolecreds: Fix security creds path to include trailing slash (#356)
Fixes the EC2 Instance Metadata Service client to no longer squash the trailing slash when requesting instance metadata. Also, fixes the iamSecurityCredsPath var to include a trailing slash preventing redirects when making requests to the EC2 Instance Metadata service. Fix #351 Related to #351
1 parent 30227e2 commit 8d7fdba

File tree

6 files changed

+45
-19
lines changed

6 files changed

+45
-19
lines changed

CHANGELOG_PENDING.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
### SDK Enhancements
44

55
### SDK Bugs
6-
* `private/model`: Handles empty map vs unset map behavior in send request ([#337](https://github.com/aws/aws-sdk-go-v2/pull/337))
7-
* Updates shape marshal model to handle the empty map vs nil map behavior. Also adds a test case to assert behavior when a user sends an empty map vs unset map.
8-
* Fixes [#332](https://github.com/aws/aws-sdk-go-v2/issues/332)
6+
* `aws/ec2rolecreds`: Fix security creds path to include trailing slash ([#356](https://github.com/aws/aws-sdk-go-v2/pull/356))
7+
* Fixes the iamSecurityCredsPath var to include a trailing slash preventing redirects when making requests to the EC2 Instance Metadata service.
8+
* Fixes [#351](https://github.com/aws/aws-sdk-go-v2/issues/351)

aws/ec2metadata/service_test.go renamed to aws/ec2metadata/api_client_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func TestClientDisableIMDS(t *testing.T) {
2020

2121
cfg := unit.Config()
2222
cfg.LogLevel = aws.LogDebugWithHTTPBody
23+
cfg.Logger = t
2324

2425
svc := ec2metadata.New(cfg)
2526
resp, err := svc.Region()

aws/ec2metadata/api_ops.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func (c *Client) GetMetadata(p string) (string, error) {
1919
op := &aws.Operation{
2020
Name: "GetMetadata",
2121
HTTPMethod: "GET",
22-
HTTPPath: path.Join("/", "meta-data", p),
22+
HTTPPath: suffixPath("/meta-data", p),
2323
}
2424

2525
output := &metadataOutput{}
@@ -35,7 +35,7 @@ func (c *Client) GetUserData() (string, error) {
3535
op := &aws.Operation{
3636
Name: "GetUserData",
3737
HTTPMethod: "GET",
38-
HTTPPath: path.Join("/", "user-data"),
38+
HTTPPath: "/user-data",
3939
}
4040

4141
output := &metadataOutput{}
@@ -56,7 +56,7 @@ func (c *Client) GetDynamicData(p string) (string, error) {
5656
op := &aws.Operation{
5757
Name: "GetDynamicData",
5858
HTTPMethod: "GET",
59-
HTTPPath: path.Join("/", "dynamic", p),
59+
HTTPPath: suffixPath("/dynamic", p),
6060
}
6161

6262
output := &metadataOutput{}
@@ -160,3 +160,11 @@ type EC2InstanceIdentityDocument struct {
160160
RamdiskID string `json:"ramdiskId"`
161161
Architecture string `json:"architecture"`
162162
}
163+
164+
func suffixPath(base, add string) string {
165+
reqPath := path.Join(base, add)
166+
if len(add) != 0 && add[len(add)-1] == '/' {
167+
reqPath += "/"
168+
}
169+
return reqPath
170+
}

aws/ec2metadata/api_test.go renamed to aws/ec2metadata/api_ops_test.go

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"io/ioutil"
88
"net/http"
99
"net/http/httptest"
10-
"path"
1110
"strings"
1211
"testing"
1312

@@ -68,7 +67,7 @@ func TestEndpoint(t *testing.T) {
6867
op := &aws.Operation{
6968
Name: "GetMetadata",
7069
HTTPMethod: "GET",
71-
HTTPPath: path.Join("/", "meta-data", "testpath"),
70+
HTTPPath: "/meta-data/testpath",
7271
}
7372

7473
req := c.NewRequest(op, nil, nil)
@@ -93,9 +92,29 @@ func TestGetMetadata(t *testing.T) {
9392
c := ec2metadata.New(cfg)
9493

9594
resp, err := c.GetMetadata("some/path")
95+
if err != nil {
96+
t.Fatalf("expect no error, got %v", err)
97+
}
98+
if e, a := "success", resp; e != a {
99+
t.Errorf("expect %v, got %v", e, a)
100+
}
101+
}
102+
103+
func TestGetMetadata_TrailingSlash(t *testing.T) {
104+
server := initTestServer(
105+
"/latest/meta-data/some/path/",
106+
"success", // real response includes suffix
107+
)
108+
defer server.Close()
109+
110+
cfg := unit.Config()
111+
cfg.EndpointResolver = aws.ResolveWithEndpointURL(server.URL + "/latest")
96112

113+
c := ec2metadata.New(cfg)
114+
115+
resp, err := c.GetMetadata("some/path/")
97116
if err != nil {
98-
t.Errorf("expect no error, got %v", err)
117+
t.Fatalf("expect no error, got %v", err)
99118
}
100119
if e, a := "success", resp; e != a {
101120
t.Errorf("expect %v, got %v", e, a)
@@ -115,9 +134,8 @@ func TestGetUserData(t *testing.T) {
115134
c := ec2metadata.New(cfg)
116135

117136
resp, err := c.GetUserData()
118-
119137
if err != nil {
120-
t.Errorf("expect no error, got %v", err)
138+
t.Fatalf("expect no error, got %v", err)
121139
}
122140
if e, a := "success", resp; e != a {
123141
t.Errorf("expect %v, got %v", e, a)
@@ -152,7 +170,7 @@ func TestGetUserData_Error(t *testing.T) {
152170

153171
resp, err := c.GetUserData()
154172
if err == nil {
155-
t.Errorf("expect error")
173+
t.Fatalf("expect error")
156174
}
157175
if len(resp) != 0 {
158176
t.Errorf("expect empty, got %v", resp)
@@ -177,9 +195,8 @@ func TestGetRegion(t *testing.T) {
177195
c := ec2metadata.New(cfg)
178196

179197
region, err := c.Region()
180-
181198
if err != nil {
182-
t.Errorf("expect no error, got %v", err)
199+
t.Fatalf("expect no error, got %v", err)
183200
}
184201
if e, a := "us-west-2", region; e != a {
185202
t.Errorf("expect %v, got %v", e, a)
@@ -217,7 +234,7 @@ func TestMetadataIAMInfo_success(t *testing.T) {
217234

218235
iamInfo, err := c.IAMInfo()
219236
if err != nil {
220-
t.Errorf("expect no error, got %v", err)
237+
t.Fatalf("expect no error, got %v", err)
221238
}
222239
if e, a := "Success", iamInfo.Code; e != a {
223240
t.Errorf("expect %v, got %v", e, a)
@@ -244,7 +261,7 @@ func TestMetadataIAMInfo_failure(t *testing.T) {
244261

245262
iamInfo, err := c.IAMInfo()
246263
if err == nil {
247-
t.Errorf("expect error")
264+
t.Fatalf("expect error")
248265
}
249266
if e, a := "", iamInfo.Code; e != a {
250267
t.Errorf("expect %v, got %v", e, a)
@@ -310,7 +327,7 @@ func TestEC2RoleProviderInstanceIdentity(t *testing.T) {
310327

311328
doc, err := c.GetInstanceIdentityDocument()
312329
if err != nil {
313-
t.Errorf("expect no error, got %v", err)
330+
t.Fatalf("expect no error, got %v", err)
314331
}
315332
if e, a := doc.AccountID, "123456789012"; e != a {
316333
t.Errorf("expect %v, got %v", e, a)

aws/ec2rolecreds/provider.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ type ec2RoleCredRespBody struct {
102102
Message string
103103
}
104104

105-
const iamSecurityCredsPath = "/iam/security-credentials"
105+
const iamSecurityCredsPath = "/iam/security-credentials/"
106106

107107
// requestCredList requests a list of credentials from the EC2 service.
108108
// If there are no credentials, or there is an error making or receiving the request

aws/ec2rolecreds/provider_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const credsFailRespTmpl = `{
3333

3434
func initTestServer(expireOn string, failAssume bool) *httptest.Server {
3535
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
36-
if r.URL.Path == "/latest/meta-data/iam/security-credentials" {
36+
if r.URL.Path == "/latest/meta-data/iam/security-credentials/" {
3737
fmt.Fprintln(w, "RoleName")
3838
} else if r.URL.Path == "/latest/meta-data/iam/security-credentials/RoleName" {
3939
if failAssume {

0 commit comments

Comments
 (0)