From b059888d6d84eb9d305261cefec7f0d6d6b00ac9 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 25 Oct 2019 21:24:07 +0300 Subject: [PATCH 1/3] add resource groups support in keyvaluetags lib --- .../service_generation_customizations.go | 2 ++ aws/internal/keyvaluetags/update_tags_gen.go | 36 +++++++++++++++++++ .../docs/r/resourcegroups_group.html.markdown | 1 + 3 files changed, 39 insertions(+) diff --git a/aws/internal/keyvaluetags/service_generation_customizations.go b/aws/internal/keyvaluetags/service_generation_customizations.go index 8321bab3b1f..3626b57c55b 100644 --- a/aws/internal/keyvaluetags/service_generation_customizations.go +++ b/aws/internal/keyvaluetags/service_generation_customizations.go @@ -270,6 +270,8 @@ func ServiceClientType(serviceName string) string { funcType = reflect.TypeOf(wafregional.New) case "workspaces": funcType = reflect.TypeOf(workspaces.New) + case "resourcegroups": + funcType = reflect.TypeOf(resourcegroups.New) default: panic(fmt.Sprintf("unrecognized ServiceClientType: %s", serviceName)) } diff --git a/aws/internal/keyvaluetags/update_tags_gen.go b/aws/internal/keyvaluetags/update_tags_gen.go index e9c15867acf..16b09080f37 100644 --- a/aws/internal/keyvaluetags/update_tags_gen.go +++ b/aws/internal/keyvaluetags/update_tags_gen.go @@ -2501,6 +2501,42 @@ func ResourcegroupsUpdateTags(conn *resourcegroups.ResourceGroups, identifier st return nil } +// ResourcegroupsUpdateTags updates resourcegroups service tags. +// The identifier is typically the Amazon Resource Name (ARN), although +// it may also be a different identifier depending on the service. +func ResourcegroupsUpdateTags(conn *resourcegroups.ResourceGroups, identifier string, oldTagsMap interface{}, newTagsMap interface{}) error { + oldTags := New(oldTagsMap) + newTags := New(newTagsMap) + + if removedTags := oldTags.Removed(newTags); len(removedTags) > 0 { + input := &resourcegroups.UntagInput{ + Arn: aws.String(identifier), + Keys: aws.StringSlice(removedTags.Keys()), + } + + _, err := conn.Untag(input) + + if err != nil { + return fmt.Errorf("error untagging resource (%s): %s", identifier, err) + } + } + + if updatedTags := oldTags.Updated(newTags); len(updatedTags) > 0 { + input := &resourcegroups.TagInput{ + Arn: aws.String(identifier), + Tags: updatedTags.IgnoreAws().ResourcegroupsTags(), + } + + _, err := conn.Tag(input) + + if err != nil { + return fmt.Errorf("error tagging resource (%s): %s", identifier, err) + } + } + + return nil +} + // Route53resolverUpdateTags updates route53resolver service tags. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. diff --git a/website/docs/r/resourcegroups_group.html.markdown b/website/docs/r/resourcegroups_group.html.markdown index 8a17ae28793..ad32ae55294 100644 --- a/website/docs/r/resourcegroups_group.html.markdown +++ b/website/docs/r/resourcegroups_group.html.markdown @@ -41,6 +41,7 @@ The following arguments are supported: * `name` - (Required) The resource group's name. A resource group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. * `description` - (Optional) A description of the resource group. * `resource_query` - (Required) A `resource_query` block. Resource queries are documented below. +* `tags` - (Optional) Key-value mapping of resource tags An `resource_query` block supports the following arguments: From f2f4d09fc7d873a779ef58ecea1f0fd77ff1633f Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 25 Oct 2019 21:56:18 +0300 Subject: [PATCH 2/3] add tag support for resource groups refactor tests --- aws/resource_aws_resourcegroups_group.go | 21 ++- aws/resource_aws_resourcegroups_group_test.go | 136 +++++++++++++++--- 2 files changed, 135 insertions(+), 22 deletions(-) diff --git a/aws/resource_aws_resourcegroups_group.go b/aws/resource_aws_resourcegroups_group.go index 3b8e2cc7bbc..30ce602419e 100644 --- a/aws/resource_aws_resourcegroups_group.go +++ b/aws/resource_aws_resourcegroups_group.go @@ -8,6 +8,7 @@ import ( "github.com/aws/aws-sdk-go/service/resourcegroups" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) func resourceAwsResourceGroupsGroup() *schema.Resource { @@ -61,6 +62,7 @@ func resourceAwsResourceGroupsGroup() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "tags": tagsSchema(), }, } } @@ -81,6 +83,7 @@ func resourceAwsResourceGroupsGroupCreate(d *schema.ResourceData, meta interface Description: aws.String(d.Get("description").(string)), Name: aws.String(d.Get("name").(string)), ResourceQuery: extractResourceGroupResourceQuery(d.Get("resource_query").([]interface{})), + Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().ResourcegroupsTags(), } res, err := conn.CreateGroup(&input) @@ -110,9 +113,10 @@ func resourceAwsResourceGroupsGroupRead(d *schema.ResourceData, meta interface{} return fmt.Errorf("error reading resource group (%s): %s", d.Id(), err) } + arn := aws.StringValue(g.Group.GroupArn) d.Set("name", aws.StringValue(g.Group.Name)) d.Set("description", aws.StringValue(g.Group.Description)) - d.Set("arn", aws.StringValue(g.Group.GroupArn)) + d.Set("arn", arn) q, err := conn.GetGroupQuery(&resourcegroups.GetGroupQueryInput{ GroupName: aws.String(d.Id()), @@ -129,6 +133,14 @@ func resourceAwsResourceGroupsGroupRead(d *schema.ResourceData, meta interface{} return fmt.Errorf("error setting resource_query: %s", err) } + tags, err := keyvaluetags.ResourcegroupsListTags(conn, arn) + if err != nil { + return fmt.Errorf("error listing tags for resource (%s): %s", arn, err) + } + if err := d.Set("tags", tags.IgnoreAws().Map()); err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + return nil } @@ -159,6 +171,13 @@ func resourceAwsResourceGroupsGroupUpdate(d *schema.ResourceData, meta interface } } + if d.HasChange("tags") { + o, n := d.GetChange("tags") + if err := keyvaluetags.ResourcegroupsUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return fmt.Errorf("error updating tags: %s", err) + } + } + return resourceAwsResourceGroupsGroupRead(d, meta) } diff --git a/aws/resource_aws_resourcegroups_group_test.go b/aws/resource_aws_resourcegroups_group_test.go index 31270ed3a48..a8a6a6843c6 100644 --- a/aws/resource_aws_resourcegroups_group_test.go +++ b/aws/resource_aws_resourcegroups_group_test.go @@ -12,25 +12,13 @@ import ( ) func TestAccAWSResourceGroup_basic(t *testing.T) { + var v resourcegroups.Group resourceName := "aws_resourcegroups_group.test" n := fmt.Sprintf("test-group-%d", acctest.RandInt()) desc1 := "Hello World" desc2 := "Foo Bar" - query1 := `{ - "ResourceTypeFilters": [ - "AWS::EC2::Instance" - ], - "TagFilters": [ - { - "Key": "Stage", - "Values": ["Test"] - } - ] -} -` - query2 := `{ "ResourceTypeFilters": [ "AWS::EC2::Instance" @@ -50,12 +38,12 @@ func TestAccAWSResourceGroup_basic(t *testing.T) { CheckDestroy: testAccCheckAWSResourceGroupDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSResourceGroupConfig_basic(n, desc1, query1), + Config: testAccAWSResourceGroupConfig_basic(n, desc1, testAccAWSResourceGroupConfigQuery), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSResourceGroupExists(resourceName), + testAccCheckAWSResourceGroupExists(resourceName, &v), resource.TestCheckResourceAttr(resourceName, "name", n), resource.TestCheckResourceAttr(resourceName, "description", desc1), - resource.TestCheckResourceAttr(resourceName, "resource_query.0.query", query1+"\n"), + resource.TestCheckResourceAttr(resourceName, "resource_query.0.query", testAccAWSResourceGroupConfigQuery+"\n"), resource.TestCheckResourceAttrSet(resourceName, "arn"), ), }, @@ -75,7 +63,52 @@ func TestAccAWSResourceGroup_basic(t *testing.T) { }) } -func testAccCheckAWSResourceGroupExists(n string) resource.TestCheckFunc { +func TestAccAWSResourceGroup_tags(t *testing.T) { + var v resourcegroups.Group + resourceName := "aws_resourcegroups_group.test" + n := fmt.Sprintf("test-group-%d", acctest.RandInt()) + desc1 := "Hello World" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSResourceGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSResourceGroupConfigTags1(n, desc1, testAccAWSResourceGroupConfigQuery, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSResourceGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSResourceGroupConfigTags2(n, desc1, testAccAWSResourceGroupConfigQuery, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSResourceGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccAWSResourceGroupConfigTags1(n, desc1, testAccAWSResourceGroupConfigQuery, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSResourceGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + +func testAccCheckAWSResourceGroupExists(n string, v *resourcegroups.Group) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -88,17 +121,26 @@ func testAccCheckAWSResourceGroupExists(n string) resource.TestCheckFunc { conn := testAccProvider.Meta().(*AWSClient).resourcegroupsconn - _, err := conn.GetGroup(&resourcegroups.GetGroupInput{ + resp, err := conn.GetGroup(&resourcegroups.GetGroupInput{ GroupName: aws.String(rs.Primary.ID), }) - return err + if err != nil { + return err + } + + if *resp.Group.Name == rs.Primary.ID { + *v = *resp.Group + return nil + } + + return fmt.Errorf("Resource Group (%s) not found", rs.Primary.ID) } } func testAccCheckAWSResourceGroupDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { - if rs.Type != "aws_waf_rule_group" { + if rs.Type != "aws_resourcegroups_group" { continue } @@ -124,7 +166,20 @@ func testAccCheckAWSResourceGroupDestroy(s *terraform.State) error { return nil } -func testAccAWSResourceGroupConfig_basic(rName string, desc string, query string) string { +const testAccAWSResourceGroupConfigQuery = `{ + "ResourceTypeFilters": [ + "AWS::EC2::Instance" + ], + "TagFilters": [ + { + "Key": "Stage", + "Values": ["Test"] + } + ] +} +` + +func testAccAWSResourceGroupConfig_basic(rName, desc, query string) string { return fmt.Sprintf(` resource "aws_resourcegroups_group" "test" { name = "%s" @@ -138,3 +193,42 @@ JSON } `, rName, desc, query) } + +func testAccAWSResourceGroupConfigTags1(rName, desc, query, tag1Key, tag1Value string) string { + return fmt.Sprintf(` +resource "aws_resourcegroups_group" "test" { + name = "%s" + description = "%s" + + resource_query { + query = < Date: Fri, 15 Nov 2019 19:24:57 +0200 Subject: [PATCH 3/3] remove keyvaluetags change --- .../service_generation_customizations.go | 2 -- aws/internal/keyvaluetags/update_tags_gen.go | 36 ------------------- 2 files changed, 38 deletions(-) diff --git a/aws/internal/keyvaluetags/service_generation_customizations.go b/aws/internal/keyvaluetags/service_generation_customizations.go index 3626b57c55b..8321bab3b1f 100644 --- a/aws/internal/keyvaluetags/service_generation_customizations.go +++ b/aws/internal/keyvaluetags/service_generation_customizations.go @@ -270,8 +270,6 @@ func ServiceClientType(serviceName string) string { funcType = reflect.TypeOf(wafregional.New) case "workspaces": funcType = reflect.TypeOf(workspaces.New) - case "resourcegroups": - funcType = reflect.TypeOf(resourcegroups.New) default: panic(fmt.Sprintf("unrecognized ServiceClientType: %s", serviceName)) } diff --git a/aws/internal/keyvaluetags/update_tags_gen.go b/aws/internal/keyvaluetags/update_tags_gen.go index 16b09080f37..e9c15867acf 100644 --- a/aws/internal/keyvaluetags/update_tags_gen.go +++ b/aws/internal/keyvaluetags/update_tags_gen.go @@ -2501,42 +2501,6 @@ func ResourcegroupsUpdateTags(conn *resourcegroups.ResourceGroups, identifier st return nil } -// ResourcegroupsUpdateTags updates resourcegroups service tags. -// The identifier is typically the Amazon Resource Name (ARN), although -// it may also be a different identifier depending on the service. -func ResourcegroupsUpdateTags(conn *resourcegroups.ResourceGroups, identifier string, oldTagsMap interface{}, newTagsMap interface{}) error { - oldTags := New(oldTagsMap) - newTags := New(newTagsMap) - - if removedTags := oldTags.Removed(newTags); len(removedTags) > 0 { - input := &resourcegroups.UntagInput{ - Arn: aws.String(identifier), - Keys: aws.StringSlice(removedTags.Keys()), - } - - _, err := conn.Untag(input) - - if err != nil { - return fmt.Errorf("error untagging resource (%s): %s", identifier, err) - } - } - - if updatedTags := oldTags.Updated(newTags); len(updatedTags) > 0 { - input := &resourcegroups.TagInput{ - Arn: aws.String(identifier), - Tags: updatedTags.IgnoreAws().ResourcegroupsTags(), - } - - _, err := conn.Tag(input) - - if err != nil { - return fmt.Errorf("error tagging resource (%s): %s", identifier, err) - } - } - - return nil -} - // Route53resolverUpdateTags updates route53resolver service tags. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service.