Skip to content

Commit e09178d

Browse files
committed
fix tmds creds response
1 parent f7e2b14 commit e09178d

File tree

17 files changed

+288
-37
lines changed

17 files changed

+288
-37
lines changed

agent/api/task/task.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,10 @@ type Task struct {
245245
// perform some action at the task level, such as pulling image from ECR
246246
ExecutionCredentialsID string `json:"executionCredentialsID"`
247247

248-
// credentialsID is used to set the CredentialsId field for the
248+
// CredentialsID is used to set the CredentialsId field for the
249249
// IAMRoleCredentials object associated with the task. This id can be
250250
// used to look up the credentials for task in the credentials manager
251-
credentialsID string
251+
CredentialsID string `json:"credentialsID"`
252252
credentialsRelativeURIUnsafe string
253253

254254
// ENIs is the list of Elastic Network Interfaces assigned to this task. The
@@ -2805,15 +2805,15 @@ func (task *Task) SetCredentialsID(id string) {
28052805
task.lock.Lock()
28062806
defer task.lock.Unlock()
28072807

2808-
task.credentialsID = id
2808+
task.CredentialsID = id
28092809
}
28102810

28112811
// GetCredentialsID gets the credentials ID for the task
28122812
func (task *Task) GetCredentialsID() string {
28132813
task.lock.RLock()
28142814
defer task.lock.RUnlock()
28152815

2816-
return task.credentialsID
2816+
return task.CredentialsID
28172817
}
28182818

28192819
// SetCredentialsRelativeURI sets the credentials relative uri for the task

agent/api/task/task_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@ func TestGetCredentialsEndpointWhenCredentialsAreSet(t *testing.T) {
10041004
Name: "c2",
10051005
Environment: make(map[string]string),
10061006
}},
1007-
credentialsID: credentialsIDInTask,
1007+
CredentialsID: credentialsIDInTask,
10081008
}
10091009

