Skip to content

Commit 8e80745

Browse files
✨ Migrate Node packages to AWS SDK v2 (#5584)
* Migrate node-related code to AWS SDK v2 * remove Session() awsclient.ConfigProvider * fix lint error * fix lint error * fix e2e job * rebase * fix e2e job * debug debug
1 parent f563206 commit 8e80745

36 files changed

+234
-1654
lines changed

bootstrap/eks/internal/userdata/node_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package userdata
1919
import (
2020
"testing"
2121

22-
"github.com/aws/aws-sdk-go/aws"
22+
"github.com/aws/aws-sdk-go-v2/aws"
2323
. "github.com/onsi/gomega"
2424
"github.com/onsi/gomega/format"
2525
"k8s.io/utils/ptr"

pkg/cloud/awserrors/errors.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ func Code(err error) (string, bool) {
6969
if awserr, ok := err.(awserr.Error); ok {
7070
return awserr.Code(), true
7171
}
72+
73+
// Handle smithy errors from AWS SDK v2
74+
if smithyErr := ParseSmithyError(err); smithyErr != nil && smithyErr.ErrorCode() != "" {
75+
return smithyErr.ErrorCode(), true
76+
}
77+
7278
return "", false
7379
}
7480

@@ -77,6 +83,12 @@ func Message(err error) string {
7783
if awserr, ok := err.(awserr.Error); ok {
7884
return awserr.Message()
7985
}
86+
87+
// Handle smithy errors from AWS SDK v2
88+
if smithyErr := ParseSmithyError(err); smithyErr != nil {
89+
return smithyErr.ErrorMessage()
90+
}
91+
8092
return ""
8193
}
8294

pkg/cloud/interfaces.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"time"
2222

2323
awsv2 "github.com/aws/aws-sdk-go-v2/aws"
24-
awsclient "github.com/aws/aws-sdk-go/aws/client"
2524
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2625
"sigs.k8s.io/controller-runtime/pkg/client"
2726

@@ -34,8 +33,7 @@ import (
3433

3534
// Session represents an AWS session.
3635
type Session interface {
37-
Session() awsclient.ConfigProvider
38-
SessionV2() awsv2.Config
36+
Session() awsv2.Config
3937
ServiceLimiter(service string) *throttle.ServiceLimiter
4038
}
4139

pkg/cloud/scope/clients.go

Lines changed: 31 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,24 @@ import (
2626
"github.com/aws/aws-sdk-go-v2/service/iam"
2727
rgapi "github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi"
2828
"github.com/aws/aws-sdk-go-v2/service/s3"
29+
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
2930
"github.com/aws/aws-sdk-go-v2/service/sqs"
3031
"github.com/aws/aws-sdk-go-v2/service/ssm"
3132
stsv2 "github.com/aws/aws-sdk-go-v2/service/sts"
32-
"github.com/aws/aws-sdk-go/aws"
33-
"github.com/aws/aws-sdk-go/aws/awserr"
34-
"github.com/aws/aws-sdk-go/aws/request"
35-
"github.com/aws/aws-sdk-go/service/secretsmanager"
36-
"github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface"
3733
"k8s.io/apimachinery/pkg/runtime"
3834

3935
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud"
4036
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/endpointsv2"
4137
awslogs "sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/logs"
42-
awsmetrics "sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/metrics"
4338
awsmetricsv2 "sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/metricsv2"
4439
stsservice "sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/services/sts"
4540
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/throttle"
4641
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/logger"
47-
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/record"
48-
"sigs.k8s.io/cluster-api-provider-aws/v2/version"
4942
)
5043

5144
// NewASGClient creates a new ASG API client for a given session.
5245
func NewASGClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logger.Wrapper, target runtime.Object) *autoscaling.Client {
53-
cfg := session.SessionV2()
46+
cfg := session.Session()
5447

5548
autoscalingOpts := []func(*autoscaling.Options){
5649
func(o *autoscaling.Options) {
@@ -68,7 +61,7 @@ func NewASGClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logg
6861

6962
// NewEC2Client creates a new EC2 API client for a given session.
7063
func NewEC2Client(scopeUser cloud.ScopeUsage, session cloud.Session, logger logger.Wrapper, target runtime.Object) *ec2.Client {
71-
cfg := session.SessionV2()
64+
cfg := session.Session()
7265
multiSvcEndpointResolver := endpointsv2.NewMultiServiceEndpointResolver()
7366
ec2EndpointResolver := &endpointsv2.EC2EndpointResolver{
7467
MultiServiceEndpointResolver: multiSvcEndpointResolver,
@@ -92,7 +85,7 @@ func NewEC2Client(scopeUser cloud.ScopeUsage, session cloud.Session, logger logg
9285

9386
// NewELBClient creates a new ELB API client for a given session.
9487
func NewELBClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logger.Wrapper, target runtime.Object) *elb.Client {
95-
cfg := session.SessionV2()
88+
cfg := session.Session()
9689
multiSvcEndpointResolver := endpointsv2.NewMultiServiceEndpointResolver()
9790
endpointResolver := &endpointsv2.ELBEndpointResolver{
9891
MultiServiceEndpointResolver: multiSvcEndpointResolver,
@@ -116,7 +109,7 @@ func NewELBClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logg
116109

117110
// NewELBv2Client creates a new ELB v2 API client for a given session.
118111
func NewELBv2Client(scopeUser cloud.ScopeUsage, session cloud.Session, logger logger.Wrapper, target runtime.Object) *elbv2.Client {
119-
cfg := session.SessionV2()
112+
cfg := session.Session()
120113
multiSvcEndpointResolver := endpointsv2.NewMultiServiceEndpointResolver()
121114
endpointResolver := &endpointsv2.ELBV2EndpointResolver{
122115
MultiServiceEndpointResolver: multiSvcEndpointResolver,
@@ -140,7 +133,7 @@ func NewELBv2Client(scopeUser cloud.ScopeUsage, session cloud.Session, logger lo
140133

141134
// NewEventBridgeClient creates a new EventBridge API client for a given session.
142135
func NewEventBridgeClient(scopeUser cloud.ScopeUsage, session cloud.Session, target runtime.Object) *eventbridge.Client {
143-
cfg := session.SessionV2()
136+
cfg := session.Session()
144137
multiSvcEndpointResolver := endpointsv2.NewMultiServiceEndpointResolver()
145138
endpointResolver := &endpointsv2.EventBridgeEndpointResolver{
146139
MultiServiceEndpointResolver: multiSvcEndpointResolver,
@@ -161,7 +154,7 @@ func NewEventBridgeClient(scopeUser cloud.ScopeUsage, session cloud.Session, tar
161154

162155
// NewSQSClient creates a new SQS API client for a given session.
163156
func NewSQSClient(scopeUser cloud.ScopeUsage, session cloud.Session, target runtime.Object) *sqs.Client {
164-
cfg := session.SessionV2()
157+
cfg := session.Session()
165158
multiSvcEndpointResolver := endpointsv2.NewMultiServiceEndpointResolver()
166159
endpointResolver := &endpointsv2.SQSEndpointResolver{
167160
MultiServiceEndpointResolver: multiSvcEndpointResolver,
@@ -182,7 +175,7 @@ func NewSQSClient(scopeUser cloud.ScopeUsage, session cloud.Session, target runt
182175

183176
// NewGlobalSQSClient for creating a new SQS API client that isn't tied to a cluster.
184177
func NewGlobalSQSClient(scopeUser cloud.ScopeUsage, session cloud.Session) *sqs.Client {
185-
cfg := session.SessionV2()
178+
cfg := session.Session()
186179
multiSvcEndpointResolver := endpointsv2.NewMultiServiceEndpointResolver()
187180
endpointResolver := &endpointsv2.SQSEndpointResolver{
188181
MultiServiceEndpointResolver: multiSvcEndpointResolver,
@@ -203,7 +196,7 @@ func NewGlobalSQSClient(scopeUser cloud.ScopeUsage, session cloud.Session) *sqs.
203196

204197
// NewResourgeTaggingClient creates a new Resource Tagging API client for a given session.
205198
func NewResourgeTaggingClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logger.Wrapper, target runtime.Object) *rgapi.Client {
206-
cfg := session.SessionV2()
199+
cfg := session.Session()
207200
multiSvcEndpointResolver := endpointsv2.NewMultiServiceEndpointResolver()
208201
endpointResolver := &endpointsv2.RGAPIEndpointResolver{
209202
MultiServiceEndpointResolver: multiSvcEndpointResolver,
@@ -222,20 +215,27 @@ func NewResourgeTaggingClient(scopeUser cloud.ScopeUsage, session cloud.Session,
222215
}
223216

224217
// NewSecretsManagerClient creates a new Secrets API client for a given session..
225-
func NewSecretsManagerClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logger.Wrapper, target runtime.Object) secretsmanageriface.SecretsManagerAPI {
226-
secretsClient := secretsmanager.New(session.Session(), aws.NewConfig().WithLogLevel(awslogs.GetAWSLogLevel(logger.GetLogger())).WithLogger(awslogs.NewWrapLogr(logger.GetLogger())))
227-
secretsClient.Handlers.Build.PushFrontNamed(getUserAgentHandler())
228-
secretsClient.Handlers.Sign.PushFront(session.ServiceLimiter(secretsClient.ServiceID).LimitRequest)
229-
secretsClient.Handlers.CompleteAttempt.PushFront(awsmetrics.CaptureRequestMetrics(scopeUser.ControllerName()))
230-
secretsClient.Handlers.CompleteAttempt.PushFront(session.ServiceLimiter(secretsClient.ServiceID).ReviewResponse)
231-
secretsClient.Handlers.Complete.PushBack(recordAWSPermissionsIssue(target))
232-
233-
return secretsClient
218+
func NewSecretsManagerClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logger.Wrapper, target runtime.Object) *secretsmanager.Client {
219+
cfg := session.Session()
220+
221+
secretsOpts := []func(*secretsmanager.Options){
222+
func(o *secretsmanager.Options) {
223+
o.Logger = logger.GetAWSLogger()
224+
o.ClientLogMode = awslogs.GetAWSLogLevelV2(logger.GetLogger())
225+
},
226+
secretsmanager.WithAPIOptions(
227+
awsmetricsv2.WithMiddlewares(scopeUser.ControllerName(), target),
228+
awsmetricsv2.WithCAPAUserAgentMiddleware(),
229+
throttle.WithServiceLimiterMiddleware(session.ServiceLimiter(secretsmanager.ServiceID)),
230+
),
231+
}
232+
233+
return secretsmanager.NewFromConfig(cfg, secretsOpts...)
234234
}
235235

236236
// NewEKSClient creates a new EKS API client for a given session.
237237
func NewEKSClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logger.Wrapper, target runtime.Object) *eks.Client {
238-
cfg := session.SessionV2()
238+
cfg := session.Session()
239239
multiSvcEndpointResolver := endpointsv2.NewMultiServiceEndpointResolver()
240240
eksEndpointResolver := &endpointsv2.EKSEndpointResolver{
241241
MultiServiceEndpointResolver: multiSvcEndpointResolver,
@@ -253,7 +253,7 @@ func NewEKSClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logg
253253

254254
// NewIAMClient creates a new IAM API client for a given session.
255255
func NewIAMClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logger.Wrapper, target runtime.Object) *iam.Client {
256-
cfg := session.SessionV2()
256+
cfg := session.Session()
257257

258258
iamOpts := []func(*iam.Options){
259259
func(o *iam.Options) {
@@ -271,7 +271,7 @@ func NewIAMClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logg
271271

272272
// NewSTSClient creates a new STS API client for a given session.
273273
func NewSTSClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logger.Wrapper, target runtime.Object) stsservice.STSClient {
274-
cfg := session.SessionV2()
274+
cfg := session.Session()
275275
multiSvcEndpointResolver := endpointsv2.NewMultiServiceEndpointResolver()
276276
stsEndpointResolver := &endpointsv2.STSEndpointResolver{
277277
MultiServiceEndpointResolver: multiSvcEndpointResolver,
@@ -294,7 +294,7 @@ func NewSTSClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logg
294294

295295
// NewSSMClient creates a new Secrets API client for a given session.
296296
func NewSSMClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logger.Wrapper, target runtime.Object) *ssm.Client {
297-
cfg := session.SessionV2()
297+
cfg := session.Session()
298298
multiSvcEndpointResolver := endpointsv2.NewMultiServiceEndpointResolver()
299299
ssmEndpointResolver := &endpointsv2.SSMEndpointResolver{
300300
MultiServiceEndpointResolver: multiSvcEndpointResolver,
@@ -316,7 +316,7 @@ func NewSSMClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logg
316316

317317
// NewS3Client creates a new S3 API client for a given session.
318318
func NewS3Client(scopeUser cloud.ScopeUsage, session cloud.Session, logger logger.Wrapper, target runtime.Object) *s3.Client {
319-
cfg := session.SessionV2()
319+
cfg := session.Session()
320320
multiSvcEndpointResolver := endpointsv2.NewMultiServiceEndpointResolver()
321321
s3EndpointResolver := &endpointsv2.S3EndpointResolver{
322322
MultiServiceEndpointResolver: multiSvcEndpointResolver,
@@ -332,28 +332,10 @@ func NewS3Client(scopeUser cloud.ScopeUsage, session cloud.Session, logger logge
332332
return s3.NewFromConfig(cfg, s3Opts...)
333333
}
334334

335-
func recordAWSPermissionsIssue(target runtime.Object) func(r *request.Request) {
336-
return func(r *request.Request) {
337-
if awsErr, ok := r.Error.(awserr.Error); ok {
338-
switch awsErr.Code() {
339-
case "AuthFailure", "UnauthorizedOperation", "NoCredentialProviders":
340-
record.Warnf(target, awsErr.Code(), "Operation %s failed with a credentials or permission issue", r.Operation.Name)
341-
}
342-
}
343-
}
344-
}
345-
346-
func getUserAgentHandler() request.NamedHandler {
347-
return request.NamedHandler{
348-
Name: "capa/user-agent",
349-
Fn: request.MakeAddToUserAgentHandler("aws.cluster.x-k8s.io", version.Get().String()),
350-
}
351-
}
352-
353335
// AWSClients contains all the aws clients used by the scopes.
354336
type AWSClients struct {
355337
ELB *elb.Client
356-
SecretsManager secretsmanageriface.SecretsManagerAPI
338+
SecretsManager *secretsmanager.Client
357339
ResourceTagging *rgapi.Client
358340
ASG *autoscaling.Client
359341
EC2 *ec2.Client

pkg/cloud/scope/cluster.go

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,6 @@ func NewClusterScope(params ClusterScopeParams) (*ClusterScope, error) {
7777
maxWaitActiveUpdateDelete: params.MaxWaitActiveUpdateDelete,
7878
}
7979

80-
session, serviceLimiters, err := sessionForClusterWithRegion(params.Client, clusterScope, params.AWSCluster.Spec.Region, params.Endpoints, params.Logger)
81-
if err != nil {
82-
return nil, errors.Errorf("failed to create aws session: %v", err)
83-
}
84-
8580
sessionv2, serviceLimitersv2, err := sessionForClusterWithRegionV2(params.Client, clusterScope, params.AWSCluster.Spec.Region, params.Endpoints, params.Logger)
8681
if err != nil {
8782
return nil, errors.Errorf("failed to create aws V2 session: %v", err)
@@ -93,10 +88,8 @@ func NewClusterScope(params ClusterScopeParams) (*ClusterScope, error) {
9388
}
9489

9590
clusterScope.patchHelper = helper
96-
clusterScope.session = session
97-
clusterScope.sessionV2 = *sessionv2
98-
clusterScope.serviceLimiters = serviceLimiters
99-
clusterScope.serviceLimitersV2 = serviceLimitersv2
91+
clusterScope.session = *sessionv2
92+
clusterScope.serviceLimiters = serviceLimitersv2
10093

10194
return clusterScope, nil
10295
}
@@ -110,11 +103,9 @@ type ClusterScope struct {
110103
Cluster *clusterv1.Cluster
111104
AWSCluster *infrav1.AWSCluster
112105

113-
session awsclient.ConfigProvider
114-
sessionV2 awsv2.Config
115-
serviceLimiters throttle.ServiceLimiters
116-
serviceLimitersV2 throttle.ServiceLimiters
117-
controllerName string
106+
session awsv2.Config
107+
serviceLimiters throttle.ServiceLimiters
108+
controllerName string
118109

119110
tagUnmanagedNetworkResources bool
120111
maxWaitActiveUpdateDelete time.Duration
@@ -361,16 +352,11 @@ func (s *ClusterScope) ClusterObj() cloud.ClusterObject {
361352
return s.Cluster
362353
}
363354

364-
// Session returns the AWS SDK session. Used for creating clients.
365-
func (s *ClusterScope) Session() awsclient.ConfigProvider {
355+
// Session returns the AWS SDK V2 session. Used for creating clients.
356+
func (s *ClusterScope) Session() awsv2.Config {
366357
return s.session
367358
}
368359

369-
// SessionV2 returns the AWS SDK V2 session. Used for creating clients.
370-
func (s *ClusterScope) SessionV2() awsv2.Config {
371-
return s.sessionV2
372-
}
373-
374360
// ServiceLimiter returns the AWS SDK session. Used for creating clients.
375361
func (s *ClusterScope) ServiceLimiter(service string) *throttle.ServiceLimiter {
376362
if sl, ok := s.serviceLimiters[service]; ok {

pkg/cloud/scope/fargate.go

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,6 @@ func NewFargateProfileScope(params FargateProfileScopeParams) (*FargateProfileSc
7070
controllerName: params.ControllerName,
7171
}
7272

73-
session, serviceLimiters, err := sessionForClusterWithRegion(params.Client, managedScope, params.ControlPlane.Spec.Region, params.Endpoints, params.Logger)
74-
if err != nil {
75-
return nil, errors.Errorf("failed to create aws session: %v", err)
76-
}
77-
7873
sessionv2, serviceLimitersv2, err := sessionForClusterWithRegionV2(params.Client, managedScope, params.ControlPlane.Spec.Region, params.Endpoints, params.Logger)
7974
if err != nil {
8075
return nil, errors.Errorf("failed to create aws v2 session: %v", err)
@@ -86,18 +81,16 @@ func NewFargateProfileScope(params FargateProfileScopeParams) (*FargateProfileSc
8681
}
8782

8883
return &FargateProfileScope{
89-
Logger: *params.Logger,
90-
Client: params.Client,
91-
Cluster: params.Cluster,
92-
ControlPlane: params.ControlPlane,
93-
FargateProfile: params.FargateProfile,
94-
patchHelper: helper,
95-
session: session,
96-
sessionV2: *sessionv2,
97-
serviceLimiters: serviceLimiters,
98-
serviceLimitersV2: serviceLimitersv2,
99-
controllerName: params.ControllerName,
100-
enableIAM: params.EnableIAM,
84+
Logger: *params.Logger,
85+
Client: params.Client,
86+
Cluster: params.Cluster,
87+
ControlPlane: params.ControlPlane,
88+
FargateProfile: params.FargateProfile,
89+
patchHelper: helper,
90+
session: *sessionv2,
91+
serviceLimiters: serviceLimitersv2,
92+
controllerName: params.ControllerName,
93+
enableIAM: params.EnableIAM,
10194
}, nil
10295
}
10396

@@ -111,11 +104,9 @@ type FargateProfileScope struct {
111104
ControlPlane *ekscontrolplanev1.AWSManagedControlPlane
112105
FargateProfile *expinfrav1.AWSFargateProfile
113106

114-
session awsclient.ConfigProvider
115-
sessionV2 awsv2.Config
116-
serviceLimiters throttle.ServiceLimiters
117-
serviceLimitersV2 throttle.ServiceLimiters
118-
controllerName string
107+
session awsv2.Config
108+
serviceLimiters throttle.ServiceLimiters
109+
controllerName string
119110

120111
enableIAM bool
121112
}
@@ -225,16 +216,11 @@ func (s *FargateProfileScope) ClusterObj() cloud.ClusterObject {
225216
return s.Cluster
226217
}
227218

228-
// Session returns the AWS SDK session. Used for creating clients.
229-
func (s *FargateProfileScope) Session() awsclient.ConfigProvider {
219+
// Session returns the AWS SDK V2 session. Used for creating clients.
220+
func (s *FargateProfileScope) Session() awsv2.Config {
230221
return s.session
231222
}
232223

233-
// SessionV2 returns the AWS SDK session. Used for creating clients.
234-
func (s *FargateProfileScope) SessionV2() awsv2.Config {
235-
return s.sessionV2
236-
}
237-
238224
// ControllerName returns the name of the controller that
239225
// created the FargateProfile.
240226
func (s *FargateProfileScope) ControllerName() string {

0 commit comments

Comments
 (0)