diff --git a/agent/api/container/container.go b/agent/api/container/container.go index cfddbf776ee..97f3210b605 100644 --- a/agent/api/container/container.go +++ b/agent/api/container/container.go @@ -896,7 +896,7 @@ func (c *Container) ShouldCreateWithASMSecret() bool { } // MergeEnvironmentVariables appends additional envVarName:envVarValue pairs to -// the the container's enviornment values structure +// the the container's environment values structure func (c *Container) MergeEnvironmentVariables(envVars map[string]string) { c.lock.Lock() defer c.lock.Unlock() diff --git a/agent/api/task/task.go b/agent/api/task/task.go index 9d7130ede27..e3a269f94e0 100644 --- a/agent/api/task/task.go +++ b/agent/api/task/task.go @@ -1357,6 +1357,9 @@ func (task *Task) ApplyExecutionRoleLogsAuth(hostConfig *dockercontainer.HostCon return &apierrors.HostConfigError{Msg: "Unable to get execution role credentials for task"} } credentialsEndpointRelativeURI := executionRoleCredentials.IAMRoleCredentials.GenerateCredentialsEndpointRelativeURI() + if hostConfig.LogConfig.Config == nil { + hostConfig.LogConfig.Config = map[string]string{} + } hostConfig.LogConfig.Config[awslogsCredsEndpointOpt] = credentialsEndpointRelativeURI return nil } @@ -2289,6 +2292,9 @@ func populateContainerSecrets(hostConfig *dockercontainer.HostConfig, container // Check if all the name and secret value for the log driver do exist // And add the secret value for this log driver into container's HostConfig if hostConfig.LogConfig.Type != "" && logDriverTokenName != "" && logDriverTokenSecretValue != "" { + if hostConfig.LogConfig.Config == nil { + hostConfig.LogConfig.Config = map[string]string{} + } hostConfig.LogConfig.Config[logDriverTokenName] = logDriverTokenSecretValue } } diff --git a/agent/api/task/task_test.go b/agent/api/task/task_test.go index a9e290a1955..817a5b5d778 100644 --- a/agent/api/task/task_test.go +++ b/agent/api/task/task_test.go @@ -1602,10 +1602,57 @@ func TestApplyExecutionRoleLogsAuthSet(t *testing.T) { } rawHostConfig, err := json.Marshal(&rawHostConfigInput) - if err != nil { - t.Fatal(err) + require.NoError(t, err) + + task := &Task{ + Arn: "arn:aws:ecs:us-east-1:012345678910:task/c09f0188-7f87-4b0f-bfc3-16296622b6fe", + Family: "testFamily", + Version: "1", + Containers: []*apicontainer.Container{ + { + Name: "c1", + DockerConfig: apicontainer.DockerConfig{ + HostConfig: strptr(string(rawHostConfig)), + }, + }, + }, + ExecutionCredentialsID: credentialsIDInTask, } + taskCredentials := credentials.TaskIAMRoleCredentials{ + IAMRoleCredentials: credentials.IAMRoleCredentials{CredentialsID: "credsid"}, + } + credentialsManager.EXPECT().GetTaskCredentials(credentialsIDInTask).Return(taskCredentials, true) + task.initializeCredentialsEndpoint(credentialsManager) + + config, err := task.DockerHostConfig(task.Containers[0], dockerMap(task), defaultDockerClientAPIVersion) + assert.Nil(t, err) + + err = task.ApplyExecutionRoleLogsAuth(config, credentialsManager) + assert.Nil(t, err) + + endpoint, ok := config.LogConfig.Config["awslogs-credentials-endpoint"] + assert.True(t, ok) + assert.Equal(t, expectedEndpoint, endpoint) +} + +func TestApplyExecutionRoleLogsAuthNoConfigInHostConfig(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + credentialsManager := mock_credentials.NewMockManager(ctrl) + + credentialsIDInTask := "credsid" + expectedEndpoint := "/v2/credentials/" + credentialsIDInTask + + rawHostConfigInput := dockercontainer.HostConfig{ + LogConfig: dockercontainer.LogConfig{ + Type: "foo", + }, + } + + rawHostConfig, err := json.Marshal(&rawHostConfigInput) + require.NoError(t, err) + task := &Task{ Arn: "arn:aws:ecs:us-east-1:012345678910:task/c09f0188-7f87-4b0f-bfc3-16296622b6fe", Family: "testFamily", @@ -1651,9 +1698,7 @@ func TestApplyExecutionRoleLogsAuthFailEmptyCredentialsID(t *testing.T) { } rawHostConfig, err := json.Marshal(&rawHostConfigInput) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) task := &Task{ Arn: "arn:aws:ecs:us-east-1:012345678910:task/c09f0188-7f87-4b0f-bfc3-16296622b6fe", @@ -1693,9 +1738,7 @@ func TestApplyExecutionRoleLogsAuthFailNoCredentialsForTask(t *testing.T) { } rawHostConfig, err := json.Marshal(&rawHostConfigInput) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) task := &Task{ Arn: "arn:aws:ecs:us-east-1:012345678910:task/c09f0188-7f87-4b0f-bfc3-16296622b6fe", @@ -2545,7 +2588,9 @@ func TestPopulateSecrets(t *testing.T) { hostConfig := &dockercontainer.HostConfig{} logDriverName := "splunk" hostConfig.LogConfig.Type = logDriverName - configMap := map[string]string{} + configMap := map[string]string{ + "splunk-option": "option", + } hostConfig.LogConfig.Config = configMap ssmRes := &ssmsecret.SSMSecretResource{} @@ -2564,6 +2609,40 @@ func TestPopulateSecrets(t *testing.T) { assert.Equal(t, "secretValue2", container.Environment["secret2"]) assert.Equal(t, "", container.Environment["secret3"]) assert.Equal(t, "secretValue3", hostConfig.LogConfig.Config["splunk-token"]) + assert.Equal(t, "option", hostConfig.LogConfig.Config["splunk-option"]) +} + +func TestPopulateSecretsNoConfigInHostConfig(t *testing.T) { + secret1 := apicontainer.Secret{ + Provider: "ssm", + Name: "splunk-token", + Region: "us-west-1", + Target: "LOG_DRIVER", + ValueFrom: "/test/secretName1", + } + + container := &apicontainer.Container{ + Name: "myName", + Image: "image:tag", + Secrets: []apicontainer.Secret{secret1}, + TransitionDependenciesMap: make(map[apicontainerstatus.ContainerStatus]apicontainer.TransitionDependencySet), + } + + task := &Task{ + Arn: "test", + ResourcesMapUnsafe: make(map[string][]taskresource.TaskResource), + Containers: []*apicontainer.Container{container}, + } + + hostConfig := &dockercontainer.HostConfig{} + logDriverName := "splunk" + hostConfig.LogConfig.Type = logDriverName + + ssmRes := &ssmsecret.SSMSecretResource{} + ssmRes.SetCachedSecretValue(secKeyLogDriver, "secretValue1") + task.AddResource(ssmsecret.ResourceName, ssmRes) + task.PopulateSecrets(hostConfig, container) + assert.Equal(t, "secretValue1", hostConfig.LogConfig.Config["splunk-token"]) } func TestPopulateSecretsAsEnvOnlySSM(t *testing.T) {