10101010
taskCredentials := credentials.TaskIAMRoleCredentials{

agent/api/task/taskvolume_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ func TestMarshalTaskVolumesEFS(t *testing.T) {
121121
"ExecutionStoppedAt": "0001-01-01T00:00:00Z",
122122
"SentStatus": "NONE",
123123
"executionCredentialsID": "",
124+
"credentialsID": "",
124125
"ENI": null,
125126
"AppMesh": null,
126127
"PlatformFields": %s
@@ -168,6 +169,7 @@ func TestUnmarshalTaskVolumesEFS(t *testing.T) {
168169
"ExecutionStoppedAt": "0001-01-01T00:00:00Z",
169170
"SentStatus": "NONE",
170171
"executionCredentialsID": "",
172+
"credentialsID": "",
171173
"ENI": null,
172174
"AppMesh": null,
173175
"PlatformFields": {}
@@ -241,6 +243,7 @@ func TestMarshalEBSVolumes(t *testing.T) {
241243
"ExecutionStoppedAt": "0001-01-01T00:00:00Z",
242244
"SentStatus": "NONE",
243245
"executionCredentialsID": "",
246+
"credentialsID": "",
244247
"ENI": null,
245248
"AppMesh": null,
246249
"PlatformFields": %s
@@ -286,6 +289,7 @@ func TestUnmarshalEBSVolumes(t *testing.T) {
286289
"ExecutionStoppedAt": "0001-01-01T00:00:00Z",
287290
"SentStatus": "NONE",
288291
"executionCredentialsID": "",
292+
"credentialsID": "",
289293
"ENI": null,
290294
"AppMesh": null,
291295
"PlatformFields": {}

agent/api/task/taskvolume_windows_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ func TestMarshalTaskVolumeFSxWindowsFileServer(t *testing.T) {
7878
"ExecutionStoppedAt": "0001-01-01T00:00:00Z",
7979
"SentStatus": "NONE",
8080
"executionCredentialsID": "",
81+
"credentialsID": "",
8182
"ENI": null,
8283
"AppMesh": null,
8384
"PlatformFields": %s
@@ -117,6 +118,7 @@ func TestUnmarshalTaskVolumeFSxWindowsFileServer(t *testing.T) {
117118
"ExecutionStoppedAt": "0001-01-01T00:00:00Z",
118119
"SentStatus": "NONE",
119120
"executionCredentialsID": "",
121+
"credentialsID": "",
120122
"ENI": null,
121123
"AppMesh": null,
122124
"PlatformFields": {}

agent/engine/data.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ func (engine *DockerTaskEngine) loadTasks() error {
5656
for _, task := range tasks {
5757
engine.state.AddTask(task)
5858

59+
// Register the task role's ID in credentials manager as soon as possible.
60+
// This ensures TMDS can distinguish between invalid credentials requests (400) and
61+
// known credentials that aren't available yet (503) after agent restart.
62+
if credentialsID := task.GetCredentialsID(); credentialsID != "" {
63+
seelog.Infof("loadTasks: Registering known credentials ID: %s for task: %s", credentialsID, task.Arn)
64+
engine.credentialsManager.AddKnownCredentialsID(credentialsID)
65+
} else {
66+
seelog.Debugf("loadTasks: Task %s has no credentials ID", task.Arn)
67+
}
68+
5969
// TODO: Will need to clean up all of the STOPPED managed daemon tasks
6070
md, ok := task.IsManagedDaemonTask()
6171
if ok {

agent/engine/data_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ import (
2727
"github.com/aws/amazon-ecs-agent/ecs-agent/api/attachment"
2828
apicontainerstatus "github.com/aws/amazon-ecs-agent/ecs-agent/api/container/status"
2929
apitaskstatus "github.com/aws/amazon-ecs-agent/ecs-agent/api/task/status"
30+
mock_credentials "github.com/aws/amazon-ecs-agent/ecs-agent/credentials/mocks"
3031
ni "github.com/aws/amazon-ecs-agent/ecs-agent/netlib/model/networkinterface"
3132

33+
"github.com/golang/mock/gomock"
3234
"github.com/stretchr/testify/assert"
3335
"github.com/stretchr/testify/require"
3436
)
@@ -376,3 +378,40 @@ func TestRemoveENIAttachmentData(t *testing.T) {
376378
require.NoError(t, err)
377379
assert.Len(t, res, 0)
378380
}
381+
382+
func TestLoadTasksRegistersCredentialsID(t *testing.T) {
383+
ctrl := gomock.NewController(t)
384+
defer ctrl.Finish()
385+
386+
dataClient := newTestDataClient(t)
387+
mockCredentialsManager := mock_credentials.NewMockManager(ctrl)
388+
389+
// Create a task with credentials ID
390+
testCredentialsID := "test-credentials-id"
391+
taskWithCredentials := &apitask.Task{
392+
Arn: testTaskARN,
393+
Containers: []*apicontainer.Container{testContainer},
394+
}
395+
// Set the credentials ID after task creation
396+
taskWithCredentials.SetCredentialsID(testCredentialsID)
397+
398+
// Save task to data client
399+
require.NoError(t, dataClient.SaveTask(taskWithCredentials))
400+
401+
engine := &DockerTaskEngine{
402+
state: dockerstate.NewTaskEngineState(),
403+
dataClient: dataClient,
404+
credentialsManager: mockCredentialsManager,
405+
}
406+
407+
// Expect credentials ID to be added to known credentials during loadTasks
408+
mockCredentialsManager.EXPECT().AddKnownCredentialsID(testCredentialsID)
409+
410+
// Call loadTasks and verify credentials ID is registered
411+
require.NoError(t, engine.loadTasks())
412+
413+
// Verify task was loaded into state
414+
task, ok := engine.state.TaskByArn(testTaskARN)
415+
assert.True(t, ok)
416+
assert.Equal(t, testCredentialsID, task.GetCredentialsID())
417+
}

agent/handlers/task_server_setup_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,17 @@ func getResponseForCredentialsRequest(t *testing.T, expectedStatus int,
11061106
recorder := httptest.NewRecorder()
11071107

11081108
creds, ok := getCredentials()
1109-
credentialsManager.EXPECT().GetTaskCredentials(gomock.Any()).Return(creds, ok)
1109+
1110+
// For credentials uninitialized tests, IsCredentialsPending should return true
1111+
if expectedStatus == http.StatusServiceUnavailable && ok {
1112+
credentialsManager.EXPECT().IsCredentialsPending(gomock.Any()).Return(true)
1113+
// GetTaskCredentials should not be called since IsCredentialsPending returns true
1114+
} else {
1115+
// For all other cases, IsCredentialsPending should return false
1116+
credentialsManager.EXPECT().IsCredentialsPending(gomock.Any()).Return(false)
1117+
credentialsManager.EXPECT().GetTaskCredentials(gomock.Any()).Return(creds, ok)
1118+
}
1119+
11101120
auditLog.EXPECT().Log(gomock.Any(), gomock.Any(), gomock.Any())
11111121

11121122
params := make(url.Values)

agent/vendor/github.com/aws/amazon-ecs-agent/ecs-agent/credentials/interface.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

agent/vendor/github.com/aws/amazon-ecs-agent/ecs-agent/credentials/manager.go

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

agent/vendor/github.com/aws/amazon-ecs-agent/ecs-agent/credentials/mocks/credentials_mocks.go

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)