diff --git a/aws/provider.go b/aws/provider.go index 16cab81d82a..4868e6a50be 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -616,6 +616,7 @@ func Provider() terraform.ResourceProvider { "aws_organizations_organizational_unit": resourceAwsOrganizationsOrganizationalUnit(), "aws_placement_group": resourceAwsPlacementGroup(), "aws_proxy_protocol_policy": resourceAwsProxyProtocolPolicy(), + "aws_quicksight_group": resourceAwsQuickSightGroup(), "aws_ram_principal_association": resourceAwsRamPrincipalAssociation(), "aws_ram_resource_association": resourceAwsRamResourceAssociation(), "aws_ram_resource_share": resourceAwsRamResourceShare(), diff --git a/aws/resource_aws_quicksight_group.go b/aws/resource_aws_quicksight_group.go new file mode 100644 index 00000000000..d9f394c29b0 --- /dev/null +++ b/aws/resource_aws_quicksight_group.go @@ -0,0 +1,187 @@ +package aws + +import ( + "fmt" + "log" + "strings" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/quicksight" +) + +func resourceAwsQuickSightGroup() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsQuickSightGroupCreate, + Read: resourceAwsQuickSightGroupRead, + Update: resourceAwsQuickSightGroupUpdate, + Delete: resourceAwsQuickSightGroupDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + + "aws_account_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "group_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "namespace": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: "default", + ValidateFunc: validation.StringInSlice([]string{ + "default", + }, false), + }, + }, + } +} + +func resourceAwsQuickSightGroupCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).quicksightconn + + awsAccountID := meta.(*AWSClient).accountid + namespace := d.Get("namespace").(string) + + if v, ok := d.GetOk("aws_account_id"); ok { + awsAccountID = v.(string) + } + + createOpts := &quicksight.CreateGroupInput{ + AwsAccountId: aws.String(awsAccountID), + Namespace: aws.String(namespace), + GroupName: aws.String(d.Get("group_name").(string)), + } + + if v, ok := d.GetOk("description"); ok { + createOpts.Description = aws.String(v.(string)) + } + + resp, err := conn.CreateGroup(createOpts) + if err != nil { + return fmt.Errorf("Error creating Quick Sight Group: %s", err) + } + + d.SetId(fmt.Sprintf("%s/%s/%s", awsAccountID, namespace, aws.StringValue(resp.Group.GroupName))) + + return resourceAwsQuickSightGroupRead(d, meta) +} + +func resourceAwsQuickSightGroupRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).quicksightconn + + awsAccountID, namespace, groupName, err := resourceAwsQuickSightGroupParseID(d.Id()) + if err != nil { + return err + } + + descOpts := &quicksight.DescribeGroupInput{ + AwsAccountId: aws.String(awsAccountID), + Namespace: aws.String(namespace), + GroupName: aws.String(groupName), + } + + resp, err := conn.DescribeGroup(descOpts) + if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { + log.Printf("[WARN] Quick Sight Group %s is already gone", d.Id()) + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("Error describing Quick Sight Group (%s): %s", d.Id(), err) + } + + d.Set("arn", resp.Group.Arn) + d.Set("aws_account_id", awsAccountID) + d.Set("group_name", resp.Group.GroupName) + d.Set("description", resp.Group.Description) + d.Set("namespace", namespace) + + return nil +} + +func resourceAwsQuickSightGroupUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).quicksightconn + + awsAccountID, namespace, groupName, err := resourceAwsQuickSightGroupParseID(d.Id()) + if err != nil { + return err + } + + updateOpts := &quicksight.UpdateGroupInput{ + AwsAccountId: aws.String(awsAccountID), + Namespace: aws.String(namespace), + GroupName: aws.String(groupName), + } + + if v, ok := d.GetOk("description"); ok { + updateOpts.Description = aws.String(v.(string)) + } + + _, err = conn.UpdateGroup(updateOpts) + if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { + log.Printf("[WARN] Quick Sight Group %s is already gone", d.Id()) + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("Error updating Quick Sight Group %s: %s", d.Id(), err) + } + + return resourceAwsQuickSightGroupRead(d, meta) +} + +func resourceAwsQuickSightGroupDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).quicksightconn + + awsAccountID, namespace, groupName, err := resourceAwsQuickSightGroupParseID(d.Id()) + if err != nil { + return err + } + + deleteOpts := &quicksight.DeleteGroupInput{ + AwsAccountId: aws.String(awsAccountID), + Namespace: aws.String(namespace), + GroupName: aws.String(groupName), + } + + if _, err := conn.DeleteGroup(deleteOpts); err != nil { + if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { + return nil + } + return fmt.Errorf("Error deleting Quick Sight Group %s: %s", d.Id(), err) + } + + return nil +} + +func resourceAwsQuickSightGroupParseID(id string) (string, string, string, error) { + parts := strings.SplitN(id, "/", 3) + if len(parts) < 3 || parts[0] == "" || parts[1] == "" || parts[2] == "" { + return "", "", "", fmt.Errorf("unexpected format of ID (%s), expected AWS_ACCOUNT_ID/NAMESPACE/GROUP_NAME", id) + } + return parts[0], parts[1], parts[2], nil +} diff --git a/aws/resource_aws_quicksight_group_test.go b/aws/resource_aws_quicksight_group_test.go new file mode 100644 index 00000000000..994ea2ffdfe --- /dev/null +++ b/aws/resource_aws_quicksight_group_test.go @@ -0,0 +1,235 @@ +package aws + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go/service/quicksight" +) + +func TestAccAWSQuickSightGroup_basic(t *testing.T) { + oldvar := os.Getenv("AWS_DEFAULT_REGION") + os.Setenv("AWS_DEFAULT_REGION", "us-east-1") + defer os.Setenv("AWS_DEFAULT_REGION", oldvar) + + var group quicksight.Group + resourceName := "aws_quicksight_group.default" + rName1 := acctest.RandomWithPrefix("tf-acc-test") + rName2 := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckQuickSightGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSQuickSightGroupConfig(rName1), + Check: resource.ComposeTestCheckFunc( + testAccCheckQuickSightGroupExists(resourceName, &group), + resource.TestCheckResourceAttr(resourceName, "group_name", rName1), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "quicksight", fmt.Sprintf("group/default/%s", rName1)), + ), + }, + { + Config: testAccAWSQuickSightGroupConfig(rName2), + Check: resource.ComposeTestCheckFunc( + testAccCheckQuickSightGroupExists(resourceName, &group), + resource.TestCheckResourceAttr(resourceName, "group_name", rName2), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "quicksight", fmt.Sprintf("group/default/%s", rName2)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSQuickSightGroup_withDescription(t *testing.T) { + oldvar := os.Getenv("AWS_DEFAULT_REGION") + os.Setenv("AWS_DEFAULT_REGION", "us-east-1") + defer os.Setenv("AWS_DEFAULT_REGION", oldvar) + + var group quicksight.Group + resourceName := "aws_quicksight_group.default" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckQuickSightGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSQuickSightGroupConfigWithDescription(rName, "Description 1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckQuickSightGroupExists(resourceName, &group), + resource.TestCheckResourceAttr(resourceName, "description", "Description 1"), + ), + }, + { + Config: testAccAWSQuickSightGroupConfigWithDescription(rName, "Description 2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckQuickSightGroupExists(resourceName, &group), + resource.TestCheckResourceAttr(resourceName, "description", "Description 2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSQuickSightGroup_disappears(t *testing.T) { + oldvar := os.Getenv("AWS_DEFAULT_REGION") + os.Setenv("AWS_DEFAULT_REGION", "us-east-1") + defer os.Setenv("AWS_DEFAULT_REGION", oldvar) + + var group quicksight.Group + resourceName := "aws_quicksight_group.default" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckQuickSightGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSQuickSightGroupConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckQuickSightGroupExists(resourceName, &group), + testAccCheckQuickSightGroupDisappears(&group), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckQuickSightGroupExists(resourceName string, group *quicksight.Group) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + awsAccountID, namespace, groupName, err := resourceAwsQuickSightGroupParseID(rs.Primary.ID) + if err != nil { + return err + } + + conn := testAccProvider.Meta().(*AWSClient).quicksightconn + + input := &quicksight.DescribeGroupInput{ + AwsAccountId: aws.String(awsAccountID), + Namespace: aws.String(namespace), + GroupName: aws.String(groupName), + } + + output, err := conn.DescribeGroup(input) + + if err != nil { + return err + } + + if output == nil || output.Group == nil { + return fmt.Errorf("Quick Sight Group (%s) not found", rs.Primary.ID) + } + + *group = *output.Group + + return nil + } +} + +func testAccCheckQuickSightGroupDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).quicksightconn + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_quicksight_group" { + continue + } + + awsAccountID, namespace, groupName, err := resourceAwsQuickSightGroupParseID(rs.Primary.ID) + if err != nil { + return err + } + + _, err = conn.DescribeGroup(&quicksight.DescribeGroupInput{ + AwsAccountId: aws.String(awsAccountID), + Namespace: aws.String(namespace), + GroupName: aws.String(groupName), + }) + if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { + continue + } + + if err != nil { + return err + } + + return fmt.Errorf("Quick Sight Group '%s' was not deleted properly", rs.Primary.ID) + } + + return nil +} + +func testAccCheckQuickSightGroupDisappears(v *quicksight.Group) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).quicksightconn + + arn, err := arn.Parse(aws.StringValue(v.Arn)) + if err != nil { + return err + } + + parts := strings.SplitN(arn.Resource, "/", 3) + + input := &quicksight.DeleteGroupInput{ + AwsAccountId: aws.String(arn.AccountID), + Namespace: aws.String(parts[1]), + GroupName: v.GroupName, + } + + if _, err := conn.DeleteGroup(input); err != nil { + return err + } + + return nil + } +} + +func testAccAWSQuickSightGroupConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_quicksight_group" "default" { + group_name = "%[1]s" +} + +`, rName) + +} + +func testAccAWSQuickSightGroupConfigWithDescription(rName, description string) string { + return fmt.Sprintf(` +data "aws_caller_identity" "current" {} + +resource "aws_quicksight_group" "default" { + aws_account_id = "${data.aws_caller_identity.current.account_id}" + group_name = "%[1]s" + description = "%[2]s" +} + +`, rName, description) + +} diff --git a/website/aws.erb b/website/aws.erb index cda0effc88c..4fbb787ee36 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -2133,6 +2133,15 @@ +
  • + QuickSight Resources + +
  • +
  • RAM Resources