registry/storage/driver/s3-aws kms support

Signed-off-by: Matt Duch <matt@learnmetrics.com>
This commit is contained in:
Matt Duch 2016-03-09 18:52:59 -06:00
parent c03b5fc5ee
commit fcb247dfce
4 changed files with 41 additions and 1 deletions

View file

@ -94,6 +94,7 @@ information about each option that appears later in this page.
regionendpoint: http://myobjects.local regionendpoint: http://myobjects.local
bucket: bucketname bucket: bucketname
encrypt: true encrypt: true
keyid: mykeyid
secure: true secure: true
v4auth: true v4auth: true
chunksize: 5242880 chunksize: 5242880
@ -359,6 +360,7 @@ Permitted values are `error`, `warn`, `info` and `debug`. The default is
regionendpoint: http://myobjects.local regionendpoint: http://myobjects.local
bucket: bucketname bucket: bucketname
encrypt: true encrypt: true
keyid: mykeyid
secure: true secure: true
v4auth: true v4auth: true
chunksize: 5242880 chunksize: 5242880

View file

@ -87,6 +87,18 @@ An implementation of the `storagedriver.StorageDriver` interface which uses Amaz
not. A boolean value. The default is false. not. A boolean value. The default is false.
</td> </td>
</tr> </tr>
<tr>
<td>
<code>keyid</code>
</td>
<td>
no
</td>
<td>
Optional KMS key ID to use for encryption (encrypt must be true, or this
parameter will be ignored). The default is none.
</td>
</tr>
<tr> <tr>
<td> <td>
<code>secure</code> <code>secure</code>
@ -163,6 +175,8 @@ An implementation of the `storagedriver.StorageDriver` interface which uses Amaz
`encrypt`: (optional) Whether you would like your data encrypted on the server side (defaults to false if not specified). `encrypt`: (optional) Whether you would like your data encrypted on the server side (defaults to false if not specified).
`keyid`: (optional) Whether you would like your data encrypted with this KMS key ID (defaults to none if not specified, will be ignored if encrypt is not true).
`secure`: (optional) Whether you would like to transfer data to the bucket over ssl or not. Defaults to true (meaning transferring over ssl) if not specified. Note that while setting this to false will improve performance, it is not recommended due to security concerns. `secure`: (optional) Whether you would like to transfer data to the bucket over ssl or not. Defaults to true (meaning transferring over ssl) if not specified. Note that while setting this to false will improve performance, it is not recommended due to security concerns.
`v4auth`: (optional) Whether you would like to use aws signature version 4 with your requests. This defaults to false if not specified (note that the eu-central-1 region does not work with version 2 signatures, so the driver will error out if initialized with this region and v4auth set to false) `v4auth`: (optional) Whether you would like to use aws signature version 4 with your requests. This defaults to false if not specified (note that the eu-central-1 region does not work with version 2 signatures, so the driver will error out if initialized with this region and v4auth set to false)

View file

@ -60,6 +60,7 @@ type DriverParameters struct {
Region string Region string
RegionEndpoint string RegionEndpoint string
Encrypt bool Encrypt bool
KeyID string
Secure bool Secure bool
ChunkSize int64 ChunkSize int64
RootDirectory string RootDirectory string
@ -100,6 +101,7 @@ type driver struct {
Bucket string Bucket string
ChunkSize int64 ChunkSize int64
Encrypt bool Encrypt bool
KeyID string
RootDirectory string RootDirectory string
StorageClass string StorageClass string
} }
@ -188,6 +190,11 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
return nil, fmt.Errorf("The secure parameter should be a boolean") return nil, fmt.Errorf("The secure parameter should be a boolean")
} }
keyID := parameters["keyid"]
if keyID == nil {
keyID = ""
}
chunkSize := int64(defaultChunkSize) chunkSize := int64(defaultChunkSize)
chunkSizeParam := parameters["chunksize"] chunkSizeParam := parameters["chunksize"]
switch v := chunkSizeParam.(type) { switch v := chunkSizeParam.(type) {
@ -243,6 +250,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
region, region,
fmt.Sprint(regionEndpoint), fmt.Sprint(regionEndpoint),
encryptBool, encryptBool,
fmt.Sprint(keyID),
secureBool, secureBool,
chunkSize, chunkSize,
fmt.Sprint(rootDirectory), fmt.Sprint(rootDirectory),
@ -317,6 +325,7 @@ func New(params DriverParameters) (*Driver, error) {
Bucket: params.Bucket, Bucket: params.Bucket,
ChunkSize: params.ChunkSize, ChunkSize: params.ChunkSize,
Encrypt: params.Encrypt, Encrypt: params.Encrypt,
KeyID: params.KeyID,
RootDirectory: params.RootDirectory, RootDirectory: params.RootDirectory,
StorageClass: params.StorageClass, StorageClass: params.StorageClass,
} }
@ -353,6 +362,7 @@ func (d *driver) PutContent(ctx context.Context, path string, contents []byte) e
ContentType: d.getContentType(), ContentType: d.getContentType(),
ACL: d.getACL(), ACL: d.getACL(),
ServerSideEncryption: d.getEncryptionMode(), ServerSideEncryption: d.getEncryptionMode(),
SSEKMSKeyId: d.getSSEKMSKeyID(),
StorageClass: d.getStorageClass(), StorageClass: d.getStorageClass(),
Body: bytes.NewReader(contents), Body: bytes.NewReader(contents),
}) })
@ -390,6 +400,7 @@ func (d *driver) Writer(ctx context.Context, path string, append bool) (storaged
ContentType: d.getContentType(), ContentType: d.getContentType(),
ACL: d.getACL(), ACL: d.getACL(),
ServerSideEncryption: d.getEncryptionMode(), ServerSideEncryption: d.getEncryptionMode(),
SSEKMSKeyId: d.getSSEKMSKeyID(),
StorageClass: d.getStorageClass(), StorageClass: d.getStorageClass(),
}) })
if err != nil { if err != nil {
@ -534,6 +545,7 @@ func (d *driver) Move(ctx context.Context, sourcePath string, destPath string) e
ContentType: d.getContentType(), ContentType: d.getContentType(),
ACL: d.getACL(), ACL: d.getACL(),
ServerSideEncryption: d.getEncryptionMode(), ServerSideEncryption: d.getEncryptionMode(),
SSEKMSKeyId: d.getSSEKMSKeyID(),
StorageClass: d.getStorageClass(), StorageClass: d.getStorageClass(),
CopySource: aws.String(d.Bucket + "/" + d.s3Path(sourcePath)), CopySource: aws.String(d.Bucket + "/" + d.s3Path(sourcePath)),
}) })
@ -645,9 +657,19 @@ func parseError(path string, err error) error {
} }
func (d *driver) getEncryptionMode() *string { func (d *driver) getEncryptionMode() *string {
if d.Encrypt { if !d.Encrypt {
return nil
}
if d.KeyID == "" {
return aws.String("AES256") return aws.String("AES256")
} }
return aws.String("aws:kms")
}
func (d *driver) getSSEKMSKeyID() *string {
if d.KeyID != "" {
return aws.String(d.KeyID)
}
return nil return nil
} }

View file

@ -27,6 +27,7 @@ func init() {
secretKey := os.Getenv("AWS_SECRET_KEY") secretKey := os.Getenv("AWS_SECRET_KEY")
bucket := os.Getenv("S3_BUCKET") bucket := os.Getenv("S3_BUCKET")
encrypt := os.Getenv("S3_ENCRYPT") encrypt := os.Getenv("S3_ENCRYPT")
keyID := os.Getenv("S3_KEY_ID")
secure := os.Getenv("S3_SECURE") secure := os.Getenv("S3_SECURE")
region := os.Getenv("AWS_REGION") region := os.Getenv("AWS_REGION")
root, err := ioutil.TempDir("", "driver-") root, err := ioutil.TempDir("", "driver-")
@ -60,6 +61,7 @@ func init() {
region, region,
regionEndpoint, regionEndpoint,
encryptBool, encryptBool,
keyID,
secureBool, secureBool,
minChunkSize, minChunkSize,
rootDirectory, rootDirectory,