Skip to content

Commit 48399a7

Browse files
authored
Merge branch 'aws:master' into fix-ecr-migration
2 parents 8f62fed + 7dda21e commit 48399a7

File tree

116 files changed

+20628
-10011
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+20628
-10011
lines changed

Diff for: CHANGELOG.md

+13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
11
# Changelog
2+
# 1.92.0
3+
* Enhancement - Migrate ECS client to aws-sdk-go-v2 [#4447](https://github.com/aws/amazon-ecs-agent/pull/4447)
4+
* Enhancement - Update tcs api model to rename osFilesystem to rootFileSystem. [#4525](https://github.com/aws/amazon-ecs-agent/pull/4525)
5+
* Enhancement - Enhance unit test TestSetInstanceIdentity [#4533](https://github.com/aws/amazon-ecs-agent/pull/4533)
6+
* Enhancement - Increased container exit reason message size from 255 to 1024 characters [#4545](https://github.com/aws/amazon-ecs-agent/pull/4545)
7+
* Enhancement - Bump golang.org/x/net from 0.33.0 to 0.36.0 in /agent [#4532](https://github.com/aws/amazon-ecs-agent/pull/4532)
8+
* Enhancement - Migrate ACS over to AWS SDK Go V2 [#4534](https://github.com/aws/amazon-ecs-agent/pull/4534)
9+
* Enhancement - Migrate ASM to aws-sdk-go-v2 [#4556](https://github.com/aws/amazon-ecs-agent/pull/4556)
10+
* Enhancement - Add IPv4 and IPv6 detection to Agent [#4561](https://github.com/aws/amazon-ecs-agent/pull/4561)
11+
* Enhancement - Update Agent build golang version to 1.23.7 [#4563](https://github.com/aws/amazon-ecs-agent/pull/4563)
12+
* Bugfix - Update tcs api model to rename BytesUtilized to bytesUtilized [#4537](https://github.com/aws/amazon-ecs-agent/pull/4537)
13+
* Bugfix - Change back to having struct field pointers within TaskProtectionResponse [#4559](https://github.com/aws/amazon-ecs-agent/pull/4559)
14+
215
# 1.91.2
316
* Bugfix - Revert "Migrate ECR client to aws-sdk-go-v2". [4539](https://github.com/aws/amazon-ecs-agent/pull/4539)
417

Diff for: GO_VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.22.7
1+
1.23.7

Diff for: GO_VERSION_WINDOWS

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.22.7
1+
1.23.7

Diff for: Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ install-golang:
395395
go install github.com/golang/mock/[email protected]
396396
go install golang.org/x/tools/cmd/[email protected]
397397
GO111MODULE=on go install github.com/fzipp/gocyclo/cmd/[email protected]
398-
GO111MODULE=on go install honnef.co/go/tools/cmd/staticcheck@2023.1.6
398+
GO111MODULE=on go install honnef.co/go/tools/cmd/staticcheck@2025.1.1
399399
touch .get-deps-stamp
400400

401401
get-deps: .get-deps-stamp
@@ -404,7 +404,7 @@ get-deps-init:
404404
go install github.com/golang/mock/[email protected]
405405
go install golang.org/x/tools/cmd/[email protected]
406406
GO111MODULE=on go install github.com/fzipp/gocyclo/cmd/[email protected]
407-
GO111MODULE=on go install honnef.co/go/tools/cmd/staticcheck@v0.4.0
407+
GO111MODULE=on go install honnef.co/go/tools/cmd/staticcheck@2025.1.1
408408

409409
amazon-linux-sources.tgz:
410410
./scripts/update-version.sh

Diff for: VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.91.2
1+
1.92.0

Diff for: agent/acs/session/payload_responder.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ func (pmHandler *payloadMessageHandler) addPayloadTasks(payload *ecsacs.PayloadM
129129
logger.Info("Received task payload from ACS", logger.Fields{
130130
loggerfield.TaskARN: apiTask.Arn,
131131
loggerfield.TaskVersion: apiTask.Version,
132-
loggerfield.DesiredStatus: apiTask.GetDesiredStatus(),
132+
loggerfield.DesiredStatus: apiTask.GetDesiredStatus().String(),
133133
})
134134

135135
if apiTask.IsFaultInjectionEnabled() {

Diff for: agent/api/container/container.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1486,7 +1486,7 @@ func (c *Container) getCredentialSpecFromCredentialSpecsContainerField() (string
14861486
c.lock.RLock()
14871487
defer c.lock.RUnlock()
14881488

1489-
if c.CredentialSpecs == nil || len(c.CredentialSpecs) == 0 {
1489+
if len(c.CredentialSpecs) == 0 {
14901490
return "", errors.New("empty container credentialSpecs")
14911491
}
14921492

Diff for: agent/api/statechange.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ func buildContainerStateChangePayload(change ContainerStateChange) (*types.Conta
521521
stat != apicontainerstatus.ContainerStopped &&
522522
stat != apicontainerstatus.ContainerRunning {
523523
logger.Warn("Not submitting unsupported upstream container state", logger.Fields{
524-
field.Status: stat,
524+
field.Status: stat.String(),
525525
field.ContainerName: change.ContainerName,
526526
field.TaskARN: change.TaskArn,
527527
})

Diff for: agent/api/task/task.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1702,8 +1702,8 @@ func (task *Task) updateTaskKnownStatus() (newStatus apitaskstatus.TaskStatus) {
17021702
logger.Debug("Found container with earliest known status", logger.Fields{
17031703
field.TaskID: task.GetID(),
17041704
field.Container: earliestKnownStatusContainer.Name,
1705-
field.KnownStatus: earliestKnownStatusContainer.GetKnownStatus(),
1706-
field.DesiredStatus: earliestKnownStatusContainer.GetDesiredStatus(),
1705+
field.KnownStatus: earliestKnownStatusContainer.GetKnownStatus().String(),
1706+
field.DesiredStatus: earliestKnownStatusContainer.GetDesiredStatus().String(),
17071707
})
17081708
// If the essential container is stopped while other containers may be running
17091709
// don't update the task status until the other containers are stopped.

Diff for: agent/api/task/task_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ import (
5959

6060
"github.com/aws/aws-sdk-go-v2/aws"
6161
"github.com/aws/aws-sdk-go-v2/service/ecs/types"
62-
"github.com/aws/aws-sdk-go/service/secretsmanager"
62+
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
6363
dockercontainer "github.com/docker/docker/api/types/container"
6464
"github.com/docker/docker/api/types/volume"
6565
"github.com/docker/go-connections/nat"
@@ -2716,8 +2716,8 @@ func TestPopulateASMAuthData(t *testing.T) {
27162716
ARN: "",
27172717
IAMRoleCredentials: executionRoleCredentials,
27182718
}, true),
2719-
asmClientCreator.EXPECT().NewASMClient(region, executionRoleCredentials).Return(mockASMClient),
2720-
mockASMClient.EXPECT().GetSecretValue(gomock.Any()).Return(asmSecretValue, nil),
2719+
asmClientCreator.EXPECT().NewASMClient(region, executionRoleCredentials).Return(mockASMClient, nil),
2720+
mockASMClient.EXPECT().GetSecretValue(gomock.Any(), gomock.Any(), gomock.Any()).Return(asmSecretValue, nil),
27212721
)
27222722

27232723
// create resource

Diff for: agent/app/agent.go

+14
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,8 @@ func (agent *ecsAgent) doStart(containerChangeEventStream *eventstream.EventStre
465465
}
466466
}
467467

468+
initializeIPCompatibility(agent.mac)
469+
468470
// Register the container instance
469471
err = agent.registerContainerInstance(client, vpcSubnetAttributes)
470472
if err != nil {
@@ -1269,3 +1271,15 @@ func contains(capabilities []string, capability string) bool {
12691271

12701272
return false
12711273
}
1274+
1275+
// Determines and sets IPv4 and IPv6 compatibility for the container instance.
1276+
//
1277+
// If there was a failure in determining IP compatibility then this function falls back
1278+
// to default settings, that is, IPv4 compatible but IPv6 incompatible.
1279+
func initializeIPCompatibility(mac string) {
1280+
if err := config.DetermineIPCompatibility(mac); err != nil {
1281+
logger.Warn("Could not determine IPv4 and IPv6 compatibility, falling back to defaults",
1282+
logger.Fields{field.Error: err})
1283+
config.SetIPCompatibilityToV4Only()
1284+
}
1285+
}

Diff for: agent/asm/asm.go

+25-23
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,25 @@
1414
package asm
1515

1616
import (
17+
"context"
1718
"encoding/json"
1819
"fmt"
1920

2021
"github.com/aws/amazon-ecs-agent/ecs-agent/logger"
21-
"github.com/aws/aws-sdk-go/aws"
22-
"github.com/aws/aws-sdk-go/aws/awserr"
23-
"github.com/aws/aws-sdk-go/service/secretsmanager"
24-
"github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface"
22+
23+
"github.com/aws/aws-sdk-go-v2/aws"
24+
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
25+
"github.com/aws/aws-sdk-go-v2/service/secretsmanager/types"
2526
"github.com/cihub/seelog"
2627
"github.com/docker/docker/api/types/registry"
2728
"github.com/pkg/errors"
2829
)
2930

31+
// For mocking purpose
32+
type SecretsManagerAPI interface {
33+
GetSecretValue(ctx context.Context, params *secretsmanager.GetSecretValueInput, optFns ...func(*secretsmanager.Options)) (*secretsmanager.GetSecretValueOutput, error)
34+
}
35+
3036
// AuthDataValue is the schema for
3137
// the SecretStringValue returned by ASM
3238
type AuthDataValue struct {
@@ -46,27 +52,23 @@ func augmentErrMsg(secretID string, err error) string {
4652
logger.Warn("augmentErrMsg: SecretID is empty (which is unexpected)")
4753
}
4854

49-
if aerr, ok := err.(awserr.Error); ok {
50-
switch aerr.Code() {
51-
case secretsmanager.ErrCodeResourceNotFoundException:
52-
secretID = "'" + secretID + "' "
53-
return resourceInitializationErrMsg(secretID)
54-
default:
55-
return fmt.Sprintf("secret %s: %s", secretID, err.Error())
56-
}
55+
var rnfe *types.ResourceNotFoundException
56+
if errors.As(err, &rnfe) {
57+
secretID = "'" + secretID + "' "
58+
return resourceInitializationErrMsg(secretID)
5759
} else {
5860
return fmt.Sprintf("secret %s: %s", secretID, err.Error())
5961
}
6062
}
6163

6264
// GetDockerAuthFromASM makes the api call to the AWS Secrets Manager service to
6365
// retrieve the docker auth data
64-
func GetDockerAuthFromASM(secretID string, client secretsmanageriface.SecretsManagerAPI) (registry.AuthConfig, error) {
66+
func GetDockerAuthFromASM(secretID string, client SecretsManagerAPI) (registry.AuthConfig, error) {
6567
in := &secretsmanager.GetSecretValueInput{
6668
SecretId: aws.String(secretID),
6769
}
6870

69-
out, err := client.GetSecretValue(in)
71+
out, err := client.GetSecretValue(context.TODO(), in)
7072
if err != nil {
7173
return registry.AuthConfig{}, errors.Wrapf(err,
7274
"asm fetching secret from the service for %s", secretID)
@@ -81,7 +83,7 @@ func extractASMValue(out *secretsmanager.GetSecretValueOutput) (registry.AuthCon
8183
"asm fetching authorization data: empty response")
8284
}
8385

84-
secretValue := aws.StringValue(out.SecretString)
86+
secretValue := aws.ToString(out.SecretString)
8587
if secretValue == "" {
8688
return registry.AuthConfig{}, errors.New(
8789
"asm fetching authorization data: empty secrets value")
@@ -95,8 +97,8 @@ func extractASMValue(out *secretsmanager.GetSecretValueOutput) (registry.AuthCon
9597
"asm fetching authorization data: unable to unmarshal secret value, invalid schema")
9698
}
9799

98-
username := aws.StringValue(authDataValue.Username)
99-
password := aws.StringValue(authDataValue.Password)
100+
username := aws.ToString(authDataValue.Username)
101+
password := aws.ToString(authDataValue.Password)
100102

101103
if username == "" {
102104
return registry.AuthConfig{}, errors.New(
@@ -117,15 +119,15 @@ func extractASMValue(out *secretsmanager.GetSecretValueOutput) (registry.AuthCon
117119
}
118120

119121
func GetSecretFromASMWithInput(input *secretsmanager.GetSecretValueInput,
120-
client secretsmanageriface.SecretsManagerAPI, jsonKey string) (string, error) {
122+
client SecretsManagerAPI, jsonKey string) (string, error) {
121123
secretID := *input.SecretId
122-
out, err := client.GetSecretValue(input)
124+
out, err := client.GetSecretValue(context.TODO(), input)
123125
if err != nil {
124126
return "", errors.Wrap(err, augmentErrMsg(secretID, err))
125127
}
126128

127129
if jsonKey == "" {
128-
return aws.StringValue(out.SecretString), nil
130+
return aws.ToString(out.SecretString), nil
129131
}
130132

131133
secretMap := make(map[string]interface{})
@@ -146,15 +148,15 @@ func GetSecretFromASMWithInput(input *secretsmanager.GetSecretValueInput,
146148

147149
// GetSecretFromASM makes the api call to the AWS Secrets Manager service to
148150
// retrieve the secret value
149-
func GetSecretFromASM(secretID string, client secretsmanageriface.SecretsManagerAPI) (string, error) {
151+
func GetSecretFromASM(secretID string, client SecretsManagerAPI) (string, error) {
150152
in := &secretsmanager.GetSecretValueInput{
151153
SecretId: aws.String(secretID),
152154
}
153155

154-
out, err := client.GetSecretValue(in)
156+
out, err := client.GetSecretValue(context.TODO(), in)
155157
if err != nil {
156158
return "", errors.Wrapf(err, "secret %s", secretID)
157159
}
158160

159-
return aws.StringValue(out.SecretString), nil
161+
return aws.ToString(out.SecretString), nil
160162
}

Diff for: agent/asm/asm_test.go

+29-20
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ import (
2121
"testing"
2222

2323
mocks "github.com/aws/amazon-ecs-agent/agent/asm/mocks"
24-
"github.com/aws/aws-sdk-go/aws"
25-
"github.com/aws/aws-sdk-go/aws/awserr"
26-
"github.com/aws/aws-sdk-go/service/secretsmanager"
24+
25+
"github.com/aws/aws-sdk-go-v2/aws"
26+
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
27+
"github.com/aws/aws-sdk-go-v2/service/secretsmanager/types"
28+
"github.com/aws/smithy-go"
2729
"github.com/golang/mock/gomock"
2830
"github.com/pkg/errors"
2931
"github.com/stretchr/testify/assert"
@@ -109,7 +111,7 @@ func TestASMGetAuthConfig(t *testing.T) {
109111
t.Run(c.Name, func(t *testing.T) {
110112
mockSecretsManager := mocks.NewMockSecretsManagerAPI(ctrl)
111113
mockSecretsManager.EXPECT().
112-
GetSecretValue(gomock.Any()).
114+
GetSecretValue(gomock.Any(), gomock.Any(), gomock.Any()).
113115
Return(c.Resp, nil)
114116

115117
_, err := GetDockerAuthFromASM("secret-value-id", mockSecretsManager)
@@ -129,7 +131,7 @@ func TestGetSecretFromASM(t *testing.T) {
129131

130132
mockSecretsManager := mocks.NewMockSecretsManagerAPI(ctrl)
131133
mockSecretsManager.EXPECT().
132-
GetSecretValue(gomock.Any()).
134+
GetSecretValue(gomock.Any(), gomock.Any(), gomock.Any()).
133135
Return(&secretsmanager.GetSecretValueOutput{
134136
SecretString: aws.String(secretValue),
135137
}, nil)
@@ -144,7 +146,7 @@ func TestGetSecretFromASMWithJsonKey(t *testing.T) {
144146

145147
mockSecretsManager := mocks.NewMockSecretsManagerAPI(ctrl)
146148
mockSecretsManager.EXPECT().
147-
GetSecretValue(gomock.Any()).
149+
GetSecretValue(gomock.Any(), gomock.Any(), gomock.Any()).
148150
Return(&secretsmanager.GetSecretValueOutput{
149151
SecretString: aws.String(jsonSecretValue),
150152
}, nil)
@@ -160,7 +162,7 @@ func TestGetSecretFromASMWithMalformedJSON(t *testing.T) {
160162

161163
mockSecretsManager := mocks.NewMockSecretsManagerAPI(ctrl)
162164
mockSecretsManager.EXPECT().
163-
GetSecretValue(gomock.Any()).
165+
GetSecretValue(gomock.Any(), gomock.Any(), gomock.Any()).
164166
Return(&secretsmanager.GetSecretValueOutput{
165167
SecretString: aws.String(malformedJsonSecretValue),
166168
}, nil)
@@ -177,7 +179,7 @@ func TestGetSecretFromASMWithJSONKeyNotFound(t *testing.T) {
177179

178180
mockSecretsManager := mocks.NewMockSecretsManagerAPI(ctrl)
179181
mockSecretsManager.EXPECT().
180-
GetSecretValue(gomock.Any()).
182+
GetSecretValue(gomock.Any(), gomock.Any(), gomock.Any()).
181183
Return(&secretsmanager.GetSecretValueOutput{
182184
SecretString: aws.String(jsonSecretValue),
183185
}, nil)
@@ -194,7 +196,7 @@ func TestGetSecretFromASMWithVersionID(t *testing.T) {
194196

195197
mockSecretsManager := mocks.NewMockSecretsManagerAPI(ctrl)
196198
mockSecretsManager.EXPECT().
197-
GetSecretValue(gomock.Any()).
199+
GetSecretValue(gomock.Any(), gomock.Any(), gomock.Any()).
198200
Return(&secretsmanager.GetSecretValueOutput{
199201
SecretString: aws.String(secretValue),
200202
}, nil)
@@ -211,7 +213,7 @@ func TestGetSecretFromASMWithVersionIDAndStage(t *testing.T) {
211213

212214
mockSecretsManager := mocks.NewMockSecretsManagerAPI(ctrl)
213215
mockSecretsManager.EXPECT().
214-
GetSecretValue(gomock.Any()).
216+
GetSecretValue(gomock.Any(), gomock.Any(), gomock.Any()).
215217
Return(&secretsmanager.GetSecretValueOutput{
216218
SecretString: aws.String(secretValue),
217219
}, nil)
@@ -243,16 +245,19 @@ func TestGetSecretFromASMWithInputErrorMessageKnownError(t *testing.T) {
243245

244246
mockSecretsManager := mocks.NewMockSecretsManagerAPI(ctrl)
245247
mockSecretsManager.EXPECT().
246-
GetSecretValue(gomock.Any()).
247-
Return(nil, awserr.New(secretsmanager.ErrCodeResourceNotFoundException, "Secrets Manager can't find the specified secret.", nil))
248+
GetSecretValue(gomock.Any(), gomock.Any(), gomock.Any()).
249+
Return(nil, &types.ResourceNotFoundException{
250+
Message: aws.String("Secrets Manager can't find the specified secret"),
251+
})
248252

249253
secretValueInput := createSecretValueInput(toPtr(valueFrom), toPtr(versionID), nil)
250254
_, err := GetSecretFromASMWithInput(secretValueInput, mockSecretsManager, jsonKey)
251255

252256
assert.Error(t, err)
253-
aerr, ok := errors.Cause(err).(awserr.Error)
254-
require.True(t, ok, "error is not of type awserr.Error")
255-
assert.Equal(t, secretsmanager.ErrCodeResourceNotFoundException, aerr.Code())
257+
var ae smithy.APIError
258+
ok := errors.As(err, &ae)
259+
require.True(t, ok, "error is not of type smithy.APIError")
260+
assert.Equal(t, (&types.ResourceNotFoundException{}).ErrorCode(), ae.ErrorCode())
256261
assert.Contains(t, err.Error(), fmt.Sprintf("ResourceNotFoundException: The task can't retrieve the secret with ARN '%s' from AWS Secrets Manager. Check whether the secret exists in the specified Region", valueFrom))
257262
}
258263

@@ -262,15 +267,19 @@ func TestGetSecretFromASMWithInputErrorMessageUnknownError(t *testing.T) {
262267

263268
mockSecretsManager := mocks.NewMockSecretsManagerAPI(ctrl)
264269
mockSecretsManager.EXPECT().
265-
GetSecretValue(gomock.Any()).
266-
Return(nil, awserr.New(secretsmanager.ErrCodeInternalServiceError, "uhoh", nil))
270+
GetSecretValue(gomock.Any(), gomock.Any(), gomock.Any()).
271+
Return(nil, &types.InternalServiceError{
272+
Message: aws.String("uhoh"),
273+
})
267274

268275
secretValueInput := createSecretValueInput(toPtr(valueFrom), toPtr(versionID), nil)
269276
_, err := GetSecretFromASMWithInput(secretValueInput, mockSecretsManager, jsonKey)
270277

271278
assert.Error(t, err)
272-
aerr, ok := errors.Cause(err).(awserr.Error)
273-
require.True(t, ok, "error is not of type awserr.Error")
274-
assert.Equal(t, secretsmanager.ErrCodeInternalServiceError, aerr.Code())
279+
var ae smithy.APIError
280+
ok := errors.As(err, &ae)
281+
require.True(t, ok, "error is not of type smithy.APIError")
282+
283+
assert.Equal(t, (&types.InternalServiceError{}).ErrorCode(), ae.ErrorCode())
275284
assert.Contains(t, err.Error(), fmt.Sprintf("secret %s: InternalServiceError: uhoh", valueFrom))
276285
}

0 commit comments

Comments
 (0)