|
14 | 14 | package awssession
|
15 | 15 |
|
16 | 16 | import (
|
| 17 | + "context" |
17 | 18 | "fmt"
|
18 | 19 | "net/http"
|
19 | 20 | "os"
|
20 | 21 |
|
| 22 | + "github.com/aws/aws-sdk-go-v2/aws" |
| 23 | + "github.com/aws/aws-sdk-go-v2/aws/retry" |
| 24 | + "github.com/aws/aws-sdk-go-v2/config" |
| 25 | + "github.com/aws/aws-sdk-go-v2/service/ec2" |
| 26 | + "github.com/aws/smithy-go" |
| 27 | + smithymiddleware "github.com/aws/smithy-go/middleware" |
| 28 | + smithyhttp "github.com/aws/smithy-go/transport/http" |
| 29 | + |
21 | 30 | "strconv"
|
22 | 31 | "time"
|
23 | 32 |
|
24 | 33 | "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger"
|
25 | 34 | "github.com/aws/amazon-vpc-cni-k8s/utils"
|
26 |
| - "github.com/aws/aws-sdk-go/aws" |
27 |
| - "github.com/aws/aws-sdk-go/aws/endpoints" |
28 |
| - "github.com/aws/aws-sdk-go/aws/request" |
29 |
| - "github.com/aws/aws-sdk-go/aws/session" |
30 |
| - "github.com/aws/aws-sdk-go/service/ec2" |
31 | 35 | )
|
32 | 36 |
|
33 | 37 | // Http client timeout env for sessions
|
@@ -59,42 +63,85 @@ func getHTTPTimeout() time.Duration {
|
59 | 63 | }
|
60 | 64 |
|
61 | 65 | // New will return an session for service clients
|
62 |
| -func New() *session.Session { |
63 |
| - awsCfg := aws.Config{ |
64 |
| - MaxRetries: aws.Int(maxRetries), |
65 |
| - HTTPClient: &http.Client{ |
66 |
| - Timeout: getHTTPTimeout(), |
67 |
| - }, |
68 |
| - STSRegionalEndpoint: endpoints.RegionalSTSEndpoint, |
| 66 | +func New(ctx context.Context) (aws.Config, error) { |
| 67 | + customHTTPClient := &http.Client{ |
| 68 | + Timeout: getHTTPTimeout()} |
| 69 | + optFns := []func(*config.LoadOptions) error{ |
| 70 | + config.WithHTTPClient(customHTTPClient), |
| 71 | + config.WithRetryMaxAttempts(maxRetries), |
| 72 | + config.WithRetryer(func() aws.Retryer { |
| 73 | + return retry.NewStandard() |
| 74 | + }), |
| 75 | + injectUserAgent, |
69 | 76 | }
|
70 | 77 |
|
71 | 78 | endpoint := os.Getenv("AWS_EC2_ENDPOINT")
|
| 79 | + |
| 80 | + //TODO (senthilx) - The endpoint resolver is using deprecated method, this should be moved to the services. |
72 | 81 | if endpoint != "" {
|
73 |
| - customResolver := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) { |
74 |
| - if service == ec2.EndpointsID { |
75 |
| - return endpoints.ResolvedEndpoint{ |
76 |
| - URL: endpoint, |
77 |
| - }, nil |
78 |
| - } |
79 |
| - return endpoints.DefaultResolver().EndpointFor(service, region, optFns...) |
80 |
| - } |
81 |
| - awsCfg.EndpointResolver = endpoints.ResolverFunc(customResolver) |
| 82 | + optFns = append(optFns, config.WithEndpointResolver(aws.EndpointResolverFunc( |
| 83 | + func(service, region string) (aws.Endpoint, error) { |
| 84 | + if service == ec2.ServiceID { |
| 85 | + return aws.Endpoint{ |
| 86 | + URL: endpoint, |
| 87 | + }, nil |
| 88 | + } |
| 89 | + // Fall back to default resolution |
| 90 | + return aws.Endpoint{}, &aws.EndpointNotFoundError{} |
| 91 | + }))) |
| 92 | + |
82 | 93 | }
|
83 | 94 |
|
84 |
| - sess := session.Must(session.NewSession(&awsCfg)) |
85 |
| - //injecting session handler info |
86 |
| - injectUserAgent(&sess.Handlers) |
| 95 | + cfg, err := config.LoadDefaultConfig(ctx, optFns...) |
| 96 | + |
| 97 | + if err != nil { |
| 98 | + return aws.Config{}, fmt.Errorf("failed to load AWS config: %w", err) |
| 99 | + } |
87 | 100 |
|
88 |
| - return sess |
| 101 | + return cfg, nil |
89 | 102 | }
|
90 | 103 |
|
91 | 104 | // injectUserAgent will inject app specific user-agent into awsSDK
|
92 |
| -func injectUserAgent(handlers *request.Handlers) { |
| 105 | +func injectUserAgent(loadOptions *config.LoadOptions) error { |
93 | 106 | version := utils.GetEnv(envVpcCniVersion, "")
|
94 |
| - handlers.Build.PushFrontNamed(request.NamedHandler{ |
95 |
| - Name: fmt.Sprintf("%s/user-agent", "amazon-vpc-cni-k8s"), |
96 |
| - Fn: request.MakeAddToUserAgentHandler( |
97 |
| - "amazon-vpc-cni-k8s", |
98 |
| - "version/"+version), |
| 107 | + userAgent := fmt.Sprintf("amazon-vpc-cni-k8s/version/%s", version) |
| 108 | + |
| 109 | + loadOptions.APIOptions = append(loadOptions.APIOptions, func(stack *smithymiddleware.Stack) error { |
| 110 | + return stack.Build.Add(&addUserAgentMiddleware{ |
| 111 | + userAgent: userAgent, |
| 112 | + }, smithymiddleware.After) |
99 | 113 | })
|
| 114 | + |
| 115 | + return nil |
| 116 | +} |
| 117 | + |
| 118 | +type addUserAgentMiddleware struct { |
| 119 | + userAgent string |
| 120 | +} |
| 121 | + |
| 122 | +func (m *addUserAgentMiddleware) HandleBuild(ctx context.Context, in smithymiddleware.BuildInput, next smithymiddleware.BuildHandler) (out smithymiddleware.BuildOutput, metadata smithymiddleware.Metadata, err error) { |
| 123 | + // Simply pass through to the next handler in the middleware chain |
| 124 | + return next.HandleBuild(ctx, in) |
| 125 | +} |
| 126 | + |
| 127 | +func (m *addUserAgentMiddleware) ID() string { |
| 128 | + return "AddUserAgent" |
| 129 | +} |
| 130 | + |
| 131 | +func (m *addUserAgentMiddleware) HandleFinalize(ctx context.Context, in smithymiddleware.FinalizeInput, next smithymiddleware.FinalizeHandler) ( |
| 132 | + out smithymiddleware.FinalizeOutput, metadata smithymiddleware.Metadata, err error) { |
| 133 | + req, ok := in.Request.(*smithyhttp.Request) |
| 134 | + if !ok { |
| 135 | + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown request type %T", in.Request)} |
| 136 | + } |
| 137 | + |
| 138 | + userAgent := req.Header.Get("User-Agent") |
| 139 | + if userAgent == "" { |
| 140 | + userAgent = m.userAgent |
| 141 | + } else { |
| 142 | + userAgent += " " + m.userAgent |
| 143 | + } |
| 144 | + req.Header.Set("User-Agent", userAgent) |
| 145 | + |
| 146 | + return next.HandleFinalize(ctx, in) |
100 | 147 | }
|
0 commit comments