Skip to content

Commit db56d86

Browse files
committed
feat(object): support sse-c encryption
1 parent 36a1f88 commit db56d86

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

internal/services/object/object.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ package object
33
import (
44
"bytes"
55
"context"
6+
"crypto/md5"
67
"encoding/base64"
78
"fmt"
9+
"github.com/aws/aws-sdk-go-v2/aws"
810
"os"
911
"strings"
1012

@@ -105,6 +107,12 @@ func ResourceObject() *schema.Resource {
105107
string(s3Types.ObjectCannedACLPublicRead),
106108
}, false),
107109
},
110+
"sse-customer-key": {
111+
Type: schema.TypeString,
112+
Optional: true,
113+
Sensitive: true,
114+
Description: "Customer's encryption keys to encrypt data (SSE-C)",
115+
},
108116
"region": regional.Schema(),
109117
"project_id": account.ProjectIDSchema(),
110118
},
@@ -148,6 +156,14 @@ func resourceObjectCreate(ctx context.Context, d *schema.ResourceData, m interfa
148156
req.ACL = s3Types.ObjectCannedACL(*visibilityStr)
149157
}
150158

159+
if encryptionKeyStr, ok := d.Get("sse-customer-key").(string); ok {
160+
encryptionKey := base64.StdEncoding.EncodeToString([]byte(encryptionKeyStr))
161+
encryptionKeyMD5 := md5.Sum([]byte(encryptionKey))
162+
req.SSECustomerAlgorithm = scw.StringPtr("AES256")
163+
req.SSECustomerKeyMD5 = aws.String(string(encryptionKeyMD5[:]))
164+
req.SSECustomerKey = aws.String(string(encryptionKey[:]))
165+
}
166+
151167
if filePath, hasFile := d.GetOk("file"); hasFile {
152168
file, err := os.Open(filePath.(string))
153169
if err != nil {

internal/services/object/object_test.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
const (
2424
ServiceName = "scw" // Name of service.
2525
EndpointsID = ServiceName // ID to look up a service endpoint with.
26+
encryptionStr = "Pignouf"
2627
)
2728

2829
func TestAccObject_Basic(t *testing.T) {
@@ -734,6 +735,85 @@ func TestAccObject_WithBucketName(t *testing.T) {
734735
})
735736
}
736737

738+
func TestAccObject_Encryption(t *testing.T) {
739+
tt := acctest.NewTestTools(t)
740+
defer tt.Cleanup()
741+
bucketName := sdkacctest.RandomWithPrefix("test-acc-scaleway-object-basic")
742+
resource.ParallelTest(t, resource.TestCase{
743+
PreCheck: func() { acctest.PreCheck(t) },
744+
ProviderFactories: tt.ProviderFactories,
745+
CheckDestroy: resource.ComposeTestCheckFunc(
746+
objectchecks.IsObjectDestroyed(tt),
747+
objectchecks.IsBucketDestroyed(tt),
748+
),
749+
Steps: []resource.TestStep{
750+
{
751+
Config: fmt.Sprintf(`
752+
resource "scaleway_object_bucket" "base-01" {
753+
name = "%s"
754+
region= "%s"
755+
tags = {
756+
foo = "bar"
757+
}
758+
}
759+
760+
resource scaleway_object "file" {
761+
bucket = scaleway_object_bucket.base-01.id
762+
key = "myfile"
763+
file = "testfixture/empty.qcow2"
764+
}
765+
`, bucketName, objectTestsMainRegion),
766+
Check: resource.ComposeTestCheckFunc(
767+
objectchecks.CheckBucketExists(tt, "scaleway_object_bucket.base-01", true),
768+
testAccCheckObjectExists(tt, "scaleway_object.file"),
769+
),
770+
},
771+
{
772+
Config: fmt.Sprintf(`
773+
resource "scaleway_object_bucket" "base-01" {
774+
name = "%s"
775+
region= "%s"
776+
tags = {
777+
foo = "bar"
778+
}
779+
}
780+
781+
resource scaleway_object "file" {
782+
bucket = scaleway_object_bucket.base-01.id
783+
key = "myfile/foo"
784+
file = "testfixture/empty.qcow2"
785+
}
786+
`, bucketName, objectTestsMainRegion),
787+
Check: resource.ComposeTestCheckFunc(
788+
objectchecks.CheckBucketExists(tt, "scaleway_object_bucket.base-01", true),
789+
testAccCheckObjectExists(tt, "scaleway_object.file"),
790+
),
791+
},
792+
{
793+
Config: fmt.Sprintf(`
794+
resource "scaleway_object_bucket" "base-01" {
795+
name = "%s"
796+
region= "%s"
797+
tags = {
798+
foo = "bar"
799+
}
800+
}
801+
802+
resource scaleway_object "file" {
803+
bucket = scaleway_object_bucket.base-01.id
804+
key = "myfile/foo/bar"
805+
file = "testfixture/empty.qcow2"
806+
}
807+
`, bucketName, objectTestsMainRegion),
808+
Check: resource.ComposeTestCheckFunc(
809+
objectchecks.CheckBucketExists(tt, "scaleway_object_bucket.base-01", true),
810+
testAccCheckObjectExists(tt, "scaleway_object.file"),
811+
),
812+
},
813+
},
814+
})
815+
}
816+
737817
func testAccCheckObjectExists(tt *acctest.TestTools, n string) resource.TestCheckFunc {
738818
return func(state *terraform.State) error {
739819
ctx := context.Background()
@@ -764,6 +844,7 @@ func testAccCheckObjectExists(tt *acctest.TestTools, n string) resource.TestChec
764844
_, err = s3Client.GetObject(ctx, &s3.GetObjectInput{
765845
Bucket: scw.StringPtr(bucketName),
766846
Key: scw.StringPtr(key),
847+
SSECustomerKey:
767848
})
768849
if err != nil {
769850
if object.IsS3Err(err, object.ErrCodeNoSuchBucket, "") {

0 commit comments

Comments
 (0)