Skip to content

Commit 7d14905

Browse files
punkwalkermjlshen
authored andcommitted
implements EndpointResolverV2 for S3 client
Signed-off-by: Pankaj Walke <[email protected]>
1 parent 5bdc662 commit 7d14905

File tree

5 files changed

+141
-7
lines changed

5 files changed

+141
-7
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ require (
2323
github.com/aws/aws-sdk-go-v2/credentials v1.17.11
2424
github.com/aws/aws-sdk-go-v2/service/s3 v1.53.1
2525
github.com/aws/aws-sdk-go-v2/service/sts v1.28.6
26-
github.com/aws/smithy-go v1.20.3
26+
github.com/aws/smithy-go v1.22.2
2727
github.com/awslabs/goformation/v4 v4.19.5
2828
github.com/blang/semver v3.5.1+incompatible
2929
github.com/coreos/ignition v0.35.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4 h1:Jux+gDDyi1Lruk+KHF91tK2K
8989
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4/go.mod h1:mUYPBhaF2lGiukDEjJX2BLRRKTmoUSitGDUgM4tRxak=
9090
github.com/aws/aws-sdk-go-v2/service/sts v1.28.6 h1:cwIxeBttqPN3qkaAjcEcsh8NYr8n2HZPkcKgPAi1phU=
9191
github.com/aws/aws-sdk-go-v2/service/sts v1.28.6/go.mod h1:FZf1/nKNEkHdGGJP/cI2MoIMquumuRK6ol3QQJNDxmw=
92-
github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE=
93-
github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
92+
github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
93+
github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
9494
github.com/awslabs/goformation/v4 v4.19.5 h1:Y+Tzh01tWg8gf//AgGKUamaja7Wx9NPiJf1FpZu4/iU=
9595
github.com/awslabs/goformation/v4 v4.19.5/go.mod h1:JoNpnVCBOUtEz9bFxc9sjy8uBUCLF5c4D1L7RhRTVM8=
9696
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=

pkg/cloud/endpoints/endpoints.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
"github.com/aws/aws-sdk-go/aws/endpoints"
2626

27+
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/endpointsv2"
2728
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/scope"
2829
)
2930

@@ -104,6 +105,8 @@ func ParseFlag(serviceEndpoints string) ([]scope.ServiceEndpoint, error) {
104105
})
105106
}
106107
}
108+
// For Go SDK V2 migration
109+
saveToServiceEndpointV2Map(endpoints)
107110

108111
return endpoints, nil
109112
}
@@ -117,3 +120,15 @@ func containsString(slice []string, s string) bool {
117120

118121
return false
119122
}
123+
124+
// TODO: punkwalker - remove this after Go SDK V2 migration
125+
func saveToServiceEndpointV2Map(src []scope.ServiceEndpoint) {
126+
for _, svc := range src {
127+
endpoint := endpointsv2.ServiceEndpoint{
128+
ServiceID: svc.ServiceID,
129+
URL: svc.URL,
130+
SigningRegion: svc.SigningRegion,
131+
}
132+
endpointsv2.ServiceEndpointsMap[svc.ServiceID] = endpoint
133+
}
134+
}

pkg/cloud/endpointsv2/endpoints.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package endpoints contains aws endpoint related utilities.
18+
package endpointsv2
19+
20+
import (
21+
"context"
22+
"errors"
23+
"net/url"
24+
"strings"
25+
26+
"github.com/aws/aws-sdk-go-v2/service/s3"
27+
smithyendpoints "github.com/aws/smithy-go/endpoints"
28+
)
29+
30+
var (
31+
errServiceEndpointFormat = errors.New("must be formatted as ${ServiceID}=${URL}")
32+
errServiceEndpointSigningRegion = errors.New("must be formatted as ${SigningRegion}:${ServiceID1}=${URL1},${ServiceID2}=${URL2...}")
33+
errServiceEndpointURL = errors.New("must use a valid URL as a service-endpoint")
34+
errServiceEndpointDuplicateServiceID = errors.New("same serviceID defined twice for signing region")
35+
// ServiceEndpointsMap Can be made private after Go SDK V2 migration
36+
ServiceEndpointsMap map[string]ServiceEndpoint
37+
)
38+
39+
// ServiceEndpointsMap Can be made private after Go SDK V2 migration
40+
// serviceEndpointV2 defines a tuple containing AWS Service resolution information for SDK V2.
41+
type ServiceEndpoint struct {
42+
ServiceID string
43+
URL string
44+
SigningRegion string
45+
}
46+
47+
// ParseFlag parses the command line flag of service endponts in the format ${SigningRegion1}:${ServiceID1}=${URL1},${ServiceID2}=${URL2}...;${SigningRegion2}...
48+
// returning a set of ServiceEndpoints.
49+
func ParseFlag(serviceEndpoints string) error {
50+
if serviceEndpoints == "" {
51+
return nil
52+
}
53+
54+
signingRegionConfigs := strings.Split(serviceEndpoints, ";")
55+
for _, regionConfig := range signingRegionConfigs {
56+
components := strings.SplitN(regionConfig, ":", 2)
57+
if len(components) != 2 {
58+
return errServiceEndpointSigningRegion
59+
}
60+
signingRegion := components[0]
61+
servicePairs := strings.Split(components[1], ",")
62+
for _, servicePair := range servicePairs {
63+
kv := strings.Split(servicePair, "=")
64+
if len(kv) != 2 {
65+
return errServiceEndpointFormat
66+
}
67+
var serviceID = kv[0]
68+
if _, ok := ServiceEndpointsMap[serviceID]; ok {
69+
return errServiceEndpointDuplicateServiceID
70+
}
71+
72+
URL, err := url.ParseRequestURI(kv[1])
73+
if err != nil {
74+
return errServiceEndpointURL
75+
}
76+
ServiceEndpointsMap[serviceID] = ServiceEndpoint{
77+
ServiceID: serviceID,
78+
URL: URL.String(),
79+
SigningRegion: signingRegion,
80+
}
81+
}
82+
}
83+
return nil
84+
}
85+
86+
// Custom EndpointResolverV2 ResolveEndpoint handlers
87+
88+
// MultiServiceEndpointResolver imeplements EndpointResolverV2 interface for services
89+
type MultiServiceEndpointResolver struct {
90+
endpoints map[string]ServiceEndpoint
91+
}
92+
93+
// NewMultiServiceEndpointResolver returns new MultiServiceEndpointResolver
94+
func NewMultiServiceEndpointResolver() *MultiServiceEndpointResolver {
95+
return &MultiServiceEndpointResolver{
96+
endpoints: ServiceEndpointsMap,
97+
}
98+
}
99+
100+
// S3EndpointResolver imeplements EndpointResolverV2 interface for S3
101+
type S3EndpointResolver struct {
102+
*MultiServiceEndpointResolver
103+
}
104+
105+
// ResolveEndpoint for S3
106+
func (s *S3EndpointResolver) ResolveEndpoint(ctx context.Context, params s3.EndpointParameters) (smithyendpoints.Endpoint, error) {
107+
// If custom endpoint not found, return default endpoint for the service
108+
if _, ok := s.endpoints[s3.ServiceID]; !ok {
109+
return s3.NewDefaultEndpointResolverV2().ResolveEndpoint(ctx, params)
110+
}
111+
112+
endpoint := ServiceEndpointsMap[s3.ServiceID]
113+
params.Endpoint = &endpoint.URL
114+
params.Region = &endpoint.SigningRegion
115+
return s3.NewDefaultEndpointResolverV2().ResolveEndpoint(ctx, params)
116+
}

pkg/cloud/scope/clients.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package scope
1818

1919
import (
2020
"context"
21-
"errors"
2221
"fmt"
2322

2423
awsv2middleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
@@ -53,9 +52,11 @@ import (
5352
"github.com/aws/smithy-go"
5453
"github.com/aws/smithy-go/middleware"
5554
smithyhttp "github.com/aws/smithy-go/transport/http"
55+
"github.com/pkg/errors"
5656
"k8s.io/apimachinery/pkg/runtime"
5757

5858
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud"
59+
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/endpointsv2"
5960
awslogs "sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/logs"
6061
awsmetrics "sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/metrics"
6162
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/logger"
@@ -208,14 +209,16 @@ func NewSSMClient(scopeUser cloud.ScopeUsage, session cloud.Session, logger logg
208209

209210
// NewS3Client creates a new S3 API client for a given session.
210211
func NewS3Client(scopeUser cloud.ScopeUsage, session cloud.Session, logger logger.Wrapper, target runtime.Object) *s3.Client {
211-
// TODO: Implement EndpointResolverV2 for Service Endpoints
212212
cfg := session.SessionV2()
213+
multiSvcEndpointResolver := endpointsv2.NewMultiServiceEndpointResolver()
214+
s3EndpointResolver := &endpointsv2.S3EndpointResolver{
215+
MultiServiceEndpointResolver: multiSvcEndpointResolver,
216+
}
213217
s3Opts := []func(*s3.Options){
214218
func(o *s3.Options) {
215219
o.Logger = logger.GetAWSLogger()
216-
},
217-
func(o *s3.Options) {
218220
o.ClientLogMode = awslogs.GetAWSLogLevelV2(logger.GetLogger())
221+
o.EndpointResolverV2 = s3EndpointResolver
219222
},
220223
s3.WithAPIOptions(
221224
func(stack *middleware.Stack) error {

0 commit comments

Comments
 (0)