-
Notifications
You must be signed in to change notification settings - Fork 46
/
session.go
86 lines (68 loc) · 2.65 KB
/
session.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package main
import (
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
)
// DefaultRegion to use for S3 credential creation
const defaultRegion = "us-east-1"
func buildSessionConfig(config *Config) aws.Config {
// By default make sure a region is specified, this is required for S3 operations
sessionConfig := aws.Config{Region: aws.String(defaultRegion)}
if config.AccessKey != "" && config.SecretKey != "" {
sessionConfig.Credentials = credentials.NewStaticCredentials(config.AccessKey, config.SecretKey, "")
}
return sessionConfig
}
func buildEndpointResolver(hostname string) endpoints.Resolver {
defaultResolver := endpoints.DefaultResolver()
fixedHost := hostname
if !strings.HasPrefix(hostname, "http") {
fixedHost = "https://" + hostname
}
return endpoints.ResolverFunc(func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
if service == endpoints.S3ServiceID {
return endpoints.ResolvedEndpoint{
URL: fixedHost,
}, nil
}
return defaultResolver.EndpointFor(service, region, optFns...)
})
}
// SessionNew - Read the config for default credentials, if not provided use environment based variables
func SessionNew(config *Config) *s3.S3 {
sessionConfig := buildSessionConfig(config)
if config.HostBase != "" && config.HostBase != "s3.amazon.com" {
sessionConfig.EndpointResolver = buildEndpointResolver(config.HostBase)
}
return s3.New(session.Must(session.NewSessionWithOptions(session.Options{
Config: sessionConfig,
SharedConfigState: session.SharedConfigEnable,
})))
}
// SessionForBucket - For a given S3 bucket, create an approprate session that references the region
// that this bucket is located in
func SessionForBucket(config *Config, bucket string) (*s3.S3, error) {
sessionConfig := buildSessionConfig(config)
if config.HostBucket == "" || config.HostBucket == "%(bucket)s.s3.amazonaws.com" {
svc := SessionNew(config)
if loc, err := svc.GetBucketLocation(&s3.GetBucketLocationInput{Bucket: &bucket}); err != nil {
return nil, err
} else if loc.LocationConstraint == nil {
// Use default service
return svc, nil
} else {
sessionConfig.Region = loc.LocationConstraint
}
} else {
host := strings.ReplaceAll(config.HostBucket, "%(bucket)s", bucket)
sessionConfig.EndpointResolver = buildEndpointResolver(host)
}
return s3.New(session.Must(session.NewSessionWithOptions(session.Options{
Config: sessionConfig,
SharedConfigState: session.SharedConfigEnable,
}))), nil
}