diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 127524395d..83ab6ce5ae 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -4,6 +4,13 @@ This document is meant to help you migrate your Terraform config to the new newe describe deprecations or breaking changes and help you to change your configuration to keep the same (or similar) behavior across different versions. +## v0.88.0 ➞ v0.89.0 +#### *(behavior change)* ForceNew removed +The `ForceNew` field was removed in favor of in-place Update for `name` parameter in: +- `snowflake_file_format` +- `snowflake_masking_policy` +So from now, these objects won't be re-created when the `name` changes, but instead only the name will be updated with `ALTER .. RENAME TO` statements. + ## v0.87.0 ➞ v0.88.0 ### snowflake_procedure resource changes #### *(behavior change)* Execute as validation added diff --git a/pkg/resources/file_format.go b/pkg/resources/file_format.go index 53ee4b7863..6e632a5cfd 100644 --- a/pkg/resources/file_format.go +++ b/pkg/resources/file_format.go @@ -7,6 +7,8 @@ import ( "fmt" "strings" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -93,7 +95,6 @@ var fileFormatSchema = map[string]*schema.Schema{ Type: schema.TypeString, Required: true, Description: "Specifies the identifier for the file format; must be unique for the database and schema in which the file format is created.", - ForceNew: true, }, "database": { Type: schema.TypeString, @@ -767,6 +768,7 @@ func UpdateFileFormat(d *schema.ResourceData, meta interface{}) error { if d.HasChange("name") { newId := sdk.NewSchemaObjectIdentifier(id.DatabaseName(), id.SchemaName(), d.Get("name").(string)) + err := client.FileFormats.Alter(ctx, id, &sdk.AlterFileFormatOptions{ Rename: &sdk.AlterFileFormatRenameOptions{ NewName: newId, @@ -775,6 +777,8 @@ func UpdateFileFormat(d *schema.ResourceData, meta interface{}) error { if err != nil { return fmt.Errorf("error renaming file format: %w", err) } + + d.SetId(helpers.EncodeSnowflakeID(newId)) id = newId } diff --git a/pkg/resources/file_format_acceptance_test.go b/pkg/resources/file_format_acceptance_test.go index a7fc9e4e0f..4a6600fc50 100644 --- a/pkg/resources/file_format_acceptance_test.go +++ b/pkg/resources/file_format_acceptance_test.go @@ -4,6 +4,8 @@ import ( "fmt" "testing" + "github.com/hashicorp/terraform-plugin-testing/plancheck" + acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources" @@ -448,6 +450,47 @@ func TestAcc_FileFormat_issue1947(t *testing.T) { }) } +func TestAcc_FileFormat_Rename(t *testing.T) { + name := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) + newName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) + comment := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) + newComment := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) + resourceName := "snowflake_file_format.test" + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + PreCheck: func() { acc.TestAccPreCheck(t) }, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: acc.CheckDestroy(t, resources.FileFormat), + Steps: []resource.TestStep{ + { + Config: fileFormatConfigWithComment(name, acc.TestDatabaseName, acc.TestSchemaName, comment), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "comment", comment), + ), + }, + { + Config: fileFormatConfigWithComment(newName, acc.TestDatabaseName, acc.TestSchemaName, newComment), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", newName), + resource.TestCheckResourceAttr(resourceName, "comment", newComment), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate), + }, + PostApplyPostRefresh: []plancheck.PlanCheck{ + plancheck.ExpectEmptyPlan(), + }, + }, + }, + }, + }) +} + func fileFormatConfigCSV(n string, databaseName string, schemaName string, fieldDelimiter string, fieldOptionallyEnclosedBy string, comment string) string { return fmt.Sprintf(` resource "snowflake_file_format" "test" { @@ -581,6 +624,18 @@ resource "snowflake_file_format" "test" { `, n, databaseName, schemaName, formatType) } +func fileFormatConfigWithComment(n string, databaseName string, schemaName string, comment string) string { + return fmt.Sprintf(` +resource "snowflake_file_format" "test" { + name = "%v" + database = "%s" + schema = "%s" + format_type = "XML" + comment = "%s" +} +`, n, databaseName, schemaName, comment) +} + func fileFormatConfigFullDefaultsWithAdditionalParam(n string, formatType string, databaseName string, schemaName string) string { return fmt.Sprintf(` resource "snowflake_file_format" "test" { diff --git a/pkg/resources/function.go b/pkg/resources/function.go index dc3361d497..ea6da70f53 100644 --- a/pkg/resources/function.go +++ b/pkg/resources/function.go @@ -657,15 +657,17 @@ func UpdateContextFunction(ctx context.Context, d *schema.ResourceData, meta int id := sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(d.Id()) if d.HasChange("name") { - name := d.Get("name") - if err := client.Functions.Alter(ctx, sdk.NewAlterFunctionRequest(id.WithoutArguments(), id.Arguments()).WithRenameTo(sdk.Pointer(sdk.NewSchemaObjectIdentifier(id.DatabaseName(), id.SchemaName(), name.(string))))); err != nil { - return diag.FromErr(err) - } - id = sdk.NewSchemaObjectIdentifierWithArguments(id.DatabaseName(), id.SchemaName(), name.(string), id.Arguments()) - if err := d.Set("name", name); err != nil { + name := d.Get("name").(string) + newId := sdk.NewSchemaObjectIdentifierWithArguments(id.DatabaseName(), id.SchemaName(), name, id.Arguments()) + + if err := client.Functions.Alter(ctx, sdk.NewAlterFunctionRequest(id.WithoutArguments(), id.Arguments()).WithRenameTo(sdk.Pointer(newId.WithoutArguments()))); err != nil { return diag.FromErr(err) } + + d.SetId(newId.FullyQualifiedName()) + id = newId } + if d.HasChange("is_secure") { secure := d.Get("is_secure") if secure.(bool) { @@ -678,6 +680,7 @@ func UpdateContextFunction(ctx context.Context, d *schema.ResourceData, meta int } } } + if d.HasChange("comment") { comment := d.Get("comment") if comment != "" { @@ -690,6 +693,7 @@ func UpdateContextFunction(ctx context.Context, d *schema.ResourceData, meta int } } } + return ReadContextFunction(ctx, d, meta) } diff --git a/pkg/resources/function_acceptance_test.go b/pkg/resources/function_acceptance_test.go index 5ecd526463..58dcf65602 100644 --- a/pkg/resources/function_acceptance_test.go +++ b/pkg/resources/function_acceptance_test.go @@ -5,6 +5,8 @@ import ( "strings" "testing" + "github.com/hashicorp/terraform-plugin-testing/plancheck" + acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources" @@ -185,6 +187,7 @@ func TestAcc_Function_complex(t *testing.T) { // proves issue https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2490 func TestAcc_Function_migrateFromVersion085(t *testing.T) { name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + comment := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resourceName := "snowflake_function.f" resource.Test(t, resource.TestCase{ @@ -206,7 +209,7 @@ func TestAcc_Function_migrateFromVersion085(t *testing.T) { Source: "Snowflake-Labs/snowflake", }, }, - Config: functionConfig(acc.TestDatabaseName, acc.TestSchemaName, name), + Config: functionConfig(acc.TestDatabaseName, acc.TestSchemaName, name, comment), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|%s|%s|VARCHAR", acc.TestDatabaseName, acc.TestSchemaName, name)), resource.TestCheckResourceAttr(resourceName, "name", name), @@ -216,7 +219,7 @@ func TestAcc_Function_migrateFromVersion085(t *testing.T) { }, { ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, - Config: functionConfig(acc.TestDatabaseName, acc.TestSchemaName, name), + Config: functionConfig(acc.TestDatabaseName, acc.TestSchemaName, name, comment), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "id", sdk.NewSchemaObjectIdentifierWithArguments(acc.TestDatabaseName, acc.TestSchemaName, name, []sdk.DataType{sdk.DataTypeVARCHAR}).FullyQualifiedName()), resource.TestCheckResourceAttr(resourceName, "name", name), @@ -228,12 +231,54 @@ func TestAcc_Function_migrateFromVersion085(t *testing.T) { }) } -func functionConfig(database string, schema string, name string) string { +func TestAcc_Function_Rename(t *testing.T) { + name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + newName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + comment := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + newComment := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + resourceName := "snowflake_function.f" + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + PreCheck: func() { acc.TestAccPreCheck(t) }, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: acc.CheckDestroy(t, resources.Function), + Steps: []resource.TestStep{ + { + Config: functionConfig(acc.TestDatabaseName, acc.TestSchemaName, name, comment), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "comment", comment), + ), + }, + { + Config: functionConfig(acc.TestDatabaseName, acc.TestSchemaName, newName, newComment), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", newName), + resource.TestCheckResourceAttr(resourceName, "comment", newComment), + ), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate), + }, + PostApplyPostRefresh: []plancheck.PlanCheck{ + plancheck.ExpectEmptyPlan(), + }, + }, + }, + }, + }) +} + +func functionConfig(database string, schema string, name string, comment string) string { return fmt.Sprintf(` resource "snowflake_function" "f" { database = "%[1]s" schema = "%[2]s" name = "%[3]s" + comment = "%[4]s" return_type = "VARCHAR" return_behavior = "IMMUTABLE" statement = "SELECT PARAM" @@ -243,5 +288,5 @@ resource "snowflake_function" "f" { type = "VARCHAR" } } -`, database, schema, name) +`, database, schema, name, comment) } diff --git a/pkg/resources/masking_policy.go b/pkg/resources/masking_policy.go index 81bd4b8514..825063f182 100644 --- a/pkg/resources/masking_policy.go +++ b/pkg/resources/masking_policy.go @@ -35,7 +35,6 @@ var maskingPolicySchema = map[string]*schema.Schema{ Type: schema.TypeString, Required: true, Description: "Specifies the identifier for the masking policy; must be unique for the database and schema in which the masking policy is created.", - ForceNew: true, }, "database": { Type: schema.TypeString, @@ -250,16 +249,30 @@ func ReadMaskingPolicy(d *schema.ResourceData, meta interface{}) error { // UpdateMaskingPolicy implements schema.UpdateFunc. func UpdateMaskingPolicy(d *schema.ResourceData, meta interface{}) error { client := meta.(*provider.Context).Client - objectIdentifier := helpers.DecodeSnowflakeID(d.Id()).(sdk.SchemaObjectIdentifier) + id := helpers.DecodeSnowflakeID(d.Id()).(sdk.SchemaObjectIdentifier) ctx := context.Background() + if d.HasChange("name") { + newID := sdk.NewSchemaObjectIdentifier(id.DatabaseName(), id.SchemaName(), d.Get("name").(string)) + + err := client.MaskingPolicies.Alter(ctx, id, &sdk.AlterMaskingPolicyOptions{ + NewName: &newID, + }) + if err != nil { + return err + } + + d.SetId(helpers.EncodeSnowflakeID(newID)) + id = newID + } + if d.HasChange("masking_expression") { alterOptions := &sdk.AlterMaskingPolicyOptions{} _, n := d.GetChange("masking_expression") alterOptions.Set = &sdk.MaskingPolicySet{ Body: sdk.String(n.(string)), } - err := client.MaskingPolicies.Alter(ctx, objectIdentifier, alterOptions) + err := client.MaskingPolicies.Alter(ctx, id, alterOptions) if err != nil { return err } @@ -276,26 +289,12 @@ func UpdateMaskingPolicy(d *schema.ResourceData, meta interface{}) error { Comment: sdk.Bool(true), } } - err := client.MaskingPolicies.Alter(ctx, objectIdentifier, alterOptions) + err := client.MaskingPolicies.Alter(ctx, id, alterOptions) if err != nil { return err } } - if d.HasChange("name") { - _, n := d.GetChange("name") - newName := n.(string) - newID := sdk.NewSchemaObjectIdentifier(objectIdentifier.DatabaseName(), objectIdentifier.SchemaName(), newName) - alterOptions := &sdk.AlterMaskingPolicyOptions{ - NewName: &newID, - } - err := client.MaskingPolicies.Alter(ctx, objectIdentifier, alterOptions) - if err != nil { - return err - } - d.SetId(helpers.EncodeSnowflakeID(newID)) - } - return ReadMaskingPolicy(d, meta) } diff --git a/pkg/resources/masking_policy_acceptance_test.go b/pkg/resources/masking_policy_acceptance_test.go index 2d270a343e..b814ea2922 100644 --- a/pkg/resources/masking_policy_acceptance_test.go +++ b/pkg/resources/masking_policy_acceptance_test.go @@ -5,12 +5,13 @@ import ( "strings" "testing" + "github.com/hashicorp/terraform-plugin-testing/plancheck" + acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" - "github.com/hashicorp/terraform-plugin-testing/plancheck" "github.com/hashicorp/terraform-plugin-testing/tfversion" ) @@ -42,19 +43,17 @@ func TestAcc_MaskingPolicy(t *testing.T) { resource.TestCheckResourceAttr("snowflake_masking_policy.test", "signature.0.column.0.type", "VARCHAR"), ), }, - // change comment - { - Config: maskingPolicyConfig(accName, accName, comment2, acc.TestDatabaseName, acc.TestSchemaName), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("snowflake_masking_policy.test", "name", accName), - resource.TestCheckResourceAttr("snowflake_masking_policy.test", "comment", comment2), - ), - }, - // rename + // rename + change comment { Config: maskingPolicyConfig(accName, accName2, comment2, acc.TestDatabaseName, acc.TestSchemaName), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("snowflake_masking_policy.test", plancheck.ResourceActionUpdate), + }, + }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_masking_policy.test", "name", accName2), + resource.TestCheckResourceAttr("snowflake_masking_policy.test", "comment", comment2), ), }, // change body and unset comment diff --git a/pkg/resources/materialized_view.go b/pkg/resources/materialized_view.go index 91d46c260b..e2f20979aa 100644 --- a/pkg/resources/materialized_view.go +++ b/pkg/resources/materialized_view.go @@ -185,9 +185,7 @@ func UpdateMaterializedView(d *schema.ResourceData, meta interface{}) error { id := helpers.DecodeSnowflakeID(d.Id()).(sdk.SchemaObjectIdentifier) if d.HasChange("name") { - newName := d.Get("name").(string) - - newId := sdk.NewSchemaObjectIdentifier(id.DatabaseName(), id.SchemaName(), newName) + newId := sdk.NewSchemaObjectIdentifier(id.DatabaseName(), id.SchemaName(), d.Get("name").(string)) err := client.MaterializedViews.Alter(ctx, sdk.NewAlterMaterializedViewRequest(id).WithRenameTo(&newId)) if err != nil { diff --git a/pkg/resources/password_policy.go b/pkg/resources/password_policy.go index a0c5ec0c83..b83fd017e8 100644 --- a/pkg/resources/password_policy.go +++ b/pkg/resources/password_policy.go @@ -266,6 +266,20 @@ func UpdatePasswordPolicy(d *schema.ResourceData, meta interface{}) error { objectIdentifier := helpers.DecodeSnowflakeID(d.Id()).(sdk.SchemaObjectIdentifier) + if d.HasChange("name") { + newId := sdk.NewSchemaObjectIdentifier(objectIdentifier.DatabaseName(), objectIdentifier.SchemaName(), d.Get("name").(string)) + + err := client.PasswordPolicies.Alter(ctx, objectIdentifier, &sdk.AlterPasswordPolicyOptions{ + NewName: &newId, + }) + if err != nil { + return err + } + + d.SetId(helpers.EncodeSnowflakeID(newId)) + objectIdentifier = newId + } + if d.HasChange("min_length") { alterOptions := &sdk.AlterPasswordPolicyOptions{ Set: &sdk.PasswordPolicySet{ @@ -412,20 +426,6 @@ func UpdatePasswordPolicy(d *schema.ResourceData, meta interface{}) error { } } - if d.HasChange("name") { - _, n := d.GetChange("name") - newName := n.(string) - newID := sdk.NewSchemaObjectIdentifier(objectIdentifier.DatabaseName(), objectIdentifier.SchemaName(), newName) - alterOptions := &sdk.AlterPasswordPolicyOptions{ - NewName: &newID, - } - err := client.PasswordPolicies.Alter(ctx, objectIdentifier, alterOptions) - if err != nil { - return err - } - d.SetId(helpers.EncodeSnowflakeID(newID)) - } - return ReadPasswordPolicy(d, meta) } diff --git a/pkg/resources/password_policy_acceptance_test.go b/pkg/resources/password_policy_acceptance_test.go index ccf44d2878..15462c81bb 100644 --- a/pkg/resources/password_policy_acceptance_test.go +++ b/pkg/resources/password_policy_acceptance_test.go @@ -4,6 +4,8 @@ import ( "strings" "testing" + "github.com/hashicorp/terraform-plugin-testing/plancheck" + acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources" @@ -102,16 +104,21 @@ func TestAcc_PasswordPolicy(t *testing.T) { } func TestAcc_PasswordPolicyMaxAgeDays(t *testing.T) { - accName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + newName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + m := func(maxAgeDays int) map[string]config.Variable { return map[string]config.Variable{ - "name": config.StringVariable(accName), + "name": config.StringVariable(name), "database": config.StringVariable(acc.TestDatabaseName), "schema": config.StringVariable(acc.TestSchemaName), "max_age_days": config.IntegerVariable(maxAgeDays), } } + configValueWithNewName := m(10) + configValueWithNewName["name"] = config.StringVariable(newName) + resource.Test(t, resource.TestCase{ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, PreCheck: func() { acc.TestAccPreCheck(t) }, @@ -143,22 +150,28 @@ func TestAcc_PasswordPolicyMaxAgeDays(t *testing.T) { resource.TestCheckResourceAttr("snowflake_password_policy.pa", "max_age_days", "0"), ), }, - // Unsets properly + // Rename + Unsets properly { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_PasswordPolicy_noOptionals"), ConfigVariables: map[string]config.Variable{ - "name": config.StringVariable(accName), + "name": config.StringVariable(newName), "database": config.StringVariable(acc.TestDatabaseName), "schema": config.StringVariable(acc.TestSchemaName), }, + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("snowflake_password_policy.pa", plancheck.ResourceActionUpdate), + }, + }, Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("snowflake_password_policy.pa", "name", newName), resource.TestCheckResourceAttr("snowflake_password_policy.pa", "max_age_days", "90"), ), }, { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_PasswordPolicy_noOptionals"), ConfigVariables: map[string]config.Variable{ - "name": config.StringVariable(accName), + "name": config.StringVariable(name), "database": config.StringVariable(acc.TestDatabaseName), "schema": config.StringVariable(acc.TestSchemaName), }, diff --git a/pkg/resources/pipe.go b/pkg/resources/pipe.go index 95cb69c15b..b11f7e13b1 100644 --- a/pkg/resources/pipe.go +++ b/pkg/resources/pipe.go @@ -13,10 +13,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -const ( - pipeIDDelimiter = '|' -) - var pipeSchema = map[string]*schema.Schema{ "name": { Type: schema.TypeString, diff --git a/pkg/resources/procedure.go b/pkg/resources/procedure.go index 649849a9d5..3134bde041 100644 --- a/pkg/resources/procedure.go +++ b/pkg/resources/procedure.go @@ -660,16 +660,17 @@ func UpdateContextProcedure(ctx context.Context, d *schema.ResourceData, meta in id := sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(d.Id()) if d.HasChange("name") { - name := d.Get("name") - err := client.Procedures.Alter(ctx, sdk.NewAlterProcedureRequest(id.WithoutArguments(), id.Arguments()).WithRenameTo(sdk.Pointer(sdk.NewSchemaObjectIdentifier(id.DatabaseName(), id.SchemaName(), name.(string))))) + newId := sdk.NewSchemaObjectIdentifierWithArguments(id.DatabaseName(), id.SchemaName(), d.Get("name").(string), id.Arguments()) + + err := client.Procedures.Alter(ctx, sdk.NewAlterProcedureRequest(id.WithoutArguments(), id.Arguments()).WithRenameTo(sdk.Pointer(newId.WithoutArguments()))) if err != nil { return diag.FromErr(err) } - id = sdk.NewSchemaObjectIdentifierWithArguments(id.DatabaseName(), id.SchemaName(), name.(string), id.Arguments()) - if err := d.Set("name", name); err != nil { - return diag.FromErr(err) - } + + d.SetId(newId.FullyQualifiedName()) + id = newId } + if d.HasChange("comment") { comment := d.Get("comment") if comment != "" { @@ -682,6 +683,7 @@ func UpdateContextProcedure(ctx context.Context, d *schema.ResourceData, meta in } } } + if d.HasChange("execute_as") { req := sdk.NewAlterProcedureRequest(id.WithoutArguments(), id.Arguments()) executeAs := d.Get("execute_as").(string) @@ -694,6 +696,7 @@ func UpdateContextProcedure(ctx context.Context, d *schema.ResourceData, meta in return diag.FromErr(err) } } + return ReadContextProcedure(ctx, d, meta) } diff --git a/pkg/resources/procedure_acceptance_test.go b/pkg/resources/procedure_acceptance_test.go index 89e77c0bed..fd99c55fa6 100644 --- a/pkg/resources/procedure_acceptance_test.go +++ b/pkg/resources/procedure_acceptance_test.go @@ -20,6 +20,8 @@ func testAccProcedure(t *testing.T, configDirectory string) { t.Helper() name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + newName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + resourceName := "snowflake_procedure.p" m := func() map[string]config.Variable { return map[string]config.Variable{ @@ -31,6 +33,7 @@ func testAccProcedure(t *testing.T, configDirectory string) { } } variableSet2 := m() + variableSet2["name"] = config.StringVariable(newName) variableSet2["comment"] = config.StringVariable("Terraform acceptance test - updated") variableSet2["execute_as"] = config.StringVariable("OWNER") @@ -65,12 +68,17 @@ func testAccProcedure(t *testing.T, configDirectory string) { ), }, - // test - change comment and caller (proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2642) + // test - rename + change comment and caller (proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2642) { ConfigDirectory: acc.ConfigurationDirectory(configDirectory), ConfigVariables: variableSet2, + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate), + }, + }, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "name", newName), resource.TestCheckResourceAttr(resourceName, "database", acc.TestDatabaseName), resource.TestCheckResourceAttr(resourceName, "schema", acc.TestSchemaName), resource.TestCheckResourceAttr(resourceName, "comment", "Terraform acceptance test - updated"), diff --git a/pkg/resources/schema.go b/pkg/resources/schema.go index e1b6cbeac8..fb8bf1fffd 100644 --- a/pkg/resources/schema.go +++ b/pkg/resources/schema.go @@ -17,10 +17,6 @@ import ( "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" ) -const ( - schemaIDDelimiter = '|' -) - var schemaSchema = map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -185,14 +181,17 @@ func UpdateSchema(d *schema.ResourceData, meta interface{}) error { ctx := context.Background() if d.HasChange("name") { - newName := d.Get("name") + newId := sdk.NewDatabaseObjectIdentifier(id.DatabaseName(), d.Get("name").(string)) + err := client.Schemas.Alter(ctx, id, &sdk.AlterSchemaOptions{ - NewName: sdk.NewDatabaseObjectIdentifier(id.DatabaseName(), newName.(string)), + NewName: newId, }) if err != nil { return fmt.Errorf("error updating schema name on %v err = %w", d.Id(), err) } - d.SetId(helpers.EncodeSnowflakeID(id.DatabaseName(), newName)) + + d.SetId(helpers.EncodeSnowflakeID(newId)) + id = newId } if d.HasChange("comment") { diff --git a/pkg/resources/schema_acceptance_test.go b/pkg/resources/schema_acceptance_test.go index 926861a967..c3037008b4 100644 --- a/pkg/resources/schema_acceptance_test.go +++ b/pkg/resources/schema_acceptance_test.go @@ -104,6 +104,11 @@ func TestAcc_Schema_Rename(t *testing.T) { "database": config.StringVariable(acc.TestDatabaseName), "comment": config.StringVariable(comment), }, + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("snowflake_schema.test", plancheck.ResourceActionUpdate), + }, + }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_schema.test", "name", newSchemaName), resource.TestCheckResourceAttr("snowflake_schema.test", "database", acc.TestDatabaseName), @@ -336,7 +341,7 @@ func TestAcc_Schema_RemoveDatabaseOutsideOfTerraform(t *testing.T) { ExpectNonEmptyPlan: true, RefreshPlanChecks: resource.RefreshPlanChecks{ PostRefresh: []plancheck.PlanCheck{ - expectsCreatePlan("snowflake_schema.test"), + plancheck.ExpectResourceAction("snowflake_schema.test", plancheck.ResourceActionCreate), }, }, }, diff --git a/pkg/resources/table.go b/pkg/resources/table.go index daec0b1902..a09174ef79 100644 --- a/pkg/resources/table.go +++ b/pkg/resources/table.go @@ -43,7 +43,6 @@ var tableSchema = map[string]*schema.Schema{ Optional: true, Description: "A list of one or more table columns/expressions to be used as clustering key(s) for the table", }, - "column": { Type: schema.TypeList, Required: true, @@ -688,9 +687,7 @@ func UpdateTable(d *schema.ResourceData, meta interface{}) error { id := helpers.DecodeSnowflakeID(d.Id()).(sdk.SchemaObjectIdentifier) if d.HasChange("name") { - newName := d.Get("name").(string) - - newId := sdk.NewSchemaObjectIdentifier(id.DatabaseName(), id.SchemaName(), newName) + newId := sdk.NewSchemaObjectIdentifier(id.DatabaseName(), id.SchemaName(), d.Get("name").(string)) err := client.Tables.Alter(ctx, sdk.NewAlterTableRequest(id).WithNewName(&newId)) if err != nil { diff --git a/pkg/resources/table_acceptance_test.go b/pkg/resources/table_acceptance_test.go index cfe494f821..8f03d72471 100644 --- a/pkg/resources/table_acceptance_test.go +++ b/pkg/resources/table_acceptance_test.go @@ -1401,6 +1401,8 @@ resource "snowflake_table" "test_table" { func TestAcc_TableRename(t *testing.T) { oldTableName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) newTableName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + oldComment := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + newComment := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) resource.Test(t, resource.TestCase{ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, @@ -1411,11 +1413,12 @@ func TestAcc_TableRename(t *testing.T) { CheckDestroy: acc.CheckDestroy(t, resources.Table), Steps: []resource.TestStep{ { - Config: tableConfigWithName(oldTableName, acc.TestDatabaseName, acc.TestSchemaName), + Config: tableConfigWithName(oldTableName, acc.TestDatabaseName, acc.TestSchemaName, oldComment), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_table.test_table", "name", oldTableName), resource.TestCheckResourceAttr("snowflake_table.test_table", "database", acc.TestDatabaseName), resource.TestCheckResourceAttr("snowflake_table.test_table", "schema", acc.TestSchemaName), + resource.TestCheckResourceAttr("snowflake_table.test_table", "comment", oldComment), resource.TestCheckResourceAttr("snowflake_table.test_table", "change_tracking", "false"), resource.TestCheckResourceAttr("snowflake_table.test_table", "column.#", "1"), resource.TestCheckResourceAttr("snowflake_table.test_table", "column.0.name", "column1"), @@ -1424,11 +1427,17 @@ func TestAcc_TableRename(t *testing.T) { ), }, { - Config: tableConfigWithName(newTableName, acc.TestDatabaseName, acc.TestSchemaName), + Config: tableConfigWithName(newTableName, acc.TestDatabaseName, acc.TestSchemaName, newComment), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("snowflake_table.test_table", plancheck.ResourceActionUpdate), + }, + }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_table.test_table", "name", newTableName), resource.TestCheckResourceAttr("snowflake_table.test_table", "database", acc.TestDatabaseName), resource.TestCheckResourceAttr("snowflake_table.test_table", "schema", acc.TestSchemaName), + resource.TestCheckResourceAttr("snowflake_table.test_table", "comment", newComment), resource.TestCheckResourceAttr("snowflake_table.test_table", "change_tracking", "false"), resource.TestCheckResourceAttr("snowflake_table.test_table", "column.#", "1"), resource.TestCheckResourceAttr("snowflake_table.test_table", "column.0.name", "column1"), @@ -1440,19 +1449,20 @@ func TestAcc_TableRename(t *testing.T) { }) } -func tableConfigWithName(tableName string, databaseName string, schemaName string) string { +func tableConfigWithName(tableName string, databaseName string, schemaName string, comment string) string { s := ` resource "snowflake_table" "test_table" { name = "%s" database = "%s" schema = "%s" + comment = "%s" column { name = "column1" type = "VARIANT" } } ` - return fmt.Sprintf(s, tableName, databaseName, schemaName) + return fmt.Sprintf(s, tableName, databaseName, schemaName, comment) } func TestAcc_Table_MaskingPolicy(t *testing.T) { diff --git a/pkg/resources/table_constraint.go b/pkg/resources/table_constraint.go index eff442d0bc..ccabb7f7cf 100644 --- a/pkg/resources/table_constraint.go +++ b/pkg/resources/table_constraint.go @@ -342,6 +342,7 @@ func CreateTableConstraint(d *schema.ResourceData, meta interface{}) error { // ReadTableConstraint implements schema.ReadFunc. func ReadTableConstraint(_ *schema.ResourceData, _ interface{}) error { + // TODO(issue-2683): Implement read operation // commenting this out since it requires an active warehouse to be set which may not be intuitive. // also it takes a while for the database to reflect changes. Would likely need to add a validation // step like in tag association. People don't like waiting 40 minutes for Terraform to run. @@ -362,6 +363,7 @@ func ReadTableConstraint(_ *schema.ResourceData, _ interface{}) error { // UpdateTableConstraint implements schema.UpdateFunc. func UpdateTableConstraint(d *schema.ResourceData, meta interface{}) error { + /* TODO(issue-2683): Update isn't be possible with non-existing Read operation. The Update logic is ready to be uncommented once the Read operation is ready. client := meta.(*provider.Context).Client ctx := context.Background() @@ -373,15 +375,20 @@ func UpdateTableConstraint(d *schema.ResourceData, meta interface{}) error { return err } - if d.HasChange("name") { - _, n := d.GetChange("name") - constraintRequest := sdk.NewTableConstraintRenameActionRequest().WithOldName(tc.name).WithNewName(n.(string)) - alterStatement := sdk.NewAlterTableRequest(*tableIdentifier).WithConstraintAction(sdk.NewTableConstraintActionRequest().WithRename(constraintRequest)) - err = client.Tables.Alter(ctx, alterStatement) - if err != nil { - return fmt.Errorf("error renaming table constraint %s err = %w", tc.name, err) + if d.HasChange("name") { + newName := d.Get("name").(string) + constraintRequest := sdk.NewTableConstraintRenameActionRequest().WithOldName(tc.name).WithNewName(newName) + alterStatement := sdk.NewAlterTableRequest(*tableIdentifier).WithConstraintAction(sdk.NewTableConstraintActionRequest().WithRename(constraintRequest)) + + err = client.Tables.Alter(ctx, alterStatement) + if err != nil { + return fmt.Errorf("error renaming table constraint %s err = %w", tc.name, err) + } + + tc.name = newName + d.SetId(tc.String()) } - } + */ return ReadTableConstraint(d, meta) } diff --git a/pkg/resources/table_constraint_acceptance_test.go b/pkg/resources/table_constraint_acceptance_test.go index 29324b03e1..fd43240570 100644 --- a/pkg/resources/table_constraint_acceptance_test.go +++ b/pkg/resources/table_constraint_acceptance_test.go @@ -299,6 +299,40 @@ func TestAcc_Table_issue2535_existingTable(t *testing.T) { }) } +// TODO(issue-2683): Uncomment once the Update operation is ready +// func TestAcc_TableConstraint_Rename(t *testing.T) { +// name := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) +// newName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) +// +// resource.Test(t, resource.TestCase{ +// ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, +// PreCheck: func() { acc.TestAccPreCheck(t) }, +// TerraformVersionChecks: []tfversion.TerraformVersionCheck{ +// tfversion.RequireAbove(tfversion.Version1_5_0), +// }, +// CheckDestroy: nil, +// Steps: []resource.TestStep{ +// { +// Config: tableConstraintUniqueConfigUsingFullyQualifiedName(name, acc.TestDatabaseName, acc.TestSchemaName), +// Check: resource.ComposeTestCheckFunc( +// resource.TestCheckResourceAttr("snowflake_table_constraint.unique", "name", name), +// ), +// }, +// { +// Config: tableConstraintUniqueConfigUsingFullyQualifiedName(newName, acc.TestDatabaseName, acc.TestSchemaName), +// ConfigPlanChecks: resource.ConfigPlanChecks{ +// PreApply: []plancheck.PlanCheck{ +// plancheck.ExpectResourceAction("snowflake_table_constraint.unique", plancheck.ResourceActionUpdate), +// }, +// }, +// Check: resource.ComposeTestCheckFunc( +// resource.TestCheckResourceAttr("snowflake_table_constraint.unique", "name", newName), +// ), +// }, +// }, +// }) +//} + func tableConstraintUniqueConfigUsingFullyQualifiedName(n string, databaseName string, schemaName string) string { return fmt.Sprintf(` resource "snowflake_table" "t" { @@ -342,3 +376,26 @@ resource "snowflake_table_constraint" "unique" { } `, n, databaseName, schemaName, n) } + +func tableConstraintWithNameAndComment(databaseName string, schemaName string, name string, comment string) string { + return fmt.Sprintf(` +resource "snowflake_table" "t" { + name = "%s" + database = "%s" + schema = "%s" + + column { + name = "col1" + type = "NUMBER(38,0)" + } +} + +resource "snowflake_table_constraint" "test" { + name = "%s" + comment = "%s" + type = "UNIQUE" + table_id = snowflake_table.t.id + columns = ["col1"] +} +`, name, databaseName, schemaName, name, comment) +} diff --git a/pkg/resources/user.go b/pkg/resources/user.go index de0fa33345..ae5d53534f 100644 --- a/pkg/resources/user.go +++ b/pkg/resources/user.go @@ -14,24 +14,6 @@ import ( "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" ) -var userProperties = []string{ - "comment", - "login_name", - "password", - "disabled", - "default_namespace", - "default_role", - "default_secondary_roles", - "default_warehouse", - "rsa_public_key", - "rsa_public_key_2", - "must_change_password", - "email", - "display_name", - "first_name", - "last_name", -} - var diffCaseInsensitive = func(k, old, new string, d *schema.ResourceData) bool { return strings.EqualFold(old, new) } @@ -311,19 +293,19 @@ func UpdateUser(d *schema.ResourceData, meta interface{}) error { id := helpers.DecodeSnowflakeID(d.Id()).(sdk.AccountObjectIdentifier) if d.HasChange("name") { - _, n := d.GetChange("name") - newName := n.(string) - newID := sdk.NewAccountObjectIdentifier(newName) - alterOptions := &sdk.AlterUserOptions{ + newID := sdk.NewAccountObjectIdentifier(d.Get("name").(string)) + + err := client.Users.Alter(ctx, id, &sdk.AlterUserOptions{ NewName: newID, - } - err := client.Users.Alter(ctx, id, alterOptions) + }) if err != nil { return err } + d.SetId(helpers.EncodeSnowflakeID(newID)) id = newID } + runSet := false alterOptions := &sdk.AlterUserOptions{ Set: &sdk.UserSet{ diff --git a/pkg/resources/user_acceptance_test.go b/pkg/resources/user_acceptance_test.go index a6865de0d8..31d08cbef3 100644 --- a/pkg/resources/user_acceptance_test.go +++ b/pkg/resources/user_acceptance_test.go @@ -41,8 +41,13 @@ func TestAcc_User(t *testing.T) { r := require.New(t) prefix := "tst-terraform" + strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) prefix2 := "tst-terraform" + strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + + comment := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + newComment := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + sshkey1, err := testhelpers.Fixture("userkey1") r.NoError(err) + sshkey2, err := testhelpers.Fixture("userkey2") r.NoError(err) @@ -55,10 +60,10 @@ func TestAcc_User(t *testing.T) { CheckDestroy: acc.CheckDestroy(t, resources.User), Steps: []resource.TestStep{ { - Config: uConfig(prefix, sshkey1, sshkey2), + Config: uConfig(prefix, sshkey1, sshkey2, comment), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_user.w", "name", prefix), - resource.TestCheckResourceAttr("snowflake_user.w", "comment", "test comment"), + resource.TestCheckResourceAttr("snowflake_user.w", "comment", comment), resource.TestCheckResourceAttr("snowflake_user.w", "login_name", strings.ToUpper(fmt.Sprintf("%s_login", prefix))), resource.TestCheckResourceAttr("snowflake_user.w", "display_name", "Display Name"), resource.TestCheckResourceAttr("snowflake_user.w", "first_name", "Marcin"), @@ -75,10 +80,15 @@ func TestAcc_User(t *testing.T) { }, // RENAME { - Config: uConfig(prefix2, sshkey1, sshkey2), + Config: uConfig(prefix2, sshkey1, sshkey2, newComment), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("snowflake_user.w", plancheck.ResourceActionUpdate), + }, + }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_user.w", "name", prefix2), - resource.TestCheckResourceAttr("snowflake_user.w", "comment", "test comment"), + resource.TestCheckResourceAttr("snowflake_user.w", "comment", newComment), resource.TestCheckResourceAttr("snowflake_user.w", "login_name", strings.ToUpper(fmt.Sprintf("%s_login", prefix2))), resource.TestCheckResourceAttr("snowflake_user.w", "display_name", "Display Name"), resource.TestCheckResourceAttr("snowflake_user.w", "first_name", "Marcin"), @@ -181,11 +191,11 @@ func removeUserOutsideOfTerraform(t *testing.T, name sdk.AccountObjectIdentifier } } -func uConfig(prefix, key1, key2 string) string { +func uConfig(prefix, key1, key2, comment string) string { s := ` resource "snowflake_user" "w" { name = "%s" - comment = "test comment" + comment = "%s" login_name = "%s_login" display_name = "Display Name" first_name = "Marcin" @@ -205,7 +215,7 @@ KEY must_change_password = true } ` - s = fmt.Sprintf(s, prefix, prefix, key1, key2) + s = fmt.Sprintf(s, prefix, comment, prefix, key1, key2) log.Printf("[DEBUG] s %s", s) return s } @@ -252,7 +262,7 @@ func TestAcc_User_issue2058(t *testing.T) { CheckDestroy: acc.CheckDestroy(t, resources.User), Steps: []resource.TestStep{ { - Config: uConfig(prefix, sshkey1, sshkey2), + Config: uConfig(prefix, sshkey1, sshkey2, "test_comment"), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_user.w", "name", prefix), ), diff --git a/pkg/resources/view.go b/pkg/resources/view.go index 30564b8e8d..0eb8bb1ef2 100644 --- a/pkg/resources/view.go +++ b/pkg/resources/view.go @@ -223,9 +223,7 @@ func UpdateView(d *schema.ResourceData, meta interface{}) error { } if d.HasChange("name") { - newName := d.Get("name").(string) - - newId := sdk.NewSchemaObjectIdentifier(id.DatabaseName(), id.SchemaName(), newName) + newId := sdk.NewSchemaObjectIdentifier(id.DatabaseName(), id.SchemaName(), d.Get("name").(string)) err := client.Views.Alter(ctx, sdk.NewAlterViewRequest(id).WithRenameTo(&newId)) if err != nil { diff --git a/pkg/resources/view_acceptance_test.go b/pkg/resources/view_acceptance_test.go index 85f4d9040d..4aabc9a3cf 100644 --- a/pkg/resources/view_acceptance_test.go +++ b/pkg/resources/view_acceptance_test.go @@ -7,6 +7,8 @@ import ( "strings" "testing" + "github.com/hashicorp/terraform-plugin-testing/plancheck" + acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources" @@ -222,6 +224,11 @@ func TestAcc_View_Rename(t *testing.T) { { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_View_basic"), ConfigVariables: m2, + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("snowflake_view.test", plancheck.ResourceActionUpdate), + }, + }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_view.test", "name", newViewName), resource.TestCheckResourceAttr("snowflake_view.test", "comment", "new comment"), diff --git a/pkg/resources/warehouse.go b/pkg/resources/warehouse.go index 4a7f998079..a2c8f40c3b 100644 --- a/pkg/resources/warehouse.go +++ b/pkg/resources/warehouse.go @@ -319,18 +319,17 @@ func UpdateWarehouse(d *schema.ResourceData, meta interface{}) error { // Change name separately if d.HasChange("name") { - if v, ok := d.GetOk("name"); ok { - newName := sdk.NewAccountObjectIdentifier(v.(string)) - err := client.Warehouses.Alter(ctx, id, &sdk.AlterWarehouseOptions{ - NewName: &newName, - }) - if err != nil { - return err - } - d.SetId(helpers.EncodeSnowflakeID(newName)) - } else { - panic("name has to be set") + newId := sdk.NewAccountObjectIdentifier(d.Get("name").(string)) + + err := client.Warehouses.Alter(ctx, id, &sdk.AlterWarehouseOptions{ + NewName: &newId, + }) + if err != nil { + return err } + + d.SetId(helpers.EncodeSnowflakeID(newId)) + id = newId } // Batch SET operations and UNSET operations diff --git a/pkg/resources/warehouse_acceptance_test.go b/pkg/resources/warehouse_acceptance_test.go index a027e6c5be..a8b8e7c9a8 100644 --- a/pkg/resources/warehouse_acceptance_test.go +++ b/pkg/resources/warehouse_acceptance_test.go @@ -20,6 +20,8 @@ import ( func TestAcc_Warehouse(t *testing.T) { prefix := "tst-terraform" + strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) prefix2 := "tst-terraform" + strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + comment := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) + newComment := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) resource.Test(t, resource.TestCase{ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, @@ -30,10 +32,10 @@ func TestAcc_Warehouse(t *testing.T) { CheckDestroy: acc.CheckDestroy(t, resources.Warehouse), Steps: []resource.TestStep{ { - Config: wConfig(prefix), + Config: wConfig(prefix, comment), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_warehouse.w", "name", prefix), - resource.TestCheckResourceAttr("snowflake_warehouse.w", "comment", "test comment"), + resource.TestCheckResourceAttr("snowflake_warehouse.w", "comment", comment), resource.TestCheckResourceAttr("snowflake_warehouse.w", "auto_suspend", "60"), resource.TestCheckResourceAttrSet("snowflake_warehouse.w", "warehouse_size"), resource.TestCheckResourceAttr("snowflake_warehouse.w", "max_concurrency_level", "8"), @@ -42,20 +44,25 @@ func TestAcc_Warehouse(t *testing.T) { }, // RENAME { - Config: wConfig(prefix2), + Config: wConfig(prefix2, newComment), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("snowflake_warehouse.w", plancheck.ResourceActionUpdate), + }, + }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_warehouse.w", "name", prefix2), - resource.TestCheckResourceAttr("snowflake_warehouse.w", "comment", "test comment"), + resource.TestCheckResourceAttr("snowflake_warehouse.w", "comment", newComment), resource.TestCheckResourceAttr("snowflake_warehouse.w", "auto_suspend", "60"), resource.TestCheckResourceAttrSet("snowflake_warehouse.w", "warehouse_size"), ), }, // CHANGE PROPERTIES (proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2652) { - Config: wConfig2(prefix2, "X-LARGE", 20, 2), + Config: wConfig2(prefix2, "X-LARGE", 20, 2, newComment), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_warehouse.w", "name", prefix2), - resource.TestCheckResourceAttr("snowflake_warehouse.w", "comment", "test comment 2"), + resource.TestCheckResourceAttr("snowflake_warehouse.w", "comment", newComment), resource.TestCheckResourceAttr("snowflake_warehouse.w", "auto_suspend", "60"), resource.TestCheckResourceAttr("snowflake_warehouse.w", "warehouse_size", "XLARGE"), resource.TestCheckResourceAttr("snowflake_warehouse.w", "max_concurrency_level", "20"), @@ -64,13 +71,13 @@ func TestAcc_Warehouse(t *testing.T) { }, // CHANGE JUST max_concurrency_level { - Config: wConfig2(prefix2, "XLARGE", 16, 2), + Config: wConfig2(prefix2, "XLARGE", 16, 2, newComment), ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{plancheck.ExpectNonEmptyPlan()}, }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_warehouse.w", "name", prefix2), - resource.TestCheckResourceAttr("snowflake_warehouse.w", "comment", "test comment 2"), + resource.TestCheckResourceAttr("snowflake_warehouse.w", "comment", newComment), resource.TestCheckResourceAttr("snowflake_warehouse.w", "auto_suspend", "60"), resource.TestCheckResourceAttr("snowflake_warehouse.w", "warehouse_size", "XLARGE"), resource.TestCheckResourceAttr("snowflake_warehouse.w", "max_concurrency_level", "16"), @@ -82,16 +89,15 @@ func TestAcc_Warehouse(t *testing.T) { ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{plancheck.ExpectNonEmptyPlan()}, }, - Config: wConfig2(prefix2, "XLARGE", 16, 2), + Config: wConfig2(prefix2, "XLARGE", 16, 2, newComment), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_warehouse.w", "name", prefix2), - resource.TestCheckResourceAttr("snowflake_warehouse.w", "comment", "test comment 2"), + resource.TestCheckResourceAttr("snowflake_warehouse.w", "comment", newComment), resource.TestCheckResourceAttr("snowflake_warehouse.w", "auto_suspend", "60"), resource.TestCheckResourceAttr("snowflake_warehouse.w", "warehouse_size", "XLARGE"), resource.TestCheckResourceAttr("snowflake_warehouse.w", "max_concurrency_level", "16"), ), }, - // IMPORT { ResourceName: "snowflake_warehouse.w", @@ -132,11 +138,11 @@ func TestAcc_WarehousePattern(t *testing.T) { }) } -func wConfig(prefix string) string { +func wConfig(prefix string, comment string) string { return fmt.Sprintf(` resource "snowflake_warehouse" "w" { name = "%s" - comment = "test comment" + comment = "%s" auto_suspend = 60 max_cluster_count = 4 @@ -146,14 +152,14 @@ resource "snowflake_warehouse" "w" { initially_suspended = true wait_for_provisioning = false } -`, prefix) +`, prefix, comment) } -func wConfig2(prefix string, size string, maxConcurrencyLevel int, minClusterCount int) string { +func wConfig2(prefix string, size string, maxConcurrencyLevel int, minClusterCount int, comment string) string { return fmt.Sprintf(` resource "snowflake_warehouse" "w" { name = "%[1]s" - comment = "test comment 2" + comment = "%[5]s" warehouse_size = "%[2]s" auto_suspend = 60 @@ -165,7 +171,7 @@ resource "snowflake_warehouse" "w" { wait_for_provisioning = false max_concurrency_level = %[3]d } -`, prefix, size, maxConcurrencyLevel, minClusterCount) +`, prefix, size, maxConcurrencyLevel, minClusterCount, comment) } func wConfigPattern(prefix string) string {