From 7ecc9931817a6cb3491363ddca18446eda584b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Fri, 22 Mar 2024 12:42:23 +0100 Subject: [PATCH 1/7] wip --- pkg/resources/database_acceptance_test.go | 23 ++++ .../grant_privileges_to_account_role.go | 51 ++++++++ ...vileges_to_account_role_acceptance_test.go | 109 +++++++++++++++++- .../grant_privileges_to_database_role.go | 11 ++ ...ileges_to_database_role_acceptance_test.go | 70 ++++++++--- pkg/resources/grant_privileges_to_role.go | 6 + pkg/resources/grant_privileges_to_share.go | 11 ++ ...ant_privileges_to_share_acceptance_test.go | 69 +++++++++++ .../OnCustomShare/test.tf | 9 ++ .../OnCustomShare/variables.tf | 11 ++ 10 files changed, 355 insertions(+), 15 deletions(-) create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnCustomShare/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnCustomShare/variables.tf diff --git a/pkg/resources/database_acceptance_test.go b/pkg/resources/database_acceptance_test.go index 2be05bd021..6c013c6d45 100644 --- a/pkg/resources/database_acceptance_test.go +++ b/pkg/resources/database_acceptance_test.go @@ -489,3 +489,26 @@ func checkAccountAndDatabaseDataRetentionTime(id sdk.AccountObjectIdentifier, ex return nil } } + +func createTemporaryDatabaseOutsideTerraform(t *testing.T, name string) func() { + t.Helper() + client, err := sdk.NewDefaultClient() + if err != nil { + t.Fatal(err) + } + ctx := context.Background() + + if err := client.Databases.Create(ctx, sdk.NewAccountObjectIdentifier(name), new(sdk.CreateDatabaseOptions)); err != nil { + if err != nil { + t.Fatal(err) + } + } + + return func() { + if err := client.Databases.Drop(ctx, sdk.NewAccountObjectIdentifier(name), new(sdk.DropDatabaseOptions)); err != nil { + if err != nil { + t.Fatal(err) + } + } + } +} diff --git a/pkg/resources/grant_privileges_to_account_role.go b/pkg/resources/grant_privileges_to_account_role.go index 14c988c8db..abb18d193c 100644 --- a/pkg/resources/grant_privileges_to_account_role.go +++ b/pkg/resources/grant_privileges_to_account_role.go @@ -2,6 +2,7 @@ package resources import ( "context" + "errors" "fmt" "log" "slices" @@ -463,6 +464,16 @@ func UpdateGrantPrivilegesToAccountRole(ctx context.Context, d *schema.ResourceD ) if err != nil { + if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { + d.SetId("") + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Warning, + Summary: "Failed to revoke all privileges. Object not found. Marking the resource as removed.", + Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err), + }, + } + } return diag.Diagnostics{ diag.Diagnostic{ Severity: diag.Error, @@ -527,6 +538,16 @@ func UpdateGrantPrivilegesToAccountRole(ctx context.Context, d *schema.ResourceD new(sdk.GrantPrivilegesToAccountRoleOptions), ) if err != nil { + if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { + d.SetId("") + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Warning, + Summary: "Failed to grant added privileges. Object not found. Marking the resource as removed.", + Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err), + }, + } + } return diag.Diagnostics{ diag.Diagnostic{ Severity: diag.Error, @@ -554,6 +575,16 @@ func UpdateGrantPrivilegesToAccountRole(ctx context.Context, d *schema.ResourceD new(sdk.RevokePrivilegesFromAccountRoleOptions), ) if err != nil { + if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { + d.SetId("") + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Warning, + Summary: "Failed to revoke removed privileges. Object not found. Marking the resource as removed.", + Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err), + }, + } + } return diag.Diagnostics{ diag.Diagnostic{ Severity: diag.Error, @@ -583,6 +614,16 @@ func UpdateGrantPrivilegesToAccountRole(ctx context.Context, d *schema.ResourceD ) if err != nil { + if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { + d.SetId("") + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Warning, + Summary: "Failed to grant all privileges. Object not found. Marking the resource as removed.", + Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err), + }, + } + } return diag.Diagnostics{ diag.Diagnostic{ Severity: diag.Error, @@ -729,6 +770,16 @@ func ReadGrantPrivilegesToAccountRole(ctx context.Context, d *schema.ResourceDat logging.DebugLogger.Printf("[DEBUG] About to show grants") grants, err := client.Grants.Show(ctx, opts) if err != nil { + if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { + d.SetId("") + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Warning, + Summary: "Failed to retrieve grants. Object not found. Marking the resource as removed.", + Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err), + }, + } + } return diag.Diagnostics{ diag.Diagnostic{ Severity: diag.Error, diff --git a/pkg/resources/grant_privileges_to_account_role_acceptance_test.go b/pkg/resources/grant_privileges_to_account_role_acceptance_test.go index 61efcbc081..af05bb9345 100644 --- a/pkg/resources/grant_privileges_to_account_role_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_account_role_acceptance_test.go @@ -450,7 +450,7 @@ func TestAcc_GrantPrivilegesToAccountRole_OnSchemaObject_OnObject_OwnershipPrivi CheckDestroy: testAccCheckAccountRolePrivilegesRevoked(name), Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createAccountRoleOutsideTerraform(t, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnObject"), ConfigVariables: configVariables, ExpectError: regexp.MustCompile("Unsupported privilege 'OWNERSHIP'"), @@ -1190,6 +1190,93 @@ func TestAcc_GrantPrivilegesToAccountRole_MLPrivileges(t *testing.T) { }) } +// proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2621 doesn't apply to this resource +func TestAcc_GrantPrivilegesToAccountRole_RemoveGrantedObjectOutsideTerraform(t *testing.T) { + name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + roleName := sdk.NewAccountObjectIdentifier(name).FullyQualifiedName() + databaseName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + configVariables := config.Variables{ + "name": config.StringVariable(roleName), + "database": config.StringVariable(databaseName), + "privileges": config.ListVariable( + config.StringVariable(string(sdk.AccountObjectPrivilegeCreateDatabaseRole)), + config.StringVariable(string(sdk.AccountObjectPrivilegeCreateSchema)), + ), + "with_grant_option": config.BoolVariable(true), + } + + var databaseCleanup func() + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + PreCheck: func() { acc.TestAccPreCheck(t) }, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: testAccCheckAccountRolePrivilegesRevoked(name), + Steps: []resource.TestStep{ + { + PreConfig: func() { + databaseCleanup = createTemporaryDatabaseOutsideTerraform(t, databaseName) + createAccountRoleOutsideTerraform(t, name) + }, + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToAccountRole/OnAccountObject"), + ConfigVariables: configVariables, + }, + { + PreConfig: func() { databaseCleanup() }, + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToAccountRole/OnAccountObject"), + ConfigVariables: configVariables, + // The error occurs in the Create operation, indicating the Read operation removed resource from the state. + ExpectError: regexp.MustCompile("An error occurred when granting privileges to account role"), + }, + }, + }) +} + +// proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2621 doesn't apply to this resource +func TestAcc_GrantPrivilegesToAccountRole_RemoveAccountRoleOutsideTerraform(t *testing.T) { + name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + roleName := sdk.NewAccountObjectIdentifier(name).FullyQualifiedName() + databaseName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + configVariables := config.Variables{ + "name": config.StringVariable(roleName), + "database": config.StringVariable(databaseName), + "privileges": config.ListVariable( + config.StringVariable(string(sdk.AccountObjectPrivilegeCreateDatabaseRole)), + config.StringVariable(string(sdk.AccountObjectPrivilegeCreateSchema)), + ), + "with_grant_option": config.BoolVariable(true), + } + + var roleCleanup func() + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + PreCheck: func() { acc.TestAccPreCheck(t) }, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: testAccCheckAccountRolePrivilegesRevoked(name), + Steps: []resource.TestStep{ + { + PreConfig: func() { + t.Cleanup(createTemporaryDatabaseOutsideTerraform(t, databaseName)) + roleCleanup = createTemporaryAccountRoleOutsideTerraform(t, name) + }, + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToAccountRole/OnAccountObject"), + ConfigVariables: configVariables, + }, + // TODO: Handle Update errors (and setId if not found) + { + PreConfig: func() { roleCleanup() }, + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToAccountRole/OnAccountObject"), + ConfigVariables: configVariables, + // The error occurs in the Create operation, indicating the Read operation removed resource from the state. + ExpectError: regexp.MustCompile("An error occurred when granting privileges to account role"), + }, + }, + }) +} + func getSecondaryAccountName(t *testing.T) (string, error) { t.Helper() config, err := sdk.ProfileConfig(testprofiles.Secondary) @@ -1265,6 +1352,26 @@ func createAccountRoleOutsideTerraform(t *testing.T, name string) { } } +func createTemporaryAccountRoleOutsideTerraform(t *testing.T, name string) func() { + t.Helper() + client, err := sdk.NewDefaultClient() + if err != nil { + t.Fatal(err) + } + ctx := context.Background() + roleId := sdk.NewAccountObjectIdentifier(name) + + if err := client.Roles.Create(ctx, sdk.NewCreateRoleRequest(roleId)); err != nil { + t.Fatal(err) + } + + return func() { + if err := client.Roles.Drop(ctx, sdk.NewDropRoleRequest(roleId)); err != nil { + t.Fatal(err) + } + } +} + func testAccCheckAccountRolePrivilegesRevoked(name string) func(*terraform.State) error { return func(state *terraform.State) error { client := acc.TestAccProvider.Meta().(*provider.Context).Client diff --git a/pkg/resources/grant_privileges_to_database_role.go b/pkg/resources/grant_privileges_to_database_role.go index 9834ca7fc0..c94960fcb6 100644 --- a/pkg/resources/grant_privileges_to_database_role.go +++ b/pkg/resources/grant_privileges_to_database_role.go @@ -2,6 +2,7 @@ package resources import ( "context" + "errors" "fmt" "log" "slices" @@ -643,6 +644,16 @@ func ReadGrantPrivilegesToDatabaseRole(ctx context.Context, d *schema.ResourceDa client := meta.(*provider.Context).Client grants, err := client.Grants.Show(ctx, opts) if err != nil { + if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { + d.SetId("") + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Warning, + Summary: "Failed to retrieve grants. Object not found. Marking the resource as removed.", + Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err), + }, + } + } return diag.Diagnostics{ diag.Diagnostic{ Severity: diag.Error, diff --git a/pkg/resources/grant_privileges_to_database_role_acceptance_test.go b/pkg/resources/grant_privileges_to_database_role_acceptance_test.go index 0de8ff0c69..b9293078b8 100644 --- a/pkg/resources/grant_privileges_to_database_role_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_database_role_acceptance_test.go @@ -46,7 +46,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnDatabase(t *testing.T) { CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( @@ -97,7 +97,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnDatabase_PrivilegesReversed(t *test CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( @@ -148,7 +148,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnSchema(t *testing.T) { CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnSchema"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( @@ -216,7 +216,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnAllSchemasInDatabase(t *testing.T) CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnAllSchemasInDatabase"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( @@ -266,7 +266,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnFutureSchemasInDatabase(t *testing. CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnFutureSchemasInDatabase"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( @@ -319,7 +319,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnSchemaObject_OnObject(t *testing.T) CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnObject"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( @@ -368,7 +368,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnSchemaObject_OnObject_OwnershipPriv CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnObject"), ConfigVariables: configVariables, ExpectError: regexp.MustCompile("Unsupported privilege 'OWNERSHIP'"), @@ -403,7 +403,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnSchemaObject_OnAll_InDatabase(t *te CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnAll_InDatabase"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( @@ -454,7 +454,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnSchemaObject_OnAllPipes(t *testing. CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnAllPipes"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( @@ -506,7 +506,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnSchemaObject_OnFuture_InDatabase(t CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnFuture_InDatabase"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( @@ -642,7 +642,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_UpdatePrivileges(t *testing.T) { CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/UpdatePrivileges/privileges"), ConfigVariables: configVariables(false, []sdk.AccountObjectPrivilege{ sdk.AccountObjectPrivilegeCreateSchema, @@ -734,7 +734,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_UpdatePrivileges_SnowflakeChecked(t * CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/UpdatePrivileges_SnowflakeChecked/privileges"), ConfigVariables: configVariables(false, []string{ sdk.AccountObjectPrivilegeCreateSchema.String(), @@ -810,7 +810,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_AlwaysApply(t *testing.T) { CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/AlwaysApply"), ConfigVariables: configVariables(false), ConfigPlanChecks: resource.ConfigPlanChecks{ @@ -930,13 +930,55 @@ func TestAcc_GrantPrivilegesToDatabaseRole_MLPrivileges(t *testing.T) { } func createDatabaseRoleOutsideTerraform(t *testing.T, name string) { +// proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2621 doesn't apply to this resource +func TestAcc_GrantPrivilegesToDatabaseRole_RemoveGrantedObjectOutsideTerraform(t *testing.T) { + name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + databaseName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + configVariables := config.Variables{ + "name": config.StringVariable(name), + "database": config.StringVariable(databaseName), + "privileges": config.ListVariable( + config.StringVariable(string(sdk.AccountObjectPrivilegeCreateSchema)), + ), + "with_grant_option": config.BoolVariable(true), + } + + var databaseCleanup func() + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + PreCheck: func() { acc.TestAccPreCheck(t) }, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, + Steps: []resource.TestStep{ + { + PreConfig: func() { + databaseCleanup = createTemporaryDatabaseOutsideTerraform(t, databaseName) + createDatabaseRoleOutsideTerraform(t, databaseName, name) + }, + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), + ConfigVariables: configVariables, + }, + { + PreConfig: func() { databaseCleanup() }, + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), + ConfigVariables: configVariables, + // The error occurs in the Create operation, indicating the Read operation removed resource from the state. + ExpectError: regexp.MustCompile("An error occurred when granting privileges to database role"), + }, + }, + }) +} + +func createDatabaseRoleOutsideTerraform(t *testing.T, databaseName string, name string) { t.Helper() client, err := sdk.NewDefaultClient() if err != nil { t.Fatal(err) } ctx := context.Background() - databaseRoleId := sdk.NewDatabaseObjectIdentifier(acc.TestDatabaseName, name) + databaseRoleId := sdk.NewDatabaseObjectIdentifier(databaseName, name) if err := client.DatabaseRoles.Create(ctx, sdk.NewCreateDatabaseRoleRequest(databaseRoleId).WithOrReplace(true)); err != nil { t.Fatal(fmt.Errorf("error database role (%s): %w", databaseRoleId.FullyQualifiedName(), err)) } diff --git a/pkg/resources/grant_privileges_to_role.go b/pkg/resources/grant_privileges_to_role.go index c54ed16fe3..19d4813cf8 100644 --- a/pkg/resources/grant_privileges_to_role.go +++ b/pkg/resources/grant_privileges_to_role.go @@ -2,6 +2,7 @@ package resources import ( "context" + "errors" "fmt" "log" "slices" @@ -831,6 +832,11 @@ func readRoleGrantPrivileges(ctx context.Context, client *sdk.Client, grantedOn grants, err := client.Grants.Show(ctx, opts) logging.DebugLogger.Printf("[DEBUG] After showing grants: err = %v", err) if err != nil { + if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { + d.SetId("") + log.Printf("[DEBUG] Failed to show grants: %s. Marking object as removed.", err) + return nil + } return fmt.Errorf("error retrieving grants for account role: %w", err) } diff --git a/pkg/resources/grant_privileges_to_share.go b/pkg/resources/grant_privileges_to_share.go index 76c2b3fd14..6618955a85 100644 --- a/pkg/resources/grant_privileges_to_share.go +++ b/pkg/resources/grant_privileges_to_share.go @@ -2,6 +2,7 @@ package resources import ( "context" + "errors" "fmt" "log" "slices" @@ -307,6 +308,16 @@ func ReadGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, met client := meta.(*provider.Context).Client grants, err := client.Grants.Show(ctx, opts) if err != nil { + if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { + d.SetId("") + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Warning, + Summary: "Failed to retrieve grants. Object not found. Marking the resource as removed.", + Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err), + }, + } + } return diag.Diagnostics{ diag.Diagnostic{ Severity: diag.Error, diff --git a/pkg/resources/grant_privileges_to_share_acceptance_test.go b/pkg/resources/grant_privileges_to_share_acceptance_test.go index c4a1a3b87c..88295246ab 100644 --- a/pkg/resources/grant_privileges_to_share_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_share_acceptance_test.go @@ -521,6 +521,52 @@ func TestAcc_GrantPrivilegesToShare_NoOnOption(t *testing.T) { }) } +// proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2621 doesn't apply to this resource +func TestAcc_GrantPrivilegesToShare_RemoveGrantedObjectOutsideTerraform(t *testing.T) { + databaseName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + shareName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + + configVariables := config.Variables{ + "to_share": config.StringVariable(shareName), + "database": config.StringVariable(databaseName), + "privileges": config.ListVariable( + config.StringVariable(sdk.ObjectPrivilegeUsage.String()), + ), + } + + var shareCleanup func() + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + PreCheck: func() { acc.TestAccPreCheck(t) }, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + Steps: []resource.TestStep{ + { + PreConfig: func() { + shareCleanup = createTemporaryShareOutsideTerraform(t, shareName) + }, + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnCustomShare"), + ConfigVariables: configVariables, + }, + { + PreConfig: func() { shareCleanup() }, + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnCustomShare"), + ConfigVariables: configVariables, + // The error occurs in the Update operation + ExpectError: regexp.MustCompile("Failed to grant added privileges. Object not found. Marking the resource as removed."), + }, + { + PreConfig: func() { shareCleanup() }, + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnCustomShare"), + ConfigVariables: configVariables, + // The error occurs in the Update operation, indicating the Read operation removed resource from the state. + ExpectError: regexp.MustCompile("An error occurred when granting privileges to share"), + }, + }, + }) +} + func testAccCheckSharePrivilegesRevoked() func(*terraform.State) error { return func(state *terraform.State) error { for _, rs := range state.RootModule().Resources { @@ -550,3 +596,26 @@ func testAccCheckSharePrivilegesRevoked() func(*terraform.State) error { return nil } } + +func createTemporaryShareOutsideTerraform(t *testing.T, name string) func() { + t.Helper() + client, err := sdk.NewDefaultClient() + if err != nil { + t.Fatal(err) + } + ctx := context.Background() + + if err := client.Shares.Create(ctx, sdk.NewAccountObjectIdentifier(name), new(sdk.CreateShareOptions)); err != nil { + if err != nil { + t.Fatal(err) + } + } + + return func() { + if err := client.Shares.Drop(ctx, sdk.NewAccountObjectIdentifier(name)); err != nil { + if err != nil { + t.Fatal(err) + } + } + } +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnCustomShare/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnCustomShare/test.tf new file mode 100644 index 0000000000..2dd4981e15 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnCustomShare/test.tf @@ -0,0 +1,9 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_grant_privileges_to_share" "test" { + to_share = var.to_share + privileges = var.privileges + on_database = snowflake_database.test.name +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnCustomShare/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnCustomShare/variables.tf new file mode 100644 index 0000000000..8f3b5923f0 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnCustomShare/variables.tf @@ -0,0 +1,11 @@ +variable "to_share" { + type = string +} + +variable "privileges" { + type = list(string) +} + +variable "database" { + type = string +} From c77a3a676f17cccc8132b2a381538f662a90f8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Fri, 29 Mar 2024 15:40:32 +0100 Subject: [PATCH 2/7] wip --- .../grant_privileges_to_account_role.go | 55 +++++-------------- ...vileges_to_account_role_acceptance_test.go | 5 +- .../grant_privileges_to_database_role.go | 15 ++++- ...ileges_to_database_role_acceptance_test.go | 51 ++++++++++++++++- pkg/resources/grant_privileges_to_share.go | 11 ++++ ...ant_privileges_to_share_acceptance_test.go | 11 +--- 6 files changed, 90 insertions(+), 58 deletions(-) diff --git a/pkg/resources/grant_privileges_to_account_role.go b/pkg/resources/grant_privileges_to_account_role.go index abb18d193c..975d5e0ebb 100644 --- a/pkg/resources/grant_privileges_to_account_role.go +++ b/pkg/resources/grant_privileges_to_account_role.go @@ -464,16 +464,6 @@ func UpdateGrantPrivilegesToAccountRole(ctx context.Context, d *schema.ResourceD ) if err != nil { - if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { - d.SetId("") - return diag.Diagnostics{ - diag.Diagnostic{ - Severity: diag.Warning, - Summary: "Failed to revoke all privileges. Object not found. Marking the resource as removed.", - Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err), - }, - } - } return diag.Diagnostics{ diag.Diagnostic{ Severity: diag.Error, @@ -538,16 +528,6 @@ func UpdateGrantPrivilegesToAccountRole(ctx context.Context, d *schema.ResourceD new(sdk.GrantPrivilegesToAccountRoleOptions), ) if err != nil { - if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { - d.SetId("") - return diag.Diagnostics{ - diag.Diagnostic{ - Severity: diag.Warning, - Summary: "Failed to grant added privileges. Object not found. Marking the resource as removed.", - Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err), - }, - } - } return diag.Diagnostics{ diag.Diagnostic{ Severity: diag.Error, @@ -575,16 +555,6 @@ func UpdateGrantPrivilegesToAccountRole(ctx context.Context, d *schema.ResourceD new(sdk.RevokePrivilegesFromAccountRoleOptions), ) if err != nil { - if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { - d.SetId("") - return diag.Diagnostics{ - diag.Diagnostic{ - Severity: diag.Warning, - Summary: "Failed to revoke removed privileges. Object not found. Marking the resource as removed.", - Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err), - }, - } - } return diag.Diagnostics{ diag.Diagnostic{ Severity: diag.Error, @@ -614,16 +584,6 @@ func UpdateGrantPrivilegesToAccountRole(ctx context.Context, d *schema.ResourceD ) if err != nil { - if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { - d.SetId("") - return diag.Diagnostics{ - diag.Diagnostic{ - Severity: diag.Warning, - Summary: "Failed to grant all privileges. Object not found. Marking the resource as removed.", - Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err), - }, - } - } return diag.Diagnostics{ diag.Diagnostic{ Severity: diag.Error, @@ -767,6 +727,17 @@ func ReadGrantPrivilegesToAccountRole(ctx context.Context, d *schema.ResourceDat client := meta.(*provider.Context).Client + if _, err := client.Roles.ShowByID(ctx, sdk.NewShowByIdRoleRequest(id.RoleName)); err != nil && err.Error() == "object does not exist" { + d.SetId("") + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Warning, + Summary: "Failed to retrieve account role. Marking the resource as removed.", + Detail: fmt.Sprintf("Id: %s", d.Id()), + }, + } + } + logging.DebugLogger.Printf("[DEBUG] About to show grants") grants, err := client.Grants.Show(ctx, opts) if err != nil { @@ -775,8 +746,8 @@ func ReadGrantPrivilegesToAccountRole(ctx context.Context, d *schema.ResourceDat return diag.Diagnostics{ diag.Diagnostic{ Severity: diag.Warning, - Summary: "Failed to retrieve grants. Object not found. Marking the resource as removed.", - Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err), + Summary: "Failed to retrieve grants. Target object not found. Marking the resource as removed.", + Detail: fmt.Sprintf("Id: %s", d.Id()), }, } } diff --git a/pkg/resources/grant_privileges_to_account_role_acceptance_test.go b/pkg/resources/grant_privileges_to_account_role_acceptance_test.go index af05bb9345..6c749f47c2 100644 --- a/pkg/resources/grant_privileges_to_account_role_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_account_role_acceptance_test.go @@ -1226,7 +1226,7 @@ func TestAcc_GrantPrivilegesToAccountRole_RemoveGrantedObjectOutsideTerraform(t PreConfig: func() { databaseCleanup() }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToAccountRole/OnAccountObject"), ConfigVariables: configVariables, - // The error occurs in the Create operation, indicating the Read operation removed resource from the state. + // The error occurs in the Create operation, indicating the Read operation removed the resource from the state in the previous step. ExpectError: regexp.MustCompile("An error occurred when granting privileges to account role"), }, }, @@ -1265,12 +1265,11 @@ func TestAcc_GrantPrivilegesToAccountRole_RemoveAccountRoleOutsideTerraform(t *t ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToAccountRole/OnAccountObject"), ConfigVariables: configVariables, }, - // TODO: Handle Update errors (and setId if not found) { PreConfig: func() { roleCleanup() }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToAccountRole/OnAccountObject"), ConfigVariables: configVariables, - // The error occurs in the Create operation, indicating the Read operation removed resource from the state. + // The error occurs in the Create operation, indicating the Read operation removed the resource from the state in the previous step. ExpectError: regexp.MustCompile("An error occurred when granting privileges to account role"), }, }, diff --git a/pkg/resources/grant_privileges_to_database_role.go b/pkg/resources/grant_privileges_to_database_role.go index c94960fcb6..4618687034 100644 --- a/pkg/resources/grant_privileges_to_database_role.go +++ b/pkg/resources/grant_privileges_to_database_role.go @@ -642,6 +642,17 @@ func ReadGrantPrivilegesToDatabaseRole(ctx context.Context, d *schema.ResourceDa } client := meta.(*provider.Context).Client + if _, err := client.DatabaseRoles.ShowByID(ctx, id.DatabaseRoleName); err != nil && err.Error() == "object does not exist" { + d.SetId("") + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Warning, + Summary: "Failed to retrieve database role. Marking the resource as removed.", + Detail: fmt.Sprintf("Id: %s", d.Id()), + }, + } + } + grants, err := client.Grants.Show(ctx, opts) if err != nil { if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { @@ -649,8 +660,8 @@ func ReadGrantPrivilegesToDatabaseRole(ctx context.Context, d *schema.ResourceDa return diag.Diagnostics{ diag.Diagnostic{ Severity: diag.Warning, - Summary: "Failed to retrieve grants. Object not found. Marking the resource as removed.", - Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err), + Summary: "Failed to retrieve grants. Target object not found. Marking the resource as removed.", + Detail: fmt.Sprintf("Id: %s", d.Id()), }, } } diff --git a/pkg/resources/grant_privileges_to_database_role_acceptance_test.go b/pkg/resources/grant_privileges_to_database_role_acceptance_test.go index b9293078b8..b4332db09f 100644 --- a/pkg/resources/grant_privileges_to_database_role_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_database_role_acceptance_test.go @@ -964,14 +964,55 @@ func TestAcc_GrantPrivilegesToDatabaseRole_RemoveGrantedObjectOutsideTerraform(t PreConfig: func() { databaseCleanup() }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), ConfigVariables: configVariables, - // The error occurs in the Create operation, indicating the Read operation removed resource from the state. + // The error occurs in the Create operation, indicating the Read operation removed the resource from the state in the previous step. ExpectError: regexp.MustCompile("An error occurred when granting privileges to database role"), }, }, }) } -func createDatabaseRoleOutsideTerraform(t *testing.T, databaseName string, name string) { +// proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2621 doesn't apply to this resource +func TestAcc_GrantPrivilegesToDatabaseRole_RemoveDatabaseRoleOutsideTerraform(t *testing.T) { + name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + databaseName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + configVariables := config.Variables{ + "name": config.StringVariable(name), + "database": config.StringVariable(databaseName), + "privileges": config.ListVariable( + config.StringVariable(string(sdk.AccountObjectPrivilegeCreateSchema)), + ), + "with_grant_option": config.BoolVariable(true), + } + + var databaseRoleCleanup func() + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + PreCheck: func() { acc.TestAccPreCheck(t) }, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, + Steps: []resource.TestStep{ + { + PreConfig: func() { + t.Cleanup(createTemporaryDatabaseOutsideTerraform(t, databaseName)) + databaseRoleCleanup = createDatabaseRoleOutsideTerraform(t, databaseName, name) + }, + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), + ConfigVariables: configVariables, + }, + { + PreConfig: func() { databaseRoleCleanup() }, + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), + ConfigVariables: configVariables, + // The error occurs in the Create operation, indicating the Read operation removed the resource from the state in the previous step. + ExpectError: regexp.MustCompile("An error occurred when granting privileges to database role"), + }, + }, + }) +} + +func createDatabaseRoleOutsideTerraform(t *testing.T, databaseName string, name string) func() { t.Helper() client, err := sdk.NewDefaultClient() if err != nil { @@ -982,6 +1023,12 @@ func createDatabaseRoleOutsideTerraform(t *testing.T, databaseName string, name if err := client.DatabaseRoles.Create(ctx, sdk.NewCreateDatabaseRoleRequest(databaseRoleId).WithOrReplace(true)); err != nil { t.Fatal(fmt.Errorf("error database role (%s): %w", databaseRoleId.FullyQualifiedName(), err)) } + + return func() { + if err := client.DatabaseRoles.Drop(ctx, sdk.NewDropDatabaseRoleRequest(databaseRoleId).WithIfExists(true)); err != nil { + t.Fatal(fmt.Errorf("error database role (%s): %w", databaseRoleId.FullyQualifiedName(), err)) + } + } } func queriedPrivilegesToDatabaseRoleEqualTo(databaseRoleName sdk.DatabaseObjectIdentifier, privileges ...string) func(s *terraform.State) error { diff --git a/pkg/resources/grant_privileges_to_share.go b/pkg/resources/grant_privileges_to_share.go index 6618955a85..73f05a30e3 100644 --- a/pkg/resources/grant_privileges_to_share.go +++ b/pkg/resources/grant_privileges_to_share.go @@ -306,6 +306,17 @@ func ReadGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, met } client := meta.(*provider.Context).Client + if _, err := client.Shares.ShowByID(ctx, id.ShareName); err != nil && errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { + d.SetId("") + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Warning, + Summary: "Failed to retrieve share. Marking the resource as removed.", + Detail: fmt.Sprintf("Id: %s", d.Id()), + }, + } + } + grants, err := client.Grants.Show(ctx, opts) if err != nil { if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { diff --git a/pkg/resources/grant_privileges_to_share_acceptance_test.go b/pkg/resources/grant_privileges_to_share_acceptance_test.go index 88295246ab..a5007fdeb6 100644 --- a/pkg/resources/grant_privileges_to_share_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_share_acceptance_test.go @@ -522,7 +522,7 @@ func TestAcc_GrantPrivilegesToShare_NoOnOption(t *testing.T) { } // proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2621 doesn't apply to this resource -func TestAcc_GrantPrivilegesToShare_RemoveGrantedObjectOutsideTerraform(t *testing.T) { +func TestAcc_GrantPrivilegesToShare_RemoveShareOutsideTerraform(t *testing.T) { databaseName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) shareName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) @@ -553,14 +553,7 @@ func TestAcc_GrantPrivilegesToShare_RemoveGrantedObjectOutsideTerraform(t *testi PreConfig: func() { shareCleanup() }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnCustomShare"), ConfigVariables: configVariables, - // The error occurs in the Update operation - ExpectError: regexp.MustCompile("Failed to grant added privileges. Object not found. Marking the resource as removed."), - }, - { - PreConfig: func() { shareCleanup() }, - ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnCustomShare"), - ConfigVariables: configVariables, - // The error occurs in the Update operation, indicating the Read operation removed resource from the state. + // The error occurs in the Create operation, indicating the Read operation removed the resource from the state in the previous step. ExpectError: regexp.MustCompile("An error occurred when granting privileges to share"), }, }, From 2fa50e71d718e24e118270e82a8c47df15762d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Fri, 29 Mar 2024 15:53:58 +0100 Subject: [PATCH 3/7] wip --- pkg/resources/grant_privileges_to_account_role.go | 1 + pkg/resources/grant_privileges_to_database_role.go | 1 + 2 files changed, 2 insertions(+) diff --git a/pkg/resources/grant_privileges_to_account_role.go b/pkg/resources/grant_privileges_to_account_role.go index 975d5e0ebb..6c244ca134 100644 --- a/pkg/resources/grant_privileges_to_account_role.go +++ b/pkg/resources/grant_privileges_to_account_role.go @@ -727,6 +727,7 @@ func ReadGrantPrivilegesToAccountRole(ctx context.Context, d *schema.ResourceDat client := meta.(*provider.Context).Client + // TODO(SNOW-891217): Use custom error. Right now, "object does not exist" error is hidden in sdk/internal/collections package if _, err := client.Roles.ShowByID(ctx, sdk.NewShowByIdRoleRequest(id.RoleName)); err != nil && err.Error() == "object does not exist" { d.SetId("") return diag.Diagnostics{ diff --git a/pkg/resources/grant_privileges_to_database_role.go b/pkg/resources/grant_privileges_to_database_role.go index 4618687034..62a05a878d 100644 --- a/pkg/resources/grant_privileges_to_database_role.go +++ b/pkg/resources/grant_privileges_to_database_role.go @@ -642,6 +642,7 @@ func ReadGrantPrivilegesToDatabaseRole(ctx context.Context, d *schema.ResourceDa } client := meta.(*provider.Context).Client + // TODO(SNOW-891217): Use custom error. Right now, "object does not exist" error is hidden in sdk/internal/collections package if _, err := client.DatabaseRoles.ShowByID(ctx, id.DatabaseRoleName); err != nil && err.Error() == "object does not exist" { d.SetId("") return diag.Diagnostics{ From 595988c2de1c439afd851cdb987f2dcb3dc9fb4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Fri, 29 Mar 2024 16:03:23 +0100 Subject: [PATCH 4/7] wip --- pkg/resources/database_acceptance_test.go | 2 +- ...vileges_to_account_role_acceptance_test.go | 26 +++++-------------- ...ileges_to_database_role_acceptance_test.go | 11 ++++---- pkg/resources/grant_privileges_to_role.go | 6 +++++ ...ant_privileges_to_share_acceptance_test.go | 4 +-- 5 files changed, 20 insertions(+), 29 deletions(-) diff --git a/pkg/resources/database_acceptance_test.go b/pkg/resources/database_acceptance_test.go index 6c013c6d45..96e3f936e3 100644 --- a/pkg/resources/database_acceptance_test.go +++ b/pkg/resources/database_acceptance_test.go @@ -490,7 +490,7 @@ func checkAccountAndDatabaseDataRetentionTime(id sdk.AccountObjectIdentifier, ex } } -func createTemporaryDatabaseOutsideTerraform(t *testing.T, name string) func() { +func createDatabaseOutsideTerraform(t *testing.T, name string) func() { t.Helper() client, err := sdk.NewDefaultClient() if err != nil { diff --git a/pkg/resources/grant_privileges_to_account_role_acceptance_test.go b/pkg/resources/grant_privileges_to_account_role_acceptance_test.go index 6c749f47c2..022cc63761 100644 --- a/pkg/resources/grant_privileges_to_account_role_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_account_role_acceptance_test.go @@ -1216,7 +1216,7 @@ func TestAcc_GrantPrivilegesToAccountRole_RemoveGrantedObjectOutsideTerraform(t Steps: []resource.TestStep{ { PreConfig: func() { - databaseCleanup = createTemporaryDatabaseOutsideTerraform(t, databaseName) + databaseCleanup = createDatabaseOutsideTerraform(t, databaseName) createAccountRoleOutsideTerraform(t, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToAccountRole/OnAccountObject"), @@ -1259,8 +1259,8 @@ func TestAcc_GrantPrivilegesToAccountRole_RemoveAccountRoleOutsideTerraform(t *t Steps: []resource.TestStep{ { PreConfig: func() { - t.Cleanup(createTemporaryDatabaseOutsideTerraform(t, databaseName)) - roleCleanup = createTemporaryAccountRoleOutsideTerraform(t, name) + t.Cleanup(createDatabaseOutsideTerraform(t, databaseName)) + roleCleanup = createAccountRoleOutsideTerraform(t, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToAccountRole/OnAccountObject"), ConfigVariables: configVariables, @@ -1338,7 +1338,7 @@ func dropSharedDatabaseOnSecondaryAccount(t *testing.T, databaseName string, sha ) } -func createAccountRoleOutsideTerraform(t *testing.T, name string) { +func createAccountRoleOutsideTerraform(t *testing.T, name string) func() { t.Helper() client, err := sdk.NewDefaultClient() if err != nil { @@ -1349,24 +1349,10 @@ func createAccountRoleOutsideTerraform(t *testing.T, name string) { if err := client.Roles.Create(ctx, sdk.NewCreateRoleRequest(roleId).WithOrReplace(true)); err != nil { t.Fatal(fmt.Errorf("error account role (%s): %w", roleId.FullyQualifiedName(), err)) } -} - -func createTemporaryAccountRoleOutsideTerraform(t *testing.T, name string) func() { - t.Helper() - client, err := sdk.NewDefaultClient() - if err != nil { - t.Fatal(err) - } - ctx := context.Background() - roleId := sdk.NewAccountObjectIdentifier(name) - - if err := client.Roles.Create(ctx, sdk.NewCreateRoleRequest(roleId)); err != nil { - t.Fatal(err) - } return func() { - if err := client.Roles.Drop(ctx, sdk.NewDropRoleRequest(roleId)); err != nil { - t.Fatal(err) + if err := client.Roles.Drop(ctx, sdk.NewDropRoleRequest(roleId).WithIfExists(true)); err != nil { + t.Fatal(fmt.Errorf("error account role (%s): %w", roleId.FullyQualifiedName(), err)) } } } diff --git a/pkg/resources/grant_privileges_to_database_role_acceptance_test.go b/pkg/resources/grant_privileges_to_database_role_acceptance_test.go index b4332db09f..b563726ce5 100644 --- a/pkg/resources/grant_privileges_to_database_role_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_database_role_acceptance_test.go @@ -556,7 +556,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnSchemaObject_OnFuture_Streamlits_In CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnFuture_InDatabase"), ConfigVariables: configVariables, ExpectError: regexp.MustCompile("Unsupported feature 'STREAMLIT'"), @@ -590,7 +590,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnSchemaObject_OnAll_Streamlits_InDat CheckDestroy: testAccCheckAccountRolePrivilegesRevoked(name), Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnAll_InDatabase"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( @@ -905,7 +905,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_MLPrivileges(t *testing.T) { CheckDestroy: testAccCheckAccountRolePrivilegesRevoked(name), Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnSchema"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( @@ -929,7 +929,6 @@ func TestAcc_GrantPrivilegesToDatabaseRole_MLPrivileges(t *testing.T) { }) } -func createDatabaseRoleOutsideTerraform(t *testing.T, name string) { // proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2621 doesn't apply to this resource func TestAcc_GrantPrivilegesToDatabaseRole_RemoveGrantedObjectOutsideTerraform(t *testing.T) { name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) @@ -954,7 +953,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_RemoveGrantedObjectOutsideTerraform(t Steps: []resource.TestStep{ { PreConfig: func() { - databaseCleanup = createTemporaryDatabaseOutsideTerraform(t, databaseName) + databaseCleanup = createDatabaseOutsideTerraform(t, databaseName) createDatabaseRoleOutsideTerraform(t, databaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), @@ -995,7 +994,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_RemoveDatabaseRoleOutsideTerraform(t Steps: []resource.TestStep{ { PreConfig: func() { - t.Cleanup(createTemporaryDatabaseOutsideTerraform(t, databaseName)) + t.Cleanup(createDatabaseOutsideTerraform(t, databaseName)) databaseRoleCleanup = createDatabaseRoleOutsideTerraform(t, databaseName, name) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), diff --git a/pkg/resources/grant_privileges_to_role.go b/pkg/resources/grant_privileges_to_role.go index 19d4813cf8..31f69e3660 100644 --- a/pkg/resources/grant_privileges_to_role.go +++ b/pkg/resources/grant_privileges_to_role.go @@ -828,6 +828,12 @@ func setRolePrivilegeOptions(privileges []string, allPrivileges bool, onAccount } func readRoleGrantPrivileges(ctx context.Context, client *sdk.Client, grantedOn sdk.ObjectType, id GrantPrivilegesToRoleID, opts *sdk.ShowGrantOptions, d *schema.ResourceData) error { + if _, err := client.Roles.ShowByID(ctx, sdk.NewShowByIdRoleRequest(sdk.NewAccountObjectIdentifier(id.RoleName))); err != nil && err.Error() == "object does not exist" { + d.SetId("") + log.Printf("[DEBUG] Failed to retrieve account role. Marking the resource as removed.") + return nil + } + logging.DebugLogger.Printf("[DEBUG] About to show grants") grants, err := client.Grants.Show(ctx, opts) logging.DebugLogger.Printf("[DEBUG] After showing grants: err = %v", err) diff --git a/pkg/resources/grant_privileges_to_share_acceptance_test.go b/pkg/resources/grant_privileges_to_share_acceptance_test.go index a5007fdeb6..e99ebcf0fe 100644 --- a/pkg/resources/grant_privileges_to_share_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_share_acceptance_test.go @@ -544,7 +544,7 @@ func TestAcc_GrantPrivilegesToShare_RemoveShareOutsideTerraform(t *testing.T) { Steps: []resource.TestStep{ { PreConfig: func() { - shareCleanup = createTemporaryShareOutsideTerraform(t, shareName) + shareCleanup = createShareOutsideTerraform(t, shareName) }, ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnCustomShare"), ConfigVariables: configVariables, @@ -590,7 +590,7 @@ func testAccCheckSharePrivilegesRevoked() func(*terraform.State) error { } } -func createTemporaryShareOutsideTerraform(t *testing.T, name string) func() { +func createShareOutsideTerraform(t *testing.T, name string) func() { t.Helper() client, err := sdk.NewDefaultClient() if err != nil { From a86d9d8a3b0d65077b022b06f48ea846f6b485c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Wed, 3 Apr 2024 15:15:06 +0200 Subject: [PATCH 5/7] Changes after review --- pkg/resources/helpers_test.go | 20 +++++ pkg/resources/schema_acceptance_test.go | 80 +++++++++++++++++++ .../test.tf | 4 + .../variables.tf | 7 ++ 4 files changed, 111 insertions(+) create mode 100644 pkg/resources/testdata/TestAcc_Schema_RemoveOutsideOfTerraform/test.tf create mode 100644 pkg/resources/testdata/TestAcc_Schema_RemoveOutsideOfTerraform/variables.tf diff --git a/pkg/resources/helpers_test.go b/pkg/resources/helpers_test.go index bb0221b64d..8d84f41124 100644 --- a/pkg/resources/helpers_test.go +++ b/pkg/resources/helpers_test.go @@ -3,6 +3,8 @@ package resources_test import ( "context" "fmt" + tfjson "github.com/hashicorp/terraform-json" + "github.com/hashicorp/terraform-plugin-testing/plancheck" "slices" "testing" @@ -551,3 +553,21 @@ func updateAccountParameter(t *testing.T, client *sdk.Client, parameter sdk.Acco require.NoError(t, err) } } + +type PlanCheck func(ctx context.Context, req plancheck.CheckPlanRequest, resp *plancheck.CheckPlanResponse) + +func (fn PlanCheck) CheckPlan(ctx context.Context, req plancheck.CheckPlanRequest, resp *plancheck.CheckPlanResponse) { + fn(ctx, req, resp) +} + +func ExpectsCreatePlan(resourceAddress string) PlanCheck { + return func(ctx context.Context, req plancheck.CheckPlanRequest, resp *plancheck.CheckPlanResponse) { + for _, rc := range req.Plan.ResourceChanges { + if rc.Address == resourceAddress && rc.Change != nil && slices.Contains(rc.Change.Actions, tfjson.ActionCreate) { + return + } + } + + resp.Error = fmt.Errorf("expected plan to contain create request for %s", resourceAddress) + } +} diff --git a/pkg/resources/schema_acceptance_test.go b/pkg/resources/schema_acceptance_test.go index bf97cec444..968575c5a0 100644 --- a/pkg/resources/schema_acceptance_test.go +++ b/pkg/resources/schema_acceptance_test.go @@ -3,6 +3,7 @@ package resources_test import ( "context" "fmt" + "regexp" "strconv" "strings" "testing" @@ -308,6 +309,76 @@ func TestAcc_Schema_DefaultDataRetentionTime_SetOutsideOfTerraform(t *testing.T) }) } +func TestAcc_Schema_RemoveDatabaseOutsideOfTerraform(t *testing.T) { + schemaName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + configVariables := map[string]config.Variable{ + "schema_name": config.StringVariable(schemaName), + "database_name": config.StringVariable(acc.TestDatabaseName), + } + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + PreCheck: func() { acc.TestAccPreCheck(t) }, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: testAccCheckSchemaDestroy, + Steps: []resource.TestStep{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_Schema_RemoveOutsideOfTerraform"), + ConfigVariables: configVariables, + }, + { + PreConfig: func() { + removeSchemaOutsideOfTerraform(t, acc.TestDatabaseName, schemaName) + }, + RefreshState: true, + ExpectNonEmptyPlan: true, + RefreshPlanChecks: resource.RefreshPlanChecks{ + PostRefresh: []plancheck.PlanCheck{ + ExpectsCreatePlan("snowflake_schema.test"), + }, + }, + }, + }, + }) +} + +func TestAcc_Schema_RemoveSchemaOutsideOfTerraform(t *testing.T) { + databaseName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + schemaName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) + configVariables := map[string]config.Variable{ + "schema_name": config.StringVariable(schemaName), + "database_name": config.StringVariable(databaseName), + } + + cleanupDatabase := createDatabaseOutsideTerraform(t, databaseName) + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + PreCheck: func() { acc.TestAccPreCheck(t) }, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: testAccCheckSchemaDestroy, + Steps: []resource.TestStep{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_Schema_RemoveOutsideOfTerraform"), + ConfigVariables: configVariables, + }, + { + PreConfig: func() { + cleanupDatabase() + }, + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_Schema_RemoveOutsideOfTerraform"), + ConfigVariables: configVariables, + // The error occurs in the Create operation, indicating the Read operation removed the resource from the state in the previous step. + ExpectError: regexp.MustCompile("error creating schema"), + }, + }, + }) +} + func checkDatabaseAndSchemaDataRetentionTime(id sdk.DatabaseObjectIdentifier, expectedDatabaseRetentionsDays int, expectedSchemaRetentionDays int) func(state *terraform.State) error { return func(state *terraform.State) error { client := acc.TestAccProvider.Meta().(*provider.Context).Client @@ -381,3 +452,12 @@ func testAccCheckSchemaDestroy(s *terraform.State) error { } return nil } + +func removeSchemaOutsideOfTerraform(t *testing.T, databaseName string, schemaName string) { + client, err := sdk.NewDefaultClient() + require.NoError(t, err) + ctx := context.Background() + + err = client.Schemas.Drop(ctx, sdk.NewDatabaseObjectIdentifier(databaseName, schemaName), new(sdk.DropSchemaOptions)) + require.NoError(t, err) +} diff --git a/pkg/resources/testdata/TestAcc_Schema_RemoveOutsideOfTerraform/test.tf b/pkg/resources/testdata/TestAcc_Schema_RemoveOutsideOfTerraform/test.tf new file mode 100644 index 0000000000..af36440e58 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_Schema_RemoveOutsideOfTerraform/test.tf @@ -0,0 +1,4 @@ +resource "snowflake_schema" "test" { + name = var.schema_name + database = var.database_name +} \ No newline at end of file diff --git a/pkg/resources/testdata/TestAcc_Schema_RemoveOutsideOfTerraform/variables.tf b/pkg/resources/testdata/TestAcc_Schema_RemoveOutsideOfTerraform/variables.tf new file mode 100644 index 0000000000..062e50b07f --- /dev/null +++ b/pkg/resources/testdata/TestAcc_Schema_RemoveOutsideOfTerraform/variables.tf @@ -0,0 +1,7 @@ +variable "schema_name" { + type = string +} + +variable "database_name" { + type = string +} From 7707671aca7dd98a497639ebd5c7fe2d62c8ee0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Wed, 3 Apr 2024 15:38:45 +0200 Subject: [PATCH 6/7] Changes after review --- go.mod | 2 +- pkg/resources/helpers_test.go | 5 +++-- pkg/resources/schema_acceptance_test.go | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1bca6424a5..00da7a83b9 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/gookit/color v1.5.4 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/go-uuid v1.0.3 + github.com/hashicorp/terraform-json v0.18.0 github.com/hashicorp/terraform-plugin-framework v1.4.2 github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 github.com/hashicorp/terraform-plugin-go v0.20.0 @@ -87,7 +88,6 @@ require ( github.com/hashicorp/hcl/v2 v2.19.1 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.19.0 // indirect - github.com/hashicorp/terraform-json v0.18.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect diff --git a/pkg/resources/helpers_test.go b/pkg/resources/helpers_test.go index 8d84f41124..229fae47f0 100644 --- a/pkg/resources/helpers_test.go +++ b/pkg/resources/helpers_test.go @@ -3,11 +3,12 @@ package resources_test import ( "context" "fmt" - tfjson "github.com/hashicorp/terraform-json" - "github.com/hashicorp/terraform-plugin-testing/plancheck" "slices" "testing" + tfjson "github.com/hashicorp/terraform-json" + "github.com/hashicorp/terraform-plugin-testing/plancheck" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider" acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" diff --git a/pkg/resources/schema_acceptance_test.go b/pkg/resources/schema_acceptance_test.go index 968575c5a0..9be604ffb1 100644 --- a/pkg/resources/schema_acceptance_test.go +++ b/pkg/resources/schema_acceptance_test.go @@ -454,6 +454,8 @@ func testAccCheckSchemaDestroy(s *terraform.State) error { } func removeSchemaOutsideOfTerraform(t *testing.T, databaseName string, schemaName string) { + t.Helper() + client, err := sdk.NewDefaultClient() require.NoError(t, err) ctx := context.Background() From 766127654ad82f678a2386645e0ef75a4ae3112a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Thu, 4 Apr 2024 11:13:17 +0200 Subject: [PATCH 7/7] Changes after review --- pkg/architests/resources_acceptance_tests_arch_test.go | 3 ++- .../grant_privileges_to_database_role_acceptance_test.go | 5 ++--- pkg/resources/helpers_test.go | 6 +++--- pkg/resources/schema_acceptance_test.go | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/architests/resources_acceptance_tests_arch_test.go b/pkg/architests/resources_acceptance_tests_arch_test.go index 008df3df01..7e3ddad5ca 100644 --- a/pkg/architests/resources_acceptance_tests_arch_test.go +++ b/pkg/architests/resources_acceptance_tests_arch_test.go @@ -1,6 +1,7 @@ package architests import ( + "regexp" "testing" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/architest" @@ -25,7 +26,7 @@ func TestArchCheck_AcceptanceTests_Resources(t *testing.T) { }) t.Run("there are no acceptance tests in other test files in the directory", func(t *testing.T) { - otherTestFiles := resourcesFiles.Filter(architest.FileNameFilterWithExclusionsProvider(architest.TestFileRegex, architest.AcceptanceTestFileRegex)) + otherTestFiles := resourcesFiles.Filter(architest.FileNameFilterWithExclusionsProvider(architest.TestFileRegex, architest.AcceptanceTestFileRegex, regexp.MustCompile("helpers_test.go"))) otherTestFiles.All(func(file *architest.File) { file.ExportedMethods().All(func(method *architest.Method) { diff --git a/pkg/resources/grant_privileges_to_database_role_acceptance_test.go b/pkg/resources/grant_privileges_to_database_role_acceptance_test.go index cc40cc38c1..0697c6dc2e 100644 --- a/pkg/resources/grant_privileges_to_database_role_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_database_role_acceptance_test.go @@ -950,7 +950,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_ChangeWithGrantOptionsOutsideOfTerraf CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigPlanChecks: resource.ConfigPlanChecks{ PostApplyPostRefresh: []plancheck.PlanCheck{ plancheck.ExpectEmptyPlan(), @@ -1001,7 +1001,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_ChangeWithGrantOptionsOutsideOfTerraf CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked, Steps: []resource.TestStep{ { - PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, + PreConfig: func() { createDatabaseRoleOutsideTerraform(t, acc.TestDatabaseName, name) }, ConfigPlanChecks: resource.ConfigPlanChecks{ PostApplyPostRefresh: []plancheck.PlanCheck{ plancheck.ExpectEmptyPlan(), @@ -1031,7 +1031,6 @@ func TestAcc_GrantPrivilegesToDatabaseRole_ChangeWithGrantOptionsOutsideOfTerraf }) } -func createDatabaseRoleOutsideTerraform(t *testing.T, name string) { // proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2621 doesn't apply to this resource func TestAcc_GrantPrivilegesToDatabaseRole_RemoveGrantedObjectOutsideTerraform(t *testing.T) { name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)) diff --git a/pkg/resources/helpers_test.go b/pkg/resources/helpers_test.go index 229fae47f0..d65409b83d 100644 --- a/pkg/resources/helpers_test.go +++ b/pkg/resources/helpers_test.go @@ -555,13 +555,13 @@ func updateAccountParameter(t *testing.T, client *sdk.Client, parameter sdk.Acco } } -type PlanCheck func(ctx context.Context, req plancheck.CheckPlanRequest, resp *plancheck.CheckPlanResponse) +type planCheck func(ctx context.Context, req plancheck.CheckPlanRequest, resp *plancheck.CheckPlanResponse) -func (fn PlanCheck) CheckPlan(ctx context.Context, req plancheck.CheckPlanRequest, resp *plancheck.CheckPlanResponse) { +func (fn planCheck) CheckPlan(ctx context.Context, req plancheck.CheckPlanRequest, resp *plancheck.CheckPlanResponse) { fn(ctx, req, resp) } -func ExpectsCreatePlan(resourceAddress string) PlanCheck { +func expectsCreatePlan(resourceAddress string) planCheck { return func(ctx context.Context, req plancheck.CheckPlanRequest, resp *plancheck.CheckPlanResponse) { for _, rc := range req.Plan.ResourceChanges { if rc.Address == resourceAddress && rc.Change != nil && slices.Contains(rc.Change.Actions, tfjson.ActionCreate) { diff --git a/pkg/resources/schema_acceptance_test.go b/pkg/resources/schema_acceptance_test.go index 9be604ffb1..bafc1c6f61 100644 --- a/pkg/resources/schema_acceptance_test.go +++ b/pkg/resources/schema_acceptance_test.go @@ -336,7 +336,7 @@ func TestAcc_Schema_RemoveDatabaseOutsideOfTerraform(t *testing.T) { ExpectNonEmptyPlan: true, RefreshPlanChecks: resource.RefreshPlanChecks{ PostRefresh: []plancheck.PlanCheck{ - ExpectsCreatePlan("snowflake_schema.test"), + expectsCreatePlan("snowflake_schema.test"), }, }, },