From 3f1bc775819d3cc37e19cc528320deec09dc9fcf Mon Sep 17 00:00:00 2001 From: David Hwang Date: Fri, 8 Dec 2023 15:02:11 -0500 Subject: [PATCH 01/17] Adds kx-dataview resource --- internal/service/finspace/kx_dataview.go | 427 ++++++++++++++++++ internal/service/finspace/kx_dataview_test.go | 241 ++++++++++ .../service/finspace/service_package_gen.go | 8 + .../docs/r/finspace_kx_dataview.html.markdown | 91 ++++ 4 files changed, 767 insertions(+) create mode 100644 internal/service/finspace/kx_dataview.go create mode 100644 internal/service/finspace/kx_dataview_test.go create mode 100644 website/docs/r/finspace_kx_dataview.html.markdown diff --git a/internal/service/finspace/kx_dataview.go b/internal/service/finspace/kx_dataview.go new file mode 100644 index 000000000000..b18aaa8f7e84 --- /dev/null +++ b/internal/service/finspace/kx_dataview.go @@ -0,0 +1,427 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package finspace + +import ( + "context" + "errors" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/finspace" + "github.com/aws/aws-sdk-go-v2/service/finspace/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/enum" + "github.com/hashicorp/terraform-provider-aws/internal/flex" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/internal/verify" + "github.com/hashicorp/terraform-provider-aws/names" + "log" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +// @SDKResource("aws_finspace_kx_dataview", name="Kx Dataview") +// @Tags(identifierAttribute="arn") +func ResourceKxDataview() *schema.Resource { + + return &schema.Resource{ + CreateWithoutTimeout: resourceKxDataviewCreate, + ReadWithoutTimeout: resourceKxDataviewRead, + UpdateWithoutTimeout: resourceKxDataviewUpdate, + DeleteWithoutTimeout: resourceKxDataviewDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(3, 63), + }, + "environment_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(3, 63), + }, + "database_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(3, 63), + }, + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 1000), + }, + "auto_update": { + Type: schema.TypeBool, + ForceNew: true, + Required: true, + }, + "changeset_id": { + Type: schema.TypeString, + Optional: true, + }, + "az_mode": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateDiagFunc: enum.Validate[types.KxAzMode](), + }, + "availability_zone_id": { + Type: schema.TypeString, + ForceNew: true, + Optional: true, + }, + "segment_configurations": { + Type: schema.TypeList, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "volume_name": { + Type: schema.TypeString, + Required: true, + }, + "db_paths": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Required: true, + }, + }, + }, + Optional: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "created_timestamp": { + Type: schema.TypeString, + Computed: true, + }, + "last_modified_timestamp": { + Type: schema.TypeString, + Computed: true, + }, + names.AttrTags: tftags.TagsSchema(), + names.AttrTagsAll: tftags.TagsSchemaComputed(), + }, + CustomizeDiff: verify.SetTagsDiff, + } +} + +const ( + ResNameKxDataview = "Kx Dataview" + kxDataviewIdPartCount = 3 +) + +func resourceKxDataviewCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + conn := meta.(*conns.AWSClient).FinSpaceClient(ctx) + + idParts := []string{ + d.Get("environment_id").(string), + d.Get("database_name").(string), + d.Get("name").(string), + } + + rId, err := flex.FlattenResourceId(idParts, kxDataviewIdPartCount, false) + if err != nil { + return append(diags, create.DiagError(names.FinSpace, create.ErrActionFlatteningResourceId, ResNameKxDataview, d.Get("name").(string), err)...) + } + d.SetId(rId) + + in := &finspace.CreateKxDataviewInput{ + DatabaseName: aws.String(d.Get("database_name").(string)), + DataviewName: aws.String(d.Get("name").(string)), + EnvironmentId: aws.String(d.Get("environment_id").(string)), + AutoUpdate: *aws.Bool(d.Get("auto_update").(bool)), + AzMode: types.KxAzMode(d.Get("az_mode").(string)), + ClientToken: aws.String(id.UniqueId()), + Tags: getTagsIn(ctx), + } + + if v, ok := d.GetOk("description"); ok { + in.Description = aws.String(v.(string)) + } + + if v, ok := d.GetOk("changeset_id"); ok { + in.ChangesetId = aws.String(v.(string)) + } + + if v, ok := d.GetOk("availability_zone_id"); ok { + in.AvailabilityZoneId = aws.String(v.(string)) + } + + if v, ok := d.GetOk("segment_configurations"); ok && len(v.([]interface{})) > 0 { + in.SegmentConfigurations = expandSegmentConfigurations(v.([]interface{})) + } + + out, err := conn.CreateKxDataview(ctx, in) + if err != nil { + return append(diags, create.DiagError(names.FinSpace, create.ErrActionCreating, ResNameKxDataview, d.Get("name").(string), err)...) + } + if out == nil || out.DataviewName == nil { + return append(diags, create.DiagError(names.FinSpace, create.ErrActionCreating, ResNameKxDataview, d.Get("name").(string), errors.New("empty output"))...) + } + if _, err := waitKxDataviewCreated(ctx, conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { + return append(diags, create.DiagError(names.FinSpace, create.ErrActionWaitingForCreation, ResNameKxDataview, d.Get("name").(string), err)...) + } + + return append(diags, resourceKxDataviewRead(ctx, d, meta)...) +} + +func resourceKxDataviewRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + conn := meta.(*conns.AWSClient).FinSpaceClient(ctx) + + out, err := findKxDataviewById(ctx, conn, d.Id()) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] FinSpace KxDataview (%s) not found, removing from state", d.Id()) + d.SetId("") + return diags + } + + if err != nil { + return append(diags, create.DiagError(names.FinSpace, create.ErrActionReading, ResNameKxDataview, d.Id(), err)...) + } + d.Set("name", out.DataviewName) + d.Set("description", out.Description) + d.Set("auto_update", out.AutoUpdate) + d.Set("changeset_id", out.ChangesetId) + d.Set("availability_zone_id", out.AvailabilityZoneId) + d.Set("status", out.Status) + d.Set("created_timestamp", out.CreatedTimestamp.String()) + d.Set("last_modified_timestamp", out.LastModifiedTimestamp.String()) + d.Set("database_name", out.DatabaseName) + d.Set("environment_id", out.EnvironmentId) + d.Set("az_mode", out.AzMode) + if err := d.Set("segment_configurations", flattenSegmentConfigurations(out.SegmentConfigurations)); err != nil { + return append(diags, create.DiagError(names.FinSpace, create.ErrActionReading, ResNameKxDataview, d.Id(), err)...) + } + + return diags +} + +func resourceKxDataviewUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + conn := meta.(*conns.AWSClient).FinSpaceClient(ctx) + in := &finspace.UpdateKxDataviewInput{ + EnvironmentId: aws.String(d.Get("environment_id").(string)), + DatabaseName: aws.String(d.Get("database_name").(string)), + DataviewName: aws.String(d.Get("name").(string)), + ClientToken: aws.String(id.UniqueId()), + } + + if v, ok := d.GetOk("changeset_id"); ok && d.HasChange("changeset_id") && d.Get("auto_update").(bool) != true { + in.ChangesetId = aws.String(v.(string)) + } + + if v, ok := d.GetOk("segment_configurations"); ok && len(v.([]interface{})) > 0 && d.HasChange("segment_configurations") { + in.SegmentConfigurations = expandSegmentConfigurations(v.([]interface{})) + } + + if _, err := conn.UpdateKxDataview(ctx, in); err != nil { + return append(diags, create.DiagError(names.FinSpace, create.ErrActionUpdating, ResNameKxDataview, d.Get("name").(string), err)...) + } + + if _, err := waitKxDataviewUpdated(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil { + return append(diags, create.DiagError(names.FinSpace, create.ErrActionWaitingForUpdate, ResNameKxDataview, d.Get("name").(string), err)...) + } + + return append(diags, resourceKxDataviewRead(ctx, d, meta)...) +} + +func resourceKxDataviewDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + conn := meta.(*conns.AWSClient).FinSpaceClient(ctx) + + _, err := conn.DeleteKxDataview(ctx, &finspace.DeleteKxDataviewInput{ + EnvironmentId: aws.String(d.Get("environment_id").(string)), + DatabaseName: aws.String(d.Get("database_name").(string)), + DataviewName: aws.String(d.Get("name").(string)), + ClientToken: aws.String(id.UniqueId()), + }) + + if err != nil { + var nfe *types.ResourceNotFoundException + if errors.As(err, &nfe) { + return diags + } + return append(diags, create.DiagError(names.FinSpace, create.ErrActionDeleting, ResNameKxDataview, d.Get("name").(string), err)...) + } + + if _, err := waitKxDataviewDeleted(ctx, conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil && !tfresource.NotFound(err) { + return append(diags, create.DiagError(names.FinSpace, create.ErrActionWaitingForDeletion, ResNameKxDataview, d.Id(), err)...) + } + return diags +} + +func findKxDataviewById(ctx context.Context, conn *finspace.Client, id string) (*finspace.GetKxDataviewOutput, error) { + idParts, err := flex.ExpandResourceId(id, kxDataviewIdPartCount, false) + if err != nil { + return nil, err + } + + in := &finspace.GetKxDataviewInput{ + EnvironmentId: aws.String(idParts[0]), + DatabaseName: aws.String(idParts[1]), + DataviewName: aws.String(idParts[2]), + } + + out, err := conn.GetKxDataview(ctx, in) + if err != nil { + var nfe *types.ResourceNotFoundException + + if errors.As(err, &nfe) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: in, + } + + } + return nil, err + } + + if out == nil || out.DataviewName == nil { + return nil, tfresource.NewEmptyResultError(in) + } + return out, nil +} + +func waitKxDataviewCreated(ctx context.Context, conn *finspace.Client, id string, timeout time.Duration) (*finspace.GetKxDataviewOutput, error) { + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(types.KxDataviewStatusCreating), + Target: enum.Slice(types.KxDataviewStatusActive), + Refresh: statusKxDataview(ctx, conn, id), + Timeout: timeout, + NotFoundChecks: 20, + ContinuousTargetOccurence: 2, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + if out, ok := outputRaw.(*finspace.GetKxDataviewOutput); ok { + return out, err + } + return nil, err +} + +func waitKxDataviewUpdated(ctx context.Context, conn *finspace.Client, id string, timeout time.Duration) (*finspace.GetKxDataviewOutput, error) { + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(types.KxDataviewStatusUpdating), + Target: enum.Slice(types.KxDataviewStatusActive), + Refresh: statusKxDataview(ctx, conn, id), + Timeout: timeout, + NotFoundChecks: 20, + ContinuousTargetOccurence: 2, + } + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if out, ok := outputRaw.(*finspace.GetKxDataviewOutput); ok { + return out, err + } + return nil, err +} + +func waitKxDataviewDeleted(ctx context.Context, conn *finspace.Client, id string, timeout time.Duration) (*finspace.GetKxDataviewOutput, error) { + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(types.KxDataviewStatusDeleting), + Target: []string{}, + Refresh: statusKxDataview(ctx, conn, id), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + if out, ok := outputRaw.(*finspace.GetKxDataviewOutput); ok { + return out, err + } + + return nil, err +} + +func statusKxDataview(ctx context.Context, conn *finspace.Client, id string) retry.StateRefreshFunc { + return func() (interface{}, string, error) { + out, err := findKxDataviewById(ctx, conn, id) + if tfresource.NotFound(err) { + return nil, "", nil + } + if err != nil { + return nil, "", err + } + return out, string(out.Status), nil + } +} + +func expandDbPath(tfList []interface{}) []string { + if tfList == nil { + return nil + } + var s []string + + for _, v := range tfList { + s = append(s, v.(string)) + } + return s +} + +func expandSegmentConfigurations(tfList []interface{}) []types.KxDataviewSegmentConfiguration { + if tfList == nil { + return nil + } + var s []types.KxDataviewSegmentConfiguration + + for _, v := range tfList { + m := v.(map[string]interface{}) + s = append(s, types.KxDataviewSegmentConfiguration{ + VolumeName: aws.String(m["volume_name"].(string)), + DbPaths: expandDbPath(m["db_paths"].([]interface{})), + }) + } + + return s +} +func flattenSegmentConfiguration(apiObject *types.KxDataviewSegmentConfiguration) map[string]interface{} { + if apiObject == nil { + return nil + } + m := map[string]interface{}{} + if v := apiObject.VolumeName; aws.ToString(v) != "" { + m["volume_name"] = aws.ToString(v) + } + if v := apiObject.DbPaths; v != nil { + m["db_paths"] = v + } + return m +} + +func flattenSegmentConfigurations(apiObjects []types.KxDataviewSegmentConfiguration) []interface{} { + if apiObjects == nil { + return nil + } + var l []interface{} + for _, apiObject := range apiObjects { + l = append(l, flattenSegmentConfiguration(&apiObject)) + } + return l +} diff --git a/internal/service/finspace/kx_dataview_test.go b/internal/service/finspace/kx_dataview_test.go new file mode 100644 index 000000000000..0a26282997d5 --- /dev/null +++ b/internal/service/finspace/kx_dataview_test.go @@ -0,0 +1,241 @@ +package finspace_test + +import ( + "context" + "errors" + "fmt" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/finspace" + "github.com/aws/aws-sdk-go-v2/service/finspace/types" + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/create" + tffinspace "github.com/hashicorp/terraform-provider-aws/internal/service/finspace" + "github.com/hashicorp/terraform-provider-aws/names" + "testing" +) + +func TestAccFinSpaceKxDataview_basic(t *testing.T) { + if testing.Short() { + t.Skip("Skipping test in short mode.") + } + + ctx := acctest.Context(t) + var kxdataview finspace.GetKxDataviewOutput + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_finspace_kx_dataview.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, finspace.ServiceID) + }, + ErrorCheck: acctest.ErrorCheck(t, finspace.ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckKxDataviewDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccKxDataviewConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckKxDataviewExists(ctx, resourceName, &kxdataview), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "status", string(types.KxDataviewStatusActive)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} +func TestAccFinSpaceKxDataview_disappears(t *testing.T) { + if testing.Short() { + t.Skip("Skipping test in short mode.") + } + + ctx := acctest.Context(t) + var kxdataview finspace.GetKxDataviewOutput + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_finspace_kx_dataview.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, finspace.ServiceID) + }, + ErrorCheck: acctest.ErrorCheck(t, finspace.ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckKxDataviewDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccKxDataviewConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckKxDataviewExists(ctx, resourceName, &kxdataview), + acctest.CheckResourceDisappears(ctx, acctest.Provider, tffinspace.ResourceKxDataview(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccKxDataviewConfigBase(rName string) string { + return fmt.Sprintf(` +resource "aws_kms_key" "test" { + deletion_window_in_days = 7 +} + +resource "aws_finspace_kx_environment" "test" { + name = %[1]q + kms_key_id = aws_kms_key.test.arn +} +resource "aws_finspace_kx_database" "test" { + name = %[1]q + environment_id = aws_finspace_kx_environment.test.id +} +`, rName) +} +func testAccKxDataviewConfig_basic(rName string) string { + return acctest.ConfigCompose( + testAccKxDataviewConfigBase(rName), + fmt.Sprintf(` +resource "aws_finspace_kx_dataview" "test" { + name = %[1]q + environment_id = aws_finspace_kx_environment.test.id + database_name = aws_finspace_kx_database.test.name + auto_update = true + az_mode = "SINGLE" + availability_zone_id = aws_finspace_kx_environment.test.availability_zones[0] +} +`, rName)) +} + +func testAccCheckKxDataviewExists(ctx context.Context, name string, kxdataview *finspace.GetKxDataviewOutput) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return create.Error(names.FinSpace, create.ErrActionCheckingExistence, tffinspace.ResNameKxDataview, name, errors.New("not found")) + } + + if rs.Primary.ID == "" { + return create.Error(names.FinSpace, create.ErrActionCheckingExistence, tffinspace.ResNameKxDataview, name, errors.New("not set")) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).FinSpaceClient(ctx) + resp, err := conn.GetKxDataview(ctx, &finspace.GetKxDataviewInput{ + DatabaseName: aws.String(rs.Primary.Attributes["database_name"]), + EnvironmentId: aws.String(rs.Primary.Attributes["environment_id"]), + DataviewName: aws.String(rs.Primary.Attributes["name"]), + }) + if err != nil { + return create.Error(names.FinSpace, create.ErrActionCheckingExistence, tffinspace.ResNameKxDataview, rs.Primary.ID, err) + } + + *kxdataview = *resp + + return nil + } +} + +func testAccCheckKxDataviewDestroy(ctx context.Context) resource.TestCheckFunc { + return func(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_finspace_kx_dataview" { + continue + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).FinSpaceClient(ctx) + _, err := conn.GetKxDataview(ctx, &finspace.GetKxDataviewInput{ + DatabaseName: aws.String(rs.Primary.Attributes["database_name"]), + EnvironmentId: aws.String(rs.Primary.Attributes["environment_id"]), + DataviewName: aws.String(rs.Primary.Attributes["name"]), + }) + if err != nil { + var nfe *types.ResourceNotFoundException + if errors.As(err, &nfe) { + return nil + } + return err + } + return create.Error(names.FinSpace, create.ErrActionCheckingExistence, tffinspace.ResNameKxDataview, rs.Primary.ID, err) + } + return nil + } +} + +func testAccKxDataviewVolumeBase(rName string) string { + return fmt.Sprintf(` +resource "aws_finspace_kx_volume" "test" { + name = %[1]q + environment_id = aws_finspace_kx_environment.test.id + availability_zones = [aws_finspace_kx_environment.test.availability_zones[0]] + az_mode = "SINGLE" + type = "NAS_1" + nas1_configuration { + type= "SSD_250" + size= 1200 + } +} +`, rName) +} + +func testAccKxDataviewConfig_withKxVolume(rName string) string { + return acctest.ConfigCompose( + testAccKxDataviewConfigBase(rName), + testAccKxDataviewVolumeBase(rName), + fmt.Sprintf(` +resource "aws_finspace_kx_dataview" "test" { + name = %[1]q + environment_id = aws_finspace_kx_environment.test.id + database_name = aws_finspace_kx_database.test.name + auto_update = true + az_mode = "SINGLE" + availability_zone_id = aws_finspace_kx_environment.test.availability_zones[0] + + segment_configurations { + db_paths = ["/*"] + volume_name = aws_finspace_kx_volume.test.name + } +} +`, rName)) +} + +func TestAccFinSpaceKxDataview_withKxVolume(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + ctx := acctest.Context(t) + + var kxdataview finspace.GetKxDataviewOutput + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_finspace_kx_dataview.test" + + resource.ParallelTest(t, resource.TestCase{ + + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, finspace.ServiceID) + }, + ErrorCheck: acctest.ErrorCheck(t, finspace.ServiceID), + + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + + CheckDestroy: testAccCheckKxDataviewDestroy(ctx), + + Steps: []resource.TestStep{ + { + Config: testAccKxDataviewConfig_withKxVolume(rName), + + Check: resource.ComposeTestCheckFunc( + testAccCheckKxDataviewExists(ctx, resourceName, &kxdataview), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "status", string(types.KxDataviewStatusActive)), + ), + }, + }, + }) +} diff --git a/internal/service/finspace/service_package_gen.go b/internal/service/finspace/service_package_gen.go index 42b687b450ea..b34d275706c8 100644 --- a/internal/service/finspace/service_package_gen.go +++ b/internal/service/finspace/service_package_gen.go @@ -60,6 +60,14 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka IdentifierAttribute: "arn", }, }, + { + Factory: ResourceKxDataview, + TypeName: "aws_finspace_kx_dataview", + Name: "Kx Dataview", + Tags: &types.ServicePackageResourceTags{ + IdentifierAttribute: "arn", + }, + }, } } diff --git a/website/docs/r/finspace_kx_dataview.html.markdown b/website/docs/r/finspace_kx_dataview.html.markdown new file mode 100644 index 000000000000..70a2b762c909 --- /dev/null +++ b/website/docs/r/finspace_kx_dataview.html.markdown @@ -0,0 +1,91 @@ +--- +subcategory: "FinSpace" +layout: "aws" +page_title: "AWS: aws_finspace_kx_dataview" +description: |- + Terraform resource for managing an AWS FinSpace Kx Dataviewk. +--- + +# Resource: aws_finspace_dataview + +Terraform resource for managing an AWS FinSpace Kx Dataview. + +## Example Usage + +### Basic Usage + +```terraform +resource "aws_finspace_kx_dataview" "example" { + name = "my-tf-kx-dataview" + environment_id = aws_finspace_kx_environment.example.id + database_name = aws_finspace_kx_database.example.name + availability_zone_id = "use1-az2" + description = "Terraform managed Kx Dataview" + az_mode = "SINGLE" + auto_update = true + + segment_configurations { + volume_name = aws_finspace_kx_volume.example.name + db_paths = ["/*"] + } +} +``` + +## Argument Reference + +The following arguments are required: + +* `az_mode` - (Required) The number of availability zones you want to assign per cluster. This can be one of the following: + * SINGLE - Assigns one availability zone per cluster. + * MULTI - Assigns all the availability zones per cluster. +* `database_name` - (Required) The name of the database where you want to create a dataview. +* `environment_id` - (Required) Unique identifier for the KX environment. +* `name` - (Required) A unique identifier for the dataview. + +The following arguments are optional: +* `auto_update` - (Optional) The option to specify whether you want to apply all the future additions and corrections automatically to the dataview, when you ingest new changesets. The default value is false. +* `availability_zone_id` - (Optional) The identifier of the availability zones. If attaching a volume, the volume must be in the same availability zone as the dataview that you are attaching to. +* `changeset_id` - (Optional) A unique identifier of the changeset of the database that you want to use to ingest data. +* `description` - (Optional) A description for the dataview. +* `segment_configurations` - (Optional) The configuration that contains the database path of the data that you want to place on each selected volume. Each segment must have a unique database path for each volume. If you do not explicitly specify any database path for a volume, they are accessible from the cluster through the default S3/object store segment. See [segment_configurations](#segment_configurations). +* `tags` - (Optional) Key-value mapping of resource tags. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. + +### segment_configurations +* `db_paths` - (Required) The database path of the data that you want to place on each selected volume. Each segment must have a unique database path for each volume. +* `volume_name` - (Required) The name of the volume that you want to attach to a dataview. This volume must be in the same availability zone as the dataview that you are attaching to. + + +## Attribute Reference + +This resource exports the following attributes in addition to the arguments above: + +* `arn` - Amazon Resource Name (ARN) identifier of the KX dataview. +* `created_timestamp` - Timestamp at which the dataview was created in FinSpace. Value determined as epoch time in milliseconds. For example, the value for Monday, November 1, 2021 12:00:00 PM UTC is specified as 1635768000000. +* `id` - A comma-delimited string joining environment ID, database name and dataview name. +* `last_modified_timestamp` - The last time that the dataview was updated in FinSpace. The value is determined as epoch time in milliseconds. For example, the value for Monday, November 1, 2021 12:00:00 PM UTC is specified as 1635768000000. +* `tags_all` - Map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). + +## Timeouts + +[Configuration options](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts): + +* `create` - (Default `30m`) +* `update` - (Default `30m`) +* `delete` - (Default `30m`) + +## Import + +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import an AWS FinSpace Kx Dataview using the `id` (environment ID, database name and dataview name, comma-delimited). For example: + +```terraform +import { + to = aws_finspace_kx_dataview.example + id = "n3ceo7wqxoxcti5tujqwzs,my-tf-kx-database,my-tf-kx-dataview" +} +``` + +Using `terraform import`, import an AWS FinSpace Kx Cluster using the `id` (environment ID and cluster name, comma-delimited). For example: + +```console +% terraform import aws_finspace_kx_dataview.example n3ceo7wqxoxcti5tujqwzs,my-tf-kx-database,my-tf-kx-dataview +``` From 31cb4334856df230e0a317a3237e92cc9f9927e1 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 10:20:51 -0500 Subject: [PATCH 02/17] r/aws_finspace_kx_dataview: add headers --- internal/service/finspace/kx_dataview_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/service/finspace/kx_dataview_test.go b/internal/service/finspace/kx_dataview_test.go index 0a26282997d5..9bce6348592a 100644 --- a/internal/service/finspace/kx_dataview_test.go +++ b/internal/service/finspace/kx_dataview_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package finspace_test import ( From 0834c20027077a46eb6939e7269d48668b31d9dc Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 10:22:25 -0500 Subject: [PATCH 03/17] r/aws_finspace_kx_dataview: prefer create.AppendDiagError --- internal/service/finspace/kx_dataview.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/internal/service/finspace/kx_dataview.go b/internal/service/finspace/kx_dataview.go index b18aaa8f7e84..09bc349afb72 100644 --- a/internal/service/finspace/kx_dataview.go +++ b/internal/service/finspace/kx_dataview.go @@ -148,7 +148,7 @@ func resourceKxDataviewCreate(ctx context.Context, d *schema.ResourceData, meta rId, err := flex.FlattenResourceId(idParts, kxDataviewIdPartCount, false) if err != nil { - return append(diags, create.DiagError(names.FinSpace, create.ErrActionFlatteningResourceId, ResNameKxDataview, d.Get("name").(string), err)...) + return create.AppendDiagError(diags, names.FinSpace, create.ErrActionFlatteningResourceId, ResNameKxDataview, d.Get("name").(string), err) } d.SetId(rId) @@ -156,7 +156,7 @@ func resourceKxDataviewCreate(ctx context.Context, d *schema.ResourceData, meta DatabaseName: aws.String(d.Get("database_name").(string)), DataviewName: aws.String(d.Get("name").(string)), EnvironmentId: aws.String(d.Get("environment_id").(string)), - AutoUpdate: *aws.Bool(d.Get("auto_update").(bool)), + AutoUpdate: d.Get("auto_update").(bool), AzMode: types.KxAzMode(d.Get("az_mode").(string)), ClientToken: aws.String(id.UniqueId()), Tags: getTagsIn(ctx), @@ -180,13 +180,13 @@ func resourceKxDataviewCreate(ctx context.Context, d *schema.ResourceData, meta out, err := conn.CreateKxDataview(ctx, in) if err != nil { - return append(diags, create.DiagError(names.FinSpace, create.ErrActionCreating, ResNameKxDataview, d.Get("name").(string), err)...) + return create.AppendDiagError(diags, names.FinSpace, create.ErrActionCreating, ResNameKxDataview, d.Get("name").(string), err) } if out == nil || out.DataviewName == nil { - return append(diags, create.DiagError(names.FinSpace, create.ErrActionCreating, ResNameKxDataview, d.Get("name").(string), errors.New("empty output"))...) + return create.AppendDiagError(diags, names.FinSpace, create.ErrActionCreating, ResNameKxDataview, d.Get("name").(string), errors.New("empty output")) } if _, err := waitKxDataviewCreated(ctx, conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { - return append(diags, create.DiagError(names.FinSpace, create.ErrActionWaitingForCreation, ResNameKxDataview, d.Get("name").(string), err)...) + return create.AppendDiagError(diags, names.FinSpace, create.ErrActionWaitingForCreation, ResNameKxDataview, d.Get("name").(string), err) } return append(diags, resourceKxDataviewRead(ctx, d, meta)...) @@ -204,7 +204,7 @@ func resourceKxDataviewRead(ctx context.Context, d *schema.ResourceData, meta in } if err != nil { - return append(diags, create.DiagError(names.FinSpace, create.ErrActionReading, ResNameKxDataview, d.Id(), err)...) + return create.AppendDiagError(diags, names.FinSpace, create.ErrActionReading, ResNameKxDataview, d.Id(), err) } d.Set("name", out.DataviewName) d.Set("description", out.Description) @@ -218,7 +218,7 @@ func resourceKxDataviewRead(ctx context.Context, d *schema.ResourceData, meta in d.Set("environment_id", out.EnvironmentId) d.Set("az_mode", out.AzMode) if err := d.Set("segment_configurations", flattenSegmentConfigurations(out.SegmentConfigurations)); err != nil { - return append(diags, create.DiagError(names.FinSpace, create.ErrActionReading, ResNameKxDataview, d.Id(), err)...) + return create.AppendDiagError(diags, names.FinSpace, create.ErrActionReading, ResNameKxDataview, d.Id(), err) } return diags @@ -243,11 +243,11 @@ func resourceKxDataviewUpdate(ctx context.Context, d *schema.ResourceData, meta } if _, err := conn.UpdateKxDataview(ctx, in); err != nil { - return append(diags, create.DiagError(names.FinSpace, create.ErrActionUpdating, ResNameKxDataview, d.Get("name").(string), err)...) + return create.AppendDiagError(diags, names.FinSpace, create.ErrActionUpdating, ResNameKxDataview, d.Get("name").(string), err) } if _, err := waitKxDataviewUpdated(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil { - return append(diags, create.DiagError(names.FinSpace, create.ErrActionWaitingForUpdate, ResNameKxDataview, d.Get("name").(string), err)...) + return create.AppendDiagError(diags, names.FinSpace, create.ErrActionWaitingForUpdate, ResNameKxDataview, d.Get("name").(string), err) } return append(diags, resourceKxDataviewRead(ctx, d, meta)...) @@ -269,11 +269,11 @@ func resourceKxDataviewDelete(ctx context.Context, d *schema.ResourceData, meta if errors.As(err, &nfe) { return diags } - return append(diags, create.DiagError(names.FinSpace, create.ErrActionDeleting, ResNameKxDataview, d.Get("name").(string), err)...) + return create.AppendDiagError(diags, names.FinSpace, create.ErrActionDeleting, ResNameKxDataview, d.Get("name").(string), err) } if _, err := waitKxDataviewDeleted(ctx, conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil && !tfresource.NotFound(err) { - return append(diags, create.DiagError(names.FinSpace, create.ErrActionWaitingForDeletion, ResNameKxDataview, d.Id(), err)...) + return create.AppendDiagError(diags, names.FinSpace, create.ErrActionWaitingForDeletion, ResNameKxDataview, d.Id(), err) } return diags } From ef5a2d87841c6583daa9963eeb3c352df901978b Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 10:24:22 -0500 Subject: [PATCH 04/17] r/aws_finspace_kx_dataview: alphabetize attributes --- internal/service/finspace/kx_dataview.go | 74 ++++++++++++------------ 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/internal/service/finspace/kx_dataview.go b/internal/service/finspace/kx_dataview.go index 09bc349afb72..add5b00bc2ed 100644 --- a/internal/service/finspace/kx_dataview.go +++ b/internal/service/finspace/kx_dataview.go @@ -6,12 +6,16 @@ package finspace import ( "context" "errors" + "log" + "time" + "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/finspace" "github.com/aws/aws-sdk-go-v2/service/finspace/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" + "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" "github.com/hashicorp/terraform-provider-aws/internal/enum" "github.com/hashicorp/terraform-provider-aws/internal/flex" @@ -19,8 +23,6 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/internal/verify" "github.com/hashicorp/terraform-provider-aws/names" - "log" - "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -50,36 +52,14 @@ func ResourceKxDataview() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringLenBetween(3, 63), - }, - "environment_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringLenBetween(3, 63), - }, - "database_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringLenBetween(3, 63), - }, - "description": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringLenBetween(1, 1000), - }, "auto_update": { Type: schema.TypeBool, ForceNew: true, Required: true, }, - "changeset_id": { + "availability_zone_id": { Type: schema.TypeString, + ForceNew: true, Optional: true, }, "az_mode": { @@ -88,11 +68,41 @@ func ResourceKxDataview() *schema.Resource { ForceNew: true, ValidateDiagFunc: enum.Validate[types.KxAzMode](), }, - "availability_zone_id": { + "changeset_id": { Type: schema.TypeString, - ForceNew: true, Optional: true, }, + "created_timestamp": { + Type: schema.TypeString, + Computed: true, + }, + "database_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(3, 63), + }, + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 1000), + }, + "environment_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(3, 63), + }, + "last_modified_timestamp": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(3, 63), + }, "segment_configurations": { Type: schema.TypeList, Elem: &schema.Resource{ @@ -116,14 +126,6 @@ func ResourceKxDataview() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "created_timestamp": { - Type: schema.TypeString, - Computed: true, - }, - "last_modified_timestamp": { - Type: schema.TypeString, - Computed: true, - }, names.AttrTags: tftags.TagsSchema(), names.AttrTagsAll: tftags.TagsSchemaComputed(), }, From bfdec1686b0c8b3ace004054682417e016e2bc4f Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 10:25:04 -0500 Subject: [PATCH 05/17] chore: changelog --- .changelog/34828.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/34828.txt diff --git a/.changelog/34828.txt b/.changelog/34828.txt new file mode 100644 index 000000000000..cfa7c1c52893 --- /dev/null +++ b/.changelog/34828.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_finspace_kx_dataview +``` From 6d8e014383f2136be2041c4c4f7a56e45e39d477 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 10:41:32 -0500 Subject: [PATCH 06/17] r/aws_finspace_kx_dataview(test): reorganize --- internal/service/finspace/kx_dataview_test.go | 152 +++++++++--------- 1 file changed, 73 insertions(+), 79 deletions(-) diff --git a/internal/service/finspace/kx_dataview_test.go b/internal/service/finspace/kx_dataview_test.go index 9bce6348592a..1410cd96274b 100644 --- a/internal/service/finspace/kx_dataview_test.go +++ b/internal/service/finspace/kx_dataview_test.go @@ -7,6 +7,8 @@ import ( "context" "errors" "fmt" + "testing" + "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/finspace" "github.com/aws/aws-sdk-go-v2/service/finspace/types" @@ -14,10 +16,10 @@ import ( "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" tffinspace "github.com/hashicorp/terraform-provider-aws/internal/service/finspace" "github.com/hashicorp/terraform-provider-aws/names" - "testing" ) func TestAccFinSpaceKxDataview_basic(t *testing.T) { @@ -26,7 +28,7 @@ func TestAccFinSpaceKxDataview_basic(t *testing.T) { } ctx := acctest.Context(t) - var kxdataview finspace.GetKxDataviewOutput + var dataview finspace.GetKxDataviewOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_finspace_kx_dataview.test" @@ -42,7 +44,7 @@ func TestAccFinSpaceKxDataview_basic(t *testing.T) { { Config: testAccKxDataviewConfig_basic(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckKxDataviewExists(ctx, resourceName, &kxdataview), + testAccCheckKxDataviewExists(ctx, resourceName, &dataview), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "status", string(types.KxDataviewStatusActive)), ), @@ -61,7 +63,7 @@ func TestAccFinSpaceKxDataview_disappears(t *testing.T) { } ctx := acctest.Context(t) - var kxdataview finspace.GetKxDataviewOutput + var dataview finspace.GetKxDataviewOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_finspace_kx_dataview.test" @@ -77,7 +79,7 @@ func TestAccFinSpaceKxDataview_disappears(t *testing.T) { { Config: testAccKxDataviewConfig_basic(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckKxDataviewExists(ctx, resourceName, &kxdataview), + testAccCheckKxDataviewExists(ctx, resourceName, &dataview), acctest.CheckResourceDisappears(ctx, acctest.Provider, tffinspace.ResourceKxDataview(), resourceName), ), ExpectNonEmptyPlan: true, @@ -86,38 +88,38 @@ func TestAccFinSpaceKxDataview_disappears(t *testing.T) { }) } -func testAccKxDataviewConfigBase(rName string) string { - return fmt.Sprintf(` -resource "aws_kms_key" "test" { - deletion_window_in_days = 7 -} +func TestAccFinSpaceKxDataview_withKxVolume(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } -resource "aws_finspace_kx_environment" "test" { - name = %[1]q - kms_key_id = aws_kms_key.test.arn -} -resource "aws_finspace_kx_database" "test" { - name = %[1]q - environment_id = aws_finspace_kx_environment.test.id -} -`, rName) -} -func testAccKxDataviewConfig_basic(rName string) string { - return acctest.ConfigCompose( - testAccKxDataviewConfigBase(rName), - fmt.Sprintf(` -resource "aws_finspace_kx_dataview" "test" { - name = %[1]q - environment_id = aws_finspace_kx_environment.test.id - database_name = aws_finspace_kx_database.test.name - auto_update = true - az_mode = "SINGLE" - availability_zone_id = aws_finspace_kx_environment.test.availability_zones[0] -} -`, rName)) + ctx := acctest.Context(t) + var dataview finspace.GetKxDataviewOutput + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_finspace_kx_dataview.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, finspace.ServiceID) + }, + ErrorCheck: acctest.ErrorCheck(t, finspace.ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckKxDataviewDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccKxDataviewConfig_withKxVolume(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckKxDataviewExists(ctx, resourceName, &dataview), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "status", string(types.KxDataviewStatusActive)), + ), + }, + }, + }) } -func testAccCheckKxDataviewExists(ctx context.Context, name string, kxdataview *finspace.GetKxDataviewOutput) resource.TestCheckFunc { +func testAccCheckKxDataviewExists(ctx context.Context, name string, dataview *finspace.GetKxDataviewOutput) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] if !ok { @@ -138,7 +140,7 @@ func testAccCheckKxDataviewExists(ctx context.Context, name string, kxdataview * return create.Error(names.FinSpace, create.ErrActionCheckingExistence, tffinspace.ResNameKxDataview, rs.Primary.ID, err) } - *kxdataview = *resp + *dataview = *resp return nil } @@ -170,8 +172,43 @@ func testAccCheckKxDataviewDestroy(ctx context.Context) resource.TestCheckFunc { } } -func testAccKxDataviewVolumeBase(rName string) string { +func testAccKxDataviewConfigBase(rName string) string { return fmt.Sprintf(` +resource "aws_kms_key" "test" { + deletion_window_in_days = 7 +} + +resource "aws_finspace_kx_environment" "test" { + name = %[1]q + kms_key_id = aws_kms_key.test.arn +} + +resource "aws_finspace_kx_database" "test" { + name = %[1]q + environment_id = aws_finspace_kx_environment.test.id +} +`, rName) +} + +func testAccKxDataviewConfig_basic(rName string) string { + return acctest.ConfigCompose( + testAccKxDataviewConfigBase(rName), + fmt.Sprintf(` +resource "aws_finspace_kx_dataview" "test" { + name = %[1]q + environment_id = aws_finspace_kx_environment.test.id + database_name = aws_finspace_kx_database.test.name + auto_update = true + az_mode = "SINGLE" + availability_zone_id = aws_finspace_kx_environment.test.availability_zones[0] +} +`, rName)) +} + +func testAccKxDataviewConfig_withKxVolume(rName string) string { + return acctest.ConfigCompose( + testAccKxDataviewConfigBase(rName), + fmt.Sprintf(` resource "aws_finspace_kx_volume" "test" { name = %[1]q environment_id = aws_finspace_kx_environment.test.id @@ -183,14 +220,7 @@ resource "aws_finspace_kx_volume" "test" { size= 1200 } } -`, rName) -} -func testAccKxDataviewConfig_withKxVolume(rName string) string { - return acctest.ConfigCompose( - testAccKxDataviewConfigBase(rName), - testAccKxDataviewVolumeBase(rName), - fmt.Sprintf(` resource "aws_finspace_kx_dataview" "test" { name = %[1]q environment_id = aws_finspace_kx_environment.test.id @@ -206,39 +236,3 @@ resource "aws_finspace_kx_dataview" "test" { } `, rName)) } - -func TestAccFinSpaceKxDataview_withKxVolume(t *testing.T) { - if testing.Short() { - t.Skip("skipping long-running test in short mode") - } - ctx := acctest.Context(t) - - var kxdataview finspace.GetKxDataviewOutput - rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resourceName := "aws_finspace_kx_dataview.test" - - resource.ParallelTest(t, resource.TestCase{ - - PreCheck: func() { - acctest.PreCheck(ctx, t) - acctest.PreCheckPartitionHasService(t, finspace.ServiceID) - }, - ErrorCheck: acctest.ErrorCheck(t, finspace.ServiceID), - - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - - CheckDestroy: testAccCheckKxDataviewDestroy(ctx), - - Steps: []resource.TestStep{ - { - Config: testAccKxDataviewConfig_withKxVolume(rName), - - Check: resource.ComposeTestCheckFunc( - testAccCheckKxDataviewExists(ctx, resourceName, &kxdataview), - resource.TestCheckResourceAttr(resourceName, "name", rName), - resource.TestCheckResourceAttr(resourceName, "status", string(types.KxDataviewStatusActive)), - ), - }, - }, - }) -} From db3b97354cb929c19ef49120650ae10cf53dde0c Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 10:44:25 -0500 Subject: [PATCH 07/17] r/aws_finspace_kx_dataview(test): prefer finder in test check func --- internal/service/finspace/kx_dataview.go | 6 +++--- internal/service/finspace/kx_dataview_test.go | 20 ++++++++----------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/internal/service/finspace/kx_dataview.go b/internal/service/finspace/kx_dataview.go index add5b00bc2ed..a269c6b11728 100644 --- a/internal/service/finspace/kx_dataview.go +++ b/internal/service/finspace/kx_dataview.go @@ -198,7 +198,7 @@ func resourceKxDataviewRead(ctx context.Context, d *schema.ResourceData, meta in var diags diag.Diagnostics conn := meta.(*conns.AWSClient).FinSpaceClient(ctx) - out, err := findKxDataviewById(ctx, conn, d.Id()) + out, err := FindKxDataviewById(ctx, conn, d.Id()) if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] FinSpace KxDataview (%s) not found, removing from state", d.Id()) d.SetId("") @@ -280,7 +280,7 @@ func resourceKxDataviewDelete(ctx context.Context, d *schema.ResourceData, meta return diags } -func findKxDataviewById(ctx context.Context, conn *finspace.Client, id string) (*finspace.GetKxDataviewOutput, error) { +func FindKxDataviewById(ctx context.Context, conn *finspace.Client, id string) (*finspace.GetKxDataviewOutput, error) { idParts, err := flex.ExpandResourceId(id, kxDataviewIdPartCount, false) if err != nil { return nil, err @@ -364,7 +364,7 @@ func waitKxDataviewDeleted(ctx context.Context, conn *finspace.Client, id string func statusKxDataview(ctx context.Context, conn *finspace.Client, id string) retry.StateRefreshFunc { return func() (interface{}, string, error) { - out, err := findKxDataviewById(ctx, conn, id) + out, err := FindKxDataviewById(ctx, conn, id) if tfresource.NotFound(err) { return nil, "", nil } diff --git a/internal/service/finspace/kx_dataview_test.go b/internal/service/finspace/kx_dataview_test.go index 1410cd96274b..9f1d7fa9862f 100644 --- a/internal/service/finspace/kx_dataview_test.go +++ b/internal/service/finspace/kx_dataview_test.go @@ -9,7 +9,6 @@ import ( "fmt" "testing" - "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/finspace" "github.com/aws/aws-sdk-go-v2/service/finspace/types" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" @@ -57,6 +56,7 @@ func TestAccFinSpaceKxDataview_basic(t *testing.T) { }, }) } + func TestAccFinSpaceKxDataview_disappears(t *testing.T) { if testing.Short() { t.Skip("Skipping test in short mode.") @@ -131,11 +131,8 @@ func testAccCheckKxDataviewExists(ctx context.Context, name string, dataview *fi } conn := acctest.Provider.Meta().(*conns.AWSClient).FinSpaceClient(ctx) - resp, err := conn.GetKxDataview(ctx, &finspace.GetKxDataviewInput{ - DatabaseName: aws.String(rs.Primary.Attributes["database_name"]), - EnvironmentId: aws.String(rs.Primary.Attributes["environment_id"]), - DataviewName: aws.String(rs.Primary.Attributes["name"]), - }) + + resp, err := tffinspace.FindKxDataviewById(ctx, conn, rs.Primary.ID) if err != nil { return create.Error(names.FinSpace, create.ErrActionCheckingExistence, tffinspace.ResNameKxDataview, rs.Primary.ID, err) } @@ -154,11 +151,8 @@ func testAccCheckKxDataviewDestroy(ctx context.Context) resource.TestCheckFunc { } conn := acctest.Provider.Meta().(*conns.AWSClient).FinSpaceClient(ctx) - _, err := conn.GetKxDataview(ctx, &finspace.GetKxDataviewInput{ - DatabaseName: aws.String(rs.Primary.Attributes["database_name"]), - EnvironmentId: aws.String(rs.Primary.Attributes["environment_id"]), - DataviewName: aws.String(rs.Primary.Attributes["name"]), - }) + + _, err := tffinspace.FindKxDataviewById(ctx, conn, rs.Primary.ID) if err != nil { var nfe *types.ResourceNotFoundException if errors.As(err, &nfe) { @@ -166,8 +160,10 @@ func testAccCheckKxDataviewDestroy(ctx context.Context) resource.TestCheckFunc { } return err } - return create.Error(names.FinSpace, create.ErrActionCheckingExistence, tffinspace.ResNameKxDataview, rs.Primary.ID, err) + + return create.Error(names.FinSpace, create.ErrActionCheckingExistence, tffinspace.ResNameKxDataview, rs.Primary.ID, errors.New("not destroyed")) } + return nil } } From b0ca6929c144d4464e6b675d68509a898a3c036b Mon Sep 17 00:00:00 2001 From: Mayank Hirani Date: Thu, 14 Dec 2023 11:28:02 -0500 Subject: [PATCH 08/17] Fix acceptance test linting. --- internal/service/finspace/kx_dataview_test.go | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/internal/service/finspace/kx_dataview_test.go b/internal/service/finspace/kx_dataview_test.go index 9f1d7fa9862f..cfe02b985c56 100644 --- a/internal/service/finspace/kx_dataview_test.go +++ b/internal/service/finspace/kx_dataview_test.go @@ -175,8 +175,8 @@ resource "aws_kms_key" "test" { } resource "aws_finspace_kx_environment" "test" { - name = %[1]q - kms_key_id = aws_kms_key.test.arn + name = %[1]q + kms_key_id = aws_kms_key.test.arn } resource "aws_finspace_kx_database" "test" { @@ -206,14 +206,14 @@ func testAccKxDataviewConfig_withKxVolume(rName string) string { testAccKxDataviewConfigBase(rName), fmt.Sprintf(` resource "aws_finspace_kx_volume" "test" { - name = %[1]q - environment_id = aws_finspace_kx_environment.test.id + name = %[1]q + environment_id = aws_finspace_kx_environment.test.id availability_zones = [aws_finspace_kx_environment.test.availability_zones[0]] - az_mode = "SINGLE" - type = "NAS_1" + az_mode = "SINGLE" + type = "NAS_1" nas1_configuration { - type= "SSD_250" - size= 1200 + type= "SSD_250" + size= 1200 } } @@ -226,8 +226,8 @@ resource "aws_finspace_kx_dataview" "test" { availability_zone_id = aws_finspace_kx_environment.test.availability_zones[0] segment_configurations { - db_paths = ["/*"] - volume_name = aws_finspace_kx_volume.test.name + db_paths = ["/*"] + volume_name = aws_finspace_kx_volume.test.name } } `, rName)) From 583c90e6da85236ea8e9280600e9b5dd190c2680 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 12:39:58 -0500 Subject: [PATCH 09/17] r/aws_finspace_kx_dataview(test): fmt config --- internal/service/finspace/kx_dataview_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/service/finspace/kx_dataview_test.go b/internal/service/finspace/kx_dataview_test.go index cfe02b985c56..88096f6bc92d 100644 --- a/internal/service/finspace/kx_dataview_test.go +++ b/internal/service/finspace/kx_dataview_test.go @@ -212,8 +212,8 @@ resource "aws_finspace_kx_volume" "test" { az_mode = "SINGLE" type = "NAS_1" nas1_configuration { - type= "SSD_250" - size= 1200 + size = 1200 + type = "SSD_250" } } @@ -227,7 +227,7 @@ resource "aws_finspace_kx_dataview" "test" { segment_configurations { db_paths = ["/*"] - volume_name = aws_finspace_kx_volume.test.name + volume_name = aws_finspace_kx_volume.test.name } } `, rName)) From 6c9ce2ae31858e5a514e62f438818b6d3953c62e Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 12:42:02 -0500 Subject: [PATCH 10/17] r/aws_finspace_kx_dataview(doc): fmt config, tidy descriptions --- website/docs/r/finspace_kx_dataview.html.markdown | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/website/docs/r/finspace_kx_dataview.html.markdown b/website/docs/r/finspace_kx_dataview.html.markdown index 70a2b762c909..7816b6651d08 100644 --- a/website/docs/r/finspace_kx_dataview.html.markdown +++ b/website/docs/r/finspace_kx_dataview.html.markdown @@ -23,7 +23,7 @@ resource "aws_finspace_kx_dataview" "example" { description = "Terraform managed Kx Dataview" az_mode = "SINGLE" auto_update = true - + segment_configurations { volume_name = aws_finspace_kx_volume.example.name db_paths = ["/*"] @@ -36,25 +36,26 @@ resource "aws_finspace_kx_dataview" "example" { The following arguments are required: * `az_mode` - (Required) The number of availability zones you want to assign per cluster. This can be one of the following: - * SINGLE - Assigns one availability zone per cluster. - * MULTI - Assigns all the availability zones per cluster. + * `SINGLE` - Assigns one availability zone per cluster. + * `MULTI` - Assigns all the availability zones per cluster. * `database_name` - (Required) The name of the database where you want to create a dataview. * `environment_id` - (Required) Unique identifier for the KX environment. * `name` - (Required) A unique identifier for the dataview. The following arguments are optional: + * `auto_update` - (Optional) The option to specify whether you want to apply all the future additions and corrections automatically to the dataview, when you ingest new changesets. The default value is false. * `availability_zone_id` - (Optional) The identifier of the availability zones. If attaching a volume, the volume must be in the same availability zone as the dataview that you are attaching to. * `changeset_id` - (Optional) A unique identifier of the changeset of the database that you want to use to ingest data. * `description` - (Optional) A description for the dataview. -* `segment_configurations` - (Optional) The configuration that contains the database path of the data that you want to place on each selected volume. Each segment must have a unique database path for each volume. If you do not explicitly specify any database path for a volume, they are accessible from the cluster through the default S3/object store segment. See [segment_configurations](#segment_configurations). +* `segment_configurations` - (Optional) The configuration that contains the database path of the data that you want to place on each selected volume. Each segment must have a unique database path for each volume. If you do not explicitly specify any database path for a volume, they are accessible from the cluster through the default S3/object store segment. See [segment_configurations](#segment_configurations-argument-reference) below. * `tags` - (Optional) Key-value mapping of resource tags. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. -### segment_configurations +### `segment_configurations` Argument Reference + * `db_paths` - (Required) The database path of the data that you want to place on each selected volume. Each segment must have a unique database path for each volume. * `volume_name` - (Required) The name of the volume that you want to attach to a dataview. This volume must be in the same availability zone as the dataview that you are attaching to. - ## Attribute Reference This resource exports the following attributes in addition to the arguments above: From 568d51a317508d1aefa5b9a9bf89eef63cc4adb7 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 12:49:52 -0500 Subject: [PATCH 11/17] r/aws_finspace_kx_dataview(doc): terrafmt, markdownlint fixes --- website/docs/r/finspace_kx_dataview.html.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/website/docs/r/finspace_kx_dataview.html.markdown b/website/docs/r/finspace_kx_dataview.html.markdown index 7816b6651d08..ad2d6b510497 100644 --- a/website/docs/r/finspace_kx_dataview.html.markdown +++ b/website/docs/r/finspace_kx_dataview.html.markdown @@ -24,7 +24,7 @@ resource "aws_finspace_kx_dataview" "example" { az_mode = "SINGLE" auto_update = true - segment_configurations { + segment_configurations { volume_name = aws_finspace_kx_volume.example.name db_paths = ["/*"] } @@ -36,9 +36,9 @@ resource "aws_finspace_kx_dataview" "example" { The following arguments are required: * `az_mode` - (Required) The number of availability zones you want to assign per cluster. This can be one of the following: - * `SINGLE` - Assigns one availability zone per cluster. - * `MULTI` - Assigns all the availability zones per cluster. -* `database_name` - (Required) The name of the database where you want to create a dataview. + * `SINGLE` - Assigns one availability zone per cluster. + * `MULTI` - Assigns all the availability zones per cluster. +* `database_name` - (Required) The name of the database where you want to create a dataview. * `environment_id` - (Required) Unique identifier for the KX environment. * `name` - (Required) A unique identifier for the dataview. @@ -63,7 +63,7 @@ This resource exports the following attributes in addition to the arguments abov * `arn` - Amazon Resource Name (ARN) identifier of the KX dataview. * `created_timestamp` - Timestamp at which the dataview was created in FinSpace. Value determined as epoch time in milliseconds. For example, the value for Monday, November 1, 2021 12:00:00 PM UTC is specified as 1635768000000. * `id` - A comma-delimited string joining environment ID, database name and dataview name. -* `last_modified_timestamp` - The last time that the dataview was updated in FinSpace. The value is determined as epoch time in milliseconds. For example, the value for Monday, November 1, 2021 12:00:00 PM UTC is specified as 1635768000000. +* `last_modified_timestamp` - The last time that the dataview was updated in FinSpace. The value is determined as epoch time in milliseconds. For example, the value for Monday, November 1, 2021 12:00:00 PM UTC is specified as 1635768000000. * `tags_all` - Map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Timeouts From f63ea254fda343a4612f96487bb0075682e0b470 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 12:51:50 -0500 Subject: [PATCH 12/17] r/aws_finspace_kx_dataview(test): terrafmt --- internal/service/finspace/kx_dataview_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/finspace/kx_dataview_test.go b/internal/service/finspace/kx_dataview_test.go index 88096f6bc92d..0dda532a6304 100644 --- a/internal/service/finspace/kx_dataview_test.go +++ b/internal/service/finspace/kx_dataview_test.go @@ -226,7 +226,7 @@ resource "aws_finspace_kx_dataview" "test" { availability_zone_id = aws_finspace_kx_environment.test.availability_zones[0] segment_configurations { - db_paths = ["/*"] + db_paths = ["/*"] volume_name = aws_finspace_kx_volume.test.name } } From 0e0b6dded79c4ae46fd8710e2dcd902508c11ba8 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 12:55:18 -0500 Subject: [PATCH 13/17] r/aws_finspace_kx_dataview(doc): missed markdownlint --- website/docs/r/finspace_kx_dataview.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/finspace_kx_dataview.html.markdown b/website/docs/r/finspace_kx_dataview.html.markdown index ad2d6b510497..f7f77da77427 100644 --- a/website/docs/r/finspace_kx_dataview.html.markdown +++ b/website/docs/r/finspace_kx_dataview.html.markdown @@ -36,8 +36,8 @@ resource "aws_finspace_kx_dataview" "example" { The following arguments are required: * `az_mode` - (Required) The number of availability zones you want to assign per cluster. This can be one of the following: - * `SINGLE` - Assigns one availability zone per cluster. - * `MULTI` - Assigns all the availability zones per cluster. + * `SINGLE` - Assigns one availability zone per cluster. + * `MULTI` - Assigns all the availability zones per cluster. * `database_name` - (Required) The name of the database where you want to create a dataview. * `environment_id` - (Required) Unique identifier for the KX environment. * `name` - (Required) A unique identifier for the dataview. From f46235636d1a666acb5caab2f8604a7491cc1d26 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 12:57:06 -0500 Subject: [PATCH 14/17] r/aws_finspace_kx_dataview: semgrep fix --- internal/service/finspace/kx_dataview.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/finspace/kx_dataview.go b/internal/service/finspace/kx_dataview.go index a269c6b11728..28e42c5fac6b 100644 --- a/internal/service/finspace/kx_dataview.go +++ b/internal/service/finspace/kx_dataview.go @@ -375,7 +375,7 @@ func statusKxDataview(ctx context.Context, conn *finspace.Client, id string) ret } } -func expandDbPath(tfList []interface{}) []string { +func expandDBPath(tfList []interface{}) []string { if tfList == nil { return nil } @@ -397,7 +397,7 @@ func expandSegmentConfigurations(tfList []interface{}) []types.KxDataviewSegment m := v.(map[string]interface{}) s = append(s, types.KxDataviewSegmentConfiguration{ VolumeName: aws.String(m["volume_name"].(string)), - DbPaths: expandDbPath(m["db_paths"].([]interface{})), + DbPaths: expandDBPath(m["db_paths"].([]interface{})), }) } From 56bedf44ff4639874d9e166350e29376a1c7d667 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 12:58:09 -0500 Subject: [PATCH 15/17] r/aws_finspace_kx_dataview: importlint fix --- internal/service/finspace/kx_dataview.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/internal/service/finspace/kx_dataview.go b/internal/service/finspace/kx_dataview.go index 28e42c5fac6b..07bc92180df1 100644 --- a/internal/service/finspace/kx_dataview.go +++ b/internal/service/finspace/kx_dataview.go @@ -15,6 +15,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" "github.com/hashicorp/terraform-provider-aws/internal/enum" @@ -23,9 +25,6 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/internal/verify" "github.com/hashicorp/terraform-provider-aws/names" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) // @SDKResource("aws_finspace_kx_dataview", name="Kx Dataview") From 95a4157290dc7ce51c8eeed999847bba618ef4aa Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 12:59:30 -0500 Subject: [PATCH 16/17] r/aws_finspace_kx_dataview(doc): fix title heading --- website/docs/r/finspace_kx_dataview.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/finspace_kx_dataview.html.markdown b/website/docs/r/finspace_kx_dataview.html.markdown index f7f77da77427..44b77ca5aa91 100644 --- a/website/docs/r/finspace_kx_dataview.html.markdown +++ b/website/docs/r/finspace_kx_dataview.html.markdown @@ -3,10 +3,10 @@ subcategory: "FinSpace" layout: "aws" page_title: "AWS: aws_finspace_kx_dataview" description: |- - Terraform resource for managing an AWS FinSpace Kx Dataviewk. + Terraform resource for managing an AWS FinSpace Kx Dataview. --- -# Resource: aws_finspace_dataview +# Resource: aws_finspace_kx_dataview Terraform resource for managing an AWS FinSpace Kx Dataview. From ce68ad0fe44a79a050128338633622d71e1d6135 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Thu, 14 Dec 2023 14:43:29 -0500 Subject: [PATCH 17/17] r/aws_finspace_kx_dataview: linter fixes --- internal/service/finspace/kx_dataview.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/service/finspace/kx_dataview.go b/internal/service/finspace/kx_dataview.go index 07bc92180df1..9618cd46bc3c 100644 --- a/internal/service/finspace/kx_dataview.go +++ b/internal/service/finspace/kx_dataview.go @@ -30,7 +30,6 @@ import ( // @SDKResource("aws_finspace_kx_dataview", name="Kx Dataview") // @Tags(identifierAttribute="arn") func ResourceKxDataview() *schema.Resource { - return &schema.Resource{ CreateWithoutTimeout: resourceKxDataviewCreate, ReadWithoutTimeout: resourceKxDataviewRead, @@ -235,7 +234,7 @@ func resourceKxDataviewUpdate(ctx context.Context, d *schema.ResourceData, meta ClientToken: aws.String(id.UniqueId()), } - if v, ok := d.GetOk("changeset_id"); ok && d.HasChange("changeset_id") && d.Get("auto_update").(bool) != true { + if v, ok := d.GetOk("changeset_id"); ok && d.HasChange("changeset_id") && !d.Get("auto_update").(bool) { in.ChangesetId = aws.String(v.(string)) } @@ -300,7 +299,6 @@ func FindKxDataviewById(ctx context.Context, conn *finspace.Client, id string) ( LastError: err, LastRequest: in, } - } return nil, err }