From 59e7982040fcb2af913a53369a55a7c2b326f9a8 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Thu, 2 Mar 2023 09:56:09 +0000 Subject: [PATCH] s3: add --s3-sts-endpoint to specify STS endpoint See: https://forum.rclone.org/t/s3-profile-failing-when-explicit-s3-endpoint-is-present/36063/ --- backend/s3/s3.go | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/backend/s3/s3.go b/backend/s3/s3.go index 25b18b5e7..58ab02abc 100644 --- a/backend/s3/s3.go +++ b/backend/s3/s3.go @@ -2266,6 +2266,11 @@ rclone's choice here. Help: `Suppress setting and reading of system metadata`, Advanced: true, Default: false, + }, { + Name: "sts_endpoint", + Help: "Endpoint for STS.\n\nLeave blank if using AWS to use the default endpoint for the region.", + Provider: "AWS", + Advanced: true, }, }}) } @@ -2352,6 +2357,7 @@ type Options struct { SecretAccessKey string `config:"secret_access_key"` Region string `config:"region"` Endpoint string `config:"endpoint"` + STSEndpoint string `config:"sts_endpoint"` LocationConstraint string `config:"location_constraint"` ACL string `config:"acl"` BucketACL string `config:"bucket_acl"` @@ -2566,16 +2572,24 @@ var defaultResolver = endpoints.DefaultResolver() // resolve (service, region) to endpoint // // Used to set endpoint for s3 services and not for other services -type resolver string +type resolver map[string]string + +// Add a service to the resolver, ignoring empty urls +func (r resolver) addService(service, url string) { + if url == "" { + return + } + if !strings.HasPrefix(url, "http") { + url = "https://" + url + } + r[service] = url +} // EndpointFor return the endpoint for s3 if set or the default if not -func (endpoint resolver) EndpointFor(service, region string, opts ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) { +func (r resolver) EndpointFor(service, region string, opts ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) { fs.Debugf(nil, "Resolving service %q region %q", service, region) - if service == "s3" { - url := string(endpoint) - if !strings.HasPrefix(url, "http") { - url = "https://" + url - } + url, ok := r[service] + if ok { return endpoints.ResolvedEndpoint{ URL: url, SigningRegion: region, @@ -2662,9 +2676,12 @@ func s3Connection(ctx context.Context, opt *Options, client *http.Client) (*s3.S if opt.Region != "" { awsConfig.WithRegion(opt.Region) } - if opt.Endpoint != "" { - // If endpoint is set, only override the s3 service so we don't break sts - awsConfig.WithEndpointResolver(resolver(opt.Endpoint)) + if opt.Endpoint != "" || opt.STSEndpoint != "" { + // If endpoints are set, override the relevant services only + r := make(resolver) + r.addService("s3", opt.Endpoint) + r.addService("sts", opt.STSEndpoint) + awsConfig.WithEndpointResolver(r) } // awsConfig.WithLogLevel(aws.LogDebugWithSigning)