Skip to content

Commit

Permalink
Merge pull request #36 from Aevin1387/s3-sse
Browse files Browse the repository at this point in the history
Add AWS S3 Server Side Encryption support.
  • Loading branch information
x4m committed May 25, 2018
2 parents 3a40d41 + 50e8c82 commit 5b91597
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 9 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ AWS_REGION: us-east-1

To configure the S3 storage class used for backup files, use `WALG_S3_STORAGE_CLASS`. By default, WAL-G uses the "STANDARD" storage class. Other supported values include "STANDARD_IA" for Infrequent Access and "REDUCED_REDUNDANCY" for Reduced Redundancy.

* `WALG_S3_SSE`

To enable S3 server-side encryption, set to the algorithm to use when storing the objects in S3 (i.e., `AES256`, `aws:kms`).

* `WALG_S3_SSE_KMS_ID`

If using S3 server-side encryption with `aws:kms`, the KMS Key ID to use for object encryption.

* `WALE_GPG_KEY_ID`

To configure GPG key for encryption and decryption. By default, no encryption is used. Public keyring is cached in the file "/.walg_key_cache".
Expand Down
29 changes: 21 additions & 8 deletions structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ func (dto *S3TarBallSentinelDto) IsIncremental() bool {
return dto.IncrementFrom != nil
}

// Finish writes an empty .json file and uploads it with the
// Finish writes a .json file description and uploads it with the
// the backup name. Finish will wait until all tar file parts
// have been uploaded. The json file will only be uploaded
// if all other parts of the backup are present in S3.
Expand All @@ -353,6 +353,15 @@ func (s *S3TarBall) Finish(sentinel *S3TarBallSentinelDto) error {
StorageClass: aws.String(tupl.StorageClass),
}

if tupl.ServerSideEncryption != "" {
input.ServerSideEncryption = aws.String(tupl.ServerSideEncryption)

if tupl.SSEKMSKeyId != "" {
// Only aws:kms implies sseKmsKeyId, checked during validation
input.SSEKMSKeyId = aws.String(tupl.SSEKMSKeyId)
}
}

tupl.wg.Add(1)
go func() {
defer tupl.wg.Done()
Expand Down Expand Up @@ -402,13 +411,15 @@ func (s *S3TarBall) Tw() *tar.Writer { return s.tw }
// Multiple tarballs can share one uploader. Must call CreateUploader()
// in 'upload.go'.
type TarUploader struct {
Upl s3manageriface.UploaderAPI
StorageClass string
Success bool
bucket string
server string
region string
wg *sync.WaitGroup
Upl s3manageriface.UploaderAPI
ServerSideEncryption string
SSEKMSKeyId string
StorageClass string
Success bool
bucket string
server string
region string
wg *sync.WaitGroup
}

// NewTarUploader creates a new tar uploader without the actual
Expand Down Expand Up @@ -437,6 +448,8 @@ func (tu *TarUploader) Finish() {
func (tu *TarUploader) Clone() *TarUploader {
return &TarUploader{
tu.Upl,
tu.ServerSideEncryption,
tu.SSEKMSKeyId,
tu.StorageClass,
tu.Success,
tu.bucket,
Expand Down
28 changes: 27 additions & 1 deletion upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,21 @@ func Configure() (*TarUploader, *Prefix, error) {
upload.StorageClass = storageClass
}

serverSideEncryption, ok := os.LookupEnv("WALG_S3_SSE")
if ok {
upload.ServerSideEncryption = serverSideEncryption
}

sseKmsKeyId, ok := os.LookupEnv("WALG_S3_SSE_KMS_ID")
if ok {
upload.SSEKMSKeyId = sseKmsKeyId
}

// Only aws:kms implies sseKmsKeyId
if (serverSideEncryption == "aws:kms") == (sseKmsKeyId == "") {
return nil, nil, errors.New("Configure: WALG_S3_SSE_KMS_ID must be set iff using aws:kms encryption")
}

upload.Upl = CreateUploader(pre.Svc, 20*1024*1024, con) //default 10 concurrency streams at 20MB

return upload, pre, err
Expand Down Expand Up @@ -171,12 +186,23 @@ func (tu *TarUploader) upload(input *s3manager.UploadInput, path string) (err er
// createUploadInput creates a s3manager.UploadInput for a TarUploader using
// the specified path and reader.
func (tu *TarUploader) createUploadInput(path string, reader io.Reader) *s3manager.UploadInput {
return &s3manager.UploadInput{
uploadInput := &s3manager.UploadInput{
Bucket: aws.String(tu.bucket),
Key: aws.String(path),
Body: reader,
StorageClass: aws.String(tu.StorageClass),
}

if tu.ServerSideEncryption != "" {
uploadInput.ServerSideEncryption = aws.String(tu.ServerSideEncryption)

if tu.SSEKMSKeyId != "" {
// Only aws:kms implies sseKmsKeyId, checked during validation
uploadInput.SSEKMSKeyId = aws.String(tu.SSEKMSKeyId)
}
}

return uploadInput
}

// StartUpload creates a lz4 writer and runs upload in the background once
Expand Down

0 comments on commit 5b91597

Please sign in to comment.