From 54484844afa41a627c8de2b7f84a94e1ba773090 Mon Sep 17 00:00:00 2001 From: Patrik Cyvoct Date: Mon, 15 Jun 2020 09:29:17 +0200 Subject: [PATCH 1/2] feat(object): add tags to buckets Signed-off-by: Patrik Cyvoct --- scaleway/resource_object_bucket.go | 77 ++++++++++++++++++++++ scaleway/resource_object_bucket_test.go | 6 ++ website/docs/r/object_bucket.html.markdown | 4 ++ 3 files changed, 87 insertions(+) diff --git a/scaleway/resource_object_bucket.go b/scaleway/resource_object_bucket.go index ee97ac6a50..01dd710f56 100644 --- a/scaleway/resource_object_bucket.go +++ b/scaleway/resource_object_bucket.go @@ -8,6 +8,7 @@ import ( "github.com/aws/aws-sdk-go/service/s3" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/scaleway/scaleway-sdk-go/scw" ) func resourceScalewayObjectBucket() *schema.Resource { @@ -38,6 +39,14 @@ func resourceScalewayObjectBucket() *schema.Resource { s3.ObjectCannedACLAuthenticatedRead, }, false), }, + "tags": { + Type: schema.TypeMap, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Optional: true, + Description: "The tags associated with this bucket", + }, "region": regionSchema(), }, } @@ -60,6 +69,27 @@ func resourceScalewayObjectBucketCreate(d *schema.ResourceData, m interface{}) e return err } + tagsSet := make([]*s3.Tag, 0) + + for key, value := range d.Get("tags").(map[string]interface{}) { + tagsSet = append(tagsSet, &s3.Tag{ + Key: &key, + Value: scw.StringPtr(value.(string)), + }) + } + + if len(tagsSet) > 0 { + _, err = s3Client.PutBucketTagging(&s3.PutBucketTaggingInput{ + Bucket: aws.String(bucketName), + Tagging: &s3.Tagging{ + TagSet: tagsSet, + }, + }) + if err != nil { + return err + } + } + d.SetId(newRegionalId(region, bucketName)) return resourceScalewayObjectBucketRead(d, m) @@ -94,6 +124,35 @@ func resourceScalewayObjectBucketRead(d *schema.ResourceData, m interface{}) err return fmt.Errorf("couldn't read bucket: %s", err) } + var tagsSet []*s3.Tag + + tagsResponse, err := s3Client.GetBucketTagging(&s3.GetBucketTaggingInput{ + Bucket: aws.String(bucketName), + }) + if err != nil { + if serr, ok := err.(awserr.Error); !ok || serr.Code() != "NoSuchTagSet" { + return fmt.Errorf("couldn't read tags from bucket: %s", err) + } + } else { + tagsSet = tagsResponse.TagSet + } + + tags := map[string]interface{}{} + + for _, tagSet := range tagsSet { + var key string + var value string + if tagSet.Key != nil { + key = *tagSet.Key + } + if tagSet.Value != nil { + value = *tagSet.Value + } + tags[key] = value + } + + _ = d.Set("tags", tags) + return nil } @@ -116,6 +175,24 @@ func resourceScalewayObjectBucketUpdate(d *schema.ResourceData, m interface{}) e } } + if d.HasChange("tags") { + tagsSet := make([]*s3.Tag, 0) + + for key, value := range d.Get("tags").(map[string]interface{}) { + tagsSet = append(tagsSet, &s3.Tag{ + Key: &key, + Value: scw.StringPtr(value.(string)), + }) + } + + _, err = s3Client.PutBucketTagging(&s3.PutBucketTaggingInput{ + Bucket: aws.String(bucketName), + Tagging: &s3.Tagging{ + TagSet: tagsSet, + }, + }) + } + return resourceScalewayObjectBucketRead(d, m) } diff --git a/scaleway/resource_object_bucket_test.go b/scaleway/resource_object_bucket_test.go index 55f31009f5..817f25fcbe 100644 --- a/scaleway/resource_object_bucket_test.go +++ b/scaleway/resource_object_bucket_test.go @@ -32,6 +32,9 @@ var ( var testAccCheckScalewayObjectBucket = fmt.Sprintf(` resource "scaleway_object_bucket" "base" { name = "%s" + tags = { + foo = "bar" + } } resource "scaleway_object_bucket" "ams-bucket" { @@ -63,6 +66,8 @@ func TestAccScalewayObjectBucket(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("scaleway_object_bucket.base", "name", testBucketName), resource.TestCheckResourceAttr("scaleway_object_bucket.base", "acl", testBucketACL), + resource.TestCheckResourceAttr("scaleway_object_bucket.base", "tags.%", "1"), + resource.TestCheckResourceAttr("scaleway_object_bucket.base", "tags.foo", "bar"), resource.TestCheckResourceAttr("scaleway_object_bucket.ams-bucket", "name", testBucketNameAms), resource.TestCheckResourceAttr("scaleway_object_bucket.par-bucket", "name", testBucketNamePar), ), @@ -72,6 +77,7 @@ func TestAccScalewayObjectBucket(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("scaleway_object_bucket.base", "name", testBucketName), resource.TestCheckResourceAttr("scaleway_object_bucket.base", "acl", testBucketUpdatedACL), + resource.TestCheckResourceAttr("scaleway_object_bucket.base", "tags.%", "0"), ), }, }, diff --git a/website/docs/r/object_bucket.html.markdown b/website/docs/r/object_bucket.html.markdown index d78596fcf8..a41a0466e5 100644 --- a/website/docs/r/object_bucket.html.markdown +++ b/website/docs/r/object_bucket.html.markdown @@ -15,6 +15,9 @@ Creates and manages Scaleway object storage buckets. For more information, see [ resource "scaleway_object_bucket" "some_bucket" { name = "some-unique-name" acl = "private" + tags = { + key = "value" + } } ``` @@ -23,6 +26,7 @@ resource "scaleway_object_bucket" "some_bucket" { The following arguments are supported: * `name` - (Required) The name of the bucket. +* `tags` - (Optional) The tags of the bucket. * `acl` - (Optional) The [canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) you want to apply to the bucket. * `region` - (Optional) The [region](https://developers.scaleway.com/en/quickstart/#region-definition) in which the bucket should be created. From e9d2c31a2a923cf0f8783aaee6394c6e3af187b7 Mon Sep 17 00:00:00 2001 From: Patrik Cyvoct Date: Tue, 15 Sep 2020 15:59:19 +0200 Subject: [PATCH 2/2] fix review Signed-off-by: Patrik Cyvoct --- scaleway/helpers_object.go | 37 ++++++++++++++++++++++ scaleway/resource_object_bucket.go | 35 ++------------------ website/docs/r/object_bucket.html.markdown | 2 +- 3 files changed, 41 insertions(+), 33 deletions(-) create mode 100644 scaleway/helpers_object.go diff --git a/scaleway/helpers_object.go b/scaleway/helpers_object.go new file mode 100644 index 0000000000..a56ef44a15 --- /dev/null +++ b/scaleway/helpers_object.go @@ -0,0 +1,37 @@ +package scaleway + +import ( + "github.com/aws/aws-sdk-go/service/s3" + "github.com/scaleway/scaleway-sdk-go/scw" +) + +func flattenObjectBucketTags(tagsSet []*s3.Tag) map[string]interface{} { + tags := map[string]interface{}{} + + for _, tagSet := range tagsSet { + var key string + var value string + if tagSet.Key != nil { + key = *tagSet.Key + } + if tagSet.Value != nil { + value = *tagSet.Value + } + tags[key] = value + } + + return tags +} + +func expandObjectBucketTags(tags interface{}) []*s3.Tag { + tagsSet := make([]*s3.Tag, 0) + + for key, value := range tags.(map[string]interface{}) { + tagsSet = append(tagsSet, &s3.Tag{ + Key: &key, + Value: scw.StringPtr(value.(string)), + }) + } + + return tagsSet +} diff --git a/scaleway/resource_object_bucket.go b/scaleway/resource_object_bucket.go index 01dd710f56..ee881fa83e 100644 --- a/scaleway/resource_object_bucket.go +++ b/scaleway/resource_object_bucket.go @@ -8,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go/service/s3" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" - "github.com/scaleway/scaleway-sdk-go/scw" ) func resourceScalewayObjectBucket() *schema.Resource { @@ -69,14 +68,7 @@ func resourceScalewayObjectBucketCreate(d *schema.ResourceData, m interface{}) e return err } - tagsSet := make([]*s3.Tag, 0) - - for key, value := range d.Get("tags").(map[string]interface{}) { - tagsSet = append(tagsSet, &s3.Tag{ - Key: &key, - Value: scw.StringPtr(value.(string)), - }) - } + tagsSet := expandObjectBucketTags(d.Get("tags")) if len(tagsSet) > 0 { _, err = s3Client.PutBucketTagging(&s3.PutBucketTaggingInput{ @@ -137,21 +129,7 @@ func resourceScalewayObjectBucketRead(d *schema.ResourceData, m interface{}) err tagsSet = tagsResponse.TagSet } - tags := map[string]interface{}{} - - for _, tagSet := range tagsSet { - var key string - var value string - if tagSet.Key != nil { - key = *tagSet.Key - } - if tagSet.Value != nil { - value = *tagSet.Value - } - tags[key] = value - } - - _ = d.Set("tags", tags) + _ = d.Set("tags", flattenObjectBucketTags(tagsSet)) return nil } @@ -176,14 +154,7 @@ func resourceScalewayObjectBucketUpdate(d *schema.ResourceData, m interface{}) e } if d.HasChange("tags") { - tagsSet := make([]*s3.Tag, 0) - - for key, value := range d.Get("tags").(map[string]interface{}) { - tagsSet = append(tagsSet, &s3.Tag{ - Key: &key, - Value: scw.StringPtr(value.(string)), - }) - } + tagsSet := expandObjectBucketTags(d.Get("tags")) _, err = s3Client.PutBucketTagging(&s3.PutBucketTaggingInput{ Bucket: aws.String(bucketName), diff --git a/website/docs/r/object_bucket.html.markdown b/website/docs/r/object_bucket.html.markdown index a41a0466e5..36740474ef 100644 --- a/website/docs/r/object_bucket.html.markdown +++ b/website/docs/r/object_bucket.html.markdown @@ -26,7 +26,7 @@ resource "scaleway_object_bucket" "some_bucket" { The following arguments are supported: * `name` - (Required) The name of the bucket. -* `tags` - (Optional) The tags of the bucket. +* `tags` - (Optional) A list of tags (key / value) for the bucket. * `acl` - (Optional) The [canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl) you want to apply to the bucket. * `region` - (Optional) The [region](https://developers.scaleway.com/en/quickstart/#region-definition) in which the bucket should be created.