Support for custom storage class and encryption method. #105

This commit is contained in:
Andrey Smirnov
2014-10-01 19:16:15 +04:00
parent a02a90a3d8
commit 8aa1954ba7
7 changed files with 69 additions and 24 deletions

View File

@@ -217,7 +217,7 @@ func (context *AptlyContext) GetPublishedStorage(name string) aptly.PublishedSto
var err error
publishedStorage, err = s3.NewPublishedStorage(params.AccessKeyID, params.SecretAccessKey,
params.Region, params.Bucket, params.ACL, params.Prefix)
params.Region, params.Bucket, params.ACL, params.Prefix, params.StorageClass, params.EncryptionMethod)
if err != nil {
Fatal(err)
}

View File

@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "APTLY" "1" "September 2014" "" ""
.TH "APTLY" "1" "October 2014" "" ""
.
.SH "NAME"
\fBaptly\fR \- Debian repository management tool
@@ -55,7 +55,9 @@ Configuration file is stored in JSON format (default values shown below):
"awsAccessKeyID": ""
"awsSecretAccessKey": "",
"prefix": "",
"acl": "public\-read"
"acl": "public\-read",
"storageClass": "",
"encryptionMethod": ""
}
}
.
@@ -141,6 +143,14 @@ bucket name
\fBawsAccessKeyID\fR, \fBawsSecretAccessKey\fR
(optional) Amazon credentials to access S3 bucket\. If not supplied, environment variables \fBAWS_ACCESS_KEY_ID\fR and \fBAWS_SECRET_ACCESS_KEY\fR are used\.
.
.TP
\fBstorageClass\fR
(optional) Amazon S3 storage class, defaults to \fBSTANDARD\fR\. Other values available: \fBREDUCED_REDUNDANCY\fR (lower price, lower redundancy)
.
.TP
\fBencryptionMethod\fR
(optional) server\-side encryption method, defaults to none\. Currently the only available encryption method is \fBAES256\fR
.
.P
In order to publish to S3, specify endpoint as \fBs3:endpoint\-name:\fR before publishing prefix on the command line, e\.g\.:
.

View File

@@ -47,7 +47,9 @@ Configuration file is stored in JSON format (default values shown below):
"awsAccessKeyID": ""
"awsSecretAccessKey": "",
"prefix": "",
"acl": "public-read"
"acl": "public-read",
"storageClass": "",
"encryptionMethod": ""
}
}
@@ -121,6 +123,13 @@ and associated settings:
(optional) Amazon credentials to access S3 bucket. If not supplied,
environment variables `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`
are used.
* `storageClass`:
(optional) Amazon S3 storage class, defaults to `STANDARD`. Other values
available: `REDUCED_REDUNDANCY` (lower price, lower redundancy)
* `encryptionMethod`:
(optional) server-side encryption method, defaults to none. Currently
the only available encryption method is `AES256`
In order to publish to S3, specify endpoint as `s3:endpoint-name:` before
publishing prefix on the command line, e.g.:

View File

@@ -13,10 +13,12 @@ import (
// PublishedStorage abstract file system with published files (actually hosted on S3)
type PublishedStorage struct {
s3 *s3.S3
bucket *s3.Bucket
acl s3.ACL
prefix string
s3 *s3.S3
bucket *s3.Bucket
acl s3.ACL
prefix string
storageClass string
encryptionMethod string
}
// Check interface
@@ -25,12 +27,22 @@ var (
)
// NewPublishedStorageRaw creates published storage from raw aws credentials
func NewPublishedStorageRaw(auth aws.Auth, region aws.Region, bucket, defaultACL, prefix string) (*PublishedStorage, error) {
func NewPublishedStorageRaw(auth aws.Auth, region aws.Region, bucket, defaultACL, prefix,
storageClass, encryptionMethod string) (*PublishedStorage, error) {
if defaultACL == "" {
defaultACL = "private"
}
result := &PublishedStorage{s3: s3.New(auth, region), acl: s3.ACL(defaultACL), prefix: prefix}
if storageClass == "STANDARD" {
storageClass = ""
}
result := &PublishedStorage{
s3: s3.New(auth, region),
acl: s3.ACL(defaultACL),
prefix: prefix,
storageClass: storageClass,
encryptionMethod: encryptionMethod}
result.bucket = result.s3.Bucket(bucket)
return result, nil
@@ -38,7 +50,8 @@ func NewPublishedStorageRaw(auth aws.Auth, region aws.Region, bucket, defaultACL
// NewPublishedStorage creates new instance of PublishedStorage with specified S3 access
// keys, region and bucket name
func NewPublishedStorage(accessKey, secretKey, region, bucket, defaultACL, prefix string) (*PublishedStorage, error) {
func NewPublishedStorage(accessKey, secretKey, region, bucket, defaultACL, prefix,
storageClass, encryptionMethod string) (*PublishedStorage, error) {
auth, err := aws.GetAuth(accessKey, secretKey)
if err != nil {
return nil, err
@@ -49,7 +62,7 @@ func NewPublishedStorage(accessKey, secretKey, region, bucket, defaultACL, prefi
return nil, fmt.Errorf("unknown region: %#v", region)
}
return NewPublishedStorageRaw(auth, awsRegion, bucket, defaultACL, prefix)
return NewPublishedStorageRaw(auth, awsRegion, bucket, defaultACL, prefix, storageClass, encryptionMethod)
}
// String
@@ -81,7 +94,17 @@ func (storage *PublishedStorage) PutFile(path string, sourceFilename string) err
return err
}
err = storage.bucket.PutReader(filepath.Join(storage.prefix, path), source, fi.Size(), "binary/octet-stream", storage.acl)
headers := map[string][]string{
"Content-Type": {"binary/octet-stream"},
}
if storage.storageClass != "" {
headers["x-amz-storage-class"] = []string{storage.storageClass}
}
if storage.encryptionMethod != "" {
headers["x-amz-server-side-encryption"] = []string{storage.encryptionMethod}
}
err = storage.bucket.PutReaderHeader(filepath.Join(storage.prefix, path), source, fi.Size(), headers, storage.acl)
if err != nil {
return fmt.Errorf("error uploading %s to %s: %s", sourceFilename, storage, err)
}

View File

@@ -24,10 +24,10 @@ func (s *PublishedStorageSuite) SetUpTest(c *C) {
c.Assert(s.srv, NotNil)
auth, _ := aws.GetAuth("aa", "bb")
s.storage, err = NewPublishedStorageRaw(auth, aws.Region{Name: "test-1", S3Endpoint: s.srv.URL(), S3LocationConstraint: true}, "test", "", "")
s.storage, err = NewPublishedStorageRaw(auth, aws.Region{Name: "test-1", S3Endpoint: s.srv.URL(), S3LocationConstraint: true}, "test", "", "", "", "")
c.Assert(err, IsNil)
s.prefixedStorage, err = NewPublishedStorageRaw(auth, aws.Region{Name: "test-1", S3Endpoint: s.srv.URL(), S3LocationConstraint: true}, "test", "", "lala")
s.prefixedStorage, err = NewPublishedStorageRaw(auth, aws.Region{Name: "test-1", S3Endpoint: s.srv.URL(), S3LocationConstraint: true}, "test", "", "lala", "", "")
c.Assert(err, IsNil)
err = s.storage.s3.Bucket("test").PutBucket("private")
@@ -39,7 +39,7 @@ func (s *PublishedStorageSuite) TearDownTest(c *C) {
}
func (s *PublishedStorageSuite) TestNewPublishedStorage(c *C) {
stor, err := NewPublishedStorage("aa", "bbb", "", "", "", "")
stor, err := NewPublishedStorage("aa", "bbb", "", "", "", "", "", "")
c.Check(stor, IsNil)
c.Check(err, ErrorMatches, "unknown region: .*")
}

View File

@@ -26,12 +26,14 @@ type ConfigStructure struct {
// S3PublishRoot describes single S3 publishing entry point
type S3PublishRoot struct {
Region string `json:"region"`
Bucket string `json:"bucket"`
AccessKeyID string `json:"awsAccessKeyID"`
SecretAccessKey string `json:"awsSecretAccessKey"`
Prefix string `json:"prefix"`
ACL string `json:"acl"`
Region string `json:"region"`
Bucket string `json:"bucket"`
AccessKeyID string `json:"awsAccessKeyID"`
SecretAccessKey string `json:"awsSecretAccessKey"`
Prefix string `json:"prefix"`
ACL string `json:"acl"`
StorageClass string `json:"storageClass"`
EncryptionMethod string `json:"encryptionMethod"`
}
// Config is configuration for aptly, shared by all modules

View File

@@ -65,8 +65,9 @@ func (s *ConfigSuite) TestSaveConfig(c *C) {
" \"awsAccessKeyID\": \"\",\n"+
" \"awsSecretAccessKey\": \"\",\n"+
" \"prefix\": \"\",\n"+
" \"acl\": \"\"\n"+
" }\n"+
" \"acl\": \"\",\n"+
" \"storageClass\": \"\",\n"+
" \"encryptionMethod\": \"\"\n"+" }\n"+
" }\n"+
"}")
}