From 7d3bdc85906c5b3efbaf9aea5b5df543e316fb60 Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Wed, 27 Nov 2019 10:59:34 -0500 Subject: [PATCH 01/21] Add rough sketch for `aws_quicksight_data_source` resource. --- aws/resource_aws_quicksight_data_source.go | 209 +++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 aws/resource_aws_quicksight_data_source.go diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go new file mode 100644 index 000000000000..793437eeda6c --- /dev/null +++ b/aws/resource_aws_quicksight_data_source.go @@ -0,0 +1,209 @@ +package aws + +import ( + "fmt" + "log" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/quicksight" +) + +func resourceAwsQuickSightDataSource() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsQuickSightDataSourceCreate, + Read: resourceAwsQuickSightDataSourceRead, + Update: resourceAwsQuickSightDataSourceUpdate, + Delete: resourceAwsQuickSightDataSourceDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + // OK + "arn": { + Type: schema.TypeString, + Computed: true, + }, + + // OK + "aws_account_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + + // TODO + "credentials": { + }, + + // TODO + "id": { + }, + + // TODO + "name": { + }, + + // TODO + "parameters": { + }, + + // TODO + "permissions": { + }, + + // TODO + "ssl_properties": { + }, + + // TODO + "tags": { + }, + + // TODO + "type": { + }, + + // TODO + "vpc_connection_properties": { + }, + + // TODO: this is a tough one... + "creation_stauts": { + Type: schema.TypeString, + }, + }, + } +} + +func resourceAwsQuickSightDataSourceCreate(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.CreateDataSourceInput{ + AwsAccountId: aws.String(awsAccountID), + Namespace: aws.String(namespace), + DataSourceName: aws.String(d.Get("group_name").(string)), + } + + if v, ok := d.GetOk("description"); ok { + createOpts.Description = aws.String(v.(string)) + } + + resp, err := conn.CreateDataSource(createOpts) + if err != nil { + return fmt.Errorf("Error creating QuickSight DataSource: %s", err) + } + + d.SetId(fmt.Sprintf("%s/%s/%s", awsAccountID, namespace, aws.StringValue(resp.DataSource.DataSourceName))) + + return resourceAwsQuickSightDataSourceRead(d, meta) +} + +func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).quicksightconn + + awsAccountID, namespace, groupName, err := resourceAwsQuickSightDataSourceParseID(d.Id()) + if err != nil { + return err + } + + descOpts := &quicksight.DescribeDataSourceInput{ + AwsAccountId: aws.String(awsAccountID), + Namespace: aws.String(namespace), + DataSourceName: aws.String(groupName), + } + + resp, err := conn.DescribeDataSource(descOpts) + if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { + log.Printf("[WARN] QuickSight DataSource %s is already gone", d.Id()) + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("Error describing QuickSight DataSource (%s): %s", d.Id(), err) + } + + d.Set("arn", resp.DataSource.Arn) + d.Set("aws_account_id", awsAccountID) + d.Set("group_name", resp.DataSource.DataSourceName) + d.Set("description", resp.DataSource.Description) + d.Set("namespace", namespace) + + return nil +} + +func resourceAwsQuickSightDataSourceUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).quicksightconn + + awsAccountID, namespace, groupName, err := resourceAwsQuickSightDataSourceParseID(d.Id()) + if err != nil { + return err + } + + updateOpts := &quicksight.UpdateDataSourceInput{ + AwsAccountId: aws.String(awsAccountID), + Namespace: aws.String(namespace), + DataSourceName: aws.String(groupName), + } + + if v, ok := d.GetOk("description"); ok { + updateOpts.Description = aws.String(v.(string)) + } + + _, err = conn.UpdateDataSource(updateOpts) + if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { + log.Printf("[WARN] QuickSight DataSource %s is already gone", d.Id()) + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("Error updating QuickSight DataSource %s: %s", d.Id(), err) + } + + return resourceAwsQuickSightDataSourceRead(d, meta) +} + +func resourceAwsQuickSightDataSourceDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).quicksightconn + + awsAccountID, namespace, groupName, err := resourceAwsQuickSightDataSourceParseID(d.Id()) + if err != nil { + return err + } + + deleteOpts := &quicksight.DeleteDataSourceInput{ + AwsAccountId: aws.String(awsAccountID), + Namespace: aws.String(namespace), + DataSourceName: aws.String(groupName), + } + + if _, err := conn.DeleteDataSource(deleteOpts); err != nil { + if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { + return nil + } + return fmt.Errorf("Error deleting QuickSight DataSource %s: %s", d.Id(), err) + } + + return nil +} + +func resourceAwsQuickSightDataSourceParseID(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/DATA_SOURCE_ID", id) + } + return parts[0], parts[1], parts[2], nil +} From 732e8e6abb2b2f34a667c64d6fbb83614e279e4e Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Wed, 27 Nov 2019 11:47:22 -0500 Subject: [PATCH 02/21] Work out `credentials` and `parameters`. --- aws/resource_aws_quicksight_data_source.go | 440 ++++++++++++++++++++- 1 file changed, 434 insertions(+), 6 deletions(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index 793437eeda6c..afac1a96423a 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -24,13 +24,11 @@ func resourceAwsQuickSightDataSource() *schema.Resource { }, Schema: map[string]*schema.Schema{ - // OK "arn": { Type: schema.TypeString, Computed: true, }, - // OK "aws_account_id": { Type: schema.TypeString, Optional: true, @@ -38,20 +36,450 @@ func resourceAwsQuickSightDataSource() *schema.Resource { ForceNew: true, }, - // TODO "credentials": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "credential_pair": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "password": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "username": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + } + }, + }, + }, + }, }, - // TODO "id": { + Type: schema.TypeString, + Required: true, }, - // TODO "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, }, - // TODO "parameters": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "amazon_elasticsearch": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "domain": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + } + }, + }, + "athena": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "work_group": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.NoZeroValues, + }, + } + }, + }, + "aurora": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "database": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "host": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "port": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + }, + } + }, + }, + "aurora_postgre_sql": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + // TODO: Extract common + "database": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "host": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "port": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + }, + } + }, + }, + "aws_iot_analytics": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "database": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + } + }, + }, + "jira": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "site_base_url": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + } + }, + }, + "maria_db": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "database": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "host": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "port": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + }, + } + }, + }, + "mysql": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "database": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "host": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "port": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + }, + } + }, + }, + "postgresql": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "database": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "host": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "port": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + }, + } + }, + }, + "presto": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "catalog": { + Type: schema.TypeString, + Required: true, + }, + "host": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "port": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + }, + } + }, + }, + "rds": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "database": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "instance_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + } + }, + }, + "redshift": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cluster_id": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.NoZeroValues, + }, + "database": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "host": { + Type: schema.TypeString, + Optional: true, + }, + "port": { + Type: schema.TypeInt, + Optional: true, + }, + } + }, + }, + "s3": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "manifest_file_location": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "bucket": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "key": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + } + } + } + } + }, + }, + "service_now": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "site_base_url": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + } + }, + }, + "snowflake": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "database": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "host": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "warehouse": { + Type: schema.TypeString, + Required: true, + }, + } + }, + }, + "spark": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "host": { + Type: schema.TypeString, + Required: true, + }, + "port": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + }, + } + }, + }, + "sql_server": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "database": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "host": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "port": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + }, + } + }, + }, + "teradata": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "database": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "host": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + "port": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + }, + } + }, + }, + "twitter": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "max_rows": { + Type: schema.TypeInt, + Required: true, + ValidateFunc: validation.IntAtLeast(1), + }, + "query": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + } + }, + }, + }, + }, }, // TODO From a97b39c5d7ab09b0824a880be0e9d475c49d02b4 Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Wed, 27 Nov 2019 13:57:44 -0500 Subject: [PATCH 03/21] Try to get build to work but it's panicing. --- aws/resource_aws_quicksight_data_source.go | 442 ++++++++++++--------- 1 file changed, 262 insertions(+), 180 deletions(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index afac1a96423a..ae2215f7fbbf 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -1,23 +1,22 @@ package aws import ( - "fmt" - "log" - "strings" + // "fmt" + // "log" + // "strings" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/quicksight" + // "github.com/aws/aws-sdk-go/aws" + // "github.com/aws/aws-sdk-go/service/quicksight" ) func resourceAwsQuickSightDataSource() *schema.Resource { return &schema.Resource{ - Create: resourceAwsQuickSightDataSourceCreate, - Read: resourceAwsQuickSightDataSourceRead, - Update: resourceAwsQuickSightDataSourceUpdate, - Delete: resourceAwsQuickSightDataSourceDelete, + // Create: resourceAwsQuickSightDataSourceCreate, + // Read: resourceAwsQuickSightDataSourceRead, + // Update: resourceAwsQuickSightDataSourceUpdate, + // Delete: resourceAwsQuickSightDataSourceDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, @@ -58,7 +57,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.NoZeroValues, }, - } + }, }, }, }, @@ -66,8 +65,9 @@ func resourceAwsQuickSightDataSource() *schema.Resource { }, "id": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, }, "name": { @@ -78,8 +78,9 @@ func resourceAwsQuickSightDataSource() *schema.Resource { "parameters": { Type: schema.TypeList, - Optional: true, + Required: true, MaxItems: 1, + MinItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "amazon_elasticsearch": { @@ -93,7 +94,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.NoZeroValues, }, - } + }, }, }, "athena": { @@ -107,7 +108,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Optional: true, ValidateFunc: validation.NoZeroValues, }, - } + }, }, }, "aurora": { @@ -131,7 +132,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.IntAtLeast(1), }, - } + }, }, }, "aurora_postgre_sql": { @@ -156,7 +157,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.IntAtLeast(1), }, - } + }, }, }, "aws_iot_analytics": { @@ -170,7 +171,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.NoZeroValues, }, - } + }, }, }, "jira": { @@ -184,7 +185,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.NoZeroValues, }, - } + }, }, }, "maria_db": { @@ -208,7 +209,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.IntAtLeast(1), }, - } + }, }, }, "mysql": { @@ -232,7 +233,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.IntAtLeast(1), }, - } + }, }, }, "postgresql": { @@ -256,7 +257,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.IntAtLeast(1), }, - } + }, }, }, "presto": { @@ -266,8 +267,8 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "catalog": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, }, "host": { Type: schema.TypeString, @@ -279,7 +280,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.IntAtLeast(1), }, - } + }, }, }, "rds": { @@ -298,7 +299,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.NoZeroValues, }, - } + }, }, }, "redshift": { @@ -318,14 +319,14 @@ func resourceAwsQuickSightDataSource() *schema.Resource { ValidateFunc: validation.NoZeroValues, }, "host": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, }, "port": { - Type: schema.TypeInt, - Optional: true, + Type: schema.TypeInt, + Optional: true, }, - } + }, }, }, "s3": { @@ -350,10 +351,10 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.NoZeroValues, }, - } - } - } - } + }, + }, + }, + }, }, }, "service_now": { @@ -367,7 +368,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.NoZeroValues, }, - } + }, }, }, "snowflake": { @@ -387,10 +388,10 @@ func resourceAwsQuickSightDataSource() *schema.Resource { ValidateFunc: validation.NoZeroValues, }, "warehouse": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, }, - } + }, }, }, "spark": { @@ -400,15 +401,15 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "host": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, }, "port": { Type: schema.TypeInt, Required: true, ValidateFunc: validation.IntAtLeast(1), }, - } + }, }, }, "sql_server": { @@ -432,7 +433,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.IntAtLeast(1), }, - } + }, }, }, "teradata": { @@ -456,7 +457,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.IntAtLeast(1), }, - } + }, }, }, "twitter": { @@ -475,163 +476,244 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Required: true, ValidateFunc: validation.NoZeroValues, }, - } + }, }, }, }, }, }, - // TODO "permissions": { + Type: schema.TypeList, + Optional: true, + MinItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "actions": { + Type: schema.TypeList, + Required: true, + MinItems: 1, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "principal": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.NoZeroValues, + }, + }, + }, }, - // TODO "ssl_properties": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "disable_ssl": { + Type: schema.TypeBool, + Optional: true, + }, + }, + }, }, - // TODO - "tags": { - }, + "tags": tagsSchema(), - // TODO + // This will be inferred from the passed `parameters` value "type": { + Type: schema.TypeString, + Computed: true, }, - // TODO "vpc_connection_properties": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "vpc_connection_arn": { + Type: schema.TypeBool, + Optional: true, + ValidateFunc: validateArn, + }, + }, + }, }, - // TODO: this is a tough one... - "creation_stauts": { + "creation_status": { Type: schema.TypeString, + Computed: true, }, }, } } -func resourceAwsQuickSightDataSourceCreate(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.CreateDataSourceInput{ - AwsAccountId: aws.String(awsAccountID), - Namespace: aws.String(namespace), - DataSourceName: aws.String(d.Get("group_name").(string)), - } - - if v, ok := d.GetOk("description"); ok { - createOpts.Description = aws.String(v.(string)) - } - - resp, err := conn.CreateDataSource(createOpts) - if err != nil { - return fmt.Errorf("Error creating QuickSight DataSource: %s", err) - } - - d.SetId(fmt.Sprintf("%s/%s/%s", awsAccountID, namespace, aws.StringValue(resp.DataSource.DataSourceName))) - - return resourceAwsQuickSightDataSourceRead(d, meta) -} - -func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).quicksightconn - - awsAccountID, namespace, groupName, err := resourceAwsQuickSightDataSourceParseID(d.Id()) - if err != nil { - return err - } - - descOpts := &quicksight.DescribeDataSourceInput{ - AwsAccountId: aws.String(awsAccountID), - Namespace: aws.String(namespace), - DataSourceName: aws.String(groupName), - } - - resp, err := conn.DescribeDataSource(descOpts) - if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { - log.Printf("[WARN] QuickSight DataSource %s is already gone", d.Id()) - d.SetId("") - return nil - } - if err != nil { - return fmt.Errorf("Error describing QuickSight DataSource (%s): %s", d.Id(), err) - } - - d.Set("arn", resp.DataSource.Arn) - d.Set("aws_account_id", awsAccountID) - d.Set("group_name", resp.DataSource.DataSourceName) - d.Set("description", resp.DataSource.Description) - d.Set("namespace", namespace) - - return nil -} - -func resourceAwsQuickSightDataSourceUpdate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).quicksightconn - - awsAccountID, namespace, groupName, err := resourceAwsQuickSightDataSourceParseID(d.Id()) - if err != nil { - return err - } - - updateOpts := &quicksight.UpdateDataSourceInput{ - AwsAccountId: aws.String(awsAccountID), - Namespace: aws.String(namespace), - DataSourceName: aws.String(groupName), - } - - if v, ok := d.GetOk("description"); ok { - updateOpts.Description = aws.String(v.(string)) - } - - _, err = conn.UpdateDataSource(updateOpts) - if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { - log.Printf("[WARN] QuickSight DataSource %s is already gone", d.Id()) - d.SetId("") - return nil - } - if err != nil { - return fmt.Errorf("Error updating QuickSight DataSource %s: %s", d.Id(), err) - } - - return resourceAwsQuickSightDataSourceRead(d, meta) -} - -func resourceAwsQuickSightDataSourceDelete(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).quicksightconn - - awsAccountID, namespace, groupName, err := resourceAwsQuickSightDataSourceParseID(d.Id()) - if err != nil { - return err - } - - deleteOpts := &quicksight.DeleteDataSourceInput{ - AwsAccountId: aws.String(awsAccountID), - Namespace: aws.String(namespace), - DataSourceName: aws.String(groupName), - } - - if _, err := conn.DeleteDataSource(deleteOpts); err != nil { - if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { - return nil - } - return fmt.Errorf("Error deleting QuickSight DataSource %s: %s", d.Id(), err) - } - - return nil -} - -func resourceAwsQuickSightDataSourceParseID(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/DATA_SOURCE_ID", id) - } - return parts[0], parts[1], parts[2], nil -} +//func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interface{}) error { +// conn := meta.(*AWSClient).quicksightconn +// +// awsAccountID := meta.(*AWSClient).accountid +// +// if v, ok := d.GetOk("aws_account_id"); ok { +// awsAccountID = v.(string) +// } +// +// params := &quicksight.CreateDataSourceInput{ +// AwsAccountId: aws.String(awsAccountID), +// DataSourceId: aws.String(d.Get("id").(string)), +// } +// +// if v := d.Get("credentials"); v != nil { +// for _, v := range v.(*schema.Set).List() { +// credentials := v.(map[string]interface{}) +// +// if v := credentials["credential_pair"]; v != nil && v.(*schema.Set) != nil { +// for _, v := range (v.(*schema.Set)).List() { +// credentialPairResource := v.(map[string]interface{}) +// credentialPair := &quicksight.CredentialPair{} +// +// if v, ok := credentialPairResource["username"]; ok && v.(string) != "" { +// credentialPair.Username = aws.String(v.(string)) +// } +// +// if v, ok := credentialPairResource["password"]; ok && v.(string) != "" { +// credentialPair.Password = aws.String(v.(string)) +// } +// +// params.Credentials = &quicksight.DataSourceCredentials{ +// CredentialPair: credentialPair, +// } +// } +// } +// } +// } +// +// // if v := d.Get("parameters"); v != nil { +// // for _, v := range v.(*schema.Set).List() { +// // dataSourceParams := v.(map[string]interface{}) +// // dataSourceParamsResource := &quicksight.DataSourceParameters{} +// // +// // if v := dataSourceParams["amazon_elasticsearch"]; v != nil && v.(*schema.Set) != nil { +// // for _, v := range (v.(*schema.Set)).List() { +// // psResource := v.(map[string]interface{}) +// // ps := &quicksight.AmazonElasticsearchParameters{} +// // +// // if v, ok := psResource["domain"]; ok && v.(string) != "" { +// // ps.Domain = aws.String(v.(string)) +// // } +// // +// // //params.Type = aws.String(quicksight.DataSourceTypeAmazonElasticsearch) +// // dataSourceParamsResource.AmazonElasticsearchParameters = ps +// // } +// // } +// // } +// // } +// +// _, err := conn.CreateDataSource(params) +// if err != nil { +// return fmt.Errorf("Error creating QuickSight Data Source: %s", err) +// } +// +// //d.SetId(fmt.Sprintf("%s/%s/%s", awsAccountID, namespace, aws.StringValue(resp.DataSource.DataSourceName))) +// +// return resourceAwsQuickSightDataSourceRead(d, meta) +//} + +//func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{}) error { +// conn := meta.(*AWSClient).quicksightconn +// +// awsAccountID, namespace, groupName, err := resourceAwsQuickSightDataSourceParseID(d.Id()) +// if err != nil { +// return err +// } +// +// descOpts := &quicksight.DescribeDataSourceInput{ +// AwsAccountId: aws.String(awsAccountID), +// Namespace: aws.String(namespace), +// DataSourceName: aws.String(groupName), +// } +// +// resp, err := conn.DescribeDataSource(descOpts) +// if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { +// log.Printf("[WARN] QuickSight DataSource %s is already gone", d.Id()) +// d.SetId("") +// return nil +// } +// if err != nil { +// return fmt.Errorf("Error describing QuickSight DataSource (%s): %s", d.Id(), err) +// } +// +// d.Set("arn", resp.DataSource.Arn) +// d.Set("aws_account_id", awsAccountID) +// d.Set("group_name", resp.DataSource.DataSourceName) +// d.Set("description", resp.DataSource.Description) +// d.Set("namespace", namespace) + +// return nil +//} + +// +//func resourceAwsQuickSightDataSourceUpdate(d *schema.ResourceData, meta interface{}) error { +// conn := meta.(*AWSClient).quicksightconn +// +// awsAccountID, namespace, groupName, err := resourceAwsQuickSightDataSourceParseID(d.Id()) +// if err != nil { +// return err +// } +// +// updateOpts := &quicksight.UpdateDataSourceInput{ +// AwsAccountId: aws.String(awsAccountID), +// Namespace: aws.String(namespace), +// DataSourceName: aws.String(groupName), +// } +// +// if v, ok := d.GetOk("description"); ok { +// updateOpts.Description = aws.String(v.(string)) +// } +// +// _, err = conn.UpdateDataSource(updateOpts) +// if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { +// log.Printf("[WARN] QuickSight DataSource %s is already gone", d.Id()) +// d.SetId("") +// return nil +// } +// if err != nil { +// return fmt.Errorf("Error updating QuickSight DataSource %s: %s", d.Id(), err) +// } +// +// return resourceAwsQuickSightDataSourceRead(d, meta) +//} +// +//func resourceAwsQuickSightDataSourceDelete(d *schema.ResourceData, meta interface{}) error { +// conn := meta.(*AWSClient).quicksightconn +// +// awsAccountID, namespace, groupName, err := resourceAwsQuickSightDataSourceParseID(d.Id()) +// if err != nil { +// return err +// } +// +// deleteOpts := &quicksight.DeleteDataSourceInput{ +// AwsAccountId: aws.String(awsAccountID), +// Namespace: aws.String(namespace), +// DataSourceName: aws.String(groupName), +// } +// +// if _, err := conn.DeleteDataSource(deleteOpts); err != nil { +// if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { +// return nil +// } +// return fmt.Errorf("Error deleting QuickSight DataSource %s: %s", d.Id(), err) +// } +// +// return nil +//} +// +//func resourceAwsQuickSightDataSourceParseID(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/DATA_SOURCE_ID", id) +// } +// return parts[0], parts[1], parts[2], nil +//} From cb8d8cc781a1f2f59f841f8bb4169cd5cd50ca9a Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Wed, 27 Nov 2019 14:44:23 -0500 Subject: [PATCH 04/21] Everything works now, must have been some environmental fluke. --- aws/resource_aws_quicksight_data_source.go | 147 +++++++++++---------- 1 file changed, 74 insertions(+), 73 deletions(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index ae2215f7fbbf..0fc2f132257e 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -1,19 +1,19 @@ package aws import ( - // "fmt" + "fmt" // "log" // "strings" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/quicksight" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" - // "github.com/aws/aws-sdk-go/aws" - // "github.com/aws/aws-sdk-go/service/quicksight" ) func resourceAwsQuickSightDataSource() *schema.Resource { return &schema.Resource{ - // Create: resourceAwsQuickSightDataSourceCreate, + Create: resourceAwsQuickSightDataSourceCreate, // Read: resourceAwsQuickSightDataSourceRead, // Update: resourceAwsQuickSightDataSourceUpdate, // Delete: resourceAwsQuickSightDataSourceDelete, @@ -551,75 +551,76 @@ func resourceAwsQuickSightDataSource() *schema.Resource { } } -//func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interface{}) error { -// conn := meta.(*AWSClient).quicksightconn -// -// awsAccountID := meta.(*AWSClient).accountid -// -// if v, ok := d.GetOk("aws_account_id"); ok { -// awsAccountID = v.(string) -// } -// -// params := &quicksight.CreateDataSourceInput{ -// AwsAccountId: aws.String(awsAccountID), -// DataSourceId: aws.String(d.Get("id").(string)), -// } -// -// if v := d.Get("credentials"); v != nil { -// for _, v := range v.(*schema.Set).List() { -// credentials := v.(map[string]interface{}) -// -// if v := credentials["credential_pair"]; v != nil && v.(*schema.Set) != nil { -// for _, v := range (v.(*schema.Set)).List() { -// credentialPairResource := v.(map[string]interface{}) -// credentialPair := &quicksight.CredentialPair{} -// -// if v, ok := credentialPairResource["username"]; ok && v.(string) != "" { -// credentialPair.Username = aws.String(v.(string)) -// } -// -// if v, ok := credentialPairResource["password"]; ok && v.(string) != "" { -// credentialPair.Password = aws.String(v.(string)) -// } -// -// params.Credentials = &quicksight.DataSourceCredentials{ -// CredentialPair: credentialPair, -// } -// } -// } -// } -// } -// -// // if v := d.Get("parameters"); v != nil { -// // for _, v := range v.(*schema.Set).List() { -// // dataSourceParams := v.(map[string]interface{}) -// // dataSourceParamsResource := &quicksight.DataSourceParameters{} -// // -// // if v := dataSourceParams["amazon_elasticsearch"]; v != nil && v.(*schema.Set) != nil { -// // for _, v := range (v.(*schema.Set)).List() { -// // psResource := v.(map[string]interface{}) -// // ps := &quicksight.AmazonElasticsearchParameters{} -// // -// // if v, ok := psResource["domain"]; ok && v.(string) != "" { -// // ps.Domain = aws.String(v.(string)) -// // } -// // -// // //params.Type = aws.String(quicksight.DataSourceTypeAmazonElasticsearch) -// // dataSourceParamsResource.AmazonElasticsearchParameters = ps -// // } -// // } -// // } -// // } -// -// _, err := conn.CreateDataSource(params) -// if err != nil { -// return fmt.Errorf("Error creating QuickSight Data Source: %s", err) -// } -// -// //d.SetId(fmt.Sprintf("%s/%s/%s", awsAccountID, namespace, aws.StringValue(resp.DataSource.DataSourceName))) -// -// return resourceAwsQuickSightDataSourceRead(d, meta) -//} +func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).quicksightconn + + awsAccountID := meta.(*AWSClient).accountid + + if v, ok := d.GetOk("aws_account_id"); ok { + awsAccountID = v.(string) + } + + params := &quicksight.CreateDataSourceInput{ + AwsAccountId: aws.String(awsAccountID), + DataSourceId: aws.String(d.Get("id").(string)), + } + + if v := d.Get("credentials"); v != nil { + for _, v := range v.(*schema.Set).List() { + credentials := v.(map[string]interface{}) + + if v := credentials["credential_pair"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + credentialPairResource := v.(map[string]interface{}) + credentialPair := &quicksight.CredentialPair{} + + if v, ok := credentialPairResource["username"]; ok && v.(string) != "" { + credentialPair.Username = aws.String(v.(string)) + } + + if v, ok := credentialPairResource["password"]; ok && v.(string) != "" { + credentialPair.Password = aws.String(v.(string)) + } + + params.Credentials = &quicksight.DataSourceCredentials{ + CredentialPair: credentialPair, + } + } + } + } + } + + if v := d.Get("parameters"); v != nil { + for _, v := range v.(*schema.Set).List() { + dataSourceParams := v.(map[string]interface{}) + dataSourceParamsResource := &quicksight.DataSourceParameters{} + + if v := dataSourceParams["amazon_elasticsearch"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.AmazonElasticsearchParameters{} + + if v, ok := psResource["domain"]; ok && v.(string) != "" { + ps.Domain = aws.String(v.(string)) + } + + params.Type = aws.String(quicksight.DataSourceTypeAmazonElasticsearch) + dataSourceParamsResource.AmazonElasticsearchParameters = ps + } + } + } + } + + _, err := conn.CreateDataSource(params) + if err != nil { + return fmt.Errorf("Error creating QuickSight Data Source: %s", err) + } + + //d.SetId(fmt.Sprintf("%s/%s/%s", awsAccountID, namespace, aws.StringValue(resp.DataSource.DataSourceName))) + + return nil + //return resourceAwsQuickSightDataSourceRead(d, meta) +} //func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{}) error { // conn := meta.(*AWSClient).quicksightconn From 7a7eda698cf1a26275d30be454859c46618a3e36 Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Wed, 27 Nov 2019 15:24:33 -0500 Subject: [PATCH 05/21] Parser parameters. --- aws/resource_aws_quicksight_data_source.go | 362 +++++++++++++++++++-- 1 file changed, 342 insertions(+), 20 deletions(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index 0fc2f132257e..6ab11bee7f5c 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -166,7 +166,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "database": { + "data_set_name": { Type: schema.TypeString, Required: true, ValidateFunc: validation.NoZeroValues, @@ -283,25 +283,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { }, }, }, - "rds": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "database": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.NoZeroValues, - }, - "instance_id": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.NoZeroValues, - }, - }, - }, - }, + // The documentation is not clear on how to pass RDS parameters... "redshift": { Type: schema.TypeList, Optional: true, @@ -608,6 +590,346 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac dataSourceParamsResource.AmazonElasticsearchParameters = ps } } + + if v := dataSourceParams["athena"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.AthenaParameters{} + + if v, ok := psResource["work_group"]; ok && v.(string) != "" { + ps.WorkGroup = aws.String(v.(string)) + } + + params.Type = aws.String(quicksight.DataSourceTypeAthena) + dataSourceParamsResource.AthenaParameters = ps + } + } + + if v := dataSourceParams["aurora"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.AuroraParameters{} + + if v, ok := psResource["database"]; ok && v.(string) != "" { + ps.Database = aws.String(v.(string)) + } + + if v, ok := psResource["host"]; ok && v.(string) != "" { + ps.Host = aws.String(v.(string)) + } + + if v, ok := psResource["port"]; ok && v.(int64) != 0 { + ps.Port = aws.Int64(v.(int64)) + } + + params.Type = aws.String(quicksight.DataSourceTypeAurora) + dataSourceParamsResource.AuroraParameters = ps + } + } + + if v := dataSourceParams["aurora_postgre_sql"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.AuroraPostgreSqlParameters{} + + if v, ok := psResource["database"]; ok && v.(string) != "" { + ps.Database = aws.String(v.(string)) + } + + if v, ok := psResource["host"]; ok && v.(string) != "" { + ps.Host = aws.String(v.(string)) + } + + if v, ok := psResource["port"]; ok && v.(int64) != 0 { + ps.Port = aws.Int64(v.(int64)) + } + + params.Type = aws.String(quicksight.DataSourceTypeAuroraPostgresql) + dataSourceParamsResource.AuroraPostgreSqlParameters = ps + } + } + + if v := dataSourceParams["aws_iot_analytics"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.AwsIotAnalyticsParameters{} + + if v, ok := psResource["data_set_name"]; ok && v.(string) != "" { + ps.DataSetName = aws.String(v.(string)) + } + + params.Type = aws.String(quicksight.DataSourceTypeAwsIotAnalytics) + dataSourceParamsResource.AwsIotAnalyticsParameters = ps + } + } + + if v := dataSourceParams["jira"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.JiraParameters{} + + if v, ok := psResource["site_base_url"]; ok && v.(string) != "" { + ps.SiteBaseUrl = aws.String(v.(string)) + } + + params.Type = aws.String(quicksight.DataSourceTypeJira) + dataSourceParamsResource.JiraParameters = ps + } + } + + if v := dataSourceParams["maria_db"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.MariaDbParameters{} + + if v, ok := psResource["database"]; ok && v.(string) != "" { + ps.Database = aws.String(v.(string)) + } + + if v, ok := psResource["host"]; ok && v.(string) != "" { + ps.Host = aws.String(v.(string)) + } + + if v, ok := psResource["port"]; ok && v.(int64) != 0 { + ps.Port = aws.Int64(v.(int64)) + } + + params.Type = aws.String(quicksight.DataSourceTypeMariadb) + dataSourceParamsResource.MariaDbParameters = ps + } + } + + if v := dataSourceParams["mysql"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.MySqlParameters{} + + if v, ok := psResource["database"]; ok && v.(string) != "" { + ps.Database = aws.String(v.(string)) + } + + if v, ok := psResource["host"]; ok && v.(string) != "" { + ps.Host = aws.String(v.(string)) + } + + if v, ok := psResource["port"]; ok && v.(int64) != 0 { + ps.Port = aws.Int64(v.(int64)) + } + + params.Type = aws.String(quicksight.DataSourceTypeMysql) + dataSourceParamsResource.MySqlParameters = ps + } + } + + if v := dataSourceParams["postgresql"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.PostgreSqlParameters{} + + if v, ok := psResource["database"]; ok && v.(string) != "" { + ps.Database = aws.String(v.(string)) + } + + if v, ok := psResource["host"]; ok && v.(string) != "" { + ps.Host = aws.String(v.(string)) + } + + if v, ok := psResource["port"]; ok && v.(int64) != 0 { + ps.Port = aws.Int64(v.(int64)) + } + + params.Type = aws.String(quicksight.DataSourceTypePostgresql) + dataSourceParamsResource.PostgreSqlParameters = ps + } + } + + if v := dataSourceParams["presto"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.PrestoParameters{} + + if v, ok := psResource["catalog"]; ok && v.(string) != "" { + ps.Catalog = aws.String(v.(string)) + } + + if v, ok := psResource["host"]; ok && v.(string) != "" { + ps.Host = aws.String(v.(string)) + } + + if v, ok := psResource["port"]; ok && v.(int64) != 0 { + ps.Port = aws.Int64(v.(int64)) + } + + params.Type = aws.String(quicksight.DataSourceTypePresto) + dataSourceParamsResource.PrestoParameters = ps + } + } + + if v := dataSourceParams["redshift"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.RedshiftParameters{} + + if v, ok := psResource["cluster_id"]; ok && v.(string) != "" { + ps.ClusterId = aws.String(v.(string)) + } + + if v, ok := psResource["database"]; ok && v.(string) != "" { + ps.Database = aws.String(v.(string)) + } + + if v, ok := psResource["host"]; ok && v.(string) != "" { + ps.Host = aws.String(v.(string)) + } + + if v, ok := psResource["port"]; ok && v.(int64) != 0 { + ps.Port = aws.Int64(v.(int64)) + } + + params.Type = aws.String(quicksight.DataSourceTypeRedshift) + dataSourceParamsResource.RedshiftParameters = ps + } + } + + if v := dataSourceParams["s3"]; v != nil && v.(*schema.Set) != nil { + s3 := v.(map[string]interface{}) + + if v := s3["manifest_file_location"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.S3Parameters{ + ManifestFileLocation: &quicksight.ManifestFileLocation{}, + } + + if v, ok := psResource["bucket"]; ok && v.(string) != "" { + ps.ManifestFileLocation.Bucket = aws.String(v.(string)) + } + + if v, ok := psResource["key"]; ok && v.(string) != "" { + ps.ManifestFileLocation.Key = aws.String(v.(string)) + } + + params.Type = aws.String(quicksight.DataSourceTypeS3) + dataSourceParamsResource.S3Parameters = ps + } + } + } + + if v := dataSourceParams["service_now"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.ServiceNowParameters{} + + if v, ok := psResource["site_base_url"]; ok && v.(string) != "" { + ps.SiteBaseUrl = aws.String(v.(string)) + } + + params.Type = aws.String(quicksight.DataSourceTypeServicenow) + dataSourceParamsResource.ServiceNowParameters = ps + } + } + + if v := dataSourceParams["snowflake"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.SnowflakeParameters{} + + if v, ok := psResource["database"]; ok && v.(string) != "" { + ps.Database = aws.String(v.(string)) + } + + if v, ok := psResource["host"]; ok && v.(string) != "" { + ps.Host = aws.String(v.(string)) + } + + if v, ok := psResource["warehouse"]; ok && v.(string) != "" { + ps.Warehouse = aws.String(v.(string)) + } + + params.Type = aws.String(quicksight.DataSourceTypeSnowflake) + dataSourceParamsResource.SnowflakeParameters = ps + } + } + + if v := dataSourceParams["spark"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.SparkParameters{} + + if v, ok := psResource["host"]; ok && v.(string) != "" { + ps.Host = aws.String(v.(string)) + } + + if v, ok := psResource["port"]; ok && v.(int64) != 0 { + ps.Port = aws.Int64(v.(int64)) + } + + params.Type = aws.String(quicksight.DataSourceTypeSpark) + dataSourceParamsResource.SparkParameters = ps + } + } + + if v := dataSourceParams["sql_server"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.SqlServerParameters{} + + if v, ok := psResource["database"]; ok && v.(string) != "" { + ps.Database = aws.String(v.(string)) + } + + if v, ok := psResource["host"]; ok && v.(string) != "" { + ps.Host = aws.String(v.(string)) + } + + if v, ok := psResource["port"]; ok && v.(int64) != 0 { + ps.Port = aws.Int64(v.(int64)) + } + + params.Type = aws.String(quicksight.DataSourceTypeSqlserver) + dataSourceParamsResource.SqlServerParameters = ps + } + } + + if v := dataSourceParams["teradata"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.TeradataParameters{} + + if v, ok := psResource["database"]; ok && v.(string) != "" { + ps.Database = aws.String(v.(string)) + } + + if v, ok := psResource["host"]; ok && v.(string) != "" { + ps.Host = aws.String(v.(string)) + } + + if v, ok := psResource["port"]; ok && v.(int64) != 0 { + ps.Port = aws.Int64(v.(int64)) + } + + params.Type = aws.String(quicksight.DataSourceTypeTeradata) + dataSourceParamsResource.TeradataParameters = ps + } + } + + if v := dataSourceParams["twitter"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.TwitterParameters{} + + if v, ok := psResource["max_rows"]; ok && v.(int64) != 0 { + ps.MaxRows = aws.Int64(v.(int64)) + } + + if v, ok := psResource["query"]; ok && v.(string) != "" { + ps.Query = aws.String(v.(string)) + } + + params.Type = aws.String(quicksight.DataSourceTypeTwitter) + dataSourceParamsResource.TwitterParameters = ps + } + } } } From 3261550042842c10c080ab375c610abbad8a16d2 Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Wed, 27 Nov 2019 16:08:42 -0500 Subject: [PATCH 06/21] First full pass at create data source. --- aws/resource_aws_quicksight_data_source.go | 69 +++++++++++++++++++--- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index 6ab11bee7f5c..ca4dc9f7319f 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -472,12 +472,10 @@ func resourceAwsQuickSightDataSource() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "actions": { - Type: schema.TypeList, + Type: schema.TypeSet, Required: true, - MinItems: 1, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, }, "principal": { Type: schema.TypeString, @@ -537,6 +535,7 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac conn := meta.(*AWSClient).quicksightconn awsAccountID := meta.(*AWSClient).accountid + id := d.Get("id").(string) if v, ok := d.GetOk("aws_account_id"); ok { awsAccountID = v.(string) @@ -544,7 +543,7 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac params := &quicksight.CreateDataSourceInput{ AwsAccountId: aws.String(awsAccountID), - DataSourceId: aws.String(d.Get("id").(string)), + DataSourceId: aws.String(id), } if v := d.Get("credentials"); v != nil { @@ -933,12 +932,66 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac } } + d.Set("type", params.Type) + + if v := d.Get("permissions"); v != nil { + params.Permissions = make([]*quicksight.ResourcePermission, 0) + + for _, v := range v.(*schema.Set).List() { + permissionResource := v.(map[string]interface{}) + permission := &quicksight.ResourcePermission{ + Actions: expandStringSet(permissionResource["actions"].(*schema.Set)), + Principal: aws.String(permissionResource["principal"].(string)), + } + + params.Permissions = append(params.Permissions, permission) + } + } + + if v := d.Get("ssl_properties"); v != nil { + for _, v := range v.(*schema.Set).List() { + sslProperties := v.(map[string]interface{}) + + if v, present := sslProperties["disable_ssl"]; present { + params.SslProperties = &quicksight.SslProperties{ + DisableSsl: aws.Bool(v.(bool)), + } + } + } + } + + if v, exists := d.GetOk("tags"); exists { + tags := make([]*quicksight.Tag, 0) + for k, v := range v.(map[string]interface{}) { + if !tagIgnoredGeneric(k) { + tags = append(tags, &quicksight.Tag{ + Key: aws.String(k), + Value: aws.String(v.(string)), + }) + } + } + + params.Tags = tags + } + + if v := d.Get("vpc_connection_properties"); v != nil { + for _, v := range v.(*schema.Set).List() { + vpcConnectionProperties := v.(map[string]interface{}) + + if v := vpcConnectionProperties["vpc_connection_arn"]; v != nil && v.(string) != "" { + params.VpcConnectionProperties = &quicksight.VpcConnectionProperties{ + VpcConnectionArn: aws.String(v.(string)), + } + } + } + } + _, err := conn.CreateDataSource(params) if err != nil { return fmt.Errorf("Error creating QuickSight Data Source: %s", err) } - //d.SetId(fmt.Sprintf("%s/%s/%s", awsAccountID, namespace, aws.StringValue(resp.DataSource.DataSourceName))) + d.SetId(fmt.Sprintf("%s/%s", awsAccountID, id)) return nil //return resourceAwsQuickSightDataSourceRead(d, meta) @@ -1032,7 +1085,7 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac // // return nil //} -// + //func resourceAwsQuickSightDataSourceParseID(id string) (string, string, string, error) { // parts := strings.SplitN(id, "/", 3) // if len(parts) < 3 || parts[0] == "" || parts[1] == "" || parts[2] == "" { From 7823336da97a39f550cd7ca931366bb745cde137 Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Wed, 27 Nov 2019 16:46:31 -0500 Subject: [PATCH 07/21] Map parameters back in read... Not sure if this is correct. --- aws/resource_aws_quicksight_data_source.go | 253 +++++++++++++++++---- 1 file changed, 209 insertions(+), 44 deletions(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index ca4dc9f7319f..fe313eeb7c30 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -2,8 +2,8 @@ package aws import ( "fmt" - // "log" - // "strings" + "log" + "strings" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/quicksight" @@ -14,7 +14,7 @@ import ( func resourceAwsQuickSightDataSource() *schema.Resource { return &schema.Resource{ Create: resourceAwsQuickSightDataSourceCreate, - // Read: resourceAwsQuickSightDataSourceRead, + Read: resourceAwsQuickSightDataSourceRead, // Update: resourceAwsQuickSightDataSourceUpdate, // Delete: resourceAwsQuickSightDataSourceDelete, @@ -141,7 +141,6 @@ func resourceAwsQuickSightDataSource() *schema.Resource { MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - // TODO: Extract common "database": { Type: schema.TypeString, Required: true, @@ -993,42 +992,208 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac d.SetId(fmt.Sprintf("%s/%s", awsAccountID, id)) - return nil - //return resourceAwsQuickSightDataSourceRead(d, meta) + return resourceAwsQuickSightDataSourceRead(d, meta) } -//func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{}) error { -// conn := meta.(*AWSClient).quicksightconn -// -// awsAccountID, namespace, groupName, err := resourceAwsQuickSightDataSourceParseID(d.Id()) -// if err != nil { -// return err -// } -// -// descOpts := &quicksight.DescribeDataSourceInput{ -// AwsAccountId: aws.String(awsAccountID), -// Namespace: aws.String(namespace), -// DataSourceName: aws.String(groupName), -// } -// -// resp, err := conn.DescribeDataSource(descOpts) -// if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { -// log.Printf("[WARN] QuickSight DataSource %s is already gone", d.Id()) -// d.SetId("") -// return nil -// } -// if err != nil { -// return fmt.Errorf("Error describing QuickSight DataSource (%s): %s", d.Id(), err) -// } -// -// d.Set("arn", resp.DataSource.Arn) -// d.Set("aws_account_id", awsAccountID) -// d.Set("group_name", resp.DataSource.DataSourceName) -// d.Set("description", resp.DataSource.Description) -// d.Set("namespace", namespace) +func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).quicksightconn -// return nil -//} + awsAccountID, dataSourceId, err := resourceAwsQuickSightDataSourceParseID(d.Id()) + if err != nil { + return err + } + + descOpts := &quicksight.DescribeDataSourceInput{ + AwsAccountId: aws.String(awsAccountID), + DataSourceId: aws.String(dataSourceId), + } + + resp, err := conn.DescribeDataSource(descOpts) + if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { + log.Printf("[WARN] QuickSight Data Source %s is already gone", d.Id()) + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("Error describing QuickSight Data Source (%s): %s", d.Id(), err) + } + + d.Set("arn", resp.DataSource.Arn) + d.Set("id", resp.DataSource.DataSourceId) + d.Set("aws_account_id", awsAccountID) + + if resp.DataSource.DataSourceParameters.AmazonElasticsearchParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "amazon_elasticsearch": { + "domain": resp.DataSource.DataSourceParameters.AmazonElasticsearchParameters.Domain, + }, + }) + } + + if resp.DataSource.DataSourceParameters.AthenaParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "athena": { + "work_group": resp.DataSource.DataSourceParameters.AthenaParameters.WorkGroup, + }, + }) + } + + if resp.DataSource.DataSourceParameters.AuroraParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "aurora": { + "database": resp.DataSource.DataSourceParameters.AuroraParameters.Database, + "host": resp.DataSource.DataSourceParameters.AuroraParameters.Host, + "port": resp.DataSource.DataSourceParameters.AuroraParameters.Port, + }, + }) + } + + if resp.DataSource.DataSourceParameters.AuroraPostgreSqlParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "aurora_postgre_sql": { + "database": resp.DataSource.DataSourceParameters.AuroraPostgreSqlParameters.Database, + "host": resp.DataSource.DataSourceParameters.AuroraPostgreSqlParameters.Host, + "port": resp.DataSource.DataSourceParameters.AuroraPostgreSqlParameters.Port, + }, + }) + } + + if resp.DataSource.DataSourceParameters.AwsIotAnalyticsParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "aws_iot_analytics": { + "data_set_name": resp.DataSource.DataSourceParameters.AwsIotAnalyticsParameters.DataSetName, + }, + }) + } + + if resp.DataSource.DataSourceParameters.JiraParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "jira": { + "site_base_url": resp.DataSource.DataSourceParameters.JiraParameters.SiteBaseUrl, + }, + }) + } + + if resp.DataSource.DataSourceParameters.MariaDbParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "maria_db": { + "database": resp.DataSource.DataSourceParameters.MariaDbParameters.Database, + "host": resp.DataSource.DataSourceParameters.MariaDbParameters.Host, + "port": resp.DataSource.DataSourceParameters.MariaDbParameters.Port, + }, + }) + } + + if resp.DataSource.DataSourceParameters.MySqlParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "mysql": { + "database": resp.DataSource.DataSourceParameters.MySqlParameters.Database, + "host": resp.DataSource.DataSourceParameters.MySqlParameters.Host, + "port": resp.DataSource.DataSourceParameters.MySqlParameters.Port, + }, + }) + } + + if resp.DataSource.DataSourceParameters.PostgreSqlParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "postgresql": { + "database": resp.DataSource.DataSourceParameters.PostgreSqlParameters.Database, + "host": resp.DataSource.DataSourceParameters.PostgreSqlParameters.Host, + "port": resp.DataSource.DataSourceParameters.PostgreSqlParameters.Port, + }, + }) + } + + if resp.DataSource.DataSourceParameters.PrestoParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "presto": { + "catalog": resp.DataSource.DataSourceParameters.PrestoParameters.Catalog, + "host": resp.DataSource.DataSourceParameters.PrestoParameters.Host, + "port": resp.DataSource.DataSourceParameters.PrestoParameters.Port, + }, + }) + } + + if resp.DataSource.DataSourceParameters.RedshiftParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "redshift": { + "cluster_id": resp.DataSource.DataSourceParameters.RedshiftParameters.ClusterId, + "database": resp.DataSource.DataSourceParameters.RedshiftParameters.Database, + "host": resp.DataSource.DataSourceParameters.RedshiftParameters.Host, + "port": resp.DataSource.DataSourceParameters.RedshiftParameters.Port, + }, + }) + } + + if resp.DataSource.DataSourceParameters.S3Parameters != nil { + d.Set("parameters", map[string]map[string]map[string]interface{}{ + "s3": { + "manifest_file_location": { + "bucket": resp.DataSource.DataSourceParameters.S3Parameters.ManifestFileLocation.Bucket, + "key": resp.DataSource.DataSourceParameters.S3Parameters.ManifestFileLocation.Key, + }, + }, + }) + } + + if resp.DataSource.DataSourceParameters.ServiceNowParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "service_now": { + "site_base_url": resp.DataSource.DataSourceParameters.ServiceNowParameters.SiteBaseUrl, + }, + }) + } + + if resp.DataSource.DataSourceParameters.SnowflakeParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "snowflake": { + "database": resp.DataSource.DataSourceParameters.SnowflakeParameters.Database, + "host": resp.DataSource.DataSourceParameters.SnowflakeParameters.Host, + "warehouse": resp.DataSource.DataSourceParameters.SnowflakeParameters.Warehouse, + }, + }) + } + + if resp.DataSource.DataSourceParameters.SparkParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "spark": { + "host": resp.DataSource.DataSourceParameters.SparkParameters.Host, + "port": resp.DataSource.DataSourceParameters.SparkParameters.Port, + }, + }) + } + + if resp.DataSource.DataSourceParameters.SqlServerParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "sql_server": { + "database": resp.DataSource.DataSourceParameters.SqlServerParameters.Database, + "host": resp.DataSource.DataSourceParameters.SqlServerParameters.Host, + "port": resp.DataSource.DataSourceParameters.SqlServerParameters.Port, + }, + }) + } + + if resp.DataSource.DataSourceParameters.TeradataParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "teradata": { + "database": resp.DataSource.DataSourceParameters.TeradataParameters.Database, + "host": resp.DataSource.DataSourceParameters.TeradataParameters.Host, + "port": resp.DataSource.DataSourceParameters.TeradataParameters.Port, + }, + }) + } + + if resp.DataSource.DataSourceParameters.TwitterParameters != nil { + d.Set("parameters", map[string]map[string]interface{}{ + "twitter": { + "max_rows": resp.DataSource.DataSourceParameters.TwitterParameters.MaxRows, + "query": resp.DataSource.DataSourceParameters.TwitterParameters.Query, + }, + }) + } + + return nil +} // //func resourceAwsQuickSightDataSourceUpdate(d *schema.ResourceData, meta interface{}) error { @@ -1086,10 +1251,10 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac // return nil //} -//func resourceAwsQuickSightDataSourceParseID(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/DATA_SOURCE_ID", id) -// } -// return parts[0], parts[1], parts[2], nil -//} +func resourceAwsQuickSightDataSourceParseID(id string) (string, string, error) { + parts := strings.SplitN(id, "/", 2) + if len(parts) < 2 || parts[0] == "" || parts[1] == "" { + return "", "", fmt.Errorf("unexpected format of ID (%s), expected AWS_ACCOUNT_ID/DATA_SOURCE_ID", id) + } + return parts[0], parts[1], nil +} From ca814199cca9b062728cd307317e1271e6ea2c5e Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Wed, 27 Nov 2019 16:55:12 -0500 Subject: [PATCH 08/21] Remove creation status since it should determine success. --- aws/resource_aws_quicksight_data_source.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index fe313eeb7c30..14c376784056 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -464,7 +464,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { }, }, - "permissions": { + "permission": { Type: schema.TypeList, Optional: true, MinItems: 1, @@ -521,11 +521,6 @@ func resourceAwsQuickSightDataSource() *schema.Resource { }, }, }, - - "creation_status": { - Type: schema.TypeString, - Computed: true, - }, }, } } @@ -992,6 +987,8 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac d.SetId(fmt.Sprintf("%s/%s", awsAccountID, id)) + // TODO: loop while creation pending (creation status) + return resourceAwsQuickSightDataSourceRead(d, meta) } From 30a8ca69fa8185e5f8eba112f355b8bb7da72554 Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Thu, 28 Nov 2019 10:11:55 -0500 Subject: [PATCH 09/21] Move required fields directly into construction. --- aws/resource_aws_quicksight_data_source.go | 674 +++++++++------------ 1 file changed, 282 insertions(+), 392 deletions(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index 14c376784056..bfac5cf4141a 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -15,7 +15,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { return &schema.Resource{ Create: resourceAwsQuickSightDataSourceCreate, Read: resourceAwsQuickSightDataSourceRead, - // Update: resourceAwsQuickSightDataSourceUpdate, + //Update: resourceAwsQuickSightDataSourceUpdate, // Delete: resourceAwsQuickSightDataSourceDelete, Importer: &schema.ResourceImporter{ @@ -540,394 +540,16 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac DataSourceId: aws.String(id), } - if v := d.Get("credentials"); v != nil { - for _, v := range v.(*schema.Set).List() { - credentials := v.(map[string]interface{}) - - if v := credentials["credential_pair"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - credentialPairResource := v.(map[string]interface{}) - credentialPair := &quicksight.CredentialPair{} - - if v, ok := credentialPairResource["username"]; ok && v.(string) != "" { - credentialPair.Username = aws.String(v.(string)) - } - - if v, ok := credentialPairResource["password"]; ok && v.(string) != "" { - credentialPair.Password = aws.String(v.(string)) - } - - params.Credentials = &quicksight.DataSourceCredentials{ - CredentialPair: credentialPair, - } - } - } - } + if credentials := resourceAwsQuickSightDataSourceCredentials(d); credentials != nil { + params.Credentials = credentials } - if v := d.Get("parameters"); v != nil { - for _, v := range v.(*schema.Set).List() { - dataSourceParams := v.(map[string]interface{}) - dataSourceParamsResource := &quicksight.DataSourceParameters{} - - if v := dataSourceParams["amazon_elasticsearch"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.AmazonElasticsearchParameters{} - - if v, ok := psResource["domain"]; ok && v.(string) != "" { - ps.Domain = aws.String(v.(string)) - } - - params.Type = aws.String(quicksight.DataSourceTypeAmazonElasticsearch) - dataSourceParamsResource.AmazonElasticsearchParameters = ps - } - } - - if v := dataSourceParams["athena"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.AthenaParameters{} - - if v, ok := psResource["work_group"]; ok && v.(string) != "" { - ps.WorkGroup = aws.String(v.(string)) - } - - params.Type = aws.String(quicksight.DataSourceTypeAthena) - dataSourceParamsResource.AthenaParameters = ps - } - } - - if v := dataSourceParams["aurora"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.AuroraParameters{} - - if v, ok := psResource["database"]; ok && v.(string) != "" { - ps.Database = aws.String(v.(string)) - } - - if v, ok := psResource["host"]; ok && v.(string) != "" { - ps.Host = aws.String(v.(string)) - } - - if v, ok := psResource["port"]; ok && v.(int64) != 0 { - ps.Port = aws.Int64(v.(int64)) - } - - params.Type = aws.String(quicksight.DataSourceTypeAurora) - dataSourceParamsResource.AuroraParameters = ps - } - } - - if v := dataSourceParams["aurora_postgre_sql"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.AuroraPostgreSqlParameters{} - - if v, ok := psResource["database"]; ok && v.(string) != "" { - ps.Database = aws.String(v.(string)) - } - - if v, ok := psResource["host"]; ok && v.(string) != "" { - ps.Host = aws.String(v.(string)) - } - - if v, ok := psResource["port"]; ok && v.(int64) != 0 { - ps.Port = aws.Int64(v.(int64)) - } - - params.Type = aws.String(quicksight.DataSourceTypeAuroraPostgresql) - dataSourceParamsResource.AuroraPostgreSqlParameters = ps - } - } - - if v := dataSourceParams["aws_iot_analytics"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.AwsIotAnalyticsParameters{} - - if v, ok := psResource["data_set_name"]; ok && v.(string) != "" { - ps.DataSetName = aws.String(v.(string)) - } - - params.Type = aws.String(quicksight.DataSourceTypeAwsIotAnalytics) - dataSourceParamsResource.AwsIotAnalyticsParameters = ps - } - } - - if v := dataSourceParams["jira"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.JiraParameters{} - - if v, ok := psResource["site_base_url"]; ok && v.(string) != "" { - ps.SiteBaseUrl = aws.String(v.(string)) - } - - params.Type = aws.String(quicksight.DataSourceTypeJira) - dataSourceParamsResource.JiraParameters = ps - } - } - - if v := dataSourceParams["maria_db"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.MariaDbParameters{} - - if v, ok := psResource["database"]; ok && v.(string) != "" { - ps.Database = aws.String(v.(string)) - } - - if v, ok := psResource["host"]; ok && v.(string) != "" { - ps.Host = aws.String(v.(string)) - } - - if v, ok := psResource["port"]; ok && v.(int64) != 0 { - ps.Port = aws.Int64(v.(int64)) - } - - params.Type = aws.String(quicksight.DataSourceTypeMariadb) - dataSourceParamsResource.MariaDbParameters = ps - } - } - - if v := dataSourceParams["mysql"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.MySqlParameters{} - - if v, ok := psResource["database"]; ok && v.(string) != "" { - ps.Database = aws.String(v.(string)) - } - - if v, ok := psResource["host"]; ok && v.(string) != "" { - ps.Host = aws.String(v.(string)) - } - - if v, ok := psResource["port"]; ok && v.(int64) != 0 { - ps.Port = aws.Int64(v.(int64)) - } - - params.Type = aws.String(quicksight.DataSourceTypeMysql) - dataSourceParamsResource.MySqlParameters = ps - } - } - - if v := dataSourceParams["postgresql"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.PostgreSqlParameters{} - - if v, ok := psResource["database"]; ok && v.(string) != "" { - ps.Database = aws.String(v.(string)) - } - - if v, ok := psResource["host"]; ok && v.(string) != "" { - ps.Host = aws.String(v.(string)) - } - - if v, ok := psResource["port"]; ok && v.(int64) != 0 { - ps.Port = aws.Int64(v.(int64)) - } - - params.Type = aws.String(quicksight.DataSourceTypePostgresql) - dataSourceParamsResource.PostgreSqlParameters = ps - } - } - - if v := dataSourceParams["presto"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.PrestoParameters{} - - if v, ok := psResource["catalog"]; ok && v.(string) != "" { - ps.Catalog = aws.String(v.(string)) - } - - if v, ok := psResource["host"]; ok && v.(string) != "" { - ps.Host = aws.String(v.(string)) - } - - if v, ok := psResource["port"]; ok && v.(int64) != 0 { - ps.Port = aws.Int64(v.(int64)) - } - - params.Type = aws.String(quicksight.DataSourceTypePresto) - dataSourceParamsResource.PrestoParameters = ps - } - } - - if v := dataSourceParams["redshift"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.RedshiftParameters{} - - if v, ok := psResource["cluster_id"]; ok && v.(string) != "" { - ps.ClusterId = aws.String(v.(string)) - } - - if v, ok := psResource["database"]; ok && v.(string) != "" { - ps.Database = aws.String(v.(string)) - } - - if v, ok := psResource["host"]; ok && v.(string) != "" { - ps.Host = aws.String(v.(string)) - } - - if v, ok := psResource["port"]; ok && v.(int64) != 0 { - ps.Port = aws.Int64(v.(int64)) - } - - params.Type = aws.String(quicksight.DataSourceTypeRedshift) - dataSourceParamsResource.RedshiftParameters = ps - } - } - - if v := dataSourceParams["s3"]; v != nil && v.(*schema.Set) != nil { - s3 := v.(map[string]interface{}) - - if v := s3["manifest_file_location"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.S3Parameters{ - ManifestFileLocation: &quicksight.ManifestFileLocation{}, - } - - if v, ok := psResource["bucket"]; ok && v.(string) != "" { - ps.ManifestFileLocation.Bucket = aws.String(v.(string)) - } - - if v, ok := psResource["key"]; ok && v.(string) != "" { - ps.ManifestFileLocation.Key = aws.String(v.(string)) - } - - params.Type = aws.String(quicksight.DataSourceTypeS3) - dataSourceParamsResource.S3Parameters = ps - } - } - } - - if v := dataSourceParams["service_now"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.ServiceNowParameters{} - - if v, ok := psResource["site_base_url"]; ok && v.(string) != "" { - ps.SiteBaseUrl = aws.String(v.(string)) - } - - params.Type = aws.String(quicksight.DataSourceTypeServicenow) - dataSourceParamsResource.ServiceNowParameters = ps - } - } - - if v := dataSourceParams["snowflake"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.SnowflakeParameters{} - - if v, ok := psResource["database"]; ok && v.(string) != "" { - ps.Database = aws.String(v.(string)) - } - - if v, ok := psResource["host"]; ok && v.(string) != "" { - ps.Host = aws.String(v.(string)) - } - - if v, ok := psResource["warehouse"]; ok && v.(string) != "" { - ps.Warehouse = aws.String(v.(string)) - } - - params.Type = aws.String(quicksight.DataSourceTypeSnowflake) - dataSourceParamsResource.SnowflakeParameters = ps - } - } - - if v := dataSourceParams["spark"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.SparkParameters{} - - if v, ok := psResource["host"]; ok && v.(string) != "" { - ps.Host = aws.String(v.(string)) - } - - if v, ok := psResource["port"]; ok && v.(int64) != 0 { - ps.Port = aws.Int64(v.(int64)) - } - - params.Type = aws.String(quicksight.DataSourceTypeSpark) - dataSourceParamsResource.SparkParameters = ps - } - } - - if v := dataSourceParams["sql_server"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.SqlServerParameters{} - - if v, ok := psResource["database"]; ok && v.(string) != "" { - ps.Database = aws.String(v.(string)) - } - - if v, ok := psResource["host"]; ok && v.(string) != "" { - ps.Host = aws.String(v.(string)) - } - - if v, ok := psResource["port"]; ok && v.(int64) != 0 { - ps.Port = aws.Int64(v.(int64)) - } - - params.Type = aws.String(quicksight.DataSourceTypeSqlserver) - dataSourceParamsResource.SqlServerParameters = ps - } - } - - if v := dataSourceParams["teradata"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.TeradataParameters{} - - if v, ok := psResource["database"]; ok && v.(string) != "" { - ps.Database = aws.String(v.(string)) - } - - if v, ok := psResource["host"]; ok && v.(string) != "" { - ps.Host = aws.String(v.(string)) - } - - if v, ok := psResource["port"]; ok && v.(int64) != 0 { - ps.Port = aws.Int64(v.(int64)) - } - - params.Type = aws.String(quicksight.DataSourceTypeTeradata) - dataSourceParamsResource.TeradataParameters = ps - } - } - - if v := dataSourceParams["twitter"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - ps := &quicksight.TwitterParameters{} - - if v, ok := psResource["max_rows"]; ok && v.(int64) != 0 { - ps.MaxRows = aws.Int64(v.(int64)) - } - - if v, ok := psResource["query"]; ok && v.(string) != "" { - ps.Query = aws.String(v.(string)) - } - - params.Type = aws.String(quicksight.DataSourceTypeTwitter) - dataSourceParamsResource.TwitterParameters = ps - } - } - } + if dataSourceType, dataSourceParameters := resourceAwsQuickSightDataSourceParameters(d); dataSourceParameters != nil { + params.Type = dataSourceType + params.DataSourceParameters = dataSourceParameters + d.Set("type", dataSourceType) } - d.Set("type", params.Type) - if v := d.Get("permissions"); v != nil { params.Permissions = make([]*quicksight.ResourcePermission, 0) @@ -987,8 +609,6 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac d.SetId(fmt.Sprintf("%s/%s", awsAccountID, id)) - // TODO: loop while creation pending (creation status) - return resourceAwsQuickSightDataSourceRead(d, meta) } @@ -1192,19 +812,17 @@ func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{ return nil } -// //func resourceAwsQuickSightDataSourceUpdate(d *schema.ResourceData, meta interface{}) error { // conn := meta.(*AWSClient).quicksightconn // -// awsAccountID, namespace, groupName, err := resourceAwsQuickSightDataSourceParseID(d.Id()) +// awsAccountID, dataSourceId, err := resourceAwsQuickSightDataSourceParseID(d.Id()) // if err != nil { // return err // } // -// updateOpts := &quicksight.UpdateDataSourceInput{ +// params := &quicksight.UpdateDataSetInput{ // AwsAccountId: aws.String(awsAccountID), -// Namespace: aws.String(namespace), -// DataSourceName: aws.String(groupName), +// DataSourceId: aws.String(id), // } // // if v, ok := d.GetOk("description"); ok { @@ -1223,6 +841,7 @@ func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{ // // return resourceAwsQuickSightDataSourceRead(d, meta) //} + // //func resourceAwsQuickSightDataSourceDelete(d *schema.ResourceData, meta interface{}) error { // conn := meta.(*AWSClient).quicksightconn @@ -1248,6 +867,277 @@ func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{ // return nil //} +func resourceAwsQuickSightDataSourceCredentials(d *schema.ResourceData) *quicksight.DataSourceCredentials { + if v := d.Get("credentials"); v != nil { + for _, v := range v.(*schema.Set).List() { + credentials := v.(map[string]interface{}) + + if v := credentials["credential_pair"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + credentialPairResource := v.(map[string]interface{}) + credentialPair := &quicksight.CredentialPair{} + + if v, ok := credentialPairResource["username"]; ok && v.(string) != "" { + credentialPair.Username = aws.String(v.(string)) + } + + if v, ok := credentialPairResource["password"]; ok && v.(string) != "" { + credentialPair.Password = aws.String(v.(string)) + } + + return &quicksight.DataSourceCredentials{ + CredentialPair: credentialPair, + } + } + } + } + } + + return nil +} + +func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, *quicksight.DataSourceParameters) { + if v := d.Get("parameters"); v != nil { + for _, v := range v.(*schema.Set).List() { + dataSourceParams := v.(map[string]interface{}) + dataSourceParamsResource := &quicksight.DataSourceParameters{} + dataSourceType := "" + + if v := dataSourceParams["amazon_elasticsearch"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypeAmazonElasticsearch + dataSourceParamsResource.AmazonElasticsearchParameters = &quicksight.AmazonElasticsearchParameters{ + Domain: aws.String(psResource["domain"].(string)), + } + } + } + + if v := dataSourceParams["athena"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.AthenaParameters{} + + if v, ok := psResource["work_group"]; ok && v.(string) != "" { + ps.WorkGroup = aws.String(v.(string)) + } + + dataSourceType = quicksight.DataSourceTypeAthena + dataSourceParamsResource.AthenaParameters = ps + } + } + + if v := dataSourceParams["aurora"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypeAurora + dataSourceParamsResource.AuroraParameters = &quicksight.AuroraParameters{ + Database: aws.String(psResource["database"].(string)), + Host: aws.String(psResource["host"].(string)), + Port: aws.Int64(psResource["port"].(int64)), + } + } + } + + if v := dataSourceParams["aurora_postgre_sql"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypeAuroraPostgresql + dataSourceParamsResource.AuroraPostgreSqlParameters = &quicksight.AuroraPostgreSqlParameters{ + Database: aws.String(psResource["database"].(string)), + Host: aws.String(psResource["host"].(string)), + Port: aws.Int64(psResource["port"].(int64)), + } + } + } + + if v := dataSourceParams["aws_iot_analytics"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypeAwsIotAnalytics + dataSourceParamsResource.AwsIotAnalyticsParameters = &quicksight.AwsIotAnalyticsParameters{ + DataSetName: aws.String(psResource["data_set_name"].(string)), + } + } + } + + if v := dataSourceParams["jira"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + + dataSourceType = quicksight.DataSourceTypeJira + dataSourceParamsResource.JiraParameters = &quicksight.JiraParameters{ + SiteBaseUrl: aws.String(psResource["site_base_url"].(string)), + } + } + } + + if v := dataSourceParams["maria_db"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + + dataSourceType = quicksight.DataSourceTypeMariadb + dataSourceParamsResource.MariaDbParameters = &quicksight.MariaDbParameters{ + Database: aws.String(psResource["database"].(string)), + Host: aws.String(psResource["host"].(string)), + Port: aws.Int64(psResource["port"].(int64)), + } + } + } + + if v := dataSourceParams["mysql"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + + dataSourceType = quicksight.DataSourceTypeMysql + dataSourceParamsResource.MySqlParameters = &quicksight.MySqlParameters{ + Database: aws.String(psResource["database"].(string)), + Host: aws.String(psResource["host"].(string)), + Port: aws.Int64(psResource["port"].(int64)), + } + } + } + + if v := dataSourceParams["postgresql"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypePostgresql + dataSourceParamsResource.PostgreSqlParameters = &quicksight.PostgreSqlParameters{ + Database: aws.String(psResource["database"].(string)), + Host: aws.String(psResource["host"].(string)), + Port: aws.Int64(psResource["port"].(int64)), + } + } + } + + if v := dataSourceParams["presto"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypePresto + dataSourceParamsResource.PrestoParameters = &quicksight.PrestoParameters{ + Catalog: aws.String(psResource["catalog"].(string)), + Host: aws.String(psResource["host"].(string)), + Port: aws.Int64(psResource["port"].(int64)), + } + } + } + + if v := dataSourceParams["redshift"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + ps := &quicksight.RedshiftParameters{ + Database: aws.String(psResource["database"].(string)), + } + + if v, ok := psResource["cluster_id"]; ok && v.(string) != "" { + ps.ClusterId = aws.String(v.(string)) + } + + if v, ok := psResource["host"]; ok && v.(string) != "" { + ps.Host = aws.String(v.(string)) + } + + if v, ok := psResource["port"]; ok && v.(int64) != 0 { + ps.Port = aws.Int64(v.(int64)) + } + + dataSourceType = quicksight.DataSourceTypeRedshift + dataSourceParamsResource.RedshiftParameters = ps + } + } + + if v := dataSourceParams["s3"]; v != nil && v.(*schema.Set) != nil { + s3 := v.(map[string]interface{}) + + if v := s3["manifest_file_location"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypeS3 + dataSourceParamsResource.S3Parameters = &quicksight.S3Parameters{ + ManifestFileLocation: &quicksight.ManifestFileLocation{ + Bucket: aws.String(psResource["bucket"].(string)), + Key: aws.String(psResource["key"].(string)), + }, + } + } + } + } + + if v := dataSourceParams["service_now"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypeServicenow + dataSourceParamsResource.ServiceNowParameters = &quicksight.ServiceNowParameters{ + SiteBaseUrl: aws.String(psResource["site_base_url"].(string)), + } + } + } + + if v := dataSourceParams["snowflake"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypeSnowflake + dataSourceParamsResource.SnowflakeParameters = &quicksight.SnowflakeParameters{ + Database: aws.String(psResource["database"].(string)), + Host: aws.String(psResource["host"].(string)), + Warehouse: aws.String(psResource["warehouse"].(string)), + } + } + } + + if v := dataSourceParams["spark"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypeSpark + dataSourceParamsResource.SparkParameters = &quicksight.SparkParameters{ + Host: aws.String(psResource["host"].(string)), + Port: aws.Int64(psResource["port"].(int64)), + } + } + } + + if v := dataSourceParams["sql_server"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypeSqlserver + dataSourceParamsResource.SqlServerParameters = &quicksight.SqlServerParameters{ + Database: aws.String(psResource["database"].(string)), + Host: aws.String(psResource["host"].(string)), + Port: aws.Int64(psResource["port"].(int64)), + } + } + } + + if v := dataSourceParams["teradata"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypeTeradata + dataSourceParamsResource.TeradataParameters = &quicksight.TeradataParameters{ + Database: aws.String(psResource["database"].(string)), + Host: aws.String(psResource["host"].(string)), + Port: aws.Int64(psResource["port"].(int64)), + } + } + } + + if v := dataSourceParams["twitter"]; v != nil && v.(*schema.Set) != nil { + for _, v := range (v.(*schema.Set)).List() { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypeTwitter + dataSourceParamsResource.TwitterParameters = &quicksight.TwitterParameters{ + MaxRows: aws.Int64(psResource["max_rows"].(int64)), + Query: aws.String(psResource["query"].(string)), + } + } + } + + return aws.String(dataSourceType), dataSourceParamsResource + } + } + + return aws.String(""), nil +} + func resourceAwsQuickSightDataSourceParseID(id string) (string, string, error) { parts := strings.SplitN(id, "/", 2) if len(parts) < 2 || parts[0] == "" || parts[1] == "" { From 1f4e96037d4a7f24d69e4451065ca9bb6028e2ce Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Thu, 28 Nov 2019 10:19:34 -0500 Subject: [PATCH 10/21] Extract remaining functions pertaining to update. --- aws/resource_aws_quicksight_data_source.go | 56 ++++++++++++++-------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index bfac5cf4141a..7e29494ba397 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -564,16 +564,8 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac } } - if v := d.Get("ssl_properties"); v != nil { - for _, v := range v.(*schema.Set).List() { - sslProperties := v.(map[string]interface{}) - - if v, present := sslProperties["disable_ssl"]; present { - params.SslProperties = &quicksight.SslProperties{ - DisableSsl: aws.Bool(v.(bool)), - } - } - } + if sslProperties := resourceAwsQuickSightDataSourceSslProperties(d); sslProperties != nil { + params.SslProperties = sslProperties } if v, exists := d.GetOk("tags"); exists { @@ -590,16 +582,8 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac params.Tags = tags } - if v := d.Get("vpc_connection_properties"); v != nil { - for _, v := range v.(*schema.Set).List() { - vpcConnectionProperties := v.(map[string]interface{}) - - if v := vpcConnectionProperties["vpc_connection_arn"]; v != nil && v.(string) != "" { - params.VpcConnectionProperties = &quicksight.VpcConnectionProperties{ - VpcConnectionArn: aws.String(v.(string)), - } - } - } + if vpcConnectionProperties := resourceAwsQuickSightDataSourceVpcConnectionProperties(d); vpcConnectionProperties != nil { + params.VpcConnectionProperties = vpcConnectionProperties } _, err := conn.CreateDataSource(params) @@ -1138,6 +1122,38 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, return aws.String(""), nil } +func resourceAwsQuickSightDataSourceSslProperties(d *schema.ResourceData) *quicksight.SslProperties { + if v := d.Get("ssl_properties"); v != nil { + for _, v := range v.(*schema.Set).List() { + sslProperties := v.(map[string]interface{}) + + if v, present := sslProperties["disable_ssl"]; present { + return &quicksight.SslProperties{ + DisableSsl: aws.Bool(v.(bool)), + } + } + } + } + + return nil +} + +func resourceAwsQuickSightDataSourceVpcConnectionProperties(d *schema.ResourceData) *quicksight.VpcConnectionProperties { + if v := d.Get("vpc_connection_properties"); v != nil { + for _, v := range v.(*schema.Set).List() { + vpcConnectionProperties := v.(map[string]interface{}) + + if v := vpcConnectionProperties["vpc_connection_arn"]; v != nil && v.(string) != "" { + return &quicksight.VpcConnectionProperties{ + VpcConnectionArn: aws.String(v.(string)), + } + } + } + } + + return nil +} + func resourceAwsQuickSightDataSourceParseID(id string) (string, string, error) { parts := strings.SplitN(id, "/", 2) if len(parts) < 2 || parts[0] == "" || parts[1] == "" { From 6011275b677c151ccdf98bdd53fb1ce4b208905a Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Thu, 28 Nov 2019 10:49:17 -0500 Subject: [PATCH 11/21] Retry describe operation until data source is in a success state. --- aws/resource_aws_quicksight_data_source.go | 26 +++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index 7e29494ba397..d1fa73585adc 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -4,9 +4,11 @@ import ( "fmt" "log" "strings" + "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/quicksight" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" ) @@ -609,7 +611,29 @@ func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{ DataSourceId: aws.String(dataSourceId), } - resp, err := conn.DescribeDataSource(descOpts) + var resp *quicksight.DescribeDataSourceOutput + err = resource.Retry(5*time.Minute, func() *resource.RetryError { + var err error + resp, err := conn.DescribeDataSource(descOpts) + + if resp != nil && resp.DataSource != nil { + status := aws.StringValue(resp.DataSource.Status) + + if status == quicksight.ResourceStatusCreationInProgress || status == quicksight.ResourceStatusUpdateInProgress { + return resource.RetryableError(fmt.Errorf("Data Source operation still in progress (%s): %s", d.Id(), status)) + } + if status == quicksight.ResourceStatusCreationFailed || status == quicksight.ResourceStatusUpdateFailed { + return resource.NonRetryableError(fmt.Errorf("Data Source operation failed (%s): %s", d.Id(), status)) + } + } + + if err != nil { + return resource.NonRetryableError(err) + } + + return nil + }) + if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { log.Printf("[WARN] QuickSight Data Source %s is already gone", d.Id()) d.SetId("") From b8dfe6b29795c37a04e2c680ed8d0d202df8da3b Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Thu, 28 Nov 2019 10:58:06 -0500 Subject: [PATCH 12/21] Super basic data source update implementation. --- aws/resource_aws_quicksight_data_source.go | 75 +++++++++++++--------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index d1fa73585adc..fd092313fca8 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -820,35 +820,52 @@ func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{ return nil } -//func resourceAwsQuickSightDataSourceUpdate(d *schema.ResourceData, meta interface{}) error { -// conn := meta.(*AWSClient).quicksightconn -// -// awsAccountID, dataSourceId, err := resourceAwsQuickSightDataSourceParseID(d.Id()) -// if err != nil { -// return err -// } -// -// params := &quicksight.UpdateDataSetInput{ -// AwsAccountId: aws.String(awsAccountID), -// DataSourceId: aws.String(id), -// } -// -// if v, ok := d.GetOk("description"); ok { -// updateOpts.Description = aws.String(v.(string)) -// } -// -// _, err = conn.UpdateDataSource(updateOpts) -// if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { -// log.Printf("[WARN] QuickSight DataSource %s is already gone", d.Id()) -// d.SetId("") -// return nil -// } -// if err != nil { -// return fmt.Errorf("Error updating QuickSight DataSource %s: %s", d.Id(), err) -// } -// -// return resourceAwsQuickSightDataSourceRead(d, meta) -//} +func resourceAwsQuickSightDataSourceUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).quicksightconn + + awsAccountID, dataSourceId, err := resourceAwsQuickSightDataSourceParseID(d.Id()) + if err != nil { + return err + } + + params := &quicksight.UpdateDataSourceInput{ + AwsAccountId: aws.String(awsAccountID), + DataSourceId: aws.String(dataSourceId), + } + + if credentials := resourceAwsQuickSightDataSourceCredentials(d); credentials != nil { + params.Credentials = credentials + } + + if dataSourceType, dataSourceParameters := resourceAwsQuickSightDataSourceParameters(d); dataSourceParameters != nil { + params.DataSourceParameters = dataSourceParameters + d.Set("type", dataSourceType) + } + + // TODO: Handle permissions + + if sslProperties := resourceAwsQuickSightDataSourceSslProperties(d); sslProperties != nil { + params.SslProperties = sslProperties + } + + // TODO: Handle tags + + if vpcConnectionProperties := resourceAwsQuickSightDataSourceVpcConnectionProperties(d); vpcConnectionProperties != nil { + params.VpcConnectionProperties = vpcConnectionProperties + } + + _, err = conn.UpdateDataSource(params) + if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { + log.Printf("[WARN] QuickSight Data Source %s is already gone", d.Id()) + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("Error updating QuickSight Data Source %s: %s", d.Id(), err) + } + + return resourceAwsQuickSightDataSourceRead(d, meta) +} // //func resourceAwsQuickSightDataSourceDelete(d *schema.ResourceData, meta interface{}) error { From 4a7b9a07ad296e06b413a540701d85a888c1239e Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Thu, 28 Nov 2019 11:02:11 -0500 Subject: [PATCH 13/21] Implment delete data source. --- aws/resource_aws_quicksight_data_source.go | 68 +++++++++++----------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index fd092313fca8..e2db9782941f 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -17,8 +17,8 @@ func resourceAwsQuickSightDataSource() *schema.Resource { return &schema.Resource{ Create: resourceAwsQuickSightDataSourceCreate, Read: resourceAwsQuickSightDataSourceRead, - //Update: resourceAwsQuickSightDataSourceUpdate, - // Delete: resourceAwsQuickSightDataSourceDelete, + Update: resourceAwsQuickSightDataSourceUpdate, + Delete: resourceAwsQuickSightDataSourceDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, @@ -530,15 +530,15 @@ func resourceAwsQuickSightDataSource() *schema.Resource { func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).quicksightconn - awsAccountID := meta.(*AWSClient).accountid + awsAccountId := meta.(*AWSClient).accountid id := d.Get("id").(string) if v, ok := d.GetOk("aws_account_id"); ok { - awsAccountID = v.(string) + awsAccountId = v.(string) } params := &quicksight.CreateDataSourceInput{ - AwsAccountId: aws.String(awsAccountID), + AwsAccountId: aws.String(awsAccountId), DataSourceId: aws.String(id), } @@ -593,7 +593,7 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac return fmt.Errorf("Error creating QuickSight Data Source: %s", err) } - d.SetId(fmt.Sprintf("%s/%s", awsAccountID, id)) + d.SetId(fmt.Sprintf("%s/%s", awsAccountId, id)) return resourceAwsQuickSightDataSourceRead(d, meta) } @@ -601,13 +601,13 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).quicksightconn - awsAccountID, dataSourceId, err := resourceAwsQuickSightDataSourceParseID(d.Id()) + awsAccountId, dataSourceId, err := resourceAwsQuickSightDataSourceParseID(d.Id()) if err != nil { return err } descOpts := &quicksight.DescribeDataSourceInput{ - AwsAccountId: aws.String(awsAccountID), + AwsAccountId: aws.String(awsAccountId), DataSourceId: aws.String(dataSourceId), } @@ -645,7 +645,7 @@ func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{ d.Set("arn", resp.DataSource.Arn) d.Set("id", resp.DataSource.DataSourceId) - d.Set("aws_account_id", awsAccountID) + d.Set("aws_account_id", awsAccountId) if resp.DataSource.DataSourceParameters.AmazonElasticsearchParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ @@ -823,13 +823,13 @@ func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{ func resourceAwsQuickSightDataSourceUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).quicksightconn - awsAccountID, dataSourceId, err := resourceAwsQuickSightDataSourceParseID(d.Id()) + awsAccountId, dataSourceId, err := resourceAwsQuickSightDataSourceParseID(d.Id()) if err != nil { return err } params := &quicksight.UpdateDataSourceInput{ - AwsAccountId: aws.String(awsAccountID), + AwsAccountId: aws.String(awsAccountId), DataSourceId: aws.String(dataSourceId), } @@ -867,30 +867,28 @@ func resourceAwsQuickSightDataSourceUpdate(d *schema.ResourceData, meta interfac return resourceAwsQuickSightDataSourceRead(d, meta) } -// -//func resourceAwsQuickSightDataSourceDelete(d *schema.ResourceData, meta interface{}) error { -// conn := meta.(*AWSClient).quicksightconn -// -// awsAccountID, namespace, groupName, err := resourceAwsQuickSightDataSourceParseID(d.Id()) -// if err != nil { -// return err -// } -// -// deleteOpts := &quicksight.DeleteDataSourceInput{ -// AwsAccountId: aws.String(awsAccountID), -// Namespace: aws.String(namespace), -// DataSourceName: aws.String(groupName), -// } -// -// if _, err := conn.DeleteDataSource(deleteOpts); err != nil { -// if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { -// return nil -// } -// return fmt.Errorf("Error deleting QuickSight DataSource %s: %s", d.Id(), err) -// } -// -// return nil -//} +func resourceAwsQuickSightDataSourceDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).quicksightconn + + awsAccountId, dataSourceId, err := resourceAwsQuickSightDataSourceParseID(d.Id()) + if err != nil { + return err + } + + deleteOpts := &quicksight.DeleteDataSourceInput{ + AwsAccountId: aws.String(awsAccountId), + DataSourceId: aws.String(dataSourceId), + } + + if _, err := conn.DeleteDataSource(deleteOpts); err != nil { + if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { + return nil + } + return fmt.Errorf("Error deleting QuickSight Data Source %s: %s", d.Id(), err) + } + + return nil +} func resourceAwsQuickSightDataSourceCredentials(d *schema.ResourceData) *quicksight.DataSourceCredentials { if v := d.Get("credentials"); v != nil { From d3b7cde934b13e9d84d01d59dbb403474a1637f8 Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Thu, 28 Nov 2019 11:24:17 -0500 Subject: [PATCH 14/21] Update data source tags. --- aws/resource_aws_quicksight_data_source.go | 45 +++++++++++++----- aws/tagsQuickSight.go | 55 ++++++++++++++++++++++ 2 files changed, 87 insertions(+), 13 deletions(-) create mode 100644 aws/tagsQuickSight.go diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index e2db9782941f..ce0a86927a13 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -570,18 +570,8 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac params.SslProperties = sslProperties } - if v, exists := d.GetOk("tags"); exists { - tags := make([]*quicksight.Tag, 0) - for k, v := range v.(map[string]interface{}) { - if !tagIgnoredGeneric(k) { - tags = append(tags, &quicksight.Tag{ - Key: aws.String(k), - Value: aws.String(v.(string)), - }) - } - } - - params.Tags = tags + if v, ok := d.GetOk("tags"); ok { + params.Tags = tagsFromMapQuickSight(v.(map[string]interface{})) } if vpcConnectionProperties := resourceAwsQuickSightDataSourceVpcConnectionProperties(d); vpcConnectionProperties != nil { @@ -848,7 +838,32 @@ func resourceAwsQuickSightDataSourceUpdate(d *schema.ResourceData, meta interfac params.SslProperties = sslProperties } - // TODO: Handle tags + if d.HasChange("tags") { + oraw, nraw := d.GetChange("tags") + o := oraw.(map[string]interface{}) + n := nraw.(map[string]interface{}) + c, r := diffTagsQuickSight(tagsFromMapQuickSight(o), tagsFromMapQuickSight(n)) + + if len(r) > 0 { + _, err := conn.UntagResource(&quicksight.UntagResourceInput{ + ResourceArn: aws.String(quicksightDataSourceArn(meta.(*AWSClient).region, awsAccountId, dataSourceId)), + TagKeys: tagKeysQuickSight(r), + }) + if err != nil { + return fmt.Errorf("Error deleting QuickSight Data Source tags: %s", err) + } + } + + if len(c) > 0 { + _, err := conn.TagResource(&quicksight.TagResourceInput{ + ResourceArn: aws.String(quicksightDataSourceArn(meta.(*AWSClient).region, awsAccountId, dataSourceId)), + Tags: c, + }) + if err != nil { + return fmt.Errorf("Error updating QuickSight Data Source tags: %s", err) + } + } + } if vpcConnectionProperties := resourceAwsQuickSightDataSourceVpcConnectionProperties(d); vpcConnectionProperties != nil { params.VpcConnectionProperties = vpcConnectionProperties @@ -1200,3 +1215,7 @@ func resourceAwsQuickSightDataSourceParseID(id string) (string, string, error) { } return parts[0], parts[1], nil } + +func quicksightDataSourceArn(awsRegion string, awsAccountId string, dataSourceId string) string { + return fmt.Sprintf("arn:aws:quicksight:%s:%s:datasource/%s", awsRegion, awsAccountId, dataSourceId) +} diff --git a/aws/tagsQuickSight.go b/aws/tagsQuickSight.go new file mode 100644 index 000000000000..04dfb589a102 --- /dev/null +++ b/aws/tagsQuickSight.go @@ -0,0 +1,55 @@ +package aws + +import ( + //"log" + //"regexp" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/quicksight" +) + +// diffTags takes our tags locally and the ones remotely and returns +// the set of tags that must be created, and the set of tags that must +// be destroyed. +func diffTagsQuickSight(oldTags, newTags []*quicksight.Tag) ([]*quicksight.Tag, []*quicksight.Tag) { + // First, we're creating everything we have + create := make(map[string]interface{}) + for _, t := range newTags { + create[aws.StringValue(t.Key)] = aws.StringValue(t.Value) + } + + // Build the list of what to remove + var remove []*quicksight.Tag + for _, t := range oldTags { + old, ok := create[aws.StringValue(t.Key)] + if !ok || old != aws.StringValue(t.Value) { + // Delete it! + remove = append(remove, t) + } else if ok { + delete(create, aws.StringValue(t.Key)) + } + } + + return tagsFromMapQuickSight(create), remove +} + +func tagsFromMapQuickSight(m map[string]interface{}) []*quicksight.Tag { + result := make([]*quicksight.Tag, 0, len(m)) + for k, v := range m { + t := &quicksight.Tag{ + Key: aws.String(k), + Value: aws.String(v.(string)), + } + result = append(result, t) + } + + return result +} + +func tagKeysQuickSight(ts []*quicksight.Tag) []*string { + result := make([]*string, 0, len(ts)) + for _, t := range ts { + result = append(result, t.Key) + } + return result +} From 43b686eb6884301a0eec5be52cb53cef062febfe Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Mon, 2 Dec 2019 09:06:33 -0500 Subject: [PATCH 15/21] Basic implementation of grant/revoke diffing. --- aws/resource_aws_quicksight_data_source.go | 170 ++++++++++++--------- aws/structure.go | 109 +++++++++++++ aws/structure_test.go | 38 +++++ aws/tagsQuickSight.go | 9 -- 4 files changed, 249 insertions(+), 77 deletions(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index ce0a86927a13..acedaa8b07b5 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -552,7 +552,7 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac d.Set("type", dataSourceType) } - if v := d.Get("permissions"); v != nil { + if v := d.Get("permission"); v != nil { params.Permissions = make([]*quicksight.ResourcePermission, 0) for _, v := range v.(*schema.Set).List() { @@ -601,13 +601,13 @@ func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{ DataSourceId: aws.String(dataSourceId), } - var resp *quicksight.DescribeDataSourceOutput + var dataSourceResp *quicksight.DescribeDataSourceOutput err = resource.Retry(5*time.Minute, func() *resource.RetryError { var err error - resp, err := conn.DescribeDataSource(descOpts) + dataSourceResp, err := conn.DescribeDataSource(descOpts) - if resp != nil && resp.DataSource != nil { - status := aws.StringValue(resp.DataSource.Status) + if dataSourceResp != nil && dataSourceResp.DataSource != nil { + status := aws.StringValue(dataSourceResp.DataSource.Status) if status == quicksight.ResourceStatusCreationInProgress || status == quicksight.ResourceStatusUpdateInProgress { return resource.RetryableError(fmt.Errorf("Data Source operation still in progress (%s): %s", d.Id(), status)) @@ -633,176 +633,191 @@ func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{ return fmt.Errorf("Error describing QuickSight Data Source (%s): %s", d.Id(), err) } - d.Set("arn", resp.DataSource.Arn) - d.Set("id", resp.DataSource.DataSourceId) + permsResp, err := conn.DescribeDataSourcePermissions(&quicksight.DescribeDataSourcePermissionsInput{ + AwsAccountId: aws.String(awsAccountId), + DataSourceId: aws.String(dataSourceId), + }) + + if err != nil { + return fmt.Errorf("Error describing QuickSight Data Source permissions (%s): %s", d.Id(), err) + } + + dataSource := dataSourceResp.DataSource + + d.Set("arn", dataSource.Arn) + d.Set("id", dataSource.DataSourceId) d.Set("aws_account_id", awsAccountId) - if resp.DataSource.DataSourceParameters.AmazonElasticsearchParameters != nil { + if err := d.Set("permission", flattenQuickSightPermissions(permsResp.Permissions)); err != nil { + return fmt.Errorf("Error setting permission error: %#v", err) + } + + if dataSource.DataSourceParameters.AmazonElasticsearchParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "amazon_elasticsearch": { - "domain": resp.DataSource.DataSourceParameters.AmazonElasticsearchParameters.Domain, + "domain": dataSource.DataSourceParameters.AmazonElasticsearchParameters.Domain, }, }) } - if resp.DataSource.DataSourceParameters.AthenaParameters != nil { + if dataSource.DataSourceParameters.AthenaParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "athena": { - "work_group": resp.DataSource.DataSourceParameters.AthenaParameters.WorkGroup, + "work_group": dataSource.DataSourceParameters.AthenaParameters.WorkGroup, }, }) } - if resp.DataSource.DataSourceParameters.AuroraParameters != nil { + if dataSource.DataSourceParameters.AuroraParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "aurora": { - "database": resp.DataSource.DataSourceParameters.AuroraParameters.Database, - "host": resp.DataSource.DataSourceParameters.AuroraParameters.Host, - "port": resp.DataSource.DataSourceParameters.AuroraParameters.Port, + "database": dataSource.DataSourceParameters.AuroraParameters.Database, + "host": dataSource.DataSourceParameters.AuroraParameters.Host, + "port": dataSource.DataSourceParameters.AuroraParameters.Port, }, }) } - if resp.DataSource.DataSourceParameters.AuroraPostgreSqlParameters != nil { + if dataSource.DataSourceParameters.AuroraPostgreSqlParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "aurora_postgre_sql": { - "database": resp.DataSource.DataSourceParameters.AuroraPostgreSqlParameters.Database, - "host": resp.DataSource.DataSourceParameters.AuroraPostgreSqlParameters.Host, - "port": resp.DataSource.DataSourceParameters.AuroraPostgreSqlParameters.Port, + "database": dataSource.DataSourceParameters.AuroraPostgreSqlParameters.Database, + "host": dataSource.DataSourceParameters.AuroraPostgreSqlParameters.Host, + "port": dataSource.DataSourceParameters.AuroraPostgreSqlParameters.Port, }, }) } - if resp.DataSource.DataSourceParameters.AwsIotAnalyticsParameters != nil { + if dataSource.DataSourceParameters.AwsIotAnalyticsParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "aws_iot_analytics": { - "data_set_name": resp.DataSource.DataSourceParameters.AwsIotAnalyticsParameters.DataSetName, + "data_set_name": dataSource.DataSourceParameters.AwsIotAnalyticsParameters.DataSetName, }, }) } - if resp.DataSource.DataSourceParameters.JiraParameters != nil { + if dataSource.DataSourceParameters.JiraParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "jira": { - "site_base_url": resp.DataSource.DataSourceParameters.JiraParameters.SiteBaseUrl, + "site_base_url": dataSource.DataSourceParameters.JiraParameters.SiteBaseUrl, }, }) } - if resp.DataSource.DataSourceParameters.MariaDbParameters != nil { + if dataSource.DataSourceParameters.MariaDbParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "maria_db": { - "database": resp.DataSource.DataSourceParameters.MariaDbParameters.Database, - "host": resp.DataSource.DataSourceParameters.MariaDbParameters.Host, - "port": resp.DataSource.DataSourceParameters.MariaDbParameters.Port, + "database": dataSource.DataSourceParameters.MariaDbParameters.Database, + "host": dataSource.DataSourceParameters.MariaDbParameters.Host, + "port": dataSource.DataSourceParameters.MariaDbParameters.Port, }, }) } - if resp.DataSource.DataSourceParameters.MySqlParameters != nil { + if dataSource.DataSourceParameters.MySqlParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "mysql": { - "database": resp.DataSource.DataSourceParameters.MySqlParameters.Database, - "host": resp.DataSource.DataSourceParameters.MySqlParameters.Host, - "port": resp.DataSource.DataSourceParameters.MySqlParameters.Port, + "database": dataSource.DataSourceParameters.MySqlParameters.Database, + "host": dataSource.DataSourceParameters.MySqlParameters.Host, + "port": dataSource.DataSourceParameters.MySqlParameters.Port, }, }) } - if resp.DataSource.DataSourceParameters.PostgreSqlParameters != nil { + if dataSource.DataSourceParameters.PostgreSqlParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "postgresql": { - "database": resp.DataSource.DataSourceParameters.PostgreSqlParameters.Database, - "host": resp.DataSource.DataSourceParameters.PostgreSqlParameters.Host, - "port": resp.DataSource.DataSourceParameters.PostgreSqlParameters.Port, + "database": dataSource.DataSourceParameters.PostgreSqlParameters.Database, + "host": dataSource.DataSourceParameters.PostgreSqlParameters.Host, + "port": dataSource.DataSourceParameters.PostgreSqlParameters.Port, }, }) } - if resp.DataSource.DataSourceParameters.PrestoParameters != nil { + if dataSource.DataSourceParameters.PrestoParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "presto": { - "catalog": resp.DataSource.DataSourceParameters.PrestoParameters.Catalog, - "host": resp.DataSource.DataSourceParameters.PrestoParameters.Host, - "port": resp.DataSource.DataSourceParameters.PrestoParameters.Port, + "catalog": dataSource.DataSourceParameters.PrestoParameters.Catalog, + "host": dataSource.DataSourceParameters.PrestoParameters.Host, + "port": dataSource.DataSourceParameters.PrestoParameters.Port, }, }) } - if resp.DataSource.DataSourceParameters.RedshiftParameters != nil { + if dataSource.DataSourceParameters.RedshiftParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "redshift": { - "cluster_id": resp.DataSource.DataSourceParameters.RedshiftParameters.ClusterId, - "database": resp.DataSource.DataSourceParameters.RedshiftParameters.Database, - "host": resp.DataSource.DataSourceParameters.RedshiftParameters.Host, - "port": resp.DataSource.DataSourceParameters.RedshiftParameters.Port, + "cluster_id": dataSource.DataSourceParameters.RedshiftParameters.ClusterId, + "database": dataSource.DataSourceParameters.RedshiftParameters.Database, + "host": dataSource.DataSourceParameters.RedshiftParameters.Host, + "port": dataSource.DataSourceParameters.RedshiftParameters.Port, }, }) } - if resp.DataSource.DataSourceParameters.S3Parameters != nil { + if dataSource.DataSourceParameters.S3Parameters != nil { d.Set("parameters", map[string]map[string]map[string]interface{}{ "s3": { "manifest_file_location": { - "bucket": resp.DataSource.DataSourceParameters.S3Parameters.ManifestFileLocation.Bucket, - "key": resp.DataSource.DataSourceParameters.S3Parameters.ManifestFileLocation.Key, + "bucket": dataSource.DataSourceParameters.S3Parameters.ManifestFileLocation.Bucket, + "key": dataSource.DataSourceParameters.S3Parameters.ManifestFileLocation.Key, }, }, }) } - if resp.DataSource.DataSourceParameters.ServiceNowParameters != nil { + if dataSource.DataSourceParameters.ServiceNowParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "service_now": { - "site_base_url": resp.DataSource.DataSourceParameters.ServiceNowParameters.SiteBaseUrl, + "site_base_url": dataSource.DataSourceParameters.ServiceNowParameters.SiteBaseUrl, }, }) } - if resp.DataSource.DataSourceParameters.SnowflakeParameters != nil { + if dataSource.DataSourceParameters.SnowflakeParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "snowflake": { - "database": resp.DataSource.DataSourceParameters.SnowflakeParameters.Database, - "host": resp.DataSource.DataSourceParameters.SnowflakeParameters.Host, - "warehouse": resp.DataSource.DataSourceParameters.SnowflakeParameters.Warehouse, + "database": dataSource.DataSourceParameters.SnowflakeParameters.Database, + "host": dataSource.DataSourceParameters.SnowflakeParameters.Host, + "warehouse": dataSource.DataSourceParameters.SnowflakeParameters.Warehouse, }, }) } - if resp.DataSource.DataSourceParameters.SparkParameters != nil { + if dataSource.DataSourceParameters.SparkParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "spark": { - "host": resp.DataSource.DataSourceParameters.SparkParameters.Host, - "port": resp.DataSource.DataSourceParameters.SparkParameters.Port, + "host": dataSource.DataSourceParameters.SparkParameters.Host, + "port": dataSource.DataSourceParameters.SparkParameters.Port, }, }) } - if resp.DataSource.DataSourceParameters.SqlServerParameters != nil { + if dataSource.DataSourceParameters.SqlServerParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "sql_server": { - "database": resp.DataSource.DataSourceParameters.SqlServerParameters.Database, - "host": resp.DataSource.DataSourceParameters.SqlServerParameters.Host, - "port": resp.DataSource.DataSourceParameters.SqlServerParameters.Port, + "database": dataSource.DataSourceParameters.SqlServerParameters.Database, + "host": dataSource.DataSourceParameters.SqlServerParameters.Host, + "port": dataSource.DataSourceParameters.SqlServerParameters.Port, }, }) } - if resp.DataSource.DataSourceParameters.TeradataParameters != nil { + if dataSource.DataSourceParameters.TeradataParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "teradata": { - "database": resp.DataSource.DataSourceParameters.TeradataParameters.Database, - "host": resp.DataSource.DataSourceParameters.TeradataParameters.Host, - "port": resp.DataSource.DataSourceParameters.TeradataParameters.Port, + "database": dataSource.DataSourceParameters.TeradataParameters.Database, + "host": dataSource.DataSourceParameters.TeradataParameters.Host, + "port": dataSource.DataSourceParameters.TeradataParameters.Port, }, }) } - if resp.DataSource.DataSourceParameters.TwitterParameters != nil { + if dataSource.DataSourceParameters.TwitterParameters != nil { d.Set("parameters", map[string]map[string]interface{}{ "twitter": { - "max_rows": resp.DataSource.DataSourceParameters.TwitterParameters.MaxRows, - "query": resp.DataSource.DataSourceParameters.TwitterParameters.Query, + "max_rows": dataSource.DataSourceParameters.TwitterParameters.MaxRows, + "query": dataSource.DataSourceParameters.TwitterParameters.Query, }, }) } @@ -832,7 +847,26 @@ func resourceAwsQuickSightDataSourceUpdate(d *schema.ResourceData, meta interfac d.Set("type", dataSourceType) } - // TODO: Handle permissions + if d.HasChange("permission") { + oraw, nraw := d.GetChange("permission") + o := oraw.(*schema.Set).List() + n := nraw.(*schema.Set).List() + toGrant, toRevoke := diffQuickSightPermissionsToGrantAndRevoke(o, n) + + if len(toGrant) > 0 || len(toRevoke) > 0 { + params := &quicksight.UpdateDataSourcePermissionsInput{ + AwsAccountId: aws.String(awsAccountId), + DataSourceId: aws.String(dataSourceId), + GrantPermissions: make([]*quicksight.ResourcePermission, 0), + RevokePermissions: make([]*quicksight.ResourcePermission, 0), + } + + _, err := conn.UpdateDataSourcePermissions(params) + if err != nil { + return fmt.Errorf("Error updating QuickSight Data Source permissions: %s", err) + } + } + } if sslProperties := resourceAwsQuickSightDataSourceSslProperties(d); sslProperties != nil { params.SslProperties = sslProperties diff --git a/aws/structure.go b/aws/structure.go index 69c32f9c069d..a79c3ecb2a94 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -38,6 +38,7 @@ import ( "github.com/aws/aws-sdk-go/service/macie" "github.com/aws/aws-sdk-go/service/mq" "github.com/aws/aws-sdk-go/service/neptune" + "github.com/aws/aws-sdk-go/service/quicksight" "github.com/aws/aws-sdk-go/service/rds" "github.com/aws/aws-sdk-go/service/redshift" "github.com/aws/aws-sdk-go/service/route53" @@ -3852,6 +3853,114 @@ func flattenCognitoIdentityPoolRolesAttachmentMappingRules(d []*cognitoidentity. return rules } +func diffQuickSightPermissionsToGrantAndRevoke(oldPerms []interface{}, newPerms []interface{}) ([]*quicksight.ResourcePermission, []*quicksight.ResourcePermission) { + // Map principal to permissions. `true` means grant, `false` means + // revoke and absence means leave alone (i.e. unchanged) + grants := make(map[string]map[string]bool, 0) + + // All new params should be granted until further notice... + for _, v := range newPerms { + s := v.(map[string]interface{}) + + if p, ok := s["principal"].(string); ok { + if _, present := grants[p]; !present { + grants[p] = make(map[string]bool, 0) + } + + for _, v := range s["actions"].(*schema.Set).List() { + grants[p][v.(string)] = true + } + } + } + + // Don't touch principal-action combos that are unchanged, revoke combos that + // are in old but not new + for _, v := range oldPerms { + s := v.(map[string]interface{}) + + if p, ok := s["principal"].(string); ok { + if principalGrants, present := grants[p]; present { + for _, v := range s["actions"].(*schema.Set).List() { + action := v.(string) + + if _, present := principalGrants[action]; !present { + // In old but not in new so revoke + grants[p][action] = false + } else { + // In old and in new so leave alone + delete(grants[p], action) + } + } + } else { + grants[p] = make(map[string]bool, 0) + + // The principal is not desired in new + // permissions so revoke all + for _, v := range s["actions"].(*schema.Set).List() { + grants[p][v.(string)] = false + } + } + + } + } + + toGrant := make([]*quicksight.ResourcePermission, 0) + toRevoke := make([]*quicksight.ResourcePermission, 0) + + for principal, actions := range grants { + grant := &quicksight.ResourcePermission{ + Principal: aws.String(principal), + Actions: make([]*string, 0), + } + revoke := &quicksight.ResourcePermission{ + Principal: aws.String(principal), + Actions: make([]*string, 0), + } + + for action, shouldGrant := range actions { + if shouldGrant { + grant.Actions = append(grant.Actions, aws.String(action)) + } else { + revoke.Actions = append(revoke.Actions, aws.String(action)) + } + } + + if len(grant.Actions) > 0 { + toGrant = append(toGrant, grant) + } + + if len(revoke.Actions) > 0 { + toRevoke = append(toRevoke, revoke) + } + } + + return toGrant, toRevoke +} + +func flattenQuickSightPermissions(perms []*quicksight.ResourcePermission) []map[string]interface{} { + values := make([]map[string]interface{}, 0) + + for _, v := range perms { + perm := make(map[string]interface{}) + + if v == nil { + return nil + } + + if v.Principal != nil { + perm["principal"] = *v.Principal + } + + if v.Actions != nil { + perm["actions"] = flattenStringList(v.Actions) + } + + values = append(values, perm) + } + + return values +} + func flattenRedshiftLogging(ls *redshift.LoggingStatus) []interface{} { if ls == nil { return []interface{}{} diff --git a/aws/structure_test.go b/aws/structure_test.go index dcc487b4f347..a1afc4197188 100644 --- a/aws/structure_test.go +++ b/aws/structure_test.go @@ -13,6 +13,7 @@ import ( "github.com/aws/aws-sdk-go/service/elasticache" "github.com/aws/aws-sdk-go/service/elb" "github.com/aws/aws-sdk-go/service/kinesis" + //"github.com/aws/aws-sdk-go/service/quicksight" "github.com/aws/aws-sdk-go/service/rds" "github.com/aws/aws-sdk-go/service/redshift" "github.com/aws/aws-sdk-go/service/route53" @@ -1337,6 +1338,43 @@ func TestCognitoUserPoolSchemaAttributeMatchesStandardAttribute(t *testing.T) { } } +func TestDiffQuickSightNoPermissionsMeansNoChanges(t *testing.T) { + empty := make([]interface{}, 0) + + toGrant, toRevoke := diffQuickSightPermissionsToGrantAndRevoke(empty, empty) + + if len(toGrant) > 0 { + t.Fatal("Expected no granted permissions, got", len(toGrant)) + } + + if len(toRevoke) > 0 { + t.Fatal("Expected no revoked permissions, got", len(toRevoke)) + } +} + +func TestDiffQuickSightNoOldMeansOnlyGrant(t *testing.T) { + empty := make([]interface{}, 0) + newPerms := []interface{}{ + map[string]interface{}{ + "principal": "principal1", + "actions": schema.NewSet(schema.HashString, []interface{}{ + "action1", + "action2", + }), + }, + } + + toGrant, toRevoke := diffQuickSightPermissionsToGrantAndRevoke(empty, newPerms) + + if len(toGrant) != 1 { + t.Fatal("Expected 1 granted permission, got", len(toGrant)) + } + + if len(toRevoke) > 0 { + t.Fatal("Expected no revoked permissions, got", len(toRevoke)) + } +} + func TestCanonicalXML(t *testing.T) { cases := []struct { Name string diff --git a/aws/tagsQuickSight.go b/aws/tagsQuickSight.go index 04dfb589a102..cd9c87f0ee54 100644 --- a/aws/tagsQuickSight.go +++ b/aws/tagsQuickSight.go @@ -1,29 +1,20 @@ package aws import ( - //"log" - //"regexp" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/quicksight" ) -// diffTags takes our tags locally and the ones remotely and returns -// the set of tags that must be created, and the set of tags that must -// be destroyed. func diffTagsQuickSight(oldTags, newTags []*quicksight.Tag) ([]*quicksight.Tag, []*quicksight.Tag) { - // First, we're creating everything we have create := make(map[string]interface{}) for _, t := range newTags { create[aws.StringValue(t.Key)] = aws.StringValue(t.Value) } - // Build the list of what to remove var remove []*quicksight.Tag for _, t := range oldTags { old, ok := create[aws.StringValue(t.Key)] if !ok || old != aws.StringValue(t.Value) { - // Delete it! remove = append(remove, t) } else if ok { delete(create, aws.StringValue(t.Key)) From acecafc06d9ee5bc32ad05f23b71b46559035b93 Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Mon, 2 Dec 2019 09:47:38 -0500 Subject: [PATCH 16/21] Test granting and revoking. --- aws/resource_aws_quicksight_data_source.go | 4 +- aws/structure.go | 68 ++++---- aws/structure_test.go | 187 ++++++++++++++++++++- 3 files changed, 225 insertions(+), 34 deletions(-) diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index acedaa8b07b5..f165582d9430 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -857,8 +857,8 @@ func resourceAwsQuickSightDataSourceUpdate(d *schema.ResourceData, meta interfac params := &quicksight.UpdateDataSourcePermissionsInput{ AwsAccountId: aws.String(awsAccountId), DataSourceId: aws.String(dataSourceId), - GrantPermissions: make([]*quicksight.ResourcePermission, 0), - RevokePermissions: make([]*quicksight.ResourcePermission, 0), + GrantPermissions: toGrant, + RevokePermissions: toRevoke, } _, err := conn.UpdateDataSourcePermissions(params) diff --git a/aws/structure.go b/aws/structure.go index a79c3ecb2a94..3a98423898b3 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -3854,6 +3854,42 @@ func flattenCognitoIdentityPoolRolesAttachmentMappingRules(d []*cognitoidentity. } func diffQuickSightPermissionsToGrantAndRevoke(oldPerms []interface{}, newPerms []interface{}) ([]*quicksight.ResourcePermission, []*quicksight.ResourcePermission) { + grants := diffQuickSightPermissionsLookup(oldPerms, newPerms) + + toGrant := make([]*quicksight.ResourcePermission, 0) + toRevoke := make([]*quicksight.ResourcePermission, 0) + + for principal, actions := range grants { + grant := &quicksight.ResourcePermission{ + Principal: aws.String(principal), + Actions: make([]*string, 0), + } + revoke := &quicksight.ResourcePermission{ + Principal: aws.String(principal), + Actions: make([]*string, 0), + } + + for action, shouldGrant := range actions { + if shouldGrant { + grant.Actions = append(grant.Actions, aws.String(action)) + } else { + revoke.Actions = append(revoke.Actions, aws.String(action)) + } + } + + if len(grant.Actions) > 0 { + toGrant = append(toGrant, grant) + } + + if len(revoke.Actions) > 0 { + toRevoke = append(toRevoke, revoke) + } + } + + return toGrant, toRevoke +} + +func diffQuickSightPermissionsLookup(oldPerms []interface{}, newPerms []interface{}) map[string]map[string]bool { // Map principal to permissions. `true` means grant, `false` means // revoke and absence means leave alone (i.e. unchanged) grants := make(map[string]map[string]bool, 0) @@ -3904,37 +3940,7 @@ func diffQuickSightPermissionsToGrantAndRevoke(oldPerms []interface{}, newPerms } } - toGrant := make([]*quicksight.ResourcePermission, 0) - toRevoke := make([]*quicksight.ResourcePermission, 0) - - for principal, actions := range grants { - grant := &quicksight.ResourcePermission{ - Principal: aws.String(principal), - Actions: make([]*string, 0), - } - revoke := &quicksight.ResourcePermission{ - Principal: aws.String(principal), - Actions: make([]*string, 0), - } - - for action, shouldGrant := range actions { - if shouldGrant { - grant.Actions = append(grant.Actions, aws.String(action)) - } else { - revoke.Actions = append(revoke.Actions, aws.String(action)) - } - } - - if len(grant.Actions) > 0 { - toGrant = append(toGrant, grant) - } - - if len(revoke.Actions) > 0 { - toRevoke = append(toRevoke, revoke) - } - } - - return toGrant, toRevoke + return grants } func flattenQuickSightPermissions(perms []*quicksight.ResourcePermission) []map[string]interface{} { diff --git a/aws/structure_test.go b/aws/structure_test.go index a1afc4197188..faba30122373 100644 --- a/aws/structure_test.go +++ b/aws/structure_test.go @@ -13,7 +13,6 @@ import ( "github.com/aws/aws-sdk-go/service/elasticache" "github.com/aws/aws-sdk-go/service/elb" "github.com/aws/aws-sdk-go/service/kinesis" - //"github.com/aws/aws-sdk-go/service/quicksight" "github.com/aws/aws-sdk-go/service/rds" "github.com/aws/aws-sdk-go/service/redshift" "github.com/aws/aws-sdk-go/service/route53" @@ -1375,6 +1374,192 @@ func TestDiffQuickSightNoOldMeansOnlyGrant(t *testing.T) { } } +func TestDiffQuickSightNoNewMeansOnlyRevoke(t *testing.T) { + empty := make([]interface{}, 0) + oldPerms := []interface{}{ + map[string]interface{}{ + "principal": "principal1", + "actions": schema.NewSet(schema.HashString, []interface{}{ + "action1", + "action2", + }), + }, + } + + toGrant, toRevoke := diffQuickSightPermissionsToGrantAndRevoke(oldPerms, empty) + + if len(toGrant) > 0 { + t.Fatal("Expected no granted permissions, got", len(toGrant)) + } + + if len(toRevoke) != 1 { + t.Fatal("Expected 1 revoked permission, got", len(toRevoke)) + } +} + +func TestDiffQuickSightIntersectingPermissionsMeansNoChange(t *testing.T) { + perms := []interface{}{ + map[string]interface{}{ + "principal": "principal1", + "actions": schema.NewSet(schema.HashString, []interface{}{ + "action1", + "action2", + }), + }, + } + + toGrant, toRevoke := diffQuickSightPermissionsToGrantAndRevoke(perms, perms) + + if len(toGrant) > 0 { + t.Fatal("Expected no granted permissions, got", len(toGrant)) + } + + if len(toRevoke) > 0 { + t.Fatal("Expected no revoked permissions, got", len(toRevoke)) + } +} + +func TestDiffQuickSightAdditionalNewPermissionsBecomeGrants(t *testing.T) { + oldPerms := []interface{}{ + map[string]interface{}{ + "principal": "principal1", + "actions": schema.NewSet(schema.HashString, []interface{}{ + "oldAction", + }), + }, + } + newPerms := []interface{}{ + map[string]interface{}{ + "principal": "principal1", + "actions": schema.NewSet(schema.HashString, []interface{}{ + "oldAction", + "newAction", + }), + }, + } + + toGrant, toRevoke := diffQuickSightPermissionsToGrantAndRevoke(oldPerms, newPerms) + + if len(toGrant) != 1 { + t.Fatal("Expected 1 granted permission, got", len(toGrant)) + } + + if len(toGrant[0].Actions) != 1 || *toGrant[0].Actions[0] != "newAction" { + t.Fatal("Expected 1 new granted action, got", len(toGrant)) + } + + if len(toRevoke) > 0 { + t.Fatal("Expected no revoked permissions, got", len(toRevoke)) + } +} + +func TestDiffQuickSightAdditionalOldPermissionsBecomeRevokes(t *testing.T) { + oldPerms := []interface{}{ + map[string]interface{}{ + "principal": "principal1", + "actions": schema.NewSet(schema.HashString, []interface{}{ + "oldAction", + "onlyOldAction", + }), + }, + } + newPerms := []interface{}{ + map[string]interface{}{ + "principal": "principal1", + "actions": schema.NewSet(schema.HashString, []interface{}{ + "oldAction", + }), + }, + } + + toGrant, toRevoke := diffQuickSightPermissionsToGrantAndRevoke(oldPerms, newPerms) + + if len(toRevoke) != 1 { + t.Fatal("Expected 1 revoked permission, got", len(toRevoke)) + } + + if len(toRevoke[0].Actions) != 1 || *toRevoke[0].Actions[0] != "onlyOldAction" { + t.Fatal("Expected 1 revoked action, got", len(toRevoke)) + } + + if len(toGrant) > 0 { + t.Fatal("Expected no granted permissions, got", len(toGrant)) + } +} + +func TestDiffQuickSightFatTest(t *testing.T) { + oldPerms := []interface{}{ + map[string]interface{}{ + "principal": "principal1", + "actions": schema.NewSet(schema.HashString, []interface{}{ + "action1", + }), + }, + map[string]interface{}{ + "principal": "principal2", + "actions": schema.NewSet(schema.HashString, []interface{}{ + "action1", + "action3", + "action4", + }), + }, + map[string]interface{}{ + "principal": "principal1", + "actions": schema.NewSet(schema.HashString, []interface{}{ + "action2", + }), + }, + map[string]interface{}{ + "principal": "principal3", + "actions": schema.NewSet(schema.HashString, []interface{}{ + "action5", + }), + }, + } + newPerms := []interface{}{ + // Leave action3 untouched, grant action5 and revoke action1 + // and action4 + map[string]interface{}{ + "principal": "principal2", + "actions": schema.NewSet(schema.HashString, []interface{}{ + "action3", + "action5", + }), + }, + // Should span principals, leaving all actions untouched for + // principal1 + map[string]interface{}{ + "principal": "principal1", + "actions": schema.NewSet(schema.HashString, []interface{}{ + "action1", + "action2", + }), + }, + // Don't mention principal3 which means revoke + } + + expected := map[string]map[string]bool{ + "principal2": { + "action1": false, + "action4": false, + "action5": true, + }, + "principal3": { + "action5": false, + }, + "principal1": make(map[string]bool, 0), + } + + lookup := diffQuickSightPermissionsLookup(oldPerms, newPerms) + + if !reflect.DeepEqual(lookup, expected) { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + lookup, + expected) + } +} + func TestCanonicalXML(t *testing.T) { cases := []struct { Name string From e99470e0ec47aa35126b779ed6ca23bbefb77895 Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Mon, 2 Dec 2019 12:14:34 -0500 Subject: [PATCH 17/21] Make acceptance tests mostly pass. --- ...resource_aws_quicksight_data_source.go.swo | Bin 0 -> 57344 bytes ...rce_aws_quicksight_data_source_test.go.swo | Bin 0 -> 20480 bytes aws/provider.go | 1 + aws/resource_aws_quicksight_data_source.go | 123 +++++------ ...esource_aws_quicksight_data_source_test.go | 198 ++++++++++++++++++ 5 files changed, 262 insertions(+), 60 deletions(-) create mode 100644 aws/.resource_aws_quicksight_data_source.go.swo create mode 100644 aws/.resource_aws_quicksight_data_source_test.go.swo create mode 100644 aws/resource_aws_quicksight_data_source_test.go diff --git a/aws/.resource_aws_quicksight_data_source.go.swo b/aws/.resource_aws_quicksight_data_source.go.swo new file mode 100644 index 0000000000000000000000000000000000000000..7370733fea827b1fda2ab24a05288966e9f3ce41 GIT binary patch literal 57344 zcmeI53z!^Lm4Jt*H1ZTsTvlmX5@sOjNeBcSi8y2u7)V0M~<=ycc2H0kN?boC^} z00Oe8fZ&IUqCB$ff}qGQsEZG94WKBEV=>lQT6x z?sd~srS$aN$jtXvyZB7^!p@AfwsR<39v)qlOczEvM@}6ouAkLewo0YcV4*ZJy;v%& z&1S69^wc`LQz%(>VYHOC2KZxO&1g2g+RhFQmj^Pba%w=GN)8pOJ-2ndC4o1+1V+n) z(+}UdZPvjvoudAp#D4KT-nQ&bFP4@7S`uhUpe2Ep1X>bkNuVWxmIPW7cr!_$T->Sc zBfRj|?n__fes2}}-q!v5Z1?-((E07$zt45QcXI>q!r9(E?uGxE(D}Ex=Pma;;YP^2 ze`oi&7tY5+=XY?=XWZ`#L+4}e@zw743!(Eny2owzyMG(?!+ZW)-Qz3W@B2dMcXE%X z-0y>2fqD14m$#klp1&}3-aXvbkNnk=G zkV0V=-FT(w!;JrX`uQJsZEO1j{4e|p9)+L4kKl*!C0GYt@Y*hIZQq0M!fo(T$im?e zgP)?je+jOIvtR`*ffHaF#Njm*=x5<6coOb~8{qSBE?}l;I~B693}!3?9STG;|iUHy$a1Y!Kx4`G&T(Dsk%!hZw-!OJO3g3sD;1U>uC2#=5;HMZmehi!77Pt{E zhYv#mH7k+2JF4bNk!xD&30 zQOLq_NWyOLbMnc9a2MPLUx!Pf43dXV0{;_JpW}<=Y$2b@b;Zl2QEOV8dwA*kqSY0b zkDVU2Mp8*Rupn!fy({bzWW#q=-pXW(~ic`BF1 zTf~|_nooDd*Q&pWRkAlYiNUIu7}#7p6|@En6dYSA3=~jm^xTMnrYm z>R*8bHx7>>@pVKc(>0tWD-(ZRp|pBns8kp&8j+91wooaThpl|dh^Q8#{xyzL9%I3; zlyasplFH_dh;OkH9!Y(;kRPye)PmWxZQ;l_tfSpvuBcV;7H0FoQddz7wa|68)^)5~ zngb0)qL?bBMl8GrZ6~hMEV%ihYGq$ptLoZu8g3+Y z!=qzaJBmj9DvD=R5t&;UDUOzRSZF@(gC+HkoOeQN2)A$YzOBY0)u}YPl7VpdkRDxKKm7}ifihHim z-RtZV#1Xnr9HD#YGxa$h(&{n^cUe*TyLE3+m&pxFtd!H)t@8xAOfH{WvKk3rUB(S1 zt2|oDNA%1F>5|ubt@e(%*WdHHbaBMe(H2V>j^x8BdpMgel!~S=d2Vzlo1boHR(B3t zxuR9-)SdstSZ-GZa!j{+k`3J~9_}Dz<4{lbSk|%HDtxPu}$>^f;UN$`|3h#Pyoe5e1)Ks0zzgW*&%m$X=kOSO64G!e{1u)2%P<0mz+chB zUxF9lS@>W0BCLVAuoH+*el{Ef-S9q`4Tr)@=+!U6^YA-(5FUX0Aqz*qp70d9^^;b#OZg3;A?*&PN`H~K;&l^nwXZZCSWi8oPMB6S8wkJ}hd>5sxOBdy?DYpER z&YhaK(mBOWOp~Ix#2UgL;r#4Y?N@JRT3jwvHG6NSqs^%*bzr*M?=I!r{V?LH1_%b_ zA2dUB4|cfUQl;uQp?_Vr`)9127FWM!@++UswZ*u^tIZR{U68k)SHfDuOONKQ(~4G_ z#yl>wc~a$gVKCm?6K|hlcT9`>=ek$)4Rp_)d;GFRO9y&;I(xd8b`SI&zii3edHhL` zS>8969gOF!e7h5Yj`$JrgX5>4?nY9tlPPN^>HtB}n;aa1-c2g&NG7!MxQh`>joV9Gn$brPx%6qRhAEK}6 zPjF%&?LU5iESgyPKJM9Xj-+mU>eRT7f*eG`P6s4bB}C_8$#%msL*BPagQ>K&;S7>6 zMka_4OjEHcrSdd9JfMH2c@s2pI9U36Dz|-JQl+qvZO#m;oOJ` zdG;ag=6xfn(*{bMms=?}vk&nyPOMrSlS|iS%M?Q==8lmhJ|{la$k!F;ojevZ0u(85 zlW~uf4%HaRIX46mMl7adTQ_qxTqDGEo!~!Mr9^+CtX?mo>I&5?ZndULfl4PgwY)@I zjAEvY{E}*w!goyg6@rf)g8^ON=GNX?4E@T&9+B1}MKN#(s(tfDNmIuHUU_r%N|Tf7jQI_y=Z{~y zkD-`Xsn4B3v?fYvUoll$UA2gY&NiP^5_*%#B>MkeXj_NMxGnns*{2 zr@&FLJ8TCpqVwMc*TZR$1F;3nggxL1Yyc0z-S9oQ1-<~MK?)W^61IWgU=O$zu7nXt z!E#stb72<9IR9U;6Z{(Pg3IA7SO$l|_V5>M1kb}$@F@Hcu7!(X1Dpgi;UD06Yz9Ap zjqn)|yTWof9Nq%2U@LeUz6V!B5i;;0I38py|4`TiUd2Z6H2eszgpa{VAU1@ZVJr9@ zHiJ9h8YsgsEQ9H=D?Ems;3x0{xD~zzSHK1k+k)5=X2SOHJT`+n;aV7lEG!3^bFec! ziVfibxD7rF>tG(d7i1iNf7l0N@Eg+o0k{>efD*_UzT}5PAoAn1_|AXzY^UnVM4FaK zY*BjjeuB;FQKn-HMi*fs-2yF;3=CkKf691LR5N z|3XvP%9mqv%2B;@8MSafE%%pkaDN$D-^!9>_7iJmNw+9gxPowe%+2>ms+3I)WLAxT zMOo=OqT;Uy@Hf-pL{}#9ePJurF){51`-Q2{*xcFbs#mL9horhkpMc`~bcKH^FuA zIS^aG$#5(<>ksh#TXg&%zzwhwJ_#0xufbj*Hh{m8_J4$D;UV}MTn@6vLKY-%%z?^} zS8ledbJgr4%Up`$y?RYiMS$4E#k12ctdTOX|3n(#7HWi9mHloFqq9* z1Gxf24R}=rguaEgZL^F>>O7%;1u}|pxT<*sap>G>P$(jQkPZ>ydvAb z!Az?GDK}qbXlX^&7dkoWRThbKZq&wK$D6Z&xSh|InRl6cf~WnUSz~l|#+MFT@k}8- zI)ZTI=}zHFCX=ppUgvcEE09RW z;To0a+o4P75bnZc7&gy2=YY)fw_yZw&<9Ik57-`_!WJO@0{6h(a2tHRs6J!m5-@zuh3_cI5;dod8$HBYc59FEuf~!F61(Jup0OR#> zd@L7HK`1vnDHw(yj_W7vm~lIT9+f@Vcs-~2fR`OU<UHnisPrSNQw!I5zh6_M9j@94izl`h zK-k}0+~R$sQG<zf}bL*YK&S=JQC&9kPKAFml9q(#mR`F zm&V?=7jxbrN-!LbluaN7P5<{TE$Kq8@uBqcq~LuU(umCYvTjMFc|o`C6}<>8KRIRO zuV4p0Ayb#q*<#8Zg7o7R>$6;+XD@_fm~t5m!PNxiDc&j^Dhq5-QK)#d4qZoImx*dg zPfYx>n{sB-7$alqfpwP)saasdOBO`sOD$C6t#pB9#>z<6wmp5cvHY*aVPpfpXd@0j z&E*Pi(2|vO2}qZ-`ZeUN@hYK|MR`;+82sWTkuf4%BW4raA0P2%NSIM;FdOg=wQ>Td zD{60!Mdb$$Ygrm{^s@vP_)`~jOtl2{uYg#M!;>fCI(CD}%ae6fp2>^Y>o|@}#*)w2 zGo?4XqLnM@2sgj%S7lB4#>kbT|G$93wo&vp^ndzq&gXh`{PWksF zX}AQA1zF>72Y4J^{s!0p;@dCt|79&dSp(o-VIy1tm&1{;H|zy_!tc@B{|#;c8RMS; ze?nh>5q=Ni%P-^kvK~MlMnKl@dmn5M+rl<*9eVnia0VO*?}VKo20OsR=;$}VIq(rU z6XwCz@FKeSH{ljo3o?d38)W|fBIt!j(Wloy4rFY82$q42&mRC&;hnG-$eMfiqfeg) zr@?9%h83_iyoL__HxT_g4?XY!I1r z71T|c7--B5bW~Gc%VuI^F{$-ok+wU%(wrCW%nz4JN~%Srp4STo9kHp4t3EcKvFvmy zyNX5d;wSjaro<)AaW^Wuvt~O})w|-(%=}EUH-qvbs;ioh&JS;{w4?LO6leYJy)2=E zO7G3)*0E>$zVuhS4GTlyO4DxOm>%dm%FNNC^Jo#2sO8BX^&Xaf;$pv(X}6nJikesU znkI{CY1M$xWKMrWf^yV-_d(7g0xFLoTPEis7iNbf7rUz_^sne%vS?+sbedv|Svi$s z`I*f6_)sBlF`Hkdl1iYgjqQWX)=o-IGpDa|Y;GZAdDD0o70UBjCMYxSw6x`{P$^3p zIMeuJ&b)OawnR|O6<+pYj)=3^4oX;liB&GGmkHj4UT~f%uft?^o^Iw76@U{;1HqW( z#>}KL30|4j2UCo9WukJbjq!cd?vQ9mJk+1ER)V(hBt03(f<&XXW5+>DnXkfRiG>Dk zQVR#Uw>WdvqF*i~p!#pd8gy74vUz5(7g+X_p@N89Hujh7%`*{Rh1<-F8n-E1iz^}u zrY`SvHAk&>UFZ?BSus*8I7y>2NboW*udx0?@PtvZde=A+2wtUXiK>-EyVQSl4sFR5 zYZ;7@+zADyb;{2<{sK&74Kj55p$E!xLP-|xV^uEJ_h5}CS%b;X`Oa1IBmhiLPKd$y z1lCZftcs2wEn_pKp^!Y&&BXy^nHIT{ zM|t9*me;L}e!a!+Vj^B`HO}T(S($5$#@LctoU2a!)dQ4aw}ZrUx(QU_Ql|YiZ>HG( zk~Y3A-C4~=?vUhmpJi4ADkG(3MX~BFwA;=gYE{n%Q->8s+(dBN$*_%HmXKiy2QLol zuWAdah}}MV`4nZuk3QEx2B^9aiL7Z-B~(8HD(Sf~Uy5awXo`V#J~r8fsiMwsvbso> ze!{IQCjS_8`gRJ}9`t2J7jV3yC=52pnlZ2!RmWGdwjILgh5s(bwVS zQ^lf{&$ua@G|sU~ir*=c6n9(im~=24+h(BWrLU#BcG~rR!wOn4ySrN%8)Zz2wTx2v zj8gri!yFZoXPYD(Zv{Ipb=U9EH-sxHFDi@u7jc?ceS>#_+*m!mdH2Sa-_Z%KpC}n@ z1m8Fo>oHfv@t&+NoED$qW-N(~J20oC8d$N1_DxoFBFe#qIy$7Lo#BjQNQ%1}NLdCY z%*s~GYtn|f86r@(x~>GoTDL`ueGdbDlY|ktNDeqzS>Gpz%;)NG8pz@LVkdj+Q1uDj zt^|rT)t0-erwE@4(fiAZp7D1Bu`t4NqG8_cmod@*r=vXnOg5@R|L0HVb0zxz$=Rz0!5uN@C<2; z><90Lcfl{v>t${I&%q+t0d7ZszZGtQuY>sCi>}`VqUTH6{8ZAXnGcm7i^Q5vMLHWA zT}quJ>G&z99^=qlbw52EN>407b~N37+%j79ix?%14|K1psd3Z zX;jknMXlzo_pQm*6ZhDHGGs22b~g>EEA*&X^|<%Dl2@1L+07Fv{fOv{TM8^(KOVvl zhcY&~heHX9+?-23fzl2|V*CUx^NxE~ZFW9iSP{+`g-TD7>n9(C~ss=K(631rGe|{Ht}-zqfuMhfem@;)(FmqI7UUV zg6({cmfd{ZY-VnlGm)U)U$pwZH52*Twc;0+ zK~-a?ZIvBcr#6!)dpuUo_pC*c3Ya+^tBP2d68dtkVdf%hyyms#Pn%?H#~9@dAexr3 z4ye~-TZBs>9+!_6Rj?#UeeemD`ffyc1{ zJO;9EUj{m1SJ(;O3NkN$6I=tIfTN%rWZb{1Z2*0}D3woz_qrOllS)wyd>eVj9Sd=W z4aG=TE*#B*-Q|w>`?1V1Sf-9GvDOw=Tk4=Q66Ibtjj28AoMQ#d4h}|U%%v*O?tDgF z++JX9W-;kGe(CvAYF*eg$hm?9$zFhw=QvCd{O>$hmJgphEbEL1N{cd3W|BCpMxC8d z!(+hU@n*3sPT1I9W7+!eXk1T~*v%W+Ggd#BvgRAkJb&H>I^q>8h9{ln&Yh-M=Ha?a zly}wbfL8{Df2}Nku3B|(X>a9;IDrj$MLfcdcQqSh{Wo;IDUE*1*mRYpl>v>dR~!*g zuwTsFQ)dD3iSHR#MrGXOjO|TV%wj4pw+e%ed9&F!l|Kp7R+?c)qk^ z&Rjv)7GAfa>Whe4PrzmoULj>76QD9OwG*LPW1-Xy?5wt^u+B({3X@^wIwceN&Jj_n z`O@B05O-;j2HNeuS;pHgbeGGRkN4mLcd?A*an^d34Pyy^C6KzAux_YFIg5(;-Gf@o zbR=wVF^tAVy*a~+rbuc^+Zb4EK++K-sL{=SeXD0gP*sX}-7+2#lrG|;|L=j$|B5^Q zZ@c>c{pk7P18^p+gb%_B*bjDrZ=>^n18#yF;j6G1I$$bHfw#hM(ED!(*&A>H90%_O zS@-XgFbJo>LTH0m(DnZhUVI1yyt{`MgA_O}L^ zw|^!SLFVc21AD_e;H?mY9pG~80VOyV-Ua^%ccc4ngh4nMX2P$~_hqfVYv5mDIqVC2 z!#m()|?(dH6C1|1#JgBwha!?K_}%*HJre(aO3WGy#X5#O&Mu4D4Y$j1osqxY+RZh_1sp>C$LkQ- zNKI5E&uc6e)1EUDSW-4{m0g1I&|$|)+O z&QW^70I8V#&DW|%W*NV_F54$N9`GRx_=MT1^drONBOJTGBU_bvwJKS$-jX10e#1k{al>V7SzC~GT86#Q zrFyBFQ%7YN?B;VSIVvzrVmhvG>C=~DZdq_AgM{ta}+PP3xgmN6&4_`L__6;w{$ zl74_=GL4DPy{n?f<7w5W@S3skHm+-AlA#^ko1JUgE7#pA)!+BmnK|estF&)26Oh<= z4-d@yGmeMHbJE73O(W8CYOorGr&;NtXSxF9PWeL@@Ai^pD{fx?#u(qF!)6}nC~aDs+_4&U}kCbnY=TB&lnSn)^{am8iQjs zE~-9CCJ~THm{fX!@iBGWc{9l^j($LQ*PH-CuQM=t!wDpCMB2VO6?!1V1}B7UX1UkH z=nWMAP~Re4p&A3IM&0Ul*wrAXaSf{?xx=KY262X11LwKGIjGL-hEHb4IUhsopmpM|*|JAPkztYwJe~ONOEo5K;90$*%&wn322TS2u^!S_M zD{u{L1R3`~0S*As@$ZNG;Cwh4R)Fm77l-H2sDiCfSg+> zJ3P6{u->6|B2+e=kJStICzMBUbK07!71aMq*+6z;f>Y%{$_?ufg*I0%a=vn7c7+ZVhN{;!og$%-lwt4nt_i8O zLT=sTkWhaYwPJP8>u`>!>IL0=mN0{o=Fw@OU-vvw=}O+p6lzfxH&ghd3DH@>KRw0_ zFqz4|ITdxdqvh$_$?mW>_ndgqR&S~Asn=mtfrN%nigwcXP$w~{&Keps(M761Vfe?B z&FhSm6f1mQ!|&z|N$5wsK7HDh^2{HHlB(R`t2eQZm%Q|9)tH;R-hkQn4=EDeHNDz{ z-JF`&Hea49pFBy0D{4AHb7>VSDcC*|33(ZPJSg^xkpW+wcdlc|qGYSg8V;duhHY## zO7#B@bp9WS?#cXr`k&6{4)p!=p$|m=pAWM4-v{7#=>B(ttOIxwYzMNw|Hbe@5dB}q z`RBtt_&;?0d*Ld`!au+-(C@zlYv5GKzyO>KyTFs^`ZBhE0W5-}LDuo#8XiX1zaQ>{ zPeB%B?tcoVKpV(f{eK48$4|!hW$!+3y}v{FEo=2Zi5=h)7zA18Psa1Vh5o-D#2&CM zyo}y2{{BzH6YvN;3=hFM@Ig2bUO@N143@$|I2w)uu?@U{9YFTrlXd4DH)&FLZs~uO{n9+}T4B68AS$exs!^@07Q89ONqR4hzI@9U~m&Lj8(}E1Iqf z{V*n{0@S{K#VoL_OcxGi@Bw#I=lhwrQy|Jbyy@ z&5(>^D63L#R`QE;EO8 z5u`dXN1vir=V(63)pI7zq+0Z!|0YU$(f?bkNuVWxmIPW7Xi1AZmh-DNd+B@6(K+aO8yR+M&yEA(; zv%M>K<>UA`B2kGkQPjlq1Be8OITK?1!}x~=B8Z|fLXbrCh@kN!f?y;@f6sjE%(mUq z9tsg=j^ED5`~AGn`_8=2`;^J^b`A}zjfL|xj#D-5J0E^_{JygWwL3RzTFop@=|)vT zmOR3E-MUlkuGV@lY!~^uFk(;1nCYpQ-c)0;W@+L~Ur%!}Ip5c0hirud8^m!_Qx3UBpUb%bY zDs991UVo^co$XMkpSI(zERnSBsRU99q!LIakV+txKq`S$0;vSvauV?B$7|Qq>bHe0 zKPx;RH}8BxczR0634QVFCINF|U;AeBHWfm8yi1X2m4 z5=bSGO5hEUfL_wH3r^Ow$3XV~qxJubYc%Zz_yhb7o`7G$m*FZn2iC!f@SD||_HB3o z?gtl!;XQD46+Q)U1a5(ya6Y_pil#jcPrw(!f^{JExCzE#7mPwToC+_Tq-lSG=in&( z7M_8x!vPqCGvH{3I>Uo-2n^_g)sTTl-l=I{gHOPja0a~e4o&+j{1JW+&%#ltz$I`p zXz=LUHSJ+|2&!-;Tn-KwHrpj*H1x+9vAsdNVU@P*D;jmrw5=|c&F0m9 z$u%$84&b0M=DThTmHHIk8-+2?F|A5YJU60%e3wM+-|O}li{$3bi%O~}V8D+$(WR)D z+N7woRTwbbqGL`PaZ$N-i5f2q9bio8>3!N>r@u<#tbS4H#zS*$Cc1EH zW1dlW`_%67s26-`%2NsTD-uq0%|hDCCYTW=?`XCqYmTsX&4)n@BW$L`@D+*|X&f~O z&3Snx{nxA=FBiR9HL4Q>3F?ZN?bn`4yCeYq^Y zVFY$dXck5BWwNpqi9sa^mw0y-N=8|4RK2X0nbDoZ8#Vcz5%*Q_@{#88(rVM66Qx)S zJ$e1Oe9Ke{+vQ8df8{Jt{vi~|@%*>bPQx+Fvq{}g1p3`2J=Po;qluP=p;2duCN&i) z9BhjYq$rPm&vQl%(c8E~rKP?iBqO!V34CM8NE5$TrZagNj@6kYymHQY4OxkIttoHH zmJEkVz4`x}!Q2~;=H55|aPD2%=oHOdVUmQJzX1b!Qg_W_Zoyb)9A^`b<9r~Cdw927 zn(nUHJ+9%*m_?%}em^qDED_&N?pUuHDa#a^%w|e=r_7@5)RQjj)kej%q$cshc^SV- zvMHllH=L%c`!OXBXL!HD;VdZmFr>4Z=}&nor)hP)IIXigwZ9HyuoXr?!HcZmcpv-=d&G+n*(x64`UuP&QbIHI(d%B7>v^7R|$>xffq7EmUgSm{oFYQfqf_ z7~jK_pm2GzM5VOIDiGL0npK~$C$GWomQ~qEx5b$6OL8$Wx5I|)HPt9SYQ1;oxC`p0-4p~mdZm>JJ zQ?E9R+)Sb0vGPpT{_fT%ewwHI0&-tzXC3T z_rrVPbXWtc;1u`?Yy5j)4_pdsU^P6$I$rkv?|@x!A;|v!ORU)+g_~gzE`<&_6W$G{ z!KttYKF1o}1o2ZiH(alaFTmg63vdg_THOT)J_zT-3GielSc~7w`CBjx`=AV0z;+me zEc}u+_2cj}xF7C=ufkX0OK>M_1MwG-HTQ#XFWe1x!DX-!I$<5Gg{P705jX?~;bJ%s zy1-SljmXt~$l|U+iW0pYpaUq|`sjHCq4WzC@sjE=r#+JGY@jq-@jx*V^K1(wh zRs+p-NYed9%rD{6AzB;uACuqRBH!JqtB}7yUEnQ|x(dZszc;^c!Ah(nsjE=akEky+ tYyB@>g(}!8^=kj<$b5$&tSA@&vax+^o+FR%F@(bq*0r9%3o`WV`43|0k1+rM literal 0 HcmV?d00001 diff --git a/aws/provider.go b/aws/provider.go index 24ebb463bb04..3ada4804fc75 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -659,6 +659,7 @@ func Provider() terraform.ResourceProvider { "aws_placement_group": resourceAwsPlacementGroup(), "aws_proxy_protocol_policy": resourceAwsProxyProtocolPolicy(), "aws_qldb_ledger": resourceAwsQLDBLedger(), + "aws_quicksight_data_source": resourceAwsQuickSightDataSource(), "aws_quicksight_group": resourceAwsQuickSightGroup(), "aws_quicksight_user": resourceAwsQuickSightUser(), "aws_ram_principal_association": resourceAwsRamPrincipalAssociation(), diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index f165582d9430..c8ddeff4f824 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -66,7 +66,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { }, }, - "id": { + "data_source_id": { Type: schema.TypeString, Required: true, ForceNew: true, @@ -531,7 +531,7 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac conn := meta.(*AWSClient).quicksightconn awsAccountId := meta.(*AWSClient).accountid - id := d.Get("id").(string) + id := d.Get("data_source_id").(string) if v, ok := d.GetOk("aws_account_id"); ok { awsAccountId = v.(string) @@ -540,6 +540,7 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac params := &quicksight.CreateDataSourceInput{ AwsAccountId: aws.String(awsAccountId), DataSourceId: aws.String(id), + Name: aws.String(d.Get("name").(string)), } if credentials := resourceAwsQuickSightDataSourceCredentials(d); credentials != nil { @@ -552,10 +553,10 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac d.Set("type", dataSourceType) } - if v := d.Get("permission"); v != nil { + if v := d.Get("permission"); v != nil && len(v.([]interface{})) != 0 { params.Permissions = make([]*quicksight.ResourcePermission, 0) - for _, v := range v.(*schema.Set).List() { + for _, v := range v.([]interface{}) { permissionResource := v.(map[string]interface{}) permission := &quicksight.ResourcePermission{ Actions: expandStringSet(permissionResource["actions"].(*schema.Set)), @@ -604,7 +605,7 @@ func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{ var dataSourceResp *quicksight.DescribeDataSourceOutput err = resource.Retry(5*time.Minute, func() *resource.RetryError { var err error - dataSourceResp, err := conn.DescribeDataSource(descOpts) + dataSourceResp, err = conn.DescribeDataSource(descOpts) if dataSourceResp != nil && dataSourceResp.DataSource != nil { status := aws.StringValue(dataSourceResp.DataSource.Status) @@ -645,7 +646,8 @@ func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{ dataSource := dataSourceResp.DataSource d.Set("arn", dataSource.Arn) - d.Set("id", dataSource.DataSourceId) + d.Set("name", dataSource.Name) + d.Set("data_source_id", dataSource.DataSourceId) d.Set("aws_account_id", awsAccountId) if err := d.Set("permission", flattenQuickSightPermissions(permsResp.Permissions)); err != nil { @@ -849,8 +851,8 @@ func resourceAwsQuickSightDataSourceUpdate(d *schema.ResourceData, meta interfac if d.HasChange("permission") { oraw, nraw := d.GetChange("permission") - o := oraw.(*schema.Set).List() - n := nraw.(*schema.Set).List() + o := oraw.([]interface{}) + n := nraw.([]interface{}) toGrant, toRevoke := diffQuickSightPermissionsToGrantAndRevoke(o, n) if len(toGrant) > 0 || len(toRevoke) > 0 { @@ -941,11 +943,11 @@ func resourceAwsQuickSightDataSourceDelete(d *schema.ResourceData, meta interfac func resourceAwsQuickSightDataSourceCredentials(d *schema.ResourceData) *quicksight.DataSourceCredentials { if v := d.Get("credentials"); v != nil { - for _, v := range v.(*schema.Set).List() { + for _, v := range v.([]interface{}) { credentials := v.(map[string]interface{}) - if v := credentials["credential_pair"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := credentials["credential_pair"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { credentialPairResource := v.(map[string]interface{}) credentialPair := &quicksight.CredentialPair{} @@ -970,13 +972,13 @@ func resourceAwsQuickSightDataSourceCredentials(d *schema.ResourceData) *quicksi func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, *quicksight.DataSourceParameters) { if v := d.Get("parameters"); v != nil { - for _, v := range v.(*schema.Set).List() { + for _, v := range v.([]interface{}) { dataSourceParams := v.(map[string]interface{}) dataSourceParamsResource := &quicksight.DataSourceParameters{} dataSourceType := "" - if v := dataSourceParams["amazon_elasticsearch"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["amazon_elasticsearch"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypeAmazonElasticsearch dataSourceParamsResource.AmazonElasticsearchParameters = &quicksight.AmazonElasticsearchParameters{ @@ -985,8 +987,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["athena"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["athena"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) ps := &quicksight.AthenaParameters{} @@ -999,8 +1001,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["aurora"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["aurora"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypeAurora dataSourceParamsResource.AuroraParameters = &quicksight.AuroraParameters{ @@ -1011,8 +1013,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["aurora_postgre_sql"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["aurora_postgre_sql"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypeAuroraPostgresql dataSourceParamsResource.AuroraPostgreSqlParameters = &quicksight.AuroraPostgreSqlParameters{ @@ -1023,8 +1025,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["aws_iot_analytics"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["aws_iot_analytics"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypeAwsIotAnalytics dataSourceParamsResource.AwsIotAnalyticsParameters = &quicksight.AwsIotAnalyticsParameters{ @@ -1033,8 +1035,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["jira"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["jira"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypeJira @@ -1044,8 +1046,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["maria_db"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["maria_db"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypeMariadb @@ -1057,8 +1059,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["mysql"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["mysql"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypeMysql @@ -1070,8 +1072,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["postgresql"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["postgresql"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypePostgresql dataSourceParamsResource.PostgreSqlParameters = &quicksight.PostgreSqlParameters{ @@ -1082,8 +1084,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["presto"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["presto"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypePresto dataSourceParamsResource.PrestoParameters = &quicksight.PrestoParameters{ @@ -1094,8 +1096,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["redshift"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["redshift"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) ps := &quicksight.RedshiftParameters{ Database: aws.String(psResource["database"].(string)), @@ -1118,25 +1120,26 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["s3"]; v != nil && v.(*schema.Set) != nil { - s3 := v.(map[string]interface{}) - - if v := s3["manifest_file_location"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { - psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypeS3 - dataSourceParamsResource.S3Parameters = &quicksight.S3Parameters{ - ManifestFileLocation: &quicksight.ManifestFileLocation{ - Bucket: aws.String(psResource["bucket"].(string)), - Key: aws.String(psResource["key"].(string)), - }, + if v := dataSourceParams["s3"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { + s3 := v.(map[string]interface{}) + if v := s3["manifest_file_location"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { + psResource := v.(map[string]interface{}) + dataSourceType = quicksight.DataSourceTypeS3 + dataSourceParamsResource.S3Parameters = &quicksight.S3Parameters{ + ManifestFileLocation: &quicksight.ManifestFileLocation{ + Bucket: aws.String(psResource["bucket"].(string)), + Key: aws.String(psResource["key"].(string)), + }, + } } } } } - if v := dataSourceParams["service_now"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["service_now"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypeServicenow dataSourceParamsResource.ServiceNowParameters = &quicksight.ServiceNowParameters{ @@ -1145,8 +1148,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["snowflake"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["snowflake"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypeSnowflake dataSourceParamsResource.SnowflakeParameters = &quicksight.SnowflakeParameters{ @@ -1157,8 +1160,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["spark"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["spark"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypeSpark dataSourceParamsResource.SparkParameters = &quicksight.SparkParameters{ @@ -1168,8 +1171,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["sql_server"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["sql_server"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypeSqlserver dataSourceParamsResource.SqlServerParameters = &quicksight.SqlServerParameters{ @@ -1180,8 +1183,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["teradata"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["teradata"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypeTeradata dataSourceParamsResource.TeradataParameters = &quicksight.TeradataParameters{ @@ -1192,8 +1195,8 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["twitter"]; v != nil && v.(*schema.Set) != nil { - for _, v := range (v.(*schema.Set)).List() { + if v := dataSourceParams["twitter"]; v != nil && v.([]interface{}) != nil { + for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) dataSourceType = quicksight.DataSourceTypeTwitter dataSourceParamsResource.TwitterParameters = &quicksight.TwitterParameters{ @@ -1212,7 +1215,7 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, func resourceAwsQuickSightDataSourceSslProperties(d *schema.ResourceData) *quicksight.SslProperties { if v := d.Get("ssl_properties"); v != nil { - for _, v := range v.(*schema.Set).List() { + for _, v := range v.([]interface{}) { sslProperties := v.(map[string]interface{}) if v, present := sslProperties["disable_ssl"]; present { @@ -1228,7 +1231,7 @@ func resourceAwsQuickSightDataSourceSslProperties(d *schema.ResourceData) *quick func resourceAwsQuickSightDataSourceVpcConnectionProperties(d *schema.ResourceData) *quicksight.VpcConnectionProperties { if v := d.Get("vpc_connection_properties"); v != nil { - for _, v := range v.(*schema.Set).List() { + for _, v := range v.([]interface{}) { vpcConnectionProperties := v.(map[string]interface{}) if v := vpcConnectionProperties["vpc_connection_arn"]; v != nil && v.(string) != "" { diff --git a/aws/resource_aws_quicksight_data_source_test.go b/aws/resource_aws_quicksight_data_source_test.go new file mode 100644 index 000000000000..34d0f385b057 --- /dev/null +++ b/aws/resource_aws_quicksight_data_source_test.go @@ -0,0 +1,198 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/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 TestAccAWSQuickSightDataSource_basic(t *testing.T) { + var dataSource quicksight.DataSource + resourceName := "aws_quicksight_data_source.default" + rName1 := acctest.RandomWithPrefix("tf-acc-test") + rId1 := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckQuickSightDataSourceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSQuickSightDataSourceConfig(rId1, rName1), + Check: resource.ComposeTestCheckFunc( + testAccCheckQuickSightDataSourceExists(resourceName, &dataSource), + resource.TestCheckResourceAttr(resourceName, "data_source_id", fmt.Sprintf(rId1)), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "quicksight", fmt.Sprintf("datasource/%s", rId1)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSQuickSightDataSource_disappears(t *testing.T) { + var dataSource quicksight.DataSource + resourceName := "aws_quicksight_data_source.default" + rName := acctest.RandomWithPrefix("tf-acc-test") + rId := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckQuickSightDataSourceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSQuickSightDataSourceConfig(rId, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckQuickSightDataSourceExists(resourceName, &dataSource), + testAccCheckQuickSightDataSourceDisappears(&dataSource), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckQuickSightDataSourceExists(resourceName string, dataSource *quicksight.DataSource) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + awsAccountID, dataSourceId, err := resourceAwsQuickSightDataSourceParseID(rs.Primary.ID) + if err != nil { + return err + } + + conn := testAccProvider.Meta().(*AWSClient).quicksightconn + + input := &quicksight.DescribeDataSourceInput{ + AwsAccountId: aws.String(awsAccountID), + DataSourceId: aws.String(dataSourceId), + } + + output, err := conn.DescribeDataSource(input) + + if err != nil { + return err + } + + if output == nil || output.DataSource == nil { + return fmt.Errorf("QuickSight Data Source (%s) not found", rs.Primary.ID) + } + + *dataSource = *output.DataSource + + return nil + } +} + +func testAccCheckQuickSightDataSourceDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).quicksightconn + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_quicksight_data_source" { + continue + } + + awsAccountID, dataSourceId, err := resourceAwsQuickSightDataSourceParseID(rs.Primary.ID) + if err != nil { + return err + } + + _, err = conn.DescribeDataSource(&quicksight.DescribeDataSourceInput{ + AwsAccountId: aws.String(awsAccountID), + DataSourceId: aws.String(dataSourceId), + }) + if isAWSErr(err, quicksight.ErrCodeResourceNotFoundException, "") { + continue + } + + if err != nil { + return err + } + + return fmt.Errorf("QuickSight Data Source '%s' was not deleted properly", rs.Primary.ID) + } + + return nil +} + +func testAccCheckQuickSightDataSourceDisappears(v *quicksight.DataSource) 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 + } + + input := &quicksight.DeleteDataSourceInput{ + AwsAccountId: aws.String(arn.AccountID), + DataSourceId: v.DataSourceId, + } + + if _, err := conn.DeleteDataSource(input); err != nil { + return err + } + + return nil + } +} + +func testAccAWSQuickSightDataSourceConfig(rId string, rName string) string { + manifestKey := acctest.RandomWithPrefix("tf-acc-test") + + return fmt.Sprintf(` +resource "aws_quicksight_data_source" "default" { + data_source_id = %[1]q + name = %[2]q + + parameters { + s3 { + manifest_file_location { + bucket = aws_s3_bucket.bucket.bucket + key = aws_s3_bucket_object.manifest.key + } + } + } +} + +resource "aws_s3_bucket" "bucket" { + acl = "public-read" +} + +resource "aws_s3_bucket_object" "manifest" { + bucket = aws_s3_bucket.bucket.bucket + key = %[3]q + content = < Date: Mon, 2 Dec 2019 14:26:27 -0500 Subject: [PATCH 18/21] Make tests pass. --- ...resource_aws_quicksight_data_source.go.swo | Bin 57344 -> 0 bytes ...rce_aws_quicksight_data_source_test.go.swo | Bin 20480 -> 0 bytes aws/resource_aws_quicksight_data_source.go | 305 +++++++++++------- 3 files changed, 183 insertions(+), 122 deletions(-) delete mode 100644 aws/.resource_aws_quicksight_data_source.go.swo delete mode 100644 aws/.resource_aws_quicksight_data_source_test.go.swo diff --git a/aws/.resource_aws_quicksight_data_source.go.swo b/aws/.resource_aws_quicksight_data_source.go.swo deleted file mode 100644 index 7370733fea827b1fda2ab24a05288966e9f3ce41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57344 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 diff --git a/aws/resource_aws_quicksight_data_source.go b/aws/resource_aws_quicksight_data_source.go index c8ddeff4f824..1b4377aa4d9a 100644 --- a/aws/resource_aws_quicksight_data_source.go +++ b/aws/resource_aws_quicksight_data_source.go @@ -137,7 +137,7 @@ func resourceAwsQuickSightDataSource() *schema.Resource { }, }, }, - "aurora_postgre_sql": { + "aurora_postgresql": { Type: schema.TypeList, Optional: true, MaxItems: 1, @@ -550,7 +550,6 @@ func resourceAwsQuickSightDataSourceCreate(d *schema.ResourceData, meta interfac if dataSourceType, dataSourceParameters := resourceAwsQuickSightDataSourceParameters(d); dataSourceParameters != nil { params.Type = dataSourceType params.DataSourceParameters = dataSourceParameters - d.Set("type", dataSourceType) } if v := d.Get("permission"); v != nil && len(v.([]interface{})) != 0 { @@ -654,176 +653,220 @@ func resourceAwsQuickSightDataSourceRead(d *schema.ResourceData, meta interface{ return fmt.Errorf("Error setting permission error: %#v", err) } + params := map[string]interface{}{} + if dataSource.DataSourceParameters.AmazonElasticsearchParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "amazon_elasticsearch": { - "domain": dataSource.DataSourceParameters.AmazonElasticsearchParameters.Domain, + params = map[string]interface{}{ + "amazon_elasticsearch": []interface{}{ + map[string]interface{}{ + "domain": dataSource.DataSourceParameters.AmazonElasticsearchParameters.Domain, + }, }, - }) + } } if dataSource.DataSourceParameters.AthenaParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "athena": { - "work_group": dataSource.DataSourceParameters.AthenaParameters.WorkGroup, + params = map[string]interface{}{ + "athena": []interface{}{ + map[string]interface{}{ + "work_group": dataSource.DataSourceParameters.AthenaParameters.WorkGroup, + }, }, - }) + } } if dataSource.DataSourceParameters.AuroraParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "aurora": { - "database": dataSource.DataSourceParameters.AuroraParameters.Database, - "host": dataSource.DataSourceParameters.AuroraParameters.Host, - "port": dataSource.DataSourceParameters.AuroraParameters.Port, + params = map[string]interface{}{ + "aurora": []interface{}{ + map[string]interface{}{ + "database": dataSource.DataSourceParameters.AuroraParameters.Database, + "host": dataSource.DataSourceParameters.AuroraParameters.Host, + "port": dataSource.DataSourceParameters.AuroraParameters.Port, + }, }, - }) + } } if dataSource.DataSourceParameters.AuroraPostgreSqlParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "aurora_postgre_sql": { - "database": dataSource.DataSourceParameters.AuroraPostgreSqlParameters.Database, - "host": dataSource.DataSourceParameters.AuroraPostgreSqlParameters.Host, - "port": dataSource.DataSourceParameters.AuroraPostgreSqlParameters.Port, + params = map[string]interface{}{ + "aurora_postgresql": []interface{}{ + map[string]interface{}{ + "database": dataSource.DataSourceParameters.AuroraPostgreSqlParameters.Database, + "host": dataSource.DataSourceParameters.AuroraPostgreSqlParameters.Host, + "port": dataSource.DataSourceParameters.AuroraPostgreSqlParameters.Port, + }, }, - }) + } } if dataSource.DataSourceParameters.AwsIotAnalyticsParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "aws_iot_analytics": { - "data_set_name": dataSource.DataSourceParameters.AwsIotAnalyticsParameters.DataSetName, + params = map[string]interface{}{ + "aws_iot_analytics": []interface{}{ + map[string]interface{}{ + "data_set_name": dataSource.DataSourceParameters.AwsIotAnalyticsParameters.DataSetName, + }, }, - }) + } } if dataSource.DataSourceParameters.JiraParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "jira": { - "site_base_url": dataSource.DataSourceParameters.JiraParameters.SiteBaseUrl, + params = map[string]interface{}{ + "jira": []interface{}{ + map[string]interface{}{ + "site_base_url": dataSource.DataSourceParameters.JiraParameters.SiteBaseUrl, + }, }, - }) + } } if dataSource.DataSourceParameters.MariaDbParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "maria_db": { - "database": dataSource.DataSourceParameters.MariaDbParameters.Database, - "host": dataSource.DataSourceParameters.MariaDbParameters.Host, - "port": dataSource.DataSourceParameters.MariaDbParameters.Port, + params = map[string]interface{}{ + "maria_db": []interface{}{ + map[string]interface{}{ + "database": dataSource.DataSourceParameters.MariaDbParameters.Database, + "host": dataSource.DataSourceParameters.MariaDbParameters.Host, + "port": dataSource.DataSourceParameters.MariaDbParameters.Port, + }, }, - }) + } } if dataSource.DataSourceParameters.MySqlParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "mysql": { - "database": dataSource.DataSourceParameters.MySqlParameters.Database, - "host": dataSource.DataSourceParameters.MySqlParameters.Host, - "port": dataSource.DataSourceParameters.MySqlParameters.Port, + params = map[string]interface{}{ + "mysql": []interface{}{ + map[string]interface{}{ + "database": dataSource.DataSourceParameters.MySqlParameters.Database, + "host": dataSource.DataSourceParameters.MySqlParameters.Host, + "port": dataSource.DataSourceParameters.MySqlParameters.Port, + }, }, - }) + } } if dataSource.DataSourceParameters.PostgreSqlParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "postgresql": { - "database": dataSource.DataSourceParameters.PostgreSqlParameters.Database, - "host": dataSource.DataSourceParameters.PostgreSqlParameters.Host, - "port": dataSource.DataSourceParameters.PostgreSqlParameters.Port, + params = map[string]interface{}{ + "postgresql": []interface{}{ + map[string]interface{}{ + "database": dataSource.DataSourceParameters.PostgreSqlParameters.Database, + "host": dataSource.DataSourceParameters.PostgreSqlParameters.Host, + "port": dataSource.DataSourceParameters.PostgreSqlParameters.Port, + }, }, - }) + } } if dataSource.DataSourceParameters.PrestoParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "presto": { - "catalog": dataSource.DataSourceParameters.PrestoParameters.Catalog, - "host": dataSource.DataSourceParameters.PrestoParameters.Host, - "port": dataSource.DataSourceParameters.PrestoParameters.Port, + params = map[string]interface{}{ + "presto": []interface{}{ + map[string]interface{}{ + "catalog": dataSource.DataSourceParameters.PrestoParameters.Catalog, + "host": dataSource.DataSourceParameters.PrestoParameters.Host, + "port": dataSource.DataSourceParameters.PrestoParameters.Port, + }, }, - }) + } } if dataSource.DataSourceParameters.RedshiftParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "redshift": { - "cluster_id": dataSource.DataSourceParameters.RedshiftParameters.ClusterId, - "database": dataSource.DataSourceParameters.RedshiftParameters.Database, - "host": dataSource.DataSourceParameters.RedshiftParameters.Host, - "port": dataSource.DataSourceParameters.RedshiftParameters.Port, + params = map[string]interface{}{ + "redshift": []interface{}{ + map[string]interface{}{ + "cluster_id": dataSource.DataSourceParameters.RedshiftParameters.ClusterId, + "database": dataSource.DataSourceParameters.RedshiftParameters.Database, + "host": dataSource.DataSourceParameters.RedshiftParameters.Host, + "port": dataSource.DataSourceParameters.RedshiftParameters.Port, + }, }, - }) + } } if dataSource.DataSourceParameters.S3Parameters != nil { - d.Set("parameters", map[string]map[string]map[string]interface{}{ - "s3": { - "manifest_file_location": { - "bucket": dataSource.DataSourceParameters.S3Parameters.ManifestFileLocation.Bucket, - "key": dataSource.DataSourceParameters.S3Parameters.ManifestFileLocation.Key, + params = map[string]interface{}{ + "s3": []interface{}{ + map[string]interface{}{ + "manifest_file_location": []interface{}{ + map[string]interface{}{ + "bucket": dataSource.DataSourceParameters.S3Parameters.ManifestFileLocation.Bucket, + "key": dataSource.DataSourceParameters.S3Parameters.ManifestFileLocation.Key, + }, + }, }, }, - }) + } } if dataSource.DataSourceParameters.ServiceNowParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "service_now": { - "site_base_url": dataSource.DataSourceParameters.ServiceNowParameters.SiteBaseUrl, + params = map[string]interface{}{ + "service_now": []interface{}{ + map[string]interface{}{ + "site_base_url": dataSource.DataSourceParameters.ServiceNowParameters.SiteBaseUrl, + }, }, - }) + } } if dataSource.DataSourceParameters.SnowflakeParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "snowflake": { - "database": dataSource.DataSourceParameters.SnowflakeParameters.Database, - "host": dataSource.DataSourceParameters.SnowflakeParameters.Host, - "warehouse": dataSource.DataSourceParameters.SnowflakeParameters.Warehouse, + params = map[string]interface{}{ + "snowflake": []interface{}{ + map[string]interface{}{ + "database": dataSource.DataSourceParameters.SnowflakeParameters.Database, + "host": dataSource.DataSourceParameters.SnowflakeParameters.Host, + "warehouse": dataSource.DataSourceParameters.SnowflakeParameters.Warehouse, + }, }, - }) + } } if dataSource.DataSourceParameters.SparkParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "spark": { - "host": dataSource.DataSourceParameters.SparkParameters.Host, - "port": dataSource.DataSourceParameters.SparkParameters.Port, + params = map[string]interface{}{ + "spark": []interface{}{ + map[string]interface{}{ + "host": dataSource.DataSourceParameters.SparkParameters.Host, + "port": dataSource.DataSourceParameters.SparkParameters.Port, + }, }, - }) + } } if dataSource.DataSourceParameters.SqlServerParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "sql_server": { - "database": dataSource.DataSourceParameters.SqlServerParameters.Database, - "host": dataSource.DataSourceParameters.SqlServerParameters.Host, - "port": dataSource.DataSourceParameters.SqlServerParameters.Port, + params = map[string]interface{}{ + "sql_server": []interface{}{ + map[string]interface{}{ + "database": dataSource.DataSourceParameters.SqlServerParameters.Database, + "host": dataSource.DataSourceParameters.SqlServerParameters.Host, + "port": dataSource.DataSourceParameters.SqlServerParameters.Port, + }, }, - }) + } } if dataSource.DataSourceParameters.TeradataParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "teradata": { - "database": dataSource.DataSourceParameters.TeradataParameters.Database, - "host": dataSource.DataSourceParameters.TeradataParameters.Host, - "port": dataSource.DataSourceParameters.TeradataParameters.Port, + params = map[string]interface{}{ + "teradata": []interface{}{ + map[string]interface{}{ + "database": dataSource.DataSourceParameters.TeradataParameters.Database, + "host": dataSource.DataSourceParameters.TeradataParameters.Host, + "port": dataSource.DataSourceParameters.TeradataParameters.Port, + }, }, - }) + } } if dataSource.DataSourceParameters.TwitterParameters != nil { - d.Set("parameters", map[string]map[string]interface{}{ - "twitter": { - "max_rows": dataSource.DataSourceParameters.TwitterParameters.MaxRows, - "query": dataSource.DataSourceParameters.TwitterParameters.Query, + params = map[string]interface{}{ + "twitter": []interface{}{ + map[string]interface{}{ + "max_rows": dataSource.DataSourceParameters.TwitterParameters.MaxRows, + "query": dataSource.DataSourceParameters.TwitterParameters.Query, + }, }, - }) + } } + d.Set("parameters", []interface{}{params}) + + d.Set("type", inferQuickSightDataSourceTypeFromKey(params)) + return nil } @@ -970,17 +1013,55 @@ func resourceAwsQuickSightDataSourceCredentials(d *schema.ResourceData) *quicksi return nil } +var quickSightDataSourceParamToDataType = map[string]string{ + "amazon_elasticsearch": quicksight.DataSourceTypeAmazonElasticsearch, + "athena": quicksight.DataSourceTypeAthena, + "aurora": quicksight.DataSourceTypeAurora, + "aurora_postgresql": quicksight.DataSourceTypeAuroraPostgresql, + "aws_iot_analytics": quicksight.DataSourceTypeAwsIotAnalytics, + "jira": quicksight.DataSourceTypeJira, + "maria_db": quicksight.DataSourceTypeMariadb, + "mysql": quicksight.DataSourceTypeMysql, + "postgresql": quicksight.DataSourceTypePostgresql, + "presto": quicksight.DataSourceTypePresto, + "redshift": quicksight.DataSourceTypeRedshift, + "s3": quicksight.DataSourceTypeS3, + "service_now": quicksight.DataSourceTypeServicenow, + "snowflake": quicksight.DataSourceTypeSnowflake, + "spark": quicksight.DataSourceTypeSpark, + "sql_server": quicksight.DataSourceTypeSqlserver, + "teradata": quicksight.DataSourceTypeTeradata, + "twitter": quicksight.DataSourceTypeTwitter, +} + +func inferQuickSightDataSourceTypeFromKey(params map[string]interface{}) string { + if len(params) == 1 { + for k := range params { + if dataSourceType, found := quickSightDataSourceParamToDataType[k]; found { + return dataSourceType + } + } + } + + for k, v := range params { + if dataSourceType, found := quickSightDataSourceParamToDataType[k]; found && v.([]interface{}) != nil && len(v.([]interface{})) > 0 { + return dataSourceType + } + } + + return "UNKNOWN" +} + func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, *quicksight.DataSourceParameters) { if v := d.Get("parameters"); v != nil { for _, v := range v.([]interface{}) { dataSourceParams := v.(map[string]interface{}) dataSourceParamsResource := &quicksight.DataSourceParameters{} - dataSourceType := "" + dataSourceType := inferQuickSightDataSourceTypeFromKey(dataSourceParams) if v := dataSourceParams["amazon_elasticsearch"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypeAmazonElasticsearch dataSourceParamsResource.AmazonElasticsearchParameters = &quicksight.AmazonElasticsearchParameters{ Domain: aws.String(psResource["domain"].(string)), } @@ -996,7 +1077,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, ps.WorkGroup = aws.String(v.(string)) } - dataSourceType = quicksight.DataSourceTypeAthena dataSourceParamsResource.AthenaParameters = ps } } @@ -1004,7 +1084,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := dataSourceParams["aurora"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypeAurora dataSourceParamsResource.AuroraParameters = &quicksight.AuroraParameters{ Database: aws.String(psResource["database"].(string)), Host: aws.String(psResource["host"].(string)), @@ -1013,10 +1092,9 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, } } - if v := dataSourceParams["aurora_postgre_sql"]; v != nil && v.([]interface{}) != nil { + if v := dataSourceParams["aurora_postgresql"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypeAuroraPostgresql dataSourceParamsResource.AuroraPostgreSqlParameters = &quicksight.AuroraPostgreSqlParameters{ Database: aws.String(psResource["database"].(string)), Host: aws.String(psResource["host"].(string)), @@ -1028,7 +1106,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := dataSourceParams["aws_iot_analytics"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypeAwsIotAnalytics dataSourceParamsResource.AwsIotAnalyticsParameters = &quicksight.AwsIotAnalyticsParameters{ DataSetName: aws.String(psResource["data_set_name"].(string)), } @@ -1038,8 +1115,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := dataSourceParams["jira"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - - dataSourceType = quicksight.DataSourceTypeJira dataSourceParamsResource.JiraParameters = &quicksight.JiraParameters{ SiteBaseUrl: aws.String(psResource["site_base_url"].(string)), } @@ -1049,8 +1124,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := dataSourceParams["maria_db"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - - dataSourceType = quicksight.DataSourceTypeMariadb dataSourceParamsResource.MariaDbParameters = &quicksight.MariaDbParameters{ Database: aws.String(psResource["database"].(string)), Host: aws.String(psResource["host"].(string)), @@ -1062,8 +1135,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := dataSourceParams["mysql"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - - dataSourceType = quicksight.DataSourceTypeMysql dataSourceParamsResource.MySqlParameters = &quicksight.MySqlParameters{ Database: aws.String(psResource["database"].(string)), Host: aws.String(psResource["host"].(string)), @@ -1075,7 +1146,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := dataSourceParams["postgresql"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypePostgresql dataSourceParamsResource.PostgreSqlParameters = &quicksight.PostgreSqlParameters{ Database: aws.String(psResource["database"].(string)), Host: aws.String(psResource["host"].(string)), @@ -1087,7 +1157,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := dataSourceParams["presto"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypePresto dataSourceParamsResource.PrestoParameters = &quicksight.PrestoParameters{ Catalog: aws.String(psResource["catalog"].(string)), Host: aws.String(psResource["host"].(string)), @@ -1115,7 +1184,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, ps.Port = aws.Int64(v.(int64)) } - dataSourceType = quicksight.DataSourceTypeRedshift dataSourceParamsResource.RedshiftParameters = ps } } @@ -1126,7 +1194,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := s3["manifest_file_location"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypeS3 dataSourceParamsResource.S3Parameters = &quicksight.S3Parameters{ ManifestFileLocation: &quicksight.ManifestFileLocation{ Bucket: aws.String(psResource["bucket"].(string)), @@ -1141,7 +1208,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := dataSourceParams["service_now"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypeServicenow dataSourceParamsResource.ServiceNowParameters = &quicksight.ServiceNowParameters{ SiteBaseUrl: aws.String(psResource["site_base_url"].(string)), } @@ -1151,7 +1217,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := dataSourceParams["snowflake"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypeSnowflake dataSourceParamsResource.SnowflakeParameters = &quicksight.SnowflakeParameters{ Database: aws.String(psResource["database"].(string)), Host: aws.String(psResource["host"].(string)), @@ -1163,7 +1228,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := dataSourceParams["spark"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypeSpark dataSourceParamsResource.SparkParameters = &quicksight.SparkParameters{ Host: aws.String(psResource["host"].(string)), Port: aws.Int64(psResource["port"].(int64)), @@ -1174,7 +1238,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := dataSourceParams["sql_server"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypeSqlserver dataSourceParamsResource.SqlServerParameters = &quicksight.SqlServerParameters{ Database: aws.String(psResource["database"].(string)), Host: aws.String(psResource["host"].(string)), @@ -1186,7 +1249,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := dataSourceParams["teradata"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypeTeradata dataSourceParamsResource.TeradataParameters = &quicksight.TeradataParameters{ Database: aws.String(psResource["database"].(string)), Host: aws.String(psResource["host"].(string)), @@ -1198,7 +1260,6 @@ func resourceAwsQuickSightDataSourceParameters(d *schema.ResourceData) (*string, if v := dataSourceParams["twitter"]; v != nil && v.([]interface{}) != nil { for _, v := range v.([]interface{}) { psResource := v.(map[string]interface{}) - dataSourceType = quicksight.DataSourceTypeTwitter dataSourceParamsResource.TwitterParameters = &quicksight.TwitterParameters{ MaxRows: aws.Int64(psResource["max_rows"].(int64)), Query: aws.String(psResource["query"].(string)), From 2edc67d5418d7fe5a61ef4dbe07b3e1499f87d05 Mon Sep 17 00:00:00 2001 From: "Michael \"Gilli\" Gilliland" Date: Mon, 2 Dec 2019 15:26:00 -0500 Subject: [PATCH 19/21] Add documentation for QuickSight data source. --- website/aws.erb | 3 + .../r/quicksight_data_source.html.markdown | 225 ++++++++++++++++++ 2 files changed, 228 insertions(+) create mode 100644 website/docs/r/quicksight_data_source.html.markdown diff --git a/website/aws.erb b/website/aws.erb index 70fdf5dce6bb..3e0050ca02e0 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -2276,6 +2276,9 @@
  • Resources