Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support a separate URL base for pre-signed URLs #1006

Merged
merged 1 commit into from
Nov 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/api-types/backupstoragelocation.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ The configurable parameters are as follows:
| `region` | string | Empty | *Example*: "us-east-1"<br><br>See [AWS documentation][3] for the full list.<br><br>Queried from the AWS S3 API if not provided. |
| `s3ForcePathStyle` | bool | `false` | Set this to `true` if you are using a local storage service like Minio. |
| `s3Url` | string | Required field for non-AWS-hosted storage| *Example*: http://minio:9000<br><br>You can specify the AWS S3 URL here for explicitness, but Ark can already generate it from `region`, and `bucket`. This field is primarily for local storage services like Minio.|
| `publicUrl` | string | Empty | *Example*: https://minio.mycluster.com<br><br>If specified, use this instead of `s3Url` when generating download URLs (e.g., for logs). This field is primarily for local storage services like Minio.|
| `kmsKeyId` | string | Empty | *Example*: "502b409c-4da1-419f-a16e-eif453b3i49f" or "alias/`<KMS-Key-Alias-Name>`"<br><br>Specify an [AWS KMS key][10] id or alias to enable encryption of the backups stored in S3. Only works with AWS S3 and may require explicitly granting key usage rights.|

#### Azure
Expand All @@ -67,4 +68,4 @@ No parameters required.
[0]: #aws
[1]: #gcp
[2]: #azure
[3]: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions
[3]: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions
58 changes: 42 additions & 16 deletions pkg/cloudprovider/aws/object_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (

const (
s3URLKey = "s3Url"
publicURLKey = "publicUrl"
kmsKeyIDKey = "kmsKeyId"
s3ForcePathStyleKey = "s3ForcePathStyle"
bucketKey = "bucket"
Expand All @@ -42,6 +43,7 @@ const (
type objectStore struct {
log logrus.FieldLogger
s3 *s3.S3
preSignS3 *s3.S3
s3Uploader *s3manager.Uploader
kmsKeyID string
}
Expand All @@ -54,6 +56,7 @@ func (o *objectStore) Init(config map[string]string) error {
var (
region = config[regionKey]
s3URL = config[s3URLKey]
publicURL = config[publicURLKey]
kmsKeyID = config[kmsKeyIDKey]
s3ForcePathStyleVal = config[s3ForcePathStyleKey]

Expand Down Expand Up @@ -83,20 +86,52 @@ func (o *objectStore) Init(config map[string]string) error {
}
}

serverConfig, err := newAWSConfig(s3URL, region, s3ForcePathStyle)
if err != nil {
return err
}

serverSession, err := getSession(serverConfig)
if err != nil {
return err
}

o.s3 = s3.New(serverSession)
o.s3Uploader = s3manager.NewUploader(serverSession)
o.kmsKeyID = kmsKeyID

if publicURL != "" {
publicConfig, err := newAWSConfig(publicURL, region, s3ForcePathStyle)
if err != nil {
return err
}
publicSession, err := getSession(publicConfig)
if err != nil {
return err
}
o.preSignS3 = s3.New(publicSession)
} else {
o.preSignS3 = o.s3
}

return nil
}

func newAWSConfig(url, region string, forcePathStyle bool) (*aws.Config, error) {
awsConfig := aws.NewConfig().
WithRegion(region).
WithS3ForcePathStyle(s3ForcePathStyle)
WithS3ForcePathStyle(forcePathStyle)

if s3URL != "" {
if !IsValidS3URLScheme(s3URL) {
return errors.Errorf("Invalid s3Url: %s", s3URL)
if url != "" {
if !IsValidS3URLScheme(url) {
return nil, errors.Errorf("Invalid s3 url: %s", url)
}

awsConfig = awsConfig.WithEndpointResolver(
endpoints.ResolverFunc(func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
if service == endpoints.S3ServiceID {
return endpoints.ResolvedEndpoint{
URL: s3URL,
URL: url,
}, nil
}

Expand All @@ -105,16 +140,7 @@ func (o *objectStore) Init(config map[string]string) error {
)
}

sess, err := getSession(awsConfig)
if err != nil {
return err
}

o.s3 = s3.New(sess)
o.s3Uploader = s3manager.NewUploader(sess)
o.kmsKeyID = kmsKeyID

return nil
return awsConfig, nil
}

func (o *objectStore) PutObject(bucket, key string, body io.Reader) error {
Expand Down Expand Up @@ -208,7 +234,7 @@ func (o *objectStore) DeleteObject(bucket, key string) error {
}

func (o *objectStore) CreateSignedURL(bucket, key string, ttl time.Duration) (string, error) {
req, _ := o.s3.GetObjectRequest(&s3.GetObjectInput{
req, _ := o.preSignS3.GetObjectRequest(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
Expand Down