Skip to content

Commit 001628e

Browse files
authored
Add support for S3 PrivateLink interface endpoints (#1568)
1 parent e924c33 commit 001628e

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

api.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -917,8 +917,8 @@ func (c *Client) makeTargetURL(bucketName, objectName, bucketLocation string, is
917917
// http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html
918918
host = c.s3AccelerateEndpoint
919919
} else {
920-
// Do not change the host if the endpoint URL is a FIPS S3 endpoint.
921-
if !s3utils.IsAmazonFIPSEndpoint(*c.endpointURL) {
920+
// Do not change the host if the endpoint URL is a FIPS S3 endpoint or a S3 PrivateLink interface endpoint
921+
if !s3utils.IsAmazonFIPSEndpoint(*c.endpointURL) && !s3utils.IsAmazonPrivateLinkEndpoint(*c.endpointURL) {
922922
// Fetch new host based on the bucket location.
923923
host = getS3Endpoint(bucketLocation)
924924
}

pkg/s3utils/utils.go

+16
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ var elbAmazonRegex = regexp.MustCompile(`elb(.*?).amazonaws.com$`)
104104
// Regular expression used to determine if the arg is elb host in china.
105105
var elbAmazonCnRegex = regexp.MustCompile(`elb(.*?).amazonaws.com.cn$`)
106106

107+
// amazonS3HostPrivateLink - regular expression used to determine if an arg is s3 host in AWS PrivateLink interface endpoints style
108+
var amazonS3HostPrivateLink = regexp.MustCompile(`^(?:bucket|accesspoint).vpce-.*?.s3.(.*?).vpce.amazonaws.com$`)
109+
107110
// GetRegionFromURL - returns a region from url host.
108111
func GetRegionFromURL(endpointURL url.URL) string {
109112
if endpointURL == sentinelURL {
@@ -139,6 +142,10 @@ func GetRegionFromURL(endpointURL url.URL) string {
139142
if len(parts) > 1 {
140143
return parts[1]
141144
}
145+
parts = amazonS3HostPrivateLink.FindStringSubmatch(endpointURL.Host)
146+
if len(parts) > 1 {
147+
return parts[1]
148+
}
142149
return ""
143150
}
144151

@@ -202,6 +209,15 @@ func IsAmazonFIPSEndpoint(endpointURL url.URL) bool {
202209
return IsAmazonFIPSUSEastWestEndpoint(endpointURL) || IsAmazonFIPSGovCloudEndpoint(endpointURL)
203210
}
204211

212+
// IsAmazonPrivateLinkEndpoint - Match if it is exactly Amazon S3 PrivateLink interface endpoint
213+
// See https://docs.aws.amazon.com/AmazonS3/latest/userguide/privatelink-interface-endpoints.html.
214+
func IsAmazonPrivateLinkEndpoint(endpointURL url.URL) bool {
215+
if endpointURL == sentinelURL {
216+
return false
217+
}
218+
return amazonS3HostPrivateLink.MatchString(endpointURL.Host)
219+
}
220+
205221
// IsGoogleEndpoint - Match if it is exactly Google cloud storage endpoint.
206222
func IsGoogleEndpoint(endpointURL url.URL) bool {
207223
if endpointURL == sentinelURL {

pkg/s3utils/utils_test.go

+14
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,18 @@ func TestGetRegionFromURL(t *testing.T) {
103103
Host: "s3.kubernetesfrontendlb-caf78da2b1f7516c.elb.amazonaws.com.cn",
104104
},
105105
},
106+
{
107+
u: url.URL{
108+
Host: "bucket.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com",
109+
},
110+
expectedRegion: "us-east-1",
111+
},
112+
{
113+
u: url.URL{
114+
Host: "accesspoint.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com",
115+
},
116+
expectedRegion: "us-east-1",
117+
},
106118
}
107119

108120
for i, testCase := range testCases {
@@ -223,6 +235,8 @@ func TestIsAmazonEndpoint(t *testing.T) {
223235
{"https://s3-us-west-1.amazonaws.com", true},
224236
{"https://s3.us-west-1.amazonaws.com", true},
225237
{"https://s3.dualstack.us-west-1.amazonaws.com", true},
238+
{"https://bucket.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com", true},
239+
{"https://accesspoint.vpce-1a2b3c4d-5e6f.s3.us-east-1.vpce.amazonaws.com", true},
226240
}
227241

228242
for i, testCase := range testCases {

0 commit comments

Comments
 (0)