From 0bc150fa4d5c2ead7a273088a7c6a3c613489bb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Mon, 29 Jan 2024 16:09:15 +0100 Subject: [PATCH 1/7] wip --- pkg/provider/provider.go | 1 + .../grant_privileges_to_account_role.go | 2 +- ...ileges_to_database_role_acceptance_test.go | 30 +- ..._privileges_to_database_role_identifier.go | 2 +- ...ileges_to_database_role_identifier_test.go | 20 +- pkg/resources/grant_privileges_to_share.go | 391 ++++++++++++++++++ .../grant_privileges_to_share_identifier.go | 97 +++++ ...ant_privileges_to_share_identifier_test.go | 204 +++++++++ pkg/resources/share.go | 2 +- pkg/sdk/grants.go | 30 +- pkg/sdk/grants_impl.go | 16 +- pkg/sdk/grants_test.go | 74 ++-- pkg/sdk/grants_validations.go | 33 +- pkg/sdk/privileges.go | 4 +- .../testint/database_role_integration_test.go | 2 +- pkg/sdk/testint/databases_integration_test.go | 4 +- pkg/sdk/testint/grants_integration_test.go | 80 ++-- pkg/sdk/testint/shares_integration_test.go | 24 +- 18 files changed, 857 insertions(+), 159 deletions(-) create mode 100644 pkg/resources/grant_privileges_to_share.go create mode 100644 pkg/resources/grant_privileges_to_share_identifier.go create mode 100644 pkg/resources/grant_privileges_to_share_identifier_test.go diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index ac77870a3c..92a0e0dc49 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -448,6 +448,7 @@ func getResources() map[string]*schema.Resource { "snowflake_grant_privileges_to_role": resources.GrantPrivilegesToRole(), "snowflake_grant_privileges_to_account_role": resources.GrantPrivilegesToAccountRole(), "snowflake_grant_privileges_to_database_role": resources.GrantPrivilegesToDatabaseRole(), + "snowflake_grant_privileges_to_share": resources.GrantPrivilegesToShare(), "snowflake_managed_account": resources.ManagedAccount(), "snowflake_masking_policy": resources.MaskingPolicy(), "snowflake_materialized_view": resources.MaterializedView(), diff --git a/pkg/resources/grant_privileges_to_account_role.go b/pkg/resources/grant_privileges_to_account_role.go index 01b42e18c3..77a464a01b 100644 --- a/pkg/resources/grant_privileges_to_account_role.go +++ b/pkg/resources/grant_privileges_to_account_role.go @@ -656,7 +656,7 @@ func DeleteGrantPrivilegesToAccountRole(ctx context.Context, d *schema.ResourceD diag.Diagnostic{ Severity: diag.Error, Summary: "An error occurred when revoking privileges from account role", - Detail: fmt.Sprintf("Id: %s\nAccount role name: %s\nError: %s", d.Id(), id.RoleName, err.Error()), + Detail: fmt.Sprintf("Id: %s\nAccount role name: %s\nError: %s", d.Id(), id.RoleName.FullyQualifiedName(), err.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 2a704dd7c3..55ad93a035 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) { Steps: []resource.TestStep{ { PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, - ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabaseShareGrantKind"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "database_role_name", databaseRoleName), @@ -56,11 +56,11 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnDatabase(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "privileges.2", string(sdk.AccountObjectPrivilegeUsage)), resource.TestCheckResourceAttr(resourceName, "on_database", databaseName), resource.TestCheckResourceAttr(resourceName, "with_grant_option", "true"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|true|false|CREATE SCHEMA,MODIFY,USAGE|OnDatabase|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|true|false|CREATE SCHEMA,MODIFY,USAGE|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), ), }, { - ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabaseShareGrantKind"), ConfigVariables: configVariables, ResourceName: resourceName, ImportState: true, @@ -97,7 +97,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnDatabase_PrivilegesReversed(t *test Steps: []resource.TestStep{ { PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, - ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabaseShareGrantKind"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "database_role_name", databaseRoleName), @@ -107,11 +107,11 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnDatabase_PrivilegesReversed(t *test resource.TestCheckResourceAttr(resourceName, "privileges.2", string(sdk.AccountObjectPrivilegeUsage)), resource.TestCheckResourceAttr(resourceName, "on_database", databaseName), resource.TestCheckResourceAttr(resourceName, "with_grant_option", "true"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|true|false|CREATE SCHEMA,MODIFY,USAGE|OnDatabase|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|true|false|CREATE SCHEMA,MODIFY,USAGE|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), ), }, { - ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabaseShareGrantKind"), ConfigVariables: configVariables, ResourceName: resourceName, ImportState: true, @@ -524,7 +524,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_UpdatePrivileges(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "privileges.#", "2"), resource.TestCheckResourceAttr(resourceName, "privileges.0", string(sdk.AccountObjectPrivilegeCreateSchema)), resource.TestCheckResourceAttr(resourceName, "privileges.1", string(sdk.AccountObjectPrivilegeModify)), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|CREATE SCHEMA,MODIFY|OnDatabase|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|CREATE SCHEMA,MODIFY|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), ), }, { @@ -540,7 +540,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_UpdatePrivileges(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "privileges.0", string(sdk.AccountObjectPrivilegeCreateSchema)), resource.TestCheckResourceAttr(resourceName, "privileges.1", string(sdk.AccountObjectPrivilegeMonitor)), resource.TestCheckResourceAttr(resourceName, "privileges.2", string(sdk.AccountObjectPrivilegeUsage)), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|CREATE SCHEMA,USAGE,MONITOR|OnDatabase|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|CREATE SCHEMA,USAGE,MONITOR|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), ), }, { @@ -549,7 +549,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_UpdatePrivileges(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "all_privileges", "true"), resource.TestCheckResourceAttr(resourceName, "privileges.#", "0"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|ALL|OnDatabase|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|ALL|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), ), }, { @@ -563,7 +563,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_UpdatePrivileges(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "privileges.#", "2"), resource.TestCheckResourceAttr(resourceName, "privileges.0", string(sdk.AccountObjectPrivilegeModify)), resource.TestCheckResourceAttr(resourceName, "privileges.1", string(sdk.AccountObjectPrivilegeMonitor)), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|MODIFY,MONITOR|OnDatabase|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|MODIFY,MONITOR|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), ), }, }, @@ -691,7 +691,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_AlwaysApply(t *testing.T) { }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "always_apply", "false"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|ALL|OnDatabase|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|ALL|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), ), }, { @@ -699,7 +699,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_AlwaysApply(t *testing.T) { ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "always_apply", "true"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|true|ALL|OnDatabase|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|true|ALL|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), ), ExpectNonEmptyPlan: true, }, @@ -713,7 +713,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_AlwaysApply(t *testing.T) { }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "always_apply", "true"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|true|ALL|OnDatabase|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|true|ALL|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), ), ExpectNonEmptyPlan: true, }, @@ -727,7 +727,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_AlwaysApply(t *testing.T) { }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "always_apply", "true"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|true|ALL|OnDatabase|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|true|ALL|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), ), ExpectNonEmptyPlan: true, }, @@ -741,7 +741,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_AlwaysApply(t *testing.T) { }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "always_apply", "false"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|ALL|OnDatabase|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|ALL|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), ), }, }, diff --git a/pkg/resources/grant_privileges_to_database_role_identifier.go b/pkg/resources/grant_privileges_to_database_role_identifier.go index 56e4ec2044..f42f0a260e 100644 --- a/pkg/resources/grant_privileges_to_database_role_identifier.go +++ b/pkg/resources/grant_privileges_to_database_role_identifier.go @@ -12,7 +12,7 @@ import ( type DatabaseRoleGrantKind string const ( - OnDatabaseDatabaseRoleGrantKind DatabaseRoleGrantKind = "OnDatabase" + OnDatabaseDatabaseRoleGrantKind DatabaseRoleGrantKind = "OnDatabaseShareGrantKind" OnSchemaDatabaseRoleGrantKind DatabaseRoleGrantKind = "OnSchema" OnSchemaObjectDatabaseRoleGrantKind DatabaseRoleGrantKind = "OnSchemaObject" ) diff --git a/pkg/resources/grant_privileges_to_database_role_identifier_test.go b/pkg/resources/grant_privileges_to_database_role_identifier_test.go index ea8cd4404b..d80a25d63c 100644 --- a/pkg/resources/grant_privileges_to_database_role_identifier_test.go +++ b/pkg/resources/grant_privileges_to_database_role_identifier_test.go @@ -16,7 +16,7 @@ func TestParseGrantPrivilegesToDatabaseRoleId(t *testing.T) { }{ { Name: "grant database role on database", - Identifier: `"database-name"."database-role"|false|false|CREATE SCHEMA,USAGE,MONITOR|OnDatabase|"on-database-name"`, + Identifier: `"database-name"."database-role"|false|false|CREATE SCHEMA,USAGE,MONITOR|OnDatabaseShareGrantKind|"on-database-name"`, Expected: GrantPrivilegesToDatabaseRoleId{ DatabaseRoleName: sdk.NewDatabaseObjectIdentifier("database-name", "database-role"), WithGrantOption: false, @@ -29,7 +29,7 @@ func TestParseGrantPrivilegesToDatabaseRoleId(t *testing.T) { }, { Name: "grant database role on database - always apply with grant option", - Identifier: `"database-name"."database-role"|true|true|CREATE SCHEMA,USAGE,MONITOR|OnDatabase|"on-database-name"`, + Identifier: `"database-name"."database-role"|true|true|CREATE SCHEMA,USAGE,MONITOR|OnDatabaseShareGrantKind|"on-database-name"`, Expected: GrantPrivilegesToDatabaseRoleId{ DatabaseRoleName: sdk.NewDatabaseObjectIdentifier("database-name", "database-role"), WithGrantOption: true, @@ -43,7 +43,7 @@ func TestParseGrantPrivilegesToDatabaseRoleId(t *testing.T) { }, { Name: "grant database role on database - all privileges", - Identifier: `"database-name"."database-role"|false|false|ALL|OnDatabase|"on-database-name"`, + Identifier: `"database-name"."database-role"|false|false|ALL|OnDatabaseShareGrantKind|"on-database-name"`, Expected: GrantPrivilegesToDatabaseRoleId{ DatabaseRoleName: sdk.NewDatabaseObjectIdentifier("database-name", "database-role"), WithGrantOption: false, @@ -224,8 +224,8 @@ func TestParseGrantPrivilegesToDatabaseRoleId(t *testing.T) { Error: "database role identifier should hold at least 6 parts", }, { - Name: "validation: grant database role not enough parts for OnDatabase kind", - Identifier: `"database-name"."role-name"|false|false|CREATE SCHEMA,USAGE,MONITOR|OnDatabase`, + Name: "validation: grant database role not enough parts for OnDatabaseShareGrantKind kind", + Identifier: `"database-name"."role-name"|false|false|CREATE SCHEMA,USAGE,MONITOR|OnDatabaseShareGrantKind`, Error: "database role identifier should hold at least 6 parts", }, { @@ -265,22 +265,22 @@ func TestParseGrantPrivilegesToDatabaseRoleId(t *testing.T) { }, { Name: "validation: grant database role empty privileges", - Identifier: `"database-name"."database-role"|false|false||OnDatabase|"on-database-name"`, + Identifier: `"database-name"."database-role"|false|false||OnDatabaseShareGrantKind|"on-database-name"`, Error: `invalid Privileges value: , should be either a comma separated list of privileges or "ALL" / "ALL PRIVILEGES" for all privileges`, }, { Name: "validation: grant database role empty with grant option", - Identifier: `"database-name"."database-role"||false|ALL PRIVILEGES|OnDatabase|"on-database-name"`, + Identifier: `"database-name"."database-role"||false|ALL PRIVILEGES|OnDatabaseShareGrantKind|"on-database-name"`, Error: `invalid WithGrantOption value: , should be either "true" or "false"`, }, { Name: "validation: grant database role empty always apply", - Identifier: `"database-name"."database-role"|false||ALL PRIVILEGES|OnDatabase|"on-database-name"`, + Identifier: `"database-name"."database-role"|false||ALL PRIVILEGES|OnDatabaseShareGrantKind|"on-database-name"`, Error: `invalid AlwaysApply value: , should be either "true" or "false"`, }, { Name: "validation: grant database role empty database role name", - Identifier: `|false|false|ALL PRIVILEGES|OnDatabase|"on-database-name"`, + Identifier: `|false|false|ALL PRIVILEGES|OnDatabaseShareGrantKind|"on-database-name"`, Error: "invalid DatabaseRoleName value: , should be a fully qualified name of database object .", }, { @@ -323,7 +323,7 @@ func TestGrantPrivilegesToDatabaseRoleIdString(t *testing.T) { DatabaseName: sdk.NewAccountObjectIdentifier("database-name"), }, }, - Expected: `"database-name"."role-name"|true|true|ALL|OnDatabase|"database-name"`, + Expected: `"database-name"."role-name"|true|true|ALL|OnDatabaseShareGrantKind|"database-name"`, }, { Name: "grant database role on schema on schema", diff --git a/pkg/resources/grant_privileges_to_share.go b/pkg/resources/grant_privileges_to_share.go new file mode 100644 index 0000000000..0867f69eb3 --- /dev/null +++ b/pkg/resources/grant_privileges_to_share.go @@ -0,0 +1,391 @@ +package resources + +import ( + "context" + "database/sql" + "fmt" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/logging" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "log" + "slices" +) + +var grantPrivilegesToShareGrantExactlyOneOfValidation = []string{ + "database_name", + "schema_name", + //"function_name", + "table_name", + "all_tables_in_schema", + "tag_name", + "view_name", +} + +var grantPrivilegesToShareSchema = map[string]*schema.Schema{ + "share_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The fully qualified name of the share on which privileges will be granted.", + ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](), + }, + "privileges": { + Type: schema.TypeSet, + Required: true, + Description: "The privileges to grant on the share.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "database_name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "TODO", + ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](), + ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, + }, + "schema_name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "TODO", + ValidateDiagFunc: IsValidIdentifier[sdk.DatabaseObjectIdentifier](), + ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, + }, + // TODO(SNOW-1021686): Because function identifier contains arguments which are not supported right now + //"function_name": { + // Type: schema.TypeString, + // Optional: true, + // ForceNew: true, + // Description: "TODO", + // ValidateDiagFunc: IsValidIdentifier[sdk.FunctionIdentifier](), + // ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, + //}, + "table_name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "TODO", + ValidateDiagFunc: IsValidIdentifier[sdk.SchemaObjectIdentifier](), + ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, + }, + "all_tables_in_schema": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "TODO", + ValidateDiagFunc: IsValidIdentifier[sdk.DatabaseObjectIdentifier](), + ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, + }, + "tag_name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "TODO", + ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](), + ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, + }, + "view_name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "TODO", + ValidateDiagFunc: IsValidIdentifier[sdk.SchemaObjectIdentifier](), + ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, + }, +} + +func GrantPrivilegesToShare() *schema.Resource { + return &schema.Resource{ + CreateContext: CreateGrantPrivilegesToShare, + UpdateContext: UpdateGrantPrivilegesToShare, + DeleteContext: DeleteGrantPrivilegesToShare, + ReadContext: ReadGrantPrivilegesToShare, + + Schema: grantPrivilegesToShareSchema, + Importer: &schema.ResourceImporter{ + StateContext: ImportGrantPrivilegesToShare(), + }, + } +} + +func ImportGrantPrivilegesToShare() func(ctx context.Context, d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { + return func(ctx context.Context, d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { + id, err := ParseGrantPrivilegesToShareId(d.Id()) + if err != nil { + return nil, err + } + if err := d.Set("share_name", id.ShareName.FullyQualifiedName()); err != nil { + return nil, err + } + if err := d.Set("privileges", id.Privileges); err != nil { + return nil, err + } + + switch id.Kind { + case OnDatabaseShareGrantKind: + if err := d.Set("database_name", id.Identifier.FullyQualifiedName()); err != nil { + return nil, err + } + case OnSchemaShareGrantKind: + if err := d.Set("schema_name", id.Identifier.FullyQualifiedName()); err != nil { + return nil, err + } + case OnFunctionShareGrantKind: + if err := d.Set("function_name", id.Identifier.FullyQualifiedName()); err != nil { + return nil, err + } + case OnTableShareGrantKind: + if err := d.Set("table_name", id.Identifier.FullyQualifiedName()); err != nil { + return nil, err + } + case OnAllTablesInSchemaShareGrantKind: + if err := d.Set("all_tables_in_schema", id.Identifier.FullyQualifiedName()); err != nil { + return nil, err + } + case OnTagShareGrantKind: + if err := d.Set("tag_name", id.Identifier.FullyQualifiedName()); err != nil { + return nil, err + } + case OnViewShareGrantKind: + if err := d.Set("view_name", id.Identifier.FullyQualifiedName()); err != nil { + return nil, err + } + } + + return []*schema.ResourceData{d}, nil + } +} + +func CreateGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { + db := meta.(*sql.DB) + client := sdk.NewClientFromDB(db) + id := createGrantPrivilegesToShareIdFromSchema(d) + log.Printf("[DEBUG] created identifier from schema: %s", id.String()) + + err := client.Grants.GrantPrivilegeToShare(ctx, getObjectPrivilegesFromSchema(d), getShareGrantOn(d), id.ShareName) + if err != nil { + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "An error occurred when granting privileges to share", + Detail: fmt.Sprintf("Id: %s\nShare name: %s\nError: %s", id.String(), id.ShareName, err.Error()), + }, + } + } + + d.SetId(id.String()) + + return ReadGrantPrivilegesToShare(ctx, d, meta) +} + +func UpdateGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { + return ReadGrantPrivilegesToShare(ctx, d, meta) +} + +func DeleteGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { + db := meta.(*sql.DB) + client := sdk.NewClientFromDB(db) + + id, err := ParseGrantPrivilegesToShareId(d.Id()) + if err != nil { + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "Failed to parse internal identifier", + Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err.Error()), + }, + } + } + + err = client.Grants.RevokePrivilegeFromShare(ctx, getObjectPrivilegesFromSchema(d), getShareGrantOn(d), id.ShareName) + if err != nil { + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "An error occurred when revoking privileges from share", + Detail: fmt.Sprintf("Id: %s\nShare name: %s\nError: %s", d.Id(), id.ShareName.FullyQualifiedName(), err.Error()), + }, + } + } + + d.SetId("") + + return nil +} + +func ReadGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { + id, err := ParseGrantPrivilegesToShareId(d.Id()) + if err != nil { + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "Failed to parse internal identifier", + Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err.Error()), + }, + } + } + + opts, grantedOn, diags := prepareShowGrantsRequestForShare(id) + if len(diags) != 0 { + return diags + } + + db := meta.(*sql.DB) + client := sdk.NewClientFromDB(db) + grants, err := client.Grants.Show(ctx, opts) + if err != nil { + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "Failed to retrieve grants", + Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err.Error()), + }, + } + } + + // TODO: Read for + var privileges []string + + logging.DebugLogger.Printf("[DEBUG] Filtering grants to be set on account: count = %d", len(grants)) + for _, grant := range grants { + if grant.GrantedTo != sdk.ObjectTypeShare { + continue + } + // Only consider privileges that are already present in the ID, so we + // don't delete privileges managed by other resources. + if !slices.Contains(id.Privileges, grant.Privilege) { + continue + } + if grant.GranteeName.Name() == id.ShareName.Name() { // TODO: id.ShareName should be outside resource identifier (forgot the name) + if grantedOn == grant.GrantedOn { + privileges = append(privileges, grant.Privilege) + } + } + } + + logging.DebugLogger.Printf("[DEBUG] Setting privileges: %v", privileges) + if err := d.Set("privileges", privileges); err != nil { + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "Error setting privileges for account role", + Detail: fmt.Sprintf("Id: %s\nPrivileges: %v\nError: %s", d.Id(), privileges, err.Error()), + }, + } + } + + return nil +} + +func createGrantPrivilegesToShareIdFromSchema(d *schema.ResourceData) *GrantPrivilegesToShareId { + id := new(GrantPrivilegesToShareId) + id.ShareName = sdk.NewAccountObjectIdentifier(d.Get("share_name").(string)) + id.Privileges = expandStringList(d.Get("privileges").(*schema.Set).List()) + + databaseName, databaseNameOk := d.GetOk("database_name") + schemaName, schemaNameOk := d.GetOk("schema_name") + tableName, tableNameOk := d.GetOk("table_name") + allTablesInSchema, allTablesInSchemaOk := d.GetOk("all_tables_in_schema") + tagName, tagNameOk := d.GetOk("tag_name") + viewName, viewNameOk := d.GetOk("view_name") + + switch { + case databaseNameOk: + id.Kind = OnDatabaseShareGrantKind + id.Identifier = sdk.NewAccountObjectIdentifierFromFullyQualifiedName(databaseName.(string)) + case schemaNameOk: + id.Kind = OnSchemaShareGrantKind + id.Identifier = sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(schemaName.(string)) + case tableNameOk: + id.Kind = OnTableShareGrantKind + id.Identifier = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(tableName.(string)) + case allTablesInSchemaOk: + id.Kind = OnAllTablesInSchemaShareGrantKind + id.Identifier = sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(allTablesInSchema.(string)) + case tagNameOk: + id.Kind = OnTagShareGrantKind + id.Identifier = sdk.NewAccountObjectIdentifierFromFullyQualifiedName(tagName.(string)) + case viewNameOk: + id.Kind = OnViewShareGrantKind + id.Identifier = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(viewName.(string)) + } + + return id +} + +func getObjectPrivilegesFromSchema(d *schema.ResourceData) []sdk.ObjectPrivilege { + privileges := expandStringList(d.Get("privileges").(*schema.Set).List()) + objectPrivileges := make([]sdk.ObjectPrivilege, len(privileges)) + for i, privilege := range privileges { + objectPrivileges[i] = sdk.ObjectPrivilege(privilege) + } + return objectPrivileges +} + +func getShareGrantOn(d *schema.ResourceData) *sdk.ShareGrantOn { + grantOn := new(sdk.ShareGrantOn) + + databaseName, databaseNameOk := d.GetOk("database_name") + schemaName, schemaNameOk := d.GetOk("schema_name") + tableName, tableNameOk := d.GetOk("table_name") + allTablesInSchema, allTablesInSchemaOk := d.GetOk("all_tables_in_schema") + tagName, tagNameOk := d.GetOk("tag_name") + viewName, viewNameOk := d.GetOk("view_name") + + switch { + case len(databaseName.(string)) > 0 && databaseNameOk: + grantOn.Database = sdk.NewAccountObjectIdentifierFromFullyQualifiedName(databaseName.(string)) + case len(schemaName.(string)) > 0 && schemaNameOk: + grantOn.Schema = sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(schemaName.(string)) + case len(tableName.(string)) > 0 && tableNameOk: + grantOn.Table = &sdk.OnTable{ + Name: sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(tableName.(string)), + } + case len(allTablesInSchema.(string)) > 0 && allTablesInSchemaOk: + grantOn.Table = &sdk.OnTable{ + AllInSchema: sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(allTablesInSchema.(string)), + } + case len(tagName.(string)) > 0 && tagNameOk: + grantOn.Tag = sdk.NewAccountObjectIdentifierFromFullyQualifiedName(tagName.(string)) + case len(viewName.(string)) > 0 && viewNameOk: + grantOn.View = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(viewName.(string)) + } + + return grantOn +} + +func prepareShowGrantsRequestForShare(id GrantPrivilegesToShareId) (*sdk.ShowGrantOptions, sdk.ObjectType, diag.Diagnostics) { + opts := new(sdk.ShowGrantOptions) + var objectType sdk.ObjectType + + switch id.Kind { + case OnDatabaseShareGrantKind: + objectType = sdk.ObjectTypeDatabase + case OnSchemaShareGrantKind: + objectType = sdk.ObjectTypeSchema + case OnTableShareGrantKind: + objectType = sdk.ObjectTypeTable + case OnAllTablesInSchemaShareGrantKind: + return nil, "", diag.Diagnostics{ + diag.Diagnostic{ + // TODO: link to the design decisions doc (SNOW-990811) + Severity: diag.Warning, + Summary: "Show with OnAll option is skipped.", + Detail: "See our document on design decisions for grants: ", + }, + } + case OnTagShareGrantKind: + objectType = sdk.ObjectTypeTag + case OnViewShareGrantKind: + objectType = sdk.ObjectTypeView + } + + opts.On = &sdk.ShowGrantsOn{ + Object: &sdk.Object{ + ObjectType: objectType, + Name: id.Identifier, + }, + } + return opts, "", nil +} diff --git a/pkg/resources/grant_privileges_to_share_identifier.go b/pkg/resources/grant_privileges_to_share_identifier.go new file mode 100644 index 0000000000..cc56e33c38 --- /dev/null +++ b/pkg/resources/grant_privileges_to_share_identifier.go @@ -0,0 +1,97 @@ +package resources + +import ( + "fmt" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" + "strings" +) + +type ShareGrantKind string + +const ( + OnDatabaseShareGrantKind ShareGrantKind = "OnDatabase" + OnSchemaShareGrantKind ShareGrantKind = "OnSchema" + OnFunctionShareGrantKind ShareGrantKind = "OnFunction" + OnTableShareGrantKind ShareGrantKind = "OnTable" + OnAllTablesInSchemaShareGrantKind ShareGrantKind = "OnAllTablesInSchema" + OnTagShareGrantKind ShareGrantKind = "OnTag" + OnViewShareGrantKind ShareGrantKind = "OnView" +) + +type GrantPrivilegesToShareId struct { + ShareName sdk.AccountObjectIdentifier + Privileges []string + Kind ShareGrantKind + Identifier sdk.ObjectIdentifier +} + +func (id *GrantPrivilegesToShareId) String() string { + return strings.Join([]string{ + id.ShareName.FullyQualifiedName(), + strings.Join(id.Privileges, ","), + string(id.Kind), + id.Identifier.FullyQualifiedName(), + }, helpers.IDDelimiter) +} + +func ParseGrantPrivilegesToShareId(idString string) (GrantPrivilegesToShareId, error) { + var grantPrivilegesToShareId GrantPrivilegesToShareId + + parts := strings.Split(idString, helpers.IDDelimiter) + if len(parts) != 4 { + return grantPrivilegesToShareId, sdk.NewError(fmt.Sprintf(`snowflake_grant_privileges_to_share id is composed out of 4 parts "|||", but got %d parts: %v`, len(parts), parts)) + } + + grantPrivilegesToShareId.ShareName = sdk.NewAccountObjectIdentifier(parts[0]) + privileges := strings.Split(parts[1], ",") + if len(privileges) == 0 || (len(privileges) == 1 && privileges[0] == "") { + return grantPrivilegesToShareId, sdk.NewError(fmt.Sprintf(`invalid Privileges value: %s, should be comma separated list of privileges`, privileges)) + } + grantPrivilegesToShareId.Privileges = privileges + grantPrivilegesToShareId.Kind = ShareGrantKind(parts[2]) + + id, err := helpers.DecodeSnowflakeParameterID(parts[3]) + if err != nil { + return grantPrivilegesToShareId, err + } + + switch grantPrivilegesToShareId.Kind { + case OnDatabaseShareGrantKind, OnTagShareGrantKind: + if typedIdentifier, ok := id.(sdk.AccountObjectIdentifier); ok { + grantPrivilegesToShareId.Identifier = typedIdentifier + } else { + return grantPrivilegesToShareId, fmt.Errorf( + "invalid identifier, expected fully qualified name of account object: %s, but instead got: %s", + getExpectedIdentifierRepresentationFromGeneric[sdk.AccountObjectIdentifier](), + getExpectedIdentifierRepresentationFromParam(id), + ) + } + case OnSchemaShareGrantKind, OnAllTablesInSchemaShareGrantKind: + if typedIdentifier, ok := id.(sdk.DatabaseObjectIdentifier); ok { + grantPrivilegesToShareId.Identifier = typedIdentifier + } else { + return grantPrivilegesToShareId, fmt.Errorf( + "invalid identifier, expected fully qualified name of database object: %s, but instead got: %s", + getExpectedIdentifierRepresentationFromGeneric[sdk.DatabaseObjectIdentifier](), + getExpectedIdentifierRepresentationFromParam(id), + ) + } + case OnTableShareGrantKind, OnViewShareGrantKind: + if typedIdentifier, ok := id.(sdk.SchemaObjectIdentifier); ok { + grantPrivilegesToShareId.Identifier = typedIdentifier + } else { + return grantPrivilegesToShareId, fmt.Errorf( + "invalid identifier, expected fully qualified name of schema object: %s, but instead got: %s", + getExpectedIdentifierRepresentationFromGeneric[sdk.SchemaObjectIdentifier](), + getExpectedIdentifierRepresentationFromParam(id), + ) + } + case OnFunctionShareGrantKind: + // TODO(SNOW-1021686): Because function identifier contains arguments which are not supported right now + default: + return grantPrivilegesToShareId, fmt.Errorf("unexpected share grant kind: %v", grantPrivilegesToShareId.Kind) + } + + return grantPrivilegesToShareId, nil +} diff --git a/pkg/resources/grant_privileges_to_share_identifier_test.go b/pkg/resources/grant_privileges_to_share_identifier_test.go new file mode 100644 index 0000000000..c56136833f --- /dev/null +++ b/pkg/resources/grant_privileges_to_share_identifier_test.go @@ -0,0 +1,204 @@ +package resources + +import ( + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" + "github.com/stretchr/testify/assert" + "testing" +) + +// TODO(SNOW-1021686): Add tests for function identifier +func TestParseGrantPrivilegesToShareId(t *testing.T) { + testCases := []struct { + Name string + Identifier string + Expected GrantPrivilegesToShareId + Error string + }{ + { + Name: "grant privileges on database to share", + Identifier: `"share-name"|REFERENCE_USAGE|OnDatabase|"on-database-name"`, + Expected: GrantPrivilegesToShareId{ + ShareName: sdk.NewAccountObjectIdentifier("share-name"), + Privileges: []string{"REFERENCE_USAGE"}, + Kind: OnDatabaseShareGrantKind, + Identifier: sdk.NewAccountObjectIdentifier("on-database-name"), + }, + }, + { + Name: "grant privileges on schema to share", + Identifier: `"share-name"|USAGE|OnSchema|"on-database-name"."on-schema-name"`, + Expected: GrantPrivilegesToShareId{ + ShareName: sdk.NewAccountObjectIdentifier("share-name"), + Privileges: []string{"USAGE"}, + Kind: OnSchemaShareGrantKind, + Identifier: sdk.NewDatabaseObjectIdentifier("on-database-name", "on-schema-name"), + }, + }, + { + Name: "grant privileges on table to share", + Identifier: `"share-name"|EVOLVE SCHEMA|OnTable|"on-database-name"."on-schema-name"."on-table-name"`, + Expected: GrantPrivilegesToShareId{ + ShareName: sdk.NewAccountObjectIdentifier("share-name"), + Privileges: []string{"EVOLVE SCHEMA"}, + Kind: OnTableShareGrantKind, + Identifier: sdk.NewSchemaObjectIdentifier("on-database-name", "on-schema-name", "on-table-name"), + }, + }, + { + Name: "grant privileges on all tables in schema to share", + Identifier: `"share-name"|EVOLVE SCHEMA,SELECT|OnAllTablesInSchema|"on-database-name"."on-schema-name"`, + Expected: GrantPrivilegesToShareId{ + ShareName: sdk.NewAccountObjectIdentifier("share-name"), + Privileges: []string{"EVOLVE SCHEMA", "SELECT"}, + Kind: OnAllTablesInSchemaShareGrantKind, + Identifier: sdk.NewDatabaseObjectIdentifier("on-database-name", "on-schema-name"), + }, + }, + { + Name: "grant privileges on tag to share", + Identifier: `"share-name"|READ|OnTag|"on-tag-name"`, + Expected: GrantPrivilegesToShareId{ + ShareName: sdk.NewAccountObjectIdentifier("share-name"), + Privileges: []string{"READ"}, + Kind: OnTagShareGrantKind, + Identifier: sdk.NewAccountObjectIdentifier("on-tag-name"), + }, + }, + { + Name: "grant privileges on view to share", + Identifier: `"share-name"|READ|OnView|"on-database-name"."on-schema-name"."on-view-name"`, + Expected: GrantPrivilegesToShareId{ + ShareName: sdk.NewAccountObjectIdentifier("share-name"), + Privileges: []string{"READ"}, + Kind: OnViewShareGrantKind, + Identifier: sdk.NewSchemaObjectIdentifier("on-database-name", "on-schema-name", "on-view-name"), + }, + }, + { + Name: "validation: not enough parts", + Identifier: `"share-name"|SELECT|OnDatabase`, + Error: `snowflake_grant_privileges_to_share id is composed out of 4 parts "|||", but got 3 parts: ["share-name" SELECT OnDatabase]`, + }, + { + Name: "validation: empty privileges", + Identifier: `"share-name"||OnDatabase|"database-name"`, + Error: `invalid Privileges value: [], should be comma separated list of privileges`, + }, + { + Name: "validation: unsupported kind", + Identifier: `"share-name"|SELECT|OnSomething|"object-name"`, + Error: `unexpected share grant kind: OnSomething`, + }, + { + Name: "validation: invalid identifier", + Identifier: `"share-name"|SELECT|OnDatabase|one.two.three.four.five.six.seven.eight.nine.ten`, + Error: `unable to classify identifier: one.two.three.four.five.six.seven.eight.nine.ten`, + }, + { + Name: "validation: invalid account object identifier", + Identifier: `"share-name"|SELECT|OnDatabase|one.two`, + Error: `invalid identifier, expected fully qualified name of account object: , but instead got: .`, + }, + { + Name: "validation: invalid database object identifier", + Identifier: `"share-name"|SELECT|OnSchema|one.two.three`, + Error: `invalid identifier, expected fully qualified name of database object: ., but instead got: ..`, + }, + { + Name: "validation: invalid schema object identifier", + Identifier: `"share-name"|SELECT|OnTable|one`, + Error: `invalid identifier, expected fully qualified name of schema object: .., but instead got: `, + }, + } + + for _, tt := range testCases { + tt := tt + t.Run(tt.Name, func(t *testing.T) { + id, err := ParseGrantPrivilegesToShareId(tt.Identifier) + if tt.Error == "" { + assert.NoError(t, err) + assert.Equal(t, tt.Expected, id) + } else { + assert.ErrorContains(t, err, tt.Error) + } + }) + } +} + +// TODO(SNOW-1021686): Add tests for function identifier +func TestGrantPrivilegesToShareIdString(t *testing.T) { + testCases := []struct { + Name string + Identifier GrantPrivilegesToShareId + Expected string + Error string + }{ + { + Name: "grant privileges on database to share", + Identifier: GrantPrivilegesToShareId{ + ShareName: sdk.NewAccountObjectIdentifier("share-name"), + Privileges: []string{"REFERENCE_USAGE"}, + Kind: OnDatabaseShareGrantKind, + Identifier: sdk.NewAccountObjectIdentifier("database-name"), + }, + Expected: `"share-name"|REFERENCE_USAGE|OnDatabase|"database-name"`, + }, + { + Name: "grant privileges on schema to share", + Identifier: GrantPrivilegesToShareId{ + ShareName: sdk.NewAccountObjectIdentifier("share-name"), + Privileges: []string{"USAGE"}, + Kind: OnSchemaShareGrantKind, + Identifier: sdk.NewDatabaseObjectIdentifier("database-name", "schema-name"), + }, + Expected: `"share-name"|USAGE|OnSchema|"database-name"."schema-name"`, + }, + { + Name: "grant privileges on table to share", + Identifier: GrantPrivilegesToShareId{ + ShareName: sdk.NewAccountObjectIdentifier("share-name"), + Privileges: []string{"EVOLVE SCHEMA", "SELECT"}, + Kind: OnTableShareGrantKind, + Identifier: sdk.NewSchemaObjectIdentifier("database-name", "schema-name", "table-name"), + }, + Expected: `"share-name"|EVOLVE SCHEMA,SELECT|OnTable|"database-name"."schema-name"."table-name"`, + }, + { + Name: "grant privileges on all tables in schema to share", + Identifier: GrantPrivilegesToShareId{ + ShareName: sdk.NewAccountObjectIdentifier("share-name"), + Privileges: []string{"EVOLVE SCHEMA", "SELECT"}, + Kind: OnAllTablesInSchemaShareGrantKind, + Identifier: sdk.NewDatabaseObjectIdentifier("database-name", "schema-name"), + }, + Expected: `"share-name"|EVOLVE SCHEMA,SELECT|OnAllTablesInSchema|"database-name"."schema-name"`, + }, + { + Name: "grant privileges on tag to share", + Identifier: GrantPrivilegesToShareId{ + ShareName: sdk.NewAccountObjectIdentifier("share-name"), + Privileges: []string{"READ"}, + Kind: OnTagShareGrantKind, + Identifier: sdk.NewAccountObjectIdentifier("tag-name"), + }, + Expected: `"share-name"|READ|OnTag|"tag-name"`, + }, + { + Name: "grant privileges on view to share", + Identifier: GrantPrivilegesToShareId{ + ShareName: sdk.NewAccountObjectIdentifier("share-name"), + Privileges: []string{"SELECT"}, + Kind: OnViewShareGrantKind, + Identifier: sdk.NewSchemaObjectIdentifier("database-name", "schema-name", "view-name"), + }, + Expected: `"share-name"|SELECT|OnView|"database-name"."schema-name"."view-name"`, + }, + } + + for _, tt := range testCases { + tt := tt + t.Run(tt.Name, func(t *testing.T) { + assert.Equal(t, tt.Expected, tt.Identifier.String()) + }) + } +} diff --git a/pkg/resources/share.go b/pkg/resources/share.go index f7d0d8cb63..240bf24d4f 100644 --- a/pkg/resources/share.go +++ b/pkg/resources/share.go @@ -123,7 +123,7 @@ func setShareAccounts(ctx context.Context, client *sdk.Client, shareID sdk.Accou // case where the main db doesn't already exist, so it will need to be revoked // before deleting the temp db. Where USAGE hasn't been already granted it is not // an error to revoke it, so it's ok to just do the revoke every time. - err = client.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeReferenceUsage, &sdk.GrantPrivilegeToShareOn{ + err = client.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeReferenceUsage, &sdk.ShareGrantOn{ Database: tempDatabaseID, }, shareID) if err != nil { diff --git a/pkg/sdk/grants.go b/pkg/sdk/grants.go index 2eb79f7372..7d2b318ed7 100644 --- a/pkg/sdk/grants.go +++ b/pkg/sdk/grants.go @@ -13,8 +13,8 @@ type Grants interface { RevokePrivilegesFromAccountRole(ctx context.Context, privileges *AccountRoleGrantPrivileges, on *AccountRoleGrantOn, role AccountObjectIdentifier, opts *RevokePrivilegesFromAccountRoleOptions) error GrantPrivilegesToDatabaseRole(ctx context.Context, privileges *DatabaseRoleGrantPrivileges, on *DatabaseRoleGrantOn, role DatabaseObjectIdentifier, opts *GrantPrivilegesToDatabaseRoleOptions) error RevokePrivilegesFromDatabaseRole(ctx context.Context, privileges *DatabaseRoleGrantPrivileges, on *DatabaseRoleGrantOn, role DatabaseObjectIdentifier, opts *RevokePrivilegesFromDatabaseRoleOptions) error - GrantPrivilegeToShare(ctx context.Context, privilege ObjectPrivilege, on *GrantPrivilegeToShareOn, to AccountObjectIdentifier) error - RevokePrivilegeFromShare(ctx context.Context, privilege ObjectPrivilege, on *RevokePrivilegeFromShareOn, from AccountObjectIdentifier) error + GrantPrivilegeToShare(ctx context.Context, privileges []ObjectPrivilege, on *ShareGrantOn, to AccountObjectIdentifier) error + RevokePrivilegeFromShare(ctx context.Context, privileges []ObjectPrivilege, on *ShareGrantOn, from AccountObjectIdentifier) error GrantOwnership(ctx context.Context, on OwnershipGrantOn, to OwnershipGrantTo, opts *GrantOwnershipOptions) error Show(ctx context.Context, opts *ShowGrantOptions) ([]Grant, error) @@ -120,17 +120,18 @@ type RevokePrivilegesFromDatabaseRoleOptions struct { // grantPrivilegeToShareOptions is based on https://docs.snowflake.com/en/sql-reference/sql/grant-privilege-share. type grantPrivilegeToShareOptions struct { - grant bool `ddl:"static" sql:"GRANT"` - privilege ObjectPrivilege `ddl:"keyword"` - On *GrantPrivilegeToShareOn `ddl:"keyword" sql:"ON"` - to AccountObjectIdentifier `ddl:"identifier" sql:"TO SHARE"` + grant bool `ddl:"static" sql:"GRANT"` + privileges []ObjectPrivilege `ddl:"-"` + On *ShareGrantOn `ddl:"keyword" sql:"ON"` + to AccountObjectIdentifier `ddl:"identifier" sql:"TO SHARE"` } -type GrantPrivilegeToShareOn struct { +type ShareGrantOn struct { Database AccountObjectIdentifier `ddl:"identifier" sql:"DATABASE"` Schema DatabaseObjectIdentifier `ddl:"identifier" sql:"SCHEMA"` Function SchemaObjectIdentifier `ddl:"identifier" sql:"FUNCTION"` Table *OnTable `ddl:"-"` + Tag AccountObjectIdentifier `ddl:"identifier" sql:"TAG"` View SchemaObjectIdentifier `ddl:"identifier" sql:"VIEW"` } @@ -141,17 +142,10 @@ type OnTable struct { // revokePrivilegeFromShareOptions is based on https://docs.snowflake.com/en/sql-reference/sql/revoke-privilege-share. type revokePrivilegeFromShareOptions struct { - revoke bool `ddl:"static" sql:"REVOKE"` - privilege ObjectPrivilege `ddl:"keyword"` - On *RevokePrivilegeFromShareOn `ddl:"keyword" sql:"ON"` - from AccountObjectIdentifier `ddl:"identifier" sql:"FROM SHARE"` -} - -type RevokePrivilegeFromShareOn struct { - Database AccountObjectIdentifier `ddl:"identifier" sql:"DATABASE"` - Schema DatabaseObjectIdentifier `ddl:"identifier" sql:"SCHEMA"` - Table *OnTable `ddl:"-"` - View *OnView `ddl:"-"` + revoke bool `ddl:"static" sql:"REVOKE"` + privileges []ObjectPrivilege `ddl:"-"` + On *ShareGrantOn `ddl:"keyword" sql:"ON"` + from AccountObjectIdentifier `ddl:"identifier" sql:"FROM SHARE"` } type OnView struct { diff --git a/pkg/sdk/grants_impl.go b/pkg/sdk/grants_impl.go index 31f978dd64..5df299e877 100644 --- a/pkg/sdk/grants_impl.go +++ b/pkg/sdk/grants_impl.go @@ -56,20 +56,20 @@ func (v *grants) RevokePrivilegesFromDatabaseRole(ctx context.Context, privilege return validateAndExec(v.client, ctx, opts) } -func (v *grants) GrantPrivilegeToShare(ctx context.Context, privilege ObjectPrivilege, on *GrantPrivilegeToShareOn, to AccountObjectIdentifier) error { +func (v *grants) GrantPrivilegeToShare(ctx context.Context, privileges []ObjectPrivilege, on *ShareGrantOn, to AccountObjectIdentifier) error { opts := &grantPrivilegeToShareOptions{ - privilege: privilege, - On: on, - to: to, + privileges: privileges, + On: on, + to: to, } return validateAndExec(v.client, ctx, opts) } -func (v *grants) RevokePrivilegeFromShare(ctx context.Context, privilege ObjectPrivilege, on *RevokePrivilegeFromShareOn, id AccountObjectIdentifier) error { +func (v *grants) RevokePrivilegeFromShare(ctx context.Context, privileges []ObjectPrivilege, on *ShareGrantOn, id AccountObjectIdentifier) error { opts := &revokePrivilegeFromShareOptions{ - privilege: privilege, - On: on, - from: id, + privileges: privileges, + On: on, + from: id, } return validateAndExec(v.client, ctx, opts) } diff --git a/pkg/sdk/grants_test.go b/pkg/sdk/grants_test.go index 9bda91c4d1..797f96e759 100644 --- a/pkg/sdk/grants_test.go +++ b/pkg/sdk/grants_test.go @@ -728,8 +728,8 @@ func TestGrantPrivilegeToShare(t *testing.T) { t.Run("on database", func(t *testing.T) { otherID := RandomAccountObjectIdentifier() opts := &grantPrivilegeToShareOptions{ - privilege: ObjectPrivilegeUsage, - On: &GrantPrivilegeToShareOn{ + privileges: []ObjectPrivilege{ObjectPrivilegeUsage}, + On: &ShareGrantOn{ Database: otherID, }, to: id, @@ -740,8 +740,8 @@ func TestGrantPrivilegeToShare(t *testing.T) { t.Run("on schema", func(t *testing.T) { otherID := RandomDatabaseObjectIdentifier() opts := &grantPrivilegeToShareOptions{ - privilege: ObjectPrivilegeUsage, - On: &GrantPrivilegeToShareOn{ + privileges: []ObjectPrivilege{ObjectPrivilegeUsage}, + On: &ShareGrantOn{ Schema: otherID, }, to: id, @@ -752,8 +752,8 @@ func TestGrantPrivilegeToShare(t *testing.T) { t.Run("on table", func(t *testing.T) { otherID := RandomSchemaObjectIdentifier() opts := &grantPrivilegeToShareOptions{ - privilege: ObjectPrivilegeUsage, - On: &GrantPrivilegeToShareOn{ + privileges: []ObjectPrivilege{ObjectPrivilegeUsage}, + On: &ShareGrantOn{ Table: &OnTable{ Name: otherID, }, @@ -766,8 +766,8 @@ func TestGrantPrivilegeToShare(t *testing.T) { t.Run("on all tables", func(t *testing.T) { otherID := RandomDatabaseObjectIdentifier() opts := &grantPrivilegeToShareOptions{ - privilege: ObjectPrivilegeUsage, - On: &GrantPrivilegeToShareOn{ + privileges: []ObjectPrivilege{ObjectPrivilegeUsage}, + On: &ShareGrantOn{ Table: &OnTable{ AllInSchema: otherID, }, @@ -780,8 +780,8 @@ func TestGrantPrivilegeToShare(t *testing.T) { t.Run("on view", func(t *testing.T) { otherID := RandomSchemaObjectIdentifier() opts := &grantPrivilegeToShareOptions{ - privilege: ObjectPrivilegeUsage, - On: &GrantPrivilegeToShareOn{ + privileges: []ObjectPrivilege{ObjectPrivilegeUsage}, + On: &ShareGrantOn{ View: otherID, }, to: id, @@ -795,8 +795,8 @@ func TestRevokePrivilegeFromShare(t *testing.T) { t.Run("on database", func(t *testing.T) { otherID := RandomAccountObjectIdentifier() opts := &revokePrivilegeFromShareOptions{ - privilege: ObjectPrivilegeUsage, - On: &RevokePrivilegeFromShareOn{ + privileges: []ObjectPrivilege{ObjectPrivilegeUsage}, + On: &ShareGrantOn{ Database: otherID, }, from: id, @@ -807,8 +807,8 @@ func TestRevokePrivilegeFromShare(t *testing.T) { t.Run("on schema", func(t *testing.T) { otherID := RandomDatabaseObjectIdentifier() opts := &revokePrivilegeFromShareOptions{ - privilege: ObjectPrivilegeUsage, - On: &RevokePrivilegeFromShareOn{ + privileges: []ObjectPrivilege{ObjectPrivilegeUsage}, + On: &ShareGrantOn{ Schema: otherID, }, from: id, @@ -819,8 +819,8 @@ func TestRevokePrivilegeFromShare(t *testing.T) { t.Run("on table", func(t *testing.T) { otherID := RandomSchemaObjectIdentifier() opts := &revokePrivilegeFromShareOptions{ - privilege: ObjectPrivilegeUsage, - On: &RevokePrivilegeFromShareOn{ + privileges: []ObjectPrivilege{ObjectPrivilegeUsage}, + On: &ShareGrantOn{ Table: &OnTable{ Name: otherID, }, @@ -833,8 +833,8 @@ func TestRevokePrivilegeFromShare(t *testing.T) { t.Run("on all tables", func(t *testing.T) { otherID := RandomDatabaseObjectIdentifier() opts := &revokePrivilegeFromShareOptions{ - privilege: ObjectPrivilegeUsage, - On: &RevokePrivilegeFromShareOn{ + privileges: []ObjectPrivilege{ObjectPrivilegeUsage}, + On: &ShareGrantOn{ Table: &OnTable{ AllInSchema: otherID, }, @@ -847,30 +847,40 @@ func TestRevokePrivilegeFromShare(t *testing.T) { t.Run("on view", func(t *testing.T) { otherID := RandomSchemaObjectIdentifier() opts := &revokePrivilegeFromShareOptions{ - privilege: ObjectPrivilegeUsage, - On: &RevokePrivilegeFromShareOn{ - View: &OnView{ - Name: otherID, - }, + privileges: []ObjectPrivilege{ObjectPrivilegeUsage}, + On: &ShareGrantOn{ + View: otherID, }, from: id, } assertOptsValidAndSQLEquals(t, opts, "REVOKE USAGE ON VIEW %s FROM SHARE %s", otherID.FullyQualifiedName(), id.FullyQualifiedName()) }) - t.Run("on all views", func(t *testing.T) { - otherID := RandomDatabaseObjectIdentifier() + t.Run("on tag", func(t *testing.T) { opts := &revokePrivilegeFromShareOptions{ - privilege: ObjectPrivilegeUsage, - On: &RevokePrivilegeFromShareOn{ - View: &OnView{ - AllInSchema: otherID, - }, + privileges: []ObjectPrivilege{ObjectPrivilegeRead}, + On: &ShareGrantOn{ + Tag: NewAccountObjectIdentifier("tag-name"), }, from: id, } - assertOptsValidAndSQLEquals(t, opts, "REVOKE USAGE ON ALL VIEWS IN SCHEMA %s FROM SHARE %s", otherID.FullyQualifiedName(), id.FullyQualifiedName()) - }) + assertOptsValidAndSQLEquals(t, opts, "REVOKE READ ON TAG \"tag-name\" FROM SHARE %s", id.FullyQualifiedName()) + }) + + // TODO: This one throws an error + //t.Run("on all views", func(t *testing.T) { + // otherID := RandomDatabaseObjectIdentifier() + // opts := &revokePrivilegeFromShareOptions{ + // privilege: ObjectPrivilegeUsage, + // On: &RevokePrivilegeFromShareOn{ + // View: &OnView{ + // AllInSchema: otherID, + // }, + // }, + // from: id, + // } + // assertOptsValidAndSQLEquals(t, opts, "REVOKE USAGE ON ALL VIEWS IN SCHEMA %s FROM SHARE %s", otherID.FullyQualifiedName(), id.FullyQualifiedName()) + //}) } func TestGrants_GrantOwnership(t *testing.T) { diff --git a/pkg/sdk/grants_validations.go b/pkg/sdk/grants_validations.go index 3f7317afbf..844580cc87 100644 --- a/pkg/sdk/grants_validations.go +++ b/pkg/sdk/grants_validations.go @@ -233,7 +233,7 @@ func (opts *grantPrivilegeToShareOptions) validate() error { if !ValidObjectIdentifier(opts.to) { errs = append(errs, ErrInvalidObjectIdentifier) } - if !valueSet(opts.On) || opts.privilege == "" { + if !valueSet(opts.On) || len(opts.privileges) == 0 { errs = append(errs, fmt.Errorf("on and privilege are required")) } if valueSet(opts.On) { @@ -244,10 +244,10 @@ func (opts *grantPrivilegeToShareOptions) validate() error { return errors.Join(errs...) } -func (v *GrantPrivilegeToShareOn) validate() error { +func (v *ShareGrantOn) validate() error { var errs []error - if !exactlyOneValueSet(v.Database, v.Schema, v.Function, v.Table, v.View) { - errs = append(errs, errExactlyOneOf("GrantPrivilegeToShareOn", "Database", "Schema", "Function", "Table", "View")) + if !exactlyOneValueSet(v.Database, v.Schema, v.Function, v.Table, v.Tag, v.View) { + errs = append(errs, errExactlyOneOf("ShareGrantOn", "Database", "Schema", "Function", "Table", "Tag", "View")) } if valueSet(v.Table) { if err := v.Table.validate(); err != nil { @@ -272,13 +272,10 @@ func (opts *revokePrivilegeFromShareOptions) validate() error { if !ValidObjectIdentifier(opts.from) { errs = append(errs, ErrInvalidObjectIdentifier) } - if !valueSet(opts.On) || opts.privilege == "" { - errs = append(errs, errNotSet("revokePrivilegeFromShareOptions", "On", "privilege")) + if !valueSet(opts.On) || len(opts.privileges) == 0 { + errs = append(errs, errNotSet("revokePrivilegeFromShareOptions", "On", "privileges")) } if valueSet(opts.On) { - if !exactlyOneValueSet(opts.On.Database, opts.On.Schema, opts.On.Table, opts.On.View) { - errs = append(errs, errExactlyOneOf("revokePrivilegeFromShareOptions", "On.Database", "On.Schema", "On.Table", "On.View")) - } if err := opts.On.validate(); err != nil { errs = append(errs, err) } @@ -286,24 +283,6 @@ func (opts *revokePrivilegeFromShareOptions) validate() error { return errors.Join(errs...) } -func (v *RevokePrivilegeFromShareOn) validate() error { - var errs []error - if !exactlyOneValueSet(v.Database, v.Schema, v.Table, v.View) { - errs = append(errs, errExactlyOneOf("RevokePrivilegeFromShareOn", "Database", "Schema", "Table", "View")) - } - if valueSet(v.Table) { - if err := v.Table.validate(); err != nil { - errs = append(errs, err) - } - } - if valueSet(v.View) { - if err := v.View.validate(); err != nil { - errs = append(errs, err) - } - } - return errors.Join(errs...) -} - func (v *OnView) validate() error { if !exactlyOneValueSet(v.Name, v.AllInSchema) { return errExactlyOneOf("OnView", "Name", "AllInSchema") diff --git a/pkg/sdk/privileges.go b/pkg/sdk/privileges.go index f07c190b90..f1e9179051 100644 --- a/pkg/sdk/privileges.go +++ b/pkg/sdk/privileges.go @@ -243,9 +243,11 @@ func (p SchemaObjectPrivilege) String() string { type ObjectPrivilege string const ( + ObjectPrivilegeReferenceUsage ObjectPrivilege = "REFERENCE_USAGE" ObjectPrivilegeUsage ObjectPrivilege = "USAGE" + ObjectPrivilegeEvolveSchema ObjectPrivilege = "EVOLVE SCHEMA" ObjectPrivilegeSelect ObjectPrivilege = "SELECT" - ObjectPrivilegeReferenceUsage ObjectPrivilege = "REFERENCE_USAGE" + ObjectPrivilegeRead ObjectPrivilege = "READ" ) func (p ObjectPrivilege) String() string { diff --git a/pkg/sdk/testint/database_role_integration_test.go b/pkg/sdk/testint/database_role_integration_test.go index c4c9a76e42..b6b883c10e 100644 --- a/pkg/sdk/testint/database_role_integration_test.go +++ b/pkg/sdk/testint/database_role_integration_test.go @@ -262,7 +262,7 @@ func TestInt_DatabaseRoles(t *testing.T) { share, shareCleanup := createShare(t, client) t.Cleanup(shareCleanup) - err := client.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.GrantPrivilegeToShareOn{Database: testDb(t).ID()}, share.ID()) + err := client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{Database: testDb(t).ID()}, share.ID()) require.NoError(t, err) grantRequest := sdk.NewGrantDatabaseRoleToShareRequest(roleId, share.ID()) diff --git a/pkg/sdk/testint/databases_integration_test.go b/pkg/sdk/testint/databases_integration_test.go index 7441ff7040..b577b7ffd4 100644 --- a/pkg/sdk/testint/databases_integration_test.go +++ b/pkg/sdk/testint/databases_integration_test.go @@ -119,12 +119,12 @@ func TestInt_CreateShared(t *testing.T) { shareTest, shareCleanup := createShare(t, secondaryClient) t.Cleanup(shareCleanup) - err := secondaryClient.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.GrantPrivilegeToShareOn{ + err := secondaryClient.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: databaseTest.ID(), }, shareTest.ID()) require.NoError(t, err) t.Cleanup(func() { - err := secondaryClient.Grants.RevokePrivilegeFromShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.RevokePrivilegeFromShareOn{ + err := secondaryClient.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: databaseTest.ID(), }, shareTest.ID()) require.NoError(t, err) diff --git a/pkg/sdk/testint/grants_integration_test.go b/pkg/sdk/testint/grants_integration_test.go index a4c6cb7063..fff2098d04 100644 --- a/pkg/sdk/testint/grants_integration_test.go +++ b/pkg/sdk/testint/grants_integration_test.go @@ -1,12 +1,11 @@ package testint import ( - "testing" - "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/internal/collections" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "testing" ) func TestInt_GrantAndRevokePrivilegesToAccountRole(t *testing.T) { @@ -409,39 +408,60 @@ func TestInt_GrantPrivilegeToShare(t *testing.T) { ctx := testContext(t) shareTest, shareCleanup := createShare(t, client) t.Cleanup(shareCleanup) - t.Run("without options", func(t *testing.T) { - err := client.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeUsage, nil, shareTest.ID()) - require.Error(t, err) - }) - t.Run("with options", func(t *testing.T) { - err := client.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.GrantPrivilegeToShareOn{ + + assertGrant := func(t *testing.T, grants []sdk.Grant, onId sdk.ObjectIdentifier, privilege sdk.ObjectPrivilege) { + t.Helper() + var shareGrant *sdk.Grant + for i, grant := range grants { + if grant.GranteeName.Name() == shareTest.ID().Name() && grant.Privilege == string(privilege) { + shareGrant = &grants[i] + break + } + } + assert.NotNil(t, shareGrant) + assert.Equal(t, sdk.ObjectTypeTable, shareGrant.GrantedOn) + assert.Equal(t, sdk.ObjectTypeShare, shareGrant.GrantedTo) + assert.Equal(t, onId.FullyQualifiedName(), shareGrant.Name.FullyQualifiedName()) + } + + t.Run("with options - multiple privileges", func(t *testing.T) { + err := client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) require.NoError(t, err) + + t.Cleanup(func() { + err := client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ + Database: testDb(t).ID(), + }, shareTest.ID()) + assert.NoError(t, err) + }) + + table, tableCleanup := createTable(t, client, testDb(t), testSchema(t)) + t.Cleanup(tableCleanup) + + err = client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeEvolveSchema, sdk.ObjectPrivilegeSelect}, &sdk.ShareGrantOn{ + Table: &sdk.OnTable{ + AllInSchema: testSchema(t).ID(), + }, + }, shareTest.ID()) + require.NoError(t, err) + grants, err := client.Grants.Show(ctx, &sdk.ShowGrantOptions{ On: &sdk.ShowGrantsOn{ Object: &sdk.Object{ - ObjectType: sdk.ObjectTypeDatabase, - Name: testDb(t).ID(), + ObjectType: sdk.ObjectTypeTable, + Name: table.ID(), }, }, }) require.NoError(t, err) - assert.LessOrEqual(t, 2, len(grants)) - var shareGrant *sdk.Grant - for i, grant := range grants { - if grant.GranteeName.Name() == shareTest.ID().Name() { - shareGrant = &grants[i] - break - } - } - assert.NotNil(t, shareGrant) - assert.Equal(t, string(sdk.ObjectPrivilegeUsage), shareGrant.Privilege) - assert.Equal(t, sdk.ObjectTypeDatabase, shareGrant.GrantedOn) - assert.Equal(t, sdk.ObjectTypeShare, shareGrant.GrantedTo) - assert.Equal(t, testDb(t).ID().Name(), shareGrant.Name.Name()) - err = client.Grants.RevokePrivilegeFromShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.RevokePrivilegeFromShareOn{ - Database: testDb(t).ID(), + assertGrant(t, grants, table.ID(), sdk.ObjectPrivilegeSelect) + + err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeEvolveSchema, sdk.ObjectPrivilegeSelect}, &sdk.ShareGrantOn{ + Table: &sdk.OnTable{ + AllInSchema: testSchema(t).ID(), + }, }, shareTest.ID()) require.NoError(t, err) }) @@ -452,16 +472,16 @@ func TestInt_RevokePrivilegeToShare(t *testing.T) { ctx := testContext(t) shareTest, shareCleanup := createShare(t, client) t.Cleanup(shareCleanup) - err := client.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.GrantPrivilegeToShareOn{ + err := client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) require.NoError(t, err) t.Run("without options", func(t *testing.T) { - err = client.Grants.RevokePrivilegeFromShare(ctx, sdk.ObjectPrivilegeUsage, nil, shareTest.ID()) + err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, nil, shareTest.ID()) require.Error(t, err) }) t.Run("with options", func(t *testing.T) { - err = client.Grants.RevokePrivilegeFromShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.RevokePrivilegeFromShareOn{ + err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) require.NoError(t, err) @@ -587,12 +607,12 @@ func TestInt_ShowGrants(t *testing.T) { ctx := testContext(t) shareTest, shareCleanup := createShare(t, client) t.Cleanup(shareCleanup) - err := client.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.GrantPrivilegeToShareOn{ + err := client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) require.NoError(t, err) t.Cleanup(func() { - err = client.Grants.RevokePrivilegeFromShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.RevokePrivilegeFromShareOn{ + err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) require.NoError(t, err) diff --git a/pkg/sdk/testint/shares_integration_test.go b/pkg/sdk/testint/shares_integration_test.go index 0050a1e43c..8b643e6467 100644 --- a/pkg/sdk/testint/shares_integration_test.go +++ b/pkg/sdk/testint/shares_integration_test.go @@ -131,12 +131,12 @@ func TestInt_SharesAlter(t *testing.T) { t.Run("add and remove accounts", func(t *testing.T) { shareTest, shareCleanup := createShare(t, client) t.Cleanup(shareCleanup) - err := client.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.GrantPrivilegeToShareOn{ + err := client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) require.NoError(t, err) t.Cleanup(func() { - err = client.Grants.RevokePrivilegeFromShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.RevokePrivilegeFromShareOn{ + err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) }) @@ -189,12 +189,12 @@ func TestInt_SharesAlter(t *testing.T) { shareTest, shareCleanup := createShare(t, secondaryClient) t.Cleanup(shareCleanup) - err := secondaryClient.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.GrantPrivilegeToShareOn{ + err := secondaryClient.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: db.ID(), }, shareTest.ID()) require.NoError(t, err) t.Cleanup(func() { - err := secondaryClient.Grants.RevokePrivilegeFromShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.RevokePrivilegeFromShareOn{ + err := secondaryClient.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: db.ID(), }, shareTest.ID()) require.NoError(t, err) @@ -229,12 +229,12 @@ func TestInt_SharesAlter(t *testing.T) { shareTest, shareCleanup := createShare(t, client) t.Cleanup(shareCleanup) - err := client.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.GrantPrivilegeToShareOn{ + err := client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) require.NoError(t, err) t.Cleanup(func() { - err = client.Grants.RevokePrivilegeFromShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.RevokePrivilegeFromShareOn{ + err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) require.NoError(t, err) @@ -284,12 +284,12 @@ func TestInt_SharesAlter(t *testing.T) { t.Run("set and unset tags", func(t *testing.T) { shareTest, shareCleanup := createShare(t, client) t.Cleanup(shareCleanup) - err := client.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.GrantPrivilegeToShareOn{ + err := client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) require.NoError(t, err) t.Cleanup(func() { - err = client.Grants.RevokePrivilegeFromShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.RevokePrivilegeFromShareOn{ + err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) require.NoError(t, err) @@ -345,12 +345,12 @@ func TestInt_ShareDescribeProvider(t *testing.T) { shareTest, shareCleanup := createShare(t, client) t.Cleanup(shareCleanup) - err := client.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.GrantPrivilegeToShareOn{ + err := client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) require.NoError(t, err) t.Cleanup(func() { - err = client.Grants.RevokePrivilegeFromShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.RevokePrivilegeFromShareOn{ + err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) require.NoError(t, err) @@ -378,12 +378,12 @@ func TestInt_ShareDescribeConsumer(t *testing.T) { shareTest, shareCleanup := createShare(t, providerClient) t.Cleanup(shareCleanup) - err := providerClient.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.GrantPrivilegeToShareOn{ + err := providerClient.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: db.ID(), }, shareTest.ID()) require.NoError(t, err) t.Cleanup(func() { - err = providerClient.Grants.RevokePrivilegeFromShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.RevokePrivilegeFromShareOn{ + err = providerClient.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: db.ID(), }, shareTest.ID()) require.NoError(t, err) From f6bf17d08252827e4d1579f53ae33732d779531f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Tue, 30 Jan 2024 14:58:49 +0100 Subject: [PATCH 2/7] wip --- pkg/resources/grant_privileges_to_share.go | 127 +++- ...ant_privileges_to_share_acceptance_test.go | 550 ++++++++++++++++++ .../grant_privileges_to_share_identifier.go | 19 +- ...ant_privileges_to_share_identifier_test.go | 90 +-- pkg/resources/share.go | 6 +- .../OnAllTablesInSchema/test.tf | 26 + .../OnAllTablesInSchema/variables.tf | 19 + .../OnAllTablesInSchema_NoGrant/test.tf | 12 + .../OnAllTablesInSchema_NoGrant/variables.tf | 11 + .../OnDatabase/test.tf | 14 + .../OnDatabase/variables.tf | 15 + .../OnDatabase_NoGrant/test.tf | 7 + .../OnDatabase_NoGrant/variables.tf | 7 + .../OnSchema/test.tf | 26 + .../OnSchema/variables.tf | 19 + .../OnSchema_NoGrant/test.tf | 12 + .../OnSchema_NoGrant/variables.tf | 11 + .../OnTable/test.tf | 36 ++ .../OnTable/variables.tf | 23 + .../OnTable_NoGrant/test.tf | 22 + .../OnTable_NoGrant/variables.tf | 15 + .../OnTag/test.tf | 32 + .../OnTag/variables.tf | 23 + .../OnTag_NoGrant/test.tf | 18 + .../OnTag_NoGrant/variables.tf | 15 + .../OnView/test.tf | 44 ++ .../OnView/variables.tf | 27 + .../OnView_NoGrant/test.tf | 26 + .../OnView_NoGrant/variables.tf | 19 + pkg/sdk/grants.go | 2 +- pkg/sdk/grants_test.go | 4 +- pkg/sdk/privileges.go | 1 - 32 files changed, 1205 insertions(+), 73 deletions(-) create mode 100644 pkg/resources/grant_privileges_to_share_acceptance_test.go create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/variables.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/variables.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/variables.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/variables.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/variables.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/variables.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/variables.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/variables.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/variables.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/variables.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/variables.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/variables.tf diff --git a/pkg/resources/grant_privileges_to_share.go b/pkg/resources/grant_privileges_to_share.go index 0867f69eb3..821ae6775c 100644 --- a/pkg/resources/grant_privileges_to_share.go +++ b/pkg/resources/grant_privileges_to_share.go @@ -24,11 +24,11 @@ var grantPrivilegesToShareGrantExactlyOneOfValidation = []string{ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ "share_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "The fully qualified name of the share on which privileges will be granted.", - ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](), + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The fully qualified name of the share on which privileges will be granted.", + //ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](), }, "privileges": { Type: schema.TypeSet, @@ -82,7 +82,7 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ Optional: true, ForceNew: true, Description: "TODO", - ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](), + ValidateDiagFunc: IsValidIdentifier[sdk.SchemaObjectIdentifier](), ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, }, "view_name": { @@ -124,17 +124,17 @@ func ImportGrantPrivilegesToShare() func(ctx context.Context, d *schema.Resource switch id.Kind { case OnDatabaseShareGrantKind: - if err := d.Set("database_name", id.Identifier.FullyQualifiedName()); err != nil { + if err := d.Set("database_name", id.Identifier.Name()); err != nil { return nil, err } case OnSchemaShareGrantKind: if err := d.Set("schema_name", id.Identifier.FullyQualifiedName()); err != nil { return nil, err } - case OnFunctionShareGrantKind: - if err := d.Set("function_name", id.Identifier.FullyQualifiedName()); err != nil { - return nil, err - } + //case OnFunctionShareGrantKind: + // if err := d.Set("function_name", id.Identifier.FullyQualifiedName()); err != nil { + // return nil, err + // } case OnTableShareGrantKind: if err := d.Set("table_name", id.Identifier.FullyQualifiedName()); err != nil { return nil, err @@ -163,7 +163,7 @@ func CreateGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, m id := createGrantPrivilegesToShareIdFromSchema(d) log.Printf("[DEBUG] created identifier from schema: %s", id.String()) - err := client.Grants.GrantPrivilegeToShare(ctx, getObjectPrivilegesFromSchema(d), getShareGrantOn(d), id.ShareName) + err := client.Grants.GrantPrivilegeToShare(ctx, getObjectPrivilegesFromSchema(d), getShareGrantOn(d), sdk.NewAccountObjectIdentifier(id.ShareName.Name())) if err != nil { return diag.Diagnostics{ diag.Diagnostic{ @@ -180,6 +180,82 @@ func CreateGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, m } func UpdateGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { + db := meta.(*sql.DB) + client := sdk.NewClientFromDB(db) + + id, err := ParseGrantPrivilegesToShareId(d.Id()) + if err != nil { + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "Failed to parse internal identifier", + Detail: fmt.Sprintf("Id: %s\nError: %s", d.Id(), err.Error()), + }, + } + } + + if d.HasChange("privileges") { + before, after := d.GetChange("privileges") + privilegesBeforeChange := expandStringList(before.(*schema.Set).List()) + privilegesAfterChange := expandStringList(after.(*schema.Set).List()) + + var privilegesToAdd, privilegesToRemove []sdk.ObjectPrivilege + + for _, privilegeBeforeChange := range privilegesBeforeChange { + if !slices.Contains(privilegesAfterChange, privilegeBeforeChange) { + privilegesToRemove = append(privilegesToRemove, sdk.ObjectPrivilege(privilegeBeforeChange)) + } + } + + for _, privilegeAfterChange := range privilegesAfterChange { + if !slices.Contains(privilegesBeforeChange, privilegeAfterChange) { + privilegesToAdd = append(privilegesToAdd, sdk.ObjectPrivilege(privilegeAfterChange)) + } + } + + grantOn := getShareGrantOn(d) + + if len(privilegesToAdd) > 0 { + err = client.Grants.GrantPrivilegeToShare( + ctx, + privilegesToAdd, + grantOn, + sdk.NewAccountObjectIdentifier(id.ShareName.Name()), + ) + if err != nil { + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "Failed to grant added privileges", + Detail: fmt.Sprintf("Id: %s\nPrivileges to add: %v\nError: %s", d.Id(), privilegesToAdd, err.Error()), + }, + } + } + } + + if len(privilegesToRemove) > 0 { + logging.DebugLogger.Printf("[DEBUG] Revoking privileges: %v", privilegesToRemove) + err = client.Grants.RevokePrivilegeFromShare( + ctx, + privilegesToRemove, + grantOn, + sdk.NewAccountObjectIdentifier(id.ShareName.Name()), + ) + if err != nil { + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "Failed to revoke removed privileges", + Detail: fmt.Sprintf("Id: %s\nPrivileges to remove: %v\nError: %s", d.Id(), privilegesToRemove, err.Error()), + }, + } + } + } + + id.Privileges = privilegesAfterChange + d.SetId(id.String()) + } + return ReadGrantPrivilegesToShare(ctx, d, meta) } @@ -198,7 +274,7 @@ func DeleteGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, m } } - err = client.Grants.RevokePrivilegeFromShare(ctx, getObjectPrivilegesFromSchema(d), getShareGrantOn(d), id.ShareName) + err = client.Grants.RevokePrivilegeFromShare(ctx, getObjectPrivilegesFromSchema(d), getShareGrantOn(d), sdk.NewAccountObjectIdentifier(id.ShareName.Name())) if err != nil { return diag.Diagnostics{ diag.Diagnostic{ @@ -244,10 +320,7 @@ func ReadGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, met } } - // TODO: Read for var privileges []string - - logging.DebugLogger.Printf("[DEBUG] Filtering grants to be set on account: count = %d", len(grants)) for _, grant := range grants { if grant.GrantedTo != sdk.ObjectTypeShare { continue @@ -264,7 +337,11 @@ func ReadGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, met } } - logging.DebugLogger.Printf("[DEBUG] Setting privileges: %v", privileges) + // It's a pseudo-role, so we have to append it whenever it's specified in the configuration + if slices.Contains(id.Privileges, sdk.ObjectPrivilegeReferenceUsage.String()) { + privileges = append(privileges, sdk.ObjectPrivilegeReferenceUsage.String()) + } + if err := d.Set("privileges", privileges); err != nil { return diag.Diagnostics{ diag.Diagnostic{ @@ -280,11 +357,12 @@ func ReadGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, met func createGrantPrivilegesToShareIdFromSchema(d *schema.ResourceData) *GrantPrivilegesToShareId { id := new(GrantPrivilegesToShareId) - id.ShareName = sdk.NewAccountObjectIdentifier(d.Get("share_name").(string)) + id.ShareName = sdk.NewExternalObjectIdentifierFromFullyQualifiedName(d.Get("share_name").(string)) id.Privileges = expandStringList(d.Get("privileges").(*schema.Set).List()) databaseName, databaseNameOk := d.GetOk("database_name") schemaName, schemaNameOk := d.GetOk("schema_name") + //functionName, functionNameOk := d.GetOk("function_name") tableName, tableNameOk := d.GetOk("table_name") allTablesInSchema, allTablesInSchemaOk := d.GetOk("all_tables_in_schema") tagName, tagNameOk := d.GetOk("tag_name") @@ -297,6 +375,9 @@ func createGrantPrivilegesToShareIdFromSchema(d *schema.ResourceData) *GrantPriv case schemaNameOk: id.Kind = OnSchemaShareGrantKind id.Identifier = sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(schemaName.(string)) + //case functionNameOk: + // id.Kind = OnFunctionShareGrantKind + // id.Identifier = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(functionName.(string)) case tableNameOk: id.Kind = OnTableShareGrantKind id.Identifier = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(tableName.(string)) @@ -305,7 +386,7 @@ func createGrantPrivilegesToShareIdFromSchema(d *schema.ResourceData) *GrantPriv id.Identifier = sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(allTablesInSchema.(string)) case tagNameOk: id.Kind = OnTagShareGrantKind - id.Identifier = sdk.NewAccountObjectIdentifierFromFullyQualifiedName(tagName.(string)) + id.Identifier = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(tagName.(string)) case viewNameOk: id.Kind = OnViewShareGrantKind id.Identifier = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(viewName.(string)) @@ -328,6 +409,7 @@ func getShareGrantOn(d *schema.ResourceData) *sdk.ShareGrantOn { databaseName, databaseNameOk := d.GetOk("database_name") schemaName, schemaNameOk := d.GetOk("schema_name") + //functionName, functionNameOk := d.GetOk("table_name") tableName, tableNameOk := d.GetOk("table_name") allTablesInSchema, allTablesInSchemaOk := d.GetOk("all_tables_in_schema") tagName, tagNameOk := d.GetOk("tag_name") @@ -338,6 +420,8 @@ func getShareGrantOn(d *schema.ResourceData) *sdk.ShareGrantOn { grantOn.Database = sdk.NewAccountObjectIdentifierFromFullyQualifiedName(databaseName.(string)) case len(schemaName.(string)) > 0 && schemaNameOk: grantOn.Schema = sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(schemaName.(string)) + //case len(functionName.(string)) > 0 && functionNameOk: + // grantOn.Function = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(functionName.(string)) case len(tableName.(string)) > 0 && tableNameOk: grantOn.Table = &sdk.OnTable{ Name: sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(tableName.(string)), @@ -347,7 +431,7 @@ func getShareGrantOn(d *schema.ResourceData) *sdk.ShareGrantOn { AllInSchema: sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(allTablesInSchema.(string)), } case len(tagName.(string)) > 0 && tagNameOk: - grantOn.Tag = sdk.NewAccountObjectIdentifierFromFullyQualifiedName(tagName.(string)) + grantOn.Tag = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(tagName.(string)) case len(viewName.(string)) > 0 && viewNameOk: grantOn.View = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(viewName.(string)) } @@ -387,5 +471,6 @@ func prepareShowGrantsRequestForShare(id GrantPrivilegesToShareId) (*sdk.ShowGra Name: id.Identifier, }, } - return opts, "", nil + + return opts, objectType, nil } diff --git a/pkg/resources/grant_privileges_to_share_acceptance_test.go b/pkg/resources/grant_privileges_to_share_acceptance_test.go new file mode 100644 index 0000000000..8aa2e421d5 --- /dev/null +++ b/pkg/resources/grant_privileges_to_share_acceptance_test.go @@ -0,0 +1,550 @@ +package resources_test + +import ( + "context" + "database/sql" + "fmt" + acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-plugin-testing/tfversion" + "github.com/stretchr/testify/require" + "strings" + "testing" +) + +func TestAcc_GrantPrivilegesToShare_OnDatabase(t *testing.T) { + databaseName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + + client, err := sdk.NewDefaultClient() + require.NoError(t, err) + currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) + require.NoError(t, err) + + shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) + configVariables := func(withGrant bool) config.Variables { + variables := config.Variables{ + "share_name": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + } + if withGrant { + variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) + variables["privileges"] = config.ListVariable( + config.StringVariable(sdk.ObjectPrivilegeUsage.String()), + ) + } + return variables + } + resourceName := "snowflake_grant_privileges_to_share.test" + + 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{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase"), + ConfigVariables: configVariables(true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), + resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeUsage.String()), + resource.TestCheckResourceAttr(resourceName, "database_name", databaseName.Name()), + ), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase"), + ConfigVariables: configVariables(true), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant"), + ConfigVariables: configVariables(false), + Check: testAccCheckSharePrivilegesRevoked(), + }, + }, + }) +} + +func TestAcc_GrantPrivilegesToShare_OnSchema(t *testing.T) { + databaseName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + schemaName := sdk.NewDatabaseObjectIdentifier(databaseName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + + client, err := sdk.NewDefaultClient() + require.NoError(t, err) + currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) + require.NoError(t, err) + + shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) + configVariables := func(withGrant bool) config.Variables { + variables := config.Variables{ + "share_name": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + "schema": config.StringVariable(schemaName.Name()), + } + if withGrant { + variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) + variables["privileges"] = config.ListVariable( + config.StringVariable(sdk.ObjectPrivilegeUsage.String()), + ) + } + return variables + } + resourceName := "snowflake_grant_privileges_to_share.test" + + 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{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnSchema"), + ConfigVariables: configVariables(true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), + resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeUsage.String()), + resource.TestCheckResourceAttr(resourceName, "schema_name", schemaName.FullyQualifiedName()), + ), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnSchema"), + ConfigVariables: configVariables(true), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant"), + ConfigVariables: configVariables(false), + Check: testAccCheckSharePrivilegesRevoked(), + }, + }, + }) +} + +func TestAcc_GrantPrivilegesToShare_OnTable(t *testing.T) { + databaseName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + schemaName := sdk.NewDatabaseObjectIdentifier(databaseName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + tableName := sdk.NewSchemaObjectIdentifier(databaseName.Name(), schemaName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + + client, err := sdk.NewDefaultClient() + require.NoError(t, err) + currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) + require.NoError(t, err) + + shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) + configVariables := func(withGrant bool) config.Variables { + variables := config.Variables{ + "share_name": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + "schema": config.StringVariable(schemaName.Name()), + "table_name": config.StringVariable(tableName.Name()), + } + if withGrant { + variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) + variables["privileges"] = config.ListVariable( + config.StringVariable(sdk.ObjectPrivilegeSelect.String()), + ) + } + return variables + } + resourceName := "snowflake_grant_privileges_to_share.test" + + 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{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnTable"), + ConfigVariables: configVariables(true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), + resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeSelect.String()), + resource.TestCheckResourceAttr(resourceName, "table_name", tableName.FullyQualifiedName()), + ), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnTable"), + ConfigVariables: configVariables(true), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnTable_NoGrant"), + ConfigVariables: configVariables(false), + Check: testAccCheckSharePrivilegesRevoked(), + }, + }, + }) +} + +func TestAcc_GrantPrivilegesToShare_OnAllTablesInSchema(t *testing.T) { + databaseName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + schemaName := sdk.NewDatabaseObjectIdentifier(databaseName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + + client, err := sdk.NewDefaultClient() + require.NoError(t, err) + currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) + require.NoError(t, err) + + shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) + configVariables := func(withGrant bool) config.Variables { + variables := config.Variables{ + "share_name": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + "schema": config.StringVariable(schemaName.Name()), + } + if withGrant { + variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) + variables["privileges"] = config.ListVariable( + config.StringVariable(sdk.ObjectPrivilegeSelect.String()), + ) + } + return variables + } + resourceName := "snowflake_grant_privileges_to_share.test" + + 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{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema"), + ConfigVariables: configVariables(true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), + resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeSelect.String()), + resource.TestCheckResourceAttr(resourceName, "all_tables_in_schema", schemaName.FullyQualifiedName()), + ), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema"), + ConfigVariables: configVariables(true), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant"), + ConfigVariables: configVariables(false), + Check: testAccCheckSharePrivilegesRevoked(), + }, + }, + }) +} + +func TestAcc_GrantPrivilegesToShare_OnView(t *testing.T) { + databaseName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + schemaName := sdk.NewDatabaseObjectIdentifier(databaseName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + tableName := sdk.NewSchemaObjectIdentifier(databaseName.Name(), schemaName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + viewName := sdk.NewSchemaObjectIdentifier(databaseName.Name(), schemaName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + + client, err := sdk.NewDefaultClient() + require.NoError(t, err) + currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) + require.NoError(t, err) + + shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) + configVariables := func(withGrant bool) config.Variables { + variables := config.Variables{ + "share_name": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + "schema": config.StringVariable(schemaName.Name()), + "table_name": config.StringVariable(tableName.Name()), + "view_name": config.StringVariable(viewName.Name()), + } + if withGrant { + variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) + variables["privileges"] = config.ListVariable( + config.StringVariable(sdk.ObjectPrivilegeSelect.String()), + ) + } + return variables + } + resourceName := "snowflake_grant_privileges_to_share.test" + + 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{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnView"), + ConfigVariables: configVariables(true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), + resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeSelect.String()), + resource.TestCheckResourceAttr(resourceName, "view_name", viewName.FullyQualifiedName()), + ), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnView"), + ConfigVariables: configVariables(true), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnView_NoGrant"), + ConfigVariables: configVariables(false), + Check: testAccCheckSharePrivilegesRevoked(), + }, + }, + }) +} + +func TestAcc_GrantPrivilegesToShare_OnTag(t *testing.T) { + databaseName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + schemaName := sdk.NewDatabaseObjectIdentifier(databaseName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + tagName := sdk.NewSchemaObjectIdentifier(databaseName.Name(), schemaName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + + client, err := sdk.NewDefaultClient() + require.NoError(t, err) + currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) + require.NoError(t, err) + + shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) + configVariables := func(withGrant bool) config.Variables { + variables := config.Variables{ + "share_name": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + "schema": config.StringVariable(schemaName.Name()), + "tag_name": config.StringVariable(tagName.Name()), + } + if withGrant { + variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) + variables["privileges"] = config.ListVariable( + config.StringVariable(sdk.ObjectPrivilegeRead.String()), + ) + } + return variables + } + resourceName := "snowflake_grant_privileges_to_share.test" + + 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{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnTag"), + ConfigVariables: configVariables(true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), + resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeRead.String()), + resource.TestCheckResourceAttr(resourceName, "tag_name", tagName.FullyQualifiedName()), + ), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnTag"), + ConfigVariables: configVariables(true), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnTag_NoGrant"), + ConfigVariables: configVariables(false), + Check: testAccCheckSharePrivilegesRevoked(), + }, + }, + }) +} + +func TestAcc_GrantPrivilegesToShare_OnPrivilegeUpdate(t *testing.T) { + databaseName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + + client, err := sdk.NewDefaultClient() + require.NoError(t, err) + currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) + require.NoError(t, err) + + shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) + configVariables := func(withGrant bool, privileges []sdk.ObjectPrivilege) config.Variables { + variables := config.Variables{ + "share_name": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + } + if withGrant { + variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) + if len(privileges) > 0 { + configPrivileges := make([]config.Variable, len(privileges)) + for i, privilege := range privileges { + configPrivileges[i] = config.StringVariable(privilege.String()) + } + variables["privileges"] = config.ListVariable(configPrivileges...) + } + } + return variables + } + resourceName := "snowflake_grant_privileges_to_share.test" + + 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{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase"), + ConfigVariables: configVariables(true, []sdk.ObjectPrivilege{ + sdk.ObjectPrivilegeReferenceUsage, + }), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), + resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeReferenceUsage.String()), + resource.TestCheckResourceAttr(resourceName, "database_name", databaseName.Name()), + ), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase"), + ConfigVariables: configVariables(true, []sdk.ObjectPrivilege{ + sdk.ObjectPrivilegeUsage, + }), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), + resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeUsage.String()), + resource.TestCheckResourceAttr(resourceName, "database_name", databaseName.Name()), + ), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase"), + ConfigVariables: configVariables(true, []sdk.ObjectPrivilege{ + sdk.ObjectPrivilegeUsage, + }), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant"), + ConfigVariables: configVariables(false, []sdk.ObjectPrivilege{}), + Check: testAccCheckSharePrivilegesRevoked(), + }, + }, + }) +} + +func TestAcc_GrantPrivilegesToShare_OnDatabaseWithReferenceUsagePrivilege(t *testing.T) { + databaseName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + + client, err := sdk.NewDefaultClient() + require.NoError(t, err) + currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) + require.NoError(t, err) + + shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) + configVariables := func(withGrant bool) config.Variables { + variables := config.Variables{ + "share_name": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + } + if withGrant { + variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) + variables["privileges"] = config.ListVariable( + config.StringVariable(sdk.ObjectPrivilegeReferenceUsage.String()), + ) + } + return variables + } + resourceName := "snowflake_grant_privileges_to_share.test" + + 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{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase"), + ConfigVariables: configVariables(true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), + resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeReferenceUsage.String()), + resource.TestCheckResourceAttr(resourceName, "database_name", databaseName.Name()), + ), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase"), + ConfigVariables: configVariables(true), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant"), + ConfigVariables: configVariables(false), + Check: testAccCheckSharePrivilegesRevoked(), + }, + }, + }) +} + +func testAccCheckSharePrivilegesRevoked() func(*terraform.State) error { + return func(state *terraform.State) error { + for _, rs := range state.RootModule().Resources { + if rs.Type != "snowflake_grant_privileges_to_share" { + continue + } + db := acc.TestAccProvider.Meta().(*sql.DB) + client := sdk.NewClientFromDB(db) + ctx := context.Background() + + id := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(rs.Primary.Attributes["share_name"]) + grants, err := client.Grants.Show(ctx, &sdk.ShowGrantOptions{ + To: &sdk.ShowGrantsTo{ + Share: sdk.NewAccountObjectIdentifier(id.Name()), + }, + }) + if err != nil { + return err + } + var grantedPrivileges []string + for _, grant := range grants { + grantedPrivileges = append(grantedPrivileges, grant.Privilege) + } + if len(grantedPrivileges) > 0 { + return fmt.Errorf("share (%s) is still granted with privileges: %v", id.FullyQualifiedName(), grantedPrivileges) + } + } + return nil + } +} diff --git a/pkg/resources/grant_privileges_to_share_identifier.go b/pkg/resources/grant_privileges_to_share_identifier.go index cc56e33c38..7305913739 100644 --- a/pkg/resources/grant_privileges_to_share_identifier.go +++ b/pkg/resources/grant_privileges_to_share_identifier.go @@ -10,9 +10,10 @@ import ( type ShareGrantKind string const ( - OnDatabaseShareGrantKind ShareGrantKind = "OnDatabase" - OnSchemaShareGrantKind ShareGrantKind = "OnSchema" - OnFunctionShareGrantKind ShareGrantKind = "OnFunction" + OnDatabaseShareGrantKind ShareGrantKind = "OnDatabase" + OnSchemaShareGrantKind ShareGrantKind = "OnSchema" + // TODO(SNOW-1021686): Because function identifier contains arguments which are not supported right now + // OnFunctionShareGrantKind ShareGrantKind = "OnFunction" OnTableShareGrantKind ShareGrantKind = "OnTable" OnAllTablesInSchemaShareGrantKind ShareGrantKind = "OnAllTablesInSchema" OnTagShareGrantKind ShareGrantKind = "OnTag" @@ -20,7 +21,7 @@ const ( ) type GrantPrivilegesToShareId struct { - ShareName sdk.AccountObjectIdentifier + ShareName sdk.ExternalObjectIdentifier Privileges []string Kind ShareGrantKind Identifier sdk.ObjectIdentifier @@ -40,10 +41,10 @@ func ParseGrantPrivilegesToShareId(idString string) (GrantPrivilegesToShareId, e parts := strings.Split(idString, helpers.IDDelimiter) if len(parts) != 4 { - return grantPrivilegesToShareId, sdk.NewError(fmt.Sprintf(`snowflake_grant_privileges_to_share id is composed out of 4 parts "|||", but got %d parts: %v`, len(parts), parts)) + return grantPrivilegesToShareId, sdk.NewError(fmt.Sprintf(`snowflake_grant_privileges_to_share id is composed out of 4 parts ".|||", but got %d parts: %v`, len(parts), parts)) } - grantPrivilegesToShareId.ShareName = sdk.NewAccountObjectIdentifier(parts[0]) + grantPrivilegesToShareId.ShareName = sdk.NewExternalObjectIdentifierFromFullyQualifiedName(parts[0]) privileges := strings.Split(parts[1], ",") if len(privileges) == 0 || (len(privileges) == 1 && privileges[0] == "") { return grantPrivilegesToShareId, sdk.NewError(fmt.Sprintf(`invalid Privileges value: %s, should be comma separated list of privileges`, privileges)) @@ -57,7 +58,7 @@ func ParseGrantPrivilegesToShareId(idString string) (GrantPrivilegesToShareId, e } switch grantPrivilegesToShareId.Kind { - case OnDatabaseShareGrantKind, OnTagShareGrantKind: + case OnDatabaseShareGrantKind: if typedIdentifier, ok := id.(sdk.AccountObjectIdentifier); ok { grantPrivilegesToShareId.Identifier = typedIdentifier } else { @@ -77,7 +78,7 @@ func ParseGrantPrivilegesToShareId(idString string) (GrantPrivilegesToShareId, e getExpectedIdentifierRepresentationFromParam(id), ) } - case OnTableShareGrantKind, OnViewShareGrantKind: + case OnTableShareGrantKind, OnViewShareGrantKind, OnTagShareGrantKind: // , OnFunctionShareGrantKind: if typedIdentifier, ok := id.(sdk.SchemaObjectIdentifier); ok { grantPrivilegesToShareId.Identifier = typedIdentifier } else { @@ -87,8 +88,6 @@ func ParseGrantPrivilegesToShareId(idString string) (GrantPrivilegesToShareId, e getExpectedIdentifierRepresentationFromParam(id), ) } - case OnFunctionShareGrantKind: - // TODO(SNOW-1021686): Because function identifier contains arguments which are not supported right now default: return grantPrivilegesToShareId, fmt.Errorf("unexpected share grant kind: %v", grantPrivilegesToShareId.Kind) } diff --git a/pkg/resources/grant_privileges_to_share_identifier_test.go b/pkg/resources/grant_privileges_to_share_identifier_test.go index c56136833f..62c50118dc 100644 --- a/pkg/resources/grant_privileges_to_share_identifier_test.go +++ b/pkg/resources/grant_privileges_to_share_identifier_test.go @@ -6,7 +6,6 @@ import ( "testing" ) -// TODO(SNOW-1021686): Add tests for function identifier func TestParseGrantPrivilegesToShareId(t *testing.T) { testCases := []struct { Name string @@ -16,9 +15,9 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { }{ { Name: "grant privileges on database to share", - Identifier: `"share-name"|REFERENCE_USAGE|OnDatabase|"on-database-name"`, + Identifier: `account-name."share-name"|REFERENCE_USAGE|OnDatabase|"on-database-name"`, Expected: GrantPrivilegesToShareId{ - ShareName: sdk.NewAccountObjectIdentifier("share-name"), + ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), Privileges: []string{"REFERENCE_USAGE"}, Kind: OnDatabaseShareGrantKind, Identifier: sdk.NewAccountObjectIdentifier("on-database-name"), @@ -26,19 +25,30 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { }, { Name: "grant privileges on schema to share", - Identifier: `"share-name"|USAGE|OnSchema|"on-database-name"."on-schema-name"`, + Identifier: `account-name."share-name"|USAGE|OnSchema|"on-database-name"."on-schema-name"`, Expected: GrantPrivilegesToShareId{ - ShareName: sdk.NewAccountObjectIdentifier("share-name"), + ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), Privileges: []string{"USAGE"}, Kind: OnSchemaShareGrantKind, Identifier: sdk.NewDatabaseObjectIdentifier("on-database-name", "on-schema-name"), }, }, + // TODO(SNOW-1021686): This is wrong and should be fixed (function's last part of identifier cannot be enclosed with quotes like that) + //{ + // Name: "grant privileges on function to share", + // Identifier: `account-name."share-name"|USAGE|OnFunction|"on-database-name"."on-schema-name".on-function-name(INT, VARCHAR)`, + // Expected: GrantPrivilegesToShareId{ + // ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + // Privileges: []string{"USAGE"}, + // Kind: OnFunctionShareGrantKind, + // Identifier: sdk.NewSchemaObjectIdentifier("on-database-name", "on-schema-name", "on-function-name(INT, VARCHAR)"), + // }, + //}, { Name: "grant privileges on table to share", - Identifier: `"share-name"|EVOLVE SCHEMA|OnTable|"on-database-name"."on-schema-name"."on-table-name"`, + Identifier: `account-name."share-name"|EVOLVE SCHEMA|OnTable|"on-database-name"."on-schema-name"."on-table-name"`, Expected: GrantPrivilegesToShareId{ - ShareName: sdk.NewAccountObjectIdentifier("share-name"), + ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), Privileges: []string{"EVOLVE SCHEMA"}, Kind: OnTableShareGrantKind, Identifier: sdk.NewSchemaObjectIdentifier("on-database-name", "on-schema-name", "on-table-name"), @@ -46,9 +56,9 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { }, { Name: "grant privileges on all tables in schema to share", - Identifier: `"share-name"|EVOLVE SCHEMA,SELECT|OnAllTablesInSchema|"on-database-name"."on-schema-name"`, + Identifier: `account-name."share-name"|EVOLVE SCHEMA,SELECT|OnAllTablesInSchema|"on-database-name"."on-schema-name"`, Expected: GrantPrivilegesToShareId{ - ShareName: sdk.NewAccountObjectIdentifier("share-name"), + ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), Privileges: []string{"EVOLVE SCHEMA", "SELECT"}, Kind: OnAllTablesInSchemaShareGrantKind, Identifier: sdk.NewDatabaseObjectIdentifier("on-database-name", "on-schema-name"), @@ -56,9 +66,9 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { }, { Name: "grant privileges on tag to share", - Identifier: `"share-name"|READ|OnTag|"on-tag-name"`, + Identifier: `account-name."share-name"|READ|OnTag|"on-tag-name"`, Expected: GrantPrivilegesToShareId{ - ShareName: sdk.NewAccountObjectIdentifier("share-name"), + ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), Privileges: []string{"READ"}, Kind: OnTagShareGrantKind, Identifier: sdk.NewAccountObjectIdentifier("on-tag-name"), @@ -66,9 +76,9 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { }, { Name: "grant privileges on view to share", - Identifier: `"share-name"|READ|OnView|"on-database-name"."on-schema-name"."on-view-name"`, + Identifier: `account-name."share-name"|READ|OnView|"on-database-name"."on-schema-name"."on-view-name"`, Expected: GrantPrivilegesToShareId{ - ShareName: sdk.NewAccountObjectIdentifier("share-name"), + ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), Privileges: []string{"READ"}, Kind: OnViewShareGrantKind, Identifier: sdk.NewSchemaObjectIdentifier("on-database-name", "on-schema-name", "on-view-name"), @@ -76,37 +86,37 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { }, { Name: "validation: not enough parts", - Identifier: `"share-name"|SELECT|OnDatabase`, - Error: `snowflake_grant_privileges_to_share id is composed out of 4 parts "|||", but got 3 parts: ["share-name" SELECT OnDatabase]`, + Identifier: `account-name."share-name"|SELECT|OnDatabase`, + Error: `snowflake_grant_privileges_to_share id is composed out of 4 parts ".|||", but got 3 parts: [account-name."share-name" SELECT OnDatabase]`, }, { Name: "validation: empty privileges", - Identifier: `"share-name"||OnDatabase|"database-name"`, + Identifier: `account-name."share-name"||OnDatabase|"database-name"`, Error: `invalid Privileges value: [], should be comma separated list of privileges`, }, { Name: "validation: unsupported kind", - Identifier: `"share-name"|SELECT|OnSomething|"object-name"`, + Identifier: `account-name."share-name"|SELECT|OnSomething|"object-name"`, Error: `unexpected share grant kind: OnSomething`, }, { Name: "validation: invalid identifier", - Identifier: `"share-name"|SELECT|OnDatabase|one.two.three.four.five.six.seven.eight.nine.ten`, + Identifier: `account-name."share-name"|SELECT|OnDatabase|one.two.three.four.five.six.seven.eight.nine.ten`, Error: `unable to classify identifier: one.two.three.four.five.six.seven.eight.nine.ten`, }, { Name: "validation: invalid account object identifier", - Identifier: `"share-name"|SELECT|OnDatabase|one.two`, + Identifier: `account-name."share-name"|SELECT|OnDatabase|one.two`, Error: `invalid identifier, expected fully qualified name of account object: , but instead got: .`, }, { Name: "validation: invalid database object identifier", - Identifier: `"share-name"|SELECT|OnSchema|one.two.three`, + Identifier: `account-name."share-name"|SELECT|OnSchema|one.two.three`, Error: `invalid identifier, expected fully qualified name of database object: ., but instead got: ..`, }, { Name: "validation: invalid schema object identifier", - Identifier: `"share-name"|SELECT|OnTable|one`, + Identifier: `account-name."share-name"|SELECT|OnTable|one`, Error: `invalid identifier, expected fully qualified name of schema object: .., but instead got: `, }, } @@ -125,7 +135,6 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { } } -// TODO(SNOW-1021686): Add tests for function identifier func TestGrantPrivilegesToShareIdString(t *testing.T) { testCases := []struct { Name string @@ -136,62 +145,73 @@ func TestGrantPrivilegesToShareIdString(t *testing.T) { { Name: "grant privileges on database to share", Identifier: GrantPrivilegesToShareId{ - ShareName: sdk.NewAccountObjectIdentifier("share-name"), + ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), Privileges: []string{"REFERENCE_USAGE"}, Kind: OnDatabaseShareGrantKind, Identifier: sdk.NewAccountObjectIdentifier("database-name"), }, - Expected: `"share-name"|REFERENCE_USAGE|OnDatabase|"database-name"`, + Expected: `account-name."share-name"|REFERENCE_USAGE|OnDatabase|"database-name"`, }, { Name: "grant privileges on schema to share", Identifier: GrantPrivilegesToShareId{ - ShareName: sdk.NewAccountObjectIdentifier("share-name"), + ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), Privileges: []string{"USAGE"}, Kind: OnSchemaShareGrantKind, Identifier: sdk.NewDatabaseObjectIdentifier("database-name", "schema-name"), }, - Expected: `"share-name"|USAGE|OnSchema|"database-name"."schema-name"`, - }, + Expected: `account-name."share-name"|USAGE|OnSchema|"database-name"."schema-name"`, + }, + // TODO(SNOW-1021686): This is wrong and should be fixed (function's last part of identifier cannot be enclosed with quotes like that) + //{ + // Name: "grant privileges on function to share", + // Identifier: GrantPrivilegesToShareId{ + // ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + // Privileges: []string{"USAGE"}, + // Kind: OnFunctionShareGrantKind, + // Identifier: sdk.NewSchemaObjectIdentifier("database-name", "schema-name", "function-name(INT, VARCHAR)"), + // }, + // Expected: `account-name."share-name"|USAGE|OnFunction|"database-name"."schema-name".\"function-name(INT, VARCHAR)\"`, + //}, { Name: "grant privileges on table to share", Identifier: GrantPrivilegesToShareId{ - ShareName: sdk.NewAccountObjectIdentifier("share-name"), + ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), Privileges: []string{"EVOLVE SCHEMA", "SELECT"}, Kind: OnTableShareGrantKind, Identifier: sdk.NewSchemaObjectIdentifier("database-name", "schema-name", "table-name"), }, - Expected: `"share-name"|EVOLVE SCHEMA,SELECT|OnTable|"database-name"."schema-name"."table-name"`, + Expected: `account-name."share-name"|EVOLVE SCHEMA,SELECT|OnTable|"database-name"."schema-name"."table-name"`, }, { Name: "grant privileges on all tables in schema to share", Identifier: GrantPrivilegesToShareId{ - ShareName: sdk.NewAccountObjectIdentifier("share-name"), + ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), Privileges: []string{"EVOLVE SCHEMA", "SELECT"}, Kind: OnAllTablesInSchemaShareGrantKind, Identifier: sdk.NewDatabaseObjectIdentifier("database-name", "schema-name"), }, - Expected: `"share-name"|EVOLVE SCHEMA,SELECT|OnAllTablesInSchema|"database-name"."schema-name"`, + Expected: `account-name."share-name"|EVOLVE SCHEMA,SELECT|OnAllTablesInSchema|"database-name"."schema-name"`, }, { Name: "grant privileges on tag to share", Identifier: GrantPrivilegesToShareId{ - ShareName: sdk.NewAccountObjectIdentifier("share-name"), + ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), Privileges: []string{"READ"}, Kind: OnTagShareGrantKind, Identifier: sdk.NewAccountObjectIdentifier("tag-name"), }, - Expected: `"share-name"|READ|OnTag|"tag-name"`, + Expected: `account-name."share-name"|READ|OnTag|"tag-name"`, }, { Name: "grant privileges on view to share", Identifier: GrantPrivilegesToShareId{ - ShareName: sdk.NewAccountObjectIdentifier("share-name"), + ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), Privileges: []string{"SELECT"}, Kind: OnViewShareGrantKind, Identifier: sdk.NewSchemaObjectIdentifier("database-name", "schema-name", "view-name"), }, - Expected: `"share-name"|SELECT|OnView|"database-name"."schema-name"."view-name"`, + Expected: `account-name."share-name"|SELECT|OnView|"database-name"."schema-name"."view-name"`, }, } diff --git a/pkg/resources/share.go b/pkg/resources/share.go index 240bf24d4f..57664010c7 100644 --- a/pkg/resources/share.go +++ b/pkg/resources/share.go @@ -123,7 +123,7 @@ func setShareAccounts(ctx context.Context, client *sdk.Client, shareID sdk.Accou // case where the main db doesn't already exist, so it will need to be revoked // before deleting the temp db. Where USAGE hasn't been already granted it is not // an error to revoke it, so it's ok to just do the revoke every time. - err = client.Grants.GrantPrivilegeToShare(ctx, sdk.ObjectPrivilegeReferenceUsage, &sdk.ShareGrantOn{ + err = client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeReferenceUsage}, &sdk.ShareGrantOn{ Database: tempDatabaseID, }, shareID) if err != nil { @@ -131,14 +131,14 @@ func setShareAccounts(ctx context.Context, client *sdk.Client, shareID sdk.Accou } defer func() { // revoke the REFERENCE_USAGE privilege during cleanup - err = client.Grants.RevokePrivilegeFromShare(ctx, sdk.ObjectPrivilegeReferenceUsage, &sdk.RevokePrivilegeFromShareOn{ + err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeReferenceUsage}, &sdk.ShareGrantOn{ Database: tempDatabaseID, }, shareID) if err != nil { log.Printf("[WARN] error revoking privilege from share (%v) err = %v", shareID.Name(), err) } // revoke the maybe automatically granted USAGE privilege during cleanup - err = client.Grants.RevokePrivilegeFromShare(ctx, sdk.ObjectPrivilegeUsage, &sdk.RevokePrivilegeFromShareOn{ + err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: tempDatabaseID, }, shareID) if err != nil { diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf new file mode 100644 index 0000000000..a239c79ba6 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf @@ -0,0 +1,26 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_schema" "test" { + name = var.schema + database = snowflake_database.test.name +} + +resource "snowflake_share" "test" { + name = var.share_name +} + +resource "snowflake_grant_privileges_to_share" "test_setup" { + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = ["USAGE"] + database_name = snowflake_database.test.name +} + +resource "snowflake_grant_privileges_to_share" "test" { + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = var.privileges + all_tables_in_schema = "\"${snowflake_schema.test.database}\".\"${snowflake_schema.test.name}\"" +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/variables.tf new file mode 100644 index 0000000000..f495d7e38e --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/variables.tf @@ -0,0 +1,19 @@ +variable "share_name" { + type = string +} + +variable "share_account_name" { + type = string +} + +variable "privileges" { + type = list(string) +} + +variable "database" { + type = string +} + +variable "schema" { + type = string +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/test.tf new file mode 100644 index 0000000000..a5632da6e2 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/test.tf @@ -0,0 +1,12 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_schema" "test" { + name = var.schema + database = snowflake_database.test.name +} + +resource "snowflake_share" "test" { + name = var.share_name +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/variables.tf new file mode 100644 index 0000000000..ba53fb83e8 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/variables.tf @@ -0,0 +1,11 @@ +variable "share_name" { + type = string +} + +variable "database" { + type = string +} + +variable "schema" { + type = string +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf new file mode 100644 index 0000000000..381f10300f --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf @@ -0,0 +1,14 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_share" "test" { + name = var.share_name +} + +resource "snowflake_grant_privileges_to_share" "test" { + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = var.privileges + database_name = snowflake_database.test.name +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/variables.tf new file mode 100644 index 0000000000..bacc3a486c --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/variables.tf @@ -0,0 +1,15 @@ +variable "share_name" { + type = string +} + +variable "share_account_name" { + type = string +} + +variable "privileges" { + type = list(string) +} + +variable "database" { + type = string +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/test.tf new file mode 100644 index 0000000000..0e0031f5ec --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/test.tf @@ -0,0 +1,7 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_share" "test" { + name = var.share_name +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/variables.tf new file mode 100644 index 0000000000..45e63e3a7d --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/variables.tf @@ -0,0 +1,7 @@ +variable "share_name" { + type = string +} + +variable "database" { + type = string +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf new file mode 100644 index 0000000000..fa0998dfc1 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf @@ -0,0 +1,26 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_schema" "test" { + name = var.schema + database = snowflake_database.test.name +} + +resource "snowflake_share" "test" { + name = var.share_name +} + +resource "snowflake_grant_privileges_to_share" "test_setup" { + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = ["USAGE"] + database_name = snowflake_database.test.name +} + +resource "snowflake_grant_privileges_to_share" "test" { + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = var.privileges + schema_name = "\"${snowflake_schema.test.database}\".\"${snowflake_schema.test.name}\"" +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/variables.tf new file mode 100644 index 0000000000..f495d7e38e --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/variables.tf @@ -0,0 +1,19 @@ +variable "share_name" { + type = string +} + +variable "share_account_name" { + type = string +} + +variable "privileges" { + type = list(string) +} + +variable "database" { + type = string +} + +variable "schema" { + type = string +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/test.tf new file mode 100644 index 0000000000..a5632da6e2 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/test.tf @@ -0,0 +1,12 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_schema" "test" { + name = var.schema + database = snowflake_database.test.name +} + +resource "snowflake_share" "test" { + name = var.share_name +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/variables.tf new file mode 100644 index 0000000000..ba53fb83e8 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/variables.tf @@ -0,0 +1,11 @@ +variable "share_name" { + type = string +} + +variable "database" { + type = string +} + +variable "schema" { + type = string +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf new file mode 100644 index 0000000000..e81fc7578f --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf @@ -0,0 +1,36 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_schema" "test" { + name = var.schema + database = snowflake_database.test.name +} + +resource "snowflake_table" "test" { + name = var.table_name + database = snowflake_database.test.name + schema = snowflake_schema.test.name + column { + name = "id" + type = "NUMBER(38,0)" + } +} + +resource "snowflake_share" "test" { + name = var.share_name +} + +resource "snowflake_grant_privileges_to_share" "test_setup" { + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = ["USAGE"] + database_name = snowflake_database.test.name +} + +resource "snowflake_grant_privileges_to_share" "test" { + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = var.privileges + table_name = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_table.test.name}\"" +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/variables.tf new file mode 100644 index 0000000000..64ca684b83 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/variables.tf @@ -0,0 +1,23 @@ +variable "share_name" { + type = string +} + +variable "share_account_name" { + type = string +} + +variable "privileges" { + type = list(string) +} + +variable "database" { + type = string +} + +variable "schema" { + type = string +} + +variable "table_name" { + type = string +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/test.tf new file mode 100644 index 0000000000..d0912b5034 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/test.tf @@ -0,0 +1,22 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_schema" "test" { + name = var.schema + database = snowflake_database.test.name +} + +resource "snowflake_table" "test" { + name = var.table_name + database = snowflake_database.test.name + schema = snowflake_schema.test.name + column { + name = "id" + type = "NUMBER(38,0)" + } +} + +resource "snowflake_share" "test" { + name = var.share_name +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/variables.tf new file mode 100644 index 0000000000..d5ef54ae92 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/variables.tf @@ -0,0 +1,15 @@ +variable "share_name" { + type = string +} + +variable "database" { + type = string +} + +variable "schema" { + type = string +} + +variable "table_name" { + type = string +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf new file mode 100644 index 0000000000..076c4371d2 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf @@ -0,0 +1,32 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_schema" "test" { + name = var.schema + database = snowflake_database.test.name +} + +resource "snowflake_tag" "test" { + name = var.tag_name + database = snowflake_database.test.name + schema = snowflake_schema.test.name +} + +resource "snowflake_share" "test" { + name = var.share_name +} + +resource "snowflake_grant_privileges_to_share" "test_setup" { + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = ["USAGE"] + database_name = snowflake_database.test.name +} + +resource "snowflake_grant_privileges_to_share" "test" { + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = var.privileges + tag_name = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_tag.test.name}\"" +} \ No newline at end of file diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/variables.tf new file mode 100644 index 0000000000..c6c6856eab --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/variables.tf @@ -0,0 +1,23 @@ +variable "share_name" { + type = string +} + +variable "share_account_name" { + type = string +} + +variable "privileges" { + type = list(string) +} + +variable "database" { + type = string +} + +variable "schema" { + type = string +} + +variable "tag_name" { + type = string +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/test.tf new file mode 100644 index 0000000000..339c360865 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/test.tf @@ -0,0 +1,18 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_schema" "test" { + name = var.schema + database = snowflake_database.test.name +} + +resource "snowflake_tag" "test" { + name = var.tag_name + database = snowflake_database.test.name + schema = snowflake_schema.test.name +} + +resource "snowflake_share" "test" { + name = var.share_name +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/variables.tf new file mode 100644 index 0000000000..6f7e3979ae --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/variables.tf @@ -0,0 +1,15 @@ +variable "share_name" { + type = string +} + +variable "database" { + type = string +} + +variable "schema" { + type = string +} + +variable "tag_name" { + type = string +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf new file mode 100644 index 0000000000..3f2cf1e60f --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf @@ -0,0 +1,44 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_schema" "test" { + name = var.schema + database = snowflake_database.test.name +} + +resource "snowflake_table" "test" { + name = var.table_name + database = snowflake_database.test.name + schema = snowflake_schema.test.name + column { + name = "id" + type = "NUMBER(38,0)" + } +} + +resource "snowflake_view" "test" { + name = var.view_name + database = snowflake_database.test.name + schema = snowflake_schema.test.name + is_secure = true + statement = "select \"id\" from \"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_table.test.name}\"" +} + +resource "snowflake_share" "test" { + name = var.share_name +} + +resource "snowflake_grant_privileges_to_share" "test_setup" { + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = ["USAGE"] + database_name = snowflake_database.test.name +} + +resource "snowflake_grant_privileges_to_share" "test" { + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = var.privileges + view_name = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_view.test.name}\"" +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/variables.tf new file mode 100644 index 0000000000..9300773331 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/variables.tf @@ -0,0 +1,27 @@ +variable "share_name" { + type = string +} + +variable "share_account_name" { + type = string +} + +variable "privileges" { + type = list(string) +} + +variable "database" { + type = string +} + +variable "schema" { + type = string +} + +variable "table_name" { + type = string +} + +variable "view_name" { + type = string +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/test.tf new file mode 100644 index 0000000000..75ab564802 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/test.tf @@ -0,0 +1,26 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_schema" "test" { + name = var.schema + database = snowflake_database.test.name +} + +resource "snowflake_table" "test" { + name = var.table_name + database = snowflake_database.test.name + schema = snowflake_schema.test.name + column { + name = "id" + type = "NUMBER(38,0)" + } +} + +resource "snowflake_view" "test" { + name = var.view_name + database = snowflake_database.test.name + schema = snowflake_schema.test.name + is_secure = true + statement = "select \"id\" from \"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_table.test.name}\"" +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/variables.tf new file mode 100644 index 0000000000..7a36d7147d --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/variables.tf @@ -0,0 +1,19 @@ +variable "share_name" { + type = string +} + +variable "database" { + type = string +} + +variable "schema" { + type = string +} + +variable "table_name" { + type = string +} + +variable "view_name" { + type = string +} diff --git a/pkg/sdk/grants.go b/pkg/sdk/grants.go index 7d2b318ed7..f06debc1eb 100644 --- a/pkg/sdk/grants.go +++ b/pkg/sdk/grants.go @@ -131,7 +131,7 @@ type ShareGrantOn struct { Schema DatabaseObjectIdentifier `ddl:"identifier" sql:"SCHEMA"` Function SchemaObjectIdentifier `ddl:"identifier" sql:"FUNCTION"` Table *OnTable `ddl:"-"` - Tag AccountObjectIdentifier `ddl:"identifier" sql:"TAG"` + Tag SchemaObjectIdentifier `ddl:"identifier" sql:"TAG"` View SchemaObjectIdentifier `ddl:"identifier" sql:"VIEW"` } diff --git a/pkg/sdk/grants_test.go b/pkg/sdk/grants_test.go index 797f96e759..56dc5c7c17 100644 --- a/pkg/sdk/grants_test.go +++ b/pkg/sdk/grants_test.go @@ -860,11 +860,11 @@ func TestRevokePrivilegeFromShare(t *testing.T) { opts := &revokePrivilegeFromShareOptions{ privileges: []ObjectPrivilege{ObjectPrivilegeRead}, On: &ShareGrantOn{ - Tag: NewAccountObjectIdentifier("tag-name"), + Tag: NewSchemaObjectIdentifier("database-name", "schema-name", "tag-name"), }, from: id, } - assertOptsValidAndSQLEquals(t, opts, "REVOKE READ ON TAG \"tag-name\" FROM SHARE %s", id.FullyQualifiedName()) + assertOptsValidAndSQLEquals(t, opts, "REVOKE READ ON TAG \"database-name\".\"schema-name\".\"tag-name\" FROM SHARE %s", id.FullyQualifiedName()) }) // TODO: This one throws an error diff --git a/pkg/sdk/privileges.go b/pkg/sdk/privileges.go index f1e9179051..201ff6f110 100644 --- a/pkg/sdk/privileges.go +++ b/pkg/sdk/privileges.go @@ -245,7 +245,6 @@ type ObjectPrivilege string const ( ObjectPrivilegeReferenceUsage ObjectPrivilege = "REFERENCE_USAGE" ObjectPrivilegeUsage ObjectPrivilege = "USAGE" - ObjectPrivilegeEvolveSchema ObjectPrivilege = "EVOLVE SCHEMA" ObjectPrivilegeSelect ObjectPrivilege = "SELECT" ObjectPrivilegeRead ObjectPrivilege = "READ" ) From 8a20d91a3beff9a61db21cc494e74768cdfbb726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Tue, 30 Jan 2024 15:07:54 +0100 Subject: [PATCH 3/7] wip --- ...ileges_to_database_role_acceptance_test.go | 30 +++++++++---------- ..._privileges_to_database_role_identifier.go | 2 +- ...ileges_to_database_role_identifier_test.go | 20 ++++++------- pkg/resources/grant_privileges_to_share.go | 17 +++++------ 4 files changed, 33 insertions(+), 36 deletions(-) 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 55ad93a035..2a704dd7c3 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) { Steps: []resource.TestStep{ { PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, - ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabaseShareGrantKind"), + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "database_role_name", databaseRoleName), @@ -56,11 +56,11 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnDatabase(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "privileges.2", string(sdk.AccountObjectPrivilegeUsage)), resource.TestCheckResourceAttr(resourceName, "on_database", databaseName), resource.TestCheckResourceAttr(resourceName, "with_grant_option", "true"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|true|false|CREATE SCHEMA,MODIFY,USAGE|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|true|false|CREATE SCHEMA,MODIFY,USAGE|OnDatabase|%s", databaseRoleName, databaseName)), ), }, { - ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabaseShareGrantKind"), + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), ConfigVariables: configVariables, ResourceName: resourceName, ImportState: true, @@ -97,7 +97,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnDatabase_PrivilegesReversed(t *test Steps: []resource.TestStep{ { PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) }, - ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabaseShareGrantKind"), + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), ConfigVariables: configVariables, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "database_role_name", databaseRoleName), @@ -107,11 +107,11 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnDatabase_PrivilegesReversed(t *test resource.TestCheckResourceAttr(resourceName, "privileges.2", string(sdk.AccountObjectPrivilegeUsage)), resource.TestCheckResourceAttr(resourceName, "on_database", databaseName), resource.TestCheckResourceAttr(resourceName, "with_grant_option", "true"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|true|false|CREATE SCHEMA,MODIFY,USAGE|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|true|false|CREATE SCHEMA,MODIFY,USAGE|OnDatabase|%s", databaseRoleName, databaseName)), ), }, { - ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabaseShareGrantKind"), + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnDatabase"), ConfigVariables: configVariables, ResourceName: resourceName, ImportState: true, @@ -524,7 +524,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_UpdatePrivileges(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "privileges.#", "2"), resource.TestCheckResourceAttr(resourceName, "privileges.0", string(sdk.AccountObjectPrivilegeCreateSchema)), resource.TestCheckResourceAttr(resourceName, "privileges.1", string(sdk.AccountObjectPrivilegeModify)), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|CREATE SCHEMA,MODIFY|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|CREATE SCHEMA,MODIFY|OnDatabase|%s", databaseRoleName, databaseName)), ), }, { @@ -540,7 +540,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_UpdatePrivileges(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "privileges.0", string(sdk.AccountObjectPrivilegeCreateSchema)), resource.TestCheckResourceAttr(resourceName, "privileges.1", string(sdk.AccountObjectPrivilegeMonitor)), resource.TestCheckResourceAttr(resourceName, "privileges.2", string(sdk.AccountObjectPrivilegeUsage)), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|CREATE SCHEMA,USAGE,MONITOR|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|CREATE SCHEMA,USAGE,MONITOR|OnDatabase|%s", databaseRoleName, databaseName)), ), }, { @@ -549,7 +549,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_UpdatePrivileges(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "all_privileges", "true"), resource.TestCheckResourceAttr(resourceName, "privileges.#", "0"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|ALL|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|ALL|OnDatabase|%s", databaseRoleName, databaseName)), ), }, { @@ -563,7 +563,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_UpdatePrivileges(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "privileges.#", "2"), resource.TestCheckResourceAttr(resourceName, "privileges.0", string(sdk.AccountObjectPrivilegeModify)), resource.TestCheckResourceAttr(resourceName, "privileges.1", string(sdk.AccountObjectPrivilegeMonitor)), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|MODIFY,MONITOR|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|MODIFY,MONITOR|OnDatabase|%s", databaseRoleName, databaseName)), ), }, }, @@ -691,7 +691,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_AlwaysApply(t *testing.T) { }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "always_apply", "false"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|ALL|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|ALL|OnDatabase|%s", databaseRoleName, databaseName)), ), }, { @@ -699,7 +699,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_AlwaysApply(t *testing.T) { ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "always_apply", "true"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|true|ALL|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|true|ALL|OnDatabase|%s", databaseRoleName, databaseName)), ), ExpectNonEmptyPlan: true, }, @@ -713,7 +713,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_AlwaysApply(t *testing.T) { }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "always_apply", "true"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|true|ALL|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|true|ALL|OnDatabase|%s", databaseRoleName, databaseName)), ), ExpectNonEmptyPlan: true, }, @@ -727,7 +727,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_AlwaysApply(t *testing.T) { }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "always_apply", "true"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|true|ALL|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|true|ALL|OnDatabase|%s", databaseRoleName, databaseName)), ), ExpectNonEmptyPlan: true, }, @@ -741,7 +741,7 @@ func TestAcc_GrantPrivilegesToDatabaseRole_AlwaysApply(t *testing.T) { }, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "always_apply", "false"), - resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|ALL|OnDatabaseShareGrantKind|%s", databaseRoleName, databaseName)), + resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|ALL|OnDatabase|%s", databaseRoleName, databaseName)), ), }, }, diff --git a/pkg/resources/grant_privileges_to_database_role_identifier.go b/pkg/resources/grant_privileges_to_database_role_identifier.go index f42f0a260e..56e4ec2044 100644 --- a/pkg/resources/grant_privileges_to_database_role_identifier.go +++ b/pkg/resources/grant_privileges_to_database_role_identifier.go @@ -12,7 +12,7 @@ import ( type DatabaseRoleGrantKind string const ( - OnDatabaseDatabaseRoleGrantKind DatabaseRoleGrantKind = "OnDatabaseShareGrantKind" + OnDatabaseDatabaseRoleGrantKind DatabaseRoleGrantKind = "OnDatabase" OnSchemaDatabaseRoleGrantKind DatabaseRoleGrantKind = "OnSchema" OnSchemaObjectDatabaseRoleGrantKind DatabaseRoleGrantKind = "OnSchemaObject" ) diff --git a/pkg/resources/grant_privileges_to_database_role_identifier_test.go b/pkg/resources/grant_privileges_to_database_role_identifier_test.go index d80a25d63c..ea8cd4404b 100644 --- a/pkg/resources/grant_privileges_to_database_role_identifier_test.go +++ b/pkg/resources/grant_privileges_to_database_role_identifier_test.go @@ -16,7 +16,7 @@ func TestParseGrantPrivilegesToDatabaseRoleId(t *testing.T) { }{ { Name: "grant database role on database", - Identifier: `"database-name"."database-role"|false|false|CREATE SCHEMA,USAGE,MONITOR|OnDatabaseShareGrantKind|"on-database-name"`, + Identifier: `"database-name"."database-role"|false|false|CREATE SCHEMA,USAGE,MONITOR|OnDatabase|"on-database-name"`, Expected: GrantPrivilegesToDatabaseRoleId{ DatabaseRoleName: sdk.NewDatabaseObjectIdentifier("database-name", "database-role"), WithGrantOption: false, @@ -29,7 +29,7 @@ func TestParseGrantPrivilegesToDatabaseRoleId(t *testing.T) { }, { Name: "grant database role on database - always apply with grant option", - Identifier: `"database-name"."database-role"|true|true|CREATE SCHEMA,USAGE,MONITOR|OnDatabaseShareGrantKind|"on-database-name"`, + Identifier: `"database-name"."database-role"|true|true|CREATE SCHEMA,USAGE,MONITOR|OnDatabase|"on-database-name"`, Expected: GrantPrivilegesToDatabaseRoleId{ DatabaseRoleName: sdk.NewDatabaseObjectIdentifier("database-name", "database-role"), WithGrantOption: true, @@ -43,7 +43,7 @@ func TestParseGrantPrivilegesToDatabaseRoleId(t *testing.T) { }, { Name: "grant database role on database - all privileges", - Identifier: `"database-name"."database-role"|false|false|ALL|OnDatabaseShareGrantKind|"on-database-name"`, + Identifier: `"database-name"."database-role"|false|false|ALL|OnDatabase|"on-database-name"`, Expected: GrantPrivilegesToDatabaseRoleId{ DatabaseRoleName: sdk.NewDatabaseObjectIdentifier("database-name", "database-role"), WithGrantOption: false, @@ -224,8 +224,8 @@ func TestParseGrantPrivilegesToDatabaseRoleId(t *testing.T) { Error: "database role identifier should hold at least 6 parts", }, { - Name: "validation: grant database role not enough parts for OnDatabaseShareGrantKind kind", - Identifier: `"database-name"."role-name"|false|false|CREATE SCHEMA,USAGE,MONITOR|OnDatabaseShareGrantKind`, + Name: "validation: grant database role not enough parts for OnDatabase kind", + Identifier: `"database-name"."role-name"|false|false|CREATE SCHEMA,USAGE,MONITOR|OnDatabase`, Error: "database role identifier should hold at least 6 parts", }, { @@ -265,22 +265,22 @@ func TestParseGrantPrivilegesToDatabaseRoleId(t *testing.T) { }, { Name: "validation: grant database role empty privileges", - Identifier: `"database-name"."database-role"|false|false||OnDatabaseShareGrantKind|"on-database-name"`, + Identifier: `"database-name"."database-role"|false|false||OnDatabase|"on-database-name"`, Error: `invalid Privileges value: , should be either a comma separated list of privileges or "ALL" / "ALL PRIVILEGES" for all privileges`, }, { Name: "validation: grant database role empty with grant option", - Identifier: `"database-name"."database-role"||false|ALL PRIVILEGES|OnDatabaseShareGrantKind|"on-database-name"`, + Identifier: `"database-name"."database-role"||false|ALL PRIVILEGES|OnDatabase|"on-database-name"`, Error: `invalid WithGrantOption value: , should be either "true" or "false"`, }, { Name: "validation: grant database role empty always apply", - Identifier: `"database-name"."database-role"|false||ALL PRIVILEGES|OnDatabaseShareGrantKind|"on-database-name"`, + Identifier: `"database-name"."database-role"|false||ALL PRIVILEGES|OnDatabase|"on-database-name"`, Error: `invalid AlwaysApply value: , should be either "true" or "false"`, }, { Name: "validation: grant database role empty database role name", - Identifier: `|false|false|ALL PRIVILEGES|OnDatabaseShareGrantKind|"on-database-name"`, + Identifier: `|false|false|ALL PRIVILEGES|OnDatabase|"on-database-name"`, Error: "invalid DatabaseRoleName value: , should be a fully qualified name of database object .", }, { @@ -323,7 +323,7 @@ func TestGrantPrivilegesToDatabaseRoleIdString(t *testing.T) { DatabaseName: sdk.NewAccountObjectIdentifier("database-name"), }, }, - Expected: `"database-name"."role-name"|true|true|ALL|OnDatabaseShareGrantKind|"database-name"`, + Expected: `"database-name"."role-name"|true|true|ALL|OnDatabase|"database-name"`, }, { Name: "grant database role on schema on schema", diff --git a/pkg/resources/grant_privileges_to_share.go b/pkg/resources/grant_privileges_to_share.go index 821ae6775c..ed56cf7595 100644 --- a/pkg/resources/grant_privileges_to_share.go +++ b/pkg/resources/grant_privileges_to_share.go @@ -4,7 +4,6 @@ import ( "context" "database/sql" "fmt" - "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/logging" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -28,7 +27,6 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ Required: true, ForceNew: true, Description: "The fully qualified name of the share on which privileges will be granted.", - //ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](), }, "privileges": { Type: schema.TypeSet, @@ -40,7 +38,7 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ Type: schema.TypeString, Optional: true, ForceNew: true, - Description: "TODO", + Description: "The fully qualified name of the database on which privileges will be granted.", ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](), ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, }, @@ -48,7 +46,7 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ Type: schema.TypeString, Optional: true, ForceNew: true, - Description: "TODO", + Description: "The fully qualified name of the schema on which privileges will be granted.", ValidateDiagFunc: IsValidIdentifier[sdk.DatabaseObjectIdentifier](), ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, }, @@ -57,7 +55,7 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ // Type: schema.TypeString, // Optional: true, // ForceNew: true, - // Description: "TODO", + // Description: "The fully qualified name of the function on which privileges will be granted.", // ValidateDiagFunc: IsValidIdentifier[sdk.FunctionIdentifier](), // ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, //}, @@ -65,7 +63,7 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ Type: schema.TypeString, Optional: true, ForceNew: true, - Description: "TODO", + Description: "The fully qualified name of the table on which privileges will be granted.", ValidateDiagFunc: IsValidIdentifier[sdk.SchemaObjectIdentifier](), ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, }, @@ -73,7 +71,7 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ Type: schema.TypeString, Optional: true, ForceNew: true, - Description: "TODO", + Description: "The fully qualified identifier for the schema for which the specified privilege will be granted for all tables.", ValidateDiagFunc: IsValidIdentifier[sdk.DatabaseObjectIdentifier](), ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, }, @@ -81,7 +79,7 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ Type: schema.TypeString, Optional: true, ForceNew: true, - Description: "TODO", + Description: "The fully qualified name of the tag on which privileges will be granted.", ValidateDiagFunc: IsValidIdentifier[sdk.SchemaObjectIdentifier](), ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, }, @@ -89,7 +87,7 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ Type: schema.TypeString, Optional: true, ForceNew: true, - Description: "TODO", + Description: "The fully qualified name of the view on which privileges will be granted.", ValidateDiagFunc: IsValidIdentifier[sdk.SchemaObjectIdentifier](), ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, }, @@ -234,7 +232,6 @@ func UpdateGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, m } if len(privilegesToRemove) > 0 { - logging.DebugLogger.Printf("[DEBUG] Revoking privileges: %v", privilegesToRemove) err = client.Grants.RevokePrivilegeFromShare( ctx, privilegesToRemove, From 393e030cdac6640dd528578ce2ff0a3d536be787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Tue, 30 Jan 2024 15:35:16 +0100 Subject: [PATCH 4/7] wip --- docs/resources/grant_privileges_to_share.md | 102 ++++++++++++++++++ .../resource.tf | 65 +++++++++++ pkg/resources/grant_privileges_to_share.go | 21 ++-- ...ant_privileges_to_share_acceptance_test.go | 5 +- .../grant_privileges_to_share_identifier.go | 3 +- ...ant_privileges_to_share_identifier_test.go | 7 +- .../OnAllTablesInSchema/test.tf | 14 +-- .../OnAllTablesInSchema_NoGrant/test.tf | 2 +- .../OnDatabase/test.tf | 6 +- .../OnSchema/test.tf | 14 +-- .../OnSchema_NoGrant/test.tf | 2 +- .../OnTable/test.tf | 12 +-- .../OnTable_NoGrant/test.tf | 6 +- .../OnTag/test.tf | 14 +-- .../OnTag_NoGrant/test.tf | 6 +- .../OnView/test.tf | 18 ++-- .../OnView_NoGrant/test.tf | 10 +- pkg/sdk/grants_test.go | 4 +- pkg/sdk/testint/grants_integration_test.go | 9 +- 19 files changed, 246 insertions(+), 74 deletions(-) create mode 100644 docs/resources/grant_privileges_to_share.md create mode 100644 examples/resources/snowflake_grant_privileges_to_share/resource.tf diff --git a/docs/resources/grant_privileges_to_share.md b/docs/resources/grant_privileges_to_share.md new file mode 100644 index 0000000000..24945ffa6e --- /dev/null +++ b/docs/resources/grant_privileges_to_share.md @@ -0,0 +1,102 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "snowflake_grant_privileges_to_share Resource - terraform-provider-snowflake" +subcategory: "" +description: |- + +--- + +# snowflake_grant_privileges_to_share (Resource) + + + +## Example Usage + +```terraform +################################## +### on database +################################## + +resource "snowflake_grant_privileges_to_share" "example" { + share_name = snowflake_share.example.name + privileges = ["USAGE"] + on_database = snowflake_database.example.name +} + +## ID: "\"account_name\".\"share_name\"|USAGE|OnDatabase|\"database_name\"" + +################################## +### on schema +################################## + +resource "snowflake_grant_privileges_to_share" "example" { + share_name = snowflake_share.example.name + privileges = ["USAGE"] + on_schema = "${snowflake_database.example.name}.${snowflake_schema.example.name}" +} + +## ID: "\"account_name\".\"share_name\"|USAGE|OnSchema|\"database_name\".\"schema_name\"" + +################################## +### on table +################################## + +resource "snowflake_grant_privileges_to_share" "example" { + share_name = snowflake_share.example.name + privileges = ["SELECT"] + on_table = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_table.example.name}" +} + +## ID: "\"account_name\".\"share_name\"|Select|OnTable|\"database_name\".\"schema_name\".\"table_name\"" + +################################## +### on all tables in schema +################################## + +resource "snowflake_grant_privileges_to_share" "example" { + share_name = snowflake_share.example.name + privileges = ["SELECT"] + on_all_tables_in_schema = "${snowflake_database.example.name}.${snowflake_schema.example.name}" +} + +################################## +### on tag +################################## + +resource "snowflake_grant_privileges_to_share" "example" { + share_name = snowflake_share.example.name + privileges = ["READ"] + on_tag = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_tag.example.name}" +} + +################################## +### on view +################################## + +resource "snowflake_grant_privileges_to_share" "example" { + share_name = snowflake_share.example.name + privileges = ["SELECT"] + on_view = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_view.example.name}" +} +``` + + +## Schema + +### Required + +- `privileges` (Set of String) The privileges to grant on the share. +- `share_name` (String) The fully qualified name of the share on which privileges will be granted. + +### Optional + +- `all_tables_in_schema` (String) The fully qualified identifier for the schema for which the specified privilege will be granted for all tables. +- `database_name` (String) The fully qualified name of the database on which privileges will be granted. +- `schema_name` (String) The fully qualified name of the schema on which privileges will be granted. +- `table_name` (String) The fully qualified name of the table on which privileges will be granted. +- `tag_name` (String) The fully qualified name of the tag on which privileges will be granted. +- `view_name` (String) The fully qualified name of the view on which privileges will be granted. + +### Read-Only + +- `id` (String) The ID of this resource. diff --git a/examples/resources/snowflake_grant_privileges_to_share/resource.tf b/examples/resources/snowflake_grant_privileges_to_share/resource.tf new file mode 100644 index 0000000000..6ca4ef79b5 --- /dev/null +++ b/examples/resources/snowflake_grant_privileges_to_share/resource.tf @@ -0,0 +1,65 @@ +################################## +### on database +################################## + +resource "snowflake_grant_privileges_to_share" "example" { + share_name = snowflake_share.example.name + privileges = ["USAGE"] + on_database = snowflake_database.example.name +} + +## ID: "\"account_name\".\"share_name\"|USAGE|OnDatabase|\"database_name\"" + +################################## +### on schema +################################## + +resource "snowflake_grant_privileges_to_share" "example" { + share_name = snowflake_share.example.name + privileges = ["USAGE"] + on_schema = "${snowflake_database.example.name}.${snowflake_schema.example.name}" +} + +## ID: "\"account_name\".\"share_name\"|USAGE|OnSchema|\"database_name\".\"schema_name\"" + +################################## +### on table +################################## + +resource "snowflake_grant_privileges_to_share" "example" { + share_name = snowflake_share.example.name + privileges = ["SELECT"] + on_table = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_table.example.name}" +} + +## ID: "\"account_name\".\"share_name\"|Select|OnTable|\"database_name\".\"schema_name\".\"table_name\"" + +################################## +### on all tables in schema +################################## + +resource "snowflake_grant_privileges_to_share" "example" { + share_name = snowflake_share.example.name + privileges = ["SELECT"] + on_all_tables_in_schema = "${snowflake_database.example.name}.${snowflake_schema.example.name}" +} + +################################## +### on tag +################################## + +resource "snowflake_grant_privileges_to_share" "example" { + share_name = snowflake_share.example.name + privileges = ["READ"] + on_tag = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_tag.example.name}" +} + +################################## +### on view +################################## + +resource "snowflake_grant_privileges_to_share" "example" { + share_name = snowflake_share.example.name + privileges = ["SELECT"] + on_view = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_view.example.name}" +} diff --git a/pkg/resources/grant_privileges_to_share.go b/pkg/resources/grant_privileges_to_share.go index ed56cf7595..8cb2ed924c 100644 --- a/pkg/resources/grant_privileges_to_share.go +++ b/pkg/resources/grant_privileges_to_share.go @@ -4,17 +4,18 @@ import ( "context" "database/sql" "fmt" + "log" + "slices" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "log" - "slices" ) var grantPrivilegesToShareGrantExactlyOneOfValidation = []string{ "database_name", "schema_name", - //"function_name", + // "function_name", "table_name", "all_tables_in_schema", "tag_name", @@ -51,14 +52,14 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, }, // TODO(SNOW-1021686): Because function identifier contains arguments which are not supported right now - //"function_name": { + // "function_name": { // Type: schema.TypeString, // Optional: true, // ForceNew: true, // Description: "The fully qualified name of the function on which privileges will be granted.", // ValidateDiagFunc: IsValidIdentifier[sdk.FunctionIdentifier](), // ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, - //}, + // }, "table_name": { Type: schema.TypeString, Optional: true, @@ -129,7 +130,7 @@ func ImportGrantPrivilegesToShare() func(ctx context.Context, d *schema.Resource if err := d.Set("schema_name", id.Identifier.FullyQualifiedName()); err != nil { return nil, err } - //case OnFunctionShareGrantKind: + // case OnFunctionShareGrantKind: // if err := d.Set("function_name", id.Identifier.FullyQualifiedName()); err != nil { // return nil, err // } @@ -359,7 +360,7 @@ func createGrantPrivilegesToShareIdFromSchema(d *schema.ResourceData) *GrantPriv databaseName, databaseNameOk := d.GetOk("database_name") schemaName, schemaNameOk := d.GetOk("schema_name") - //functionName, functionNameOk := d.GetOk("function_name") + // functionName, functionNameOk := d.GetOk("function_name") tableName, tableNameOk := d.GetOk("table_name") allTablesInSchema, allTablesInSchemaOk := d.GetOk("all_tables_in_schema") tagName, tagNameOk := d.GetOk("tag_name") @@ -372,7 +373,7 @@ func createGrantPrivilegesToShareIdFromSchema(d *schema.ResourceData) *GrantPriv case schemaNameOk: id.Kind = OnSchemaShareGrantKind id.Identifier = sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(schemaName.(string)) - //case functionNameOk: + // case functionNameOk: // id.Kind = OnFunctionShareGrantKind // id.Identifier = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(functionName.(string)) case tableNameOk: @@ -406,7 +407,7 @@ func getShareGrantOn(d *schema.ResourceData) *sdk.ShareGrantOn { databaseName, databaseNameOk := d.GetOk("database_name") schemaName, schemaNameOk := d.GetOk("schema_name") - //functionName, functionNameOk := d.GetOk("table_name") + // functionName, functionNameOk := d.GetOk("table_name") tableName, tableNameOk := d.GetOk("table_name") allTablesInSchema, allTablesInSchemaOk := d.GetOk("all_tables_in_schema") tagName, tagNameOk := d.GetOk("tag_name") @@ -417,7 +418,7 @@ func getShareGrantOn(d *schema.ResourceData) *sdk.ShareGrantOn { grantOn.Database = sdk.NewAccountObjectIdentifierFromFullyQualifiedName(databaseName.(string)) case len(schemaName.(string)) > 0 && schemaNameOk: grantOn.Schema = sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(schemaName.(string)) - //case len(functionName.(string)) > 0 && functionNameOk: + // case len(functionName.(string)) > 0 && functionNameOk: // grantOn.Function = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(functionName.(string)) case len(tableName.(string)) > 0 && tableNameOk: grantOn.Table = &sdk.OnTable{ diff --git a/pkg/resources/grant_privileges_to_share_acceptance_test.go b/pkg/resources/grant_privileges_to_share_acceptance_test.go index 8aa2e421d5..732eeb6109 100644 --- a/pkg/resources/grant_privileges_to_share_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_share_acceptance_test.go @@ -4,6 +4,9 @@ import ( "context" "database/sql" "fmt" + "strings" + "testing" + acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" "github.com/hashicorp/terraform-plugin-testing/config" @@ -12,8 +15,6 @@ import ( "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-plugin-testing/tfversion" "github.com/stretchr/testify/require" - "strings" - "testing" ) func TestAcc_GrantPrivilegesToShare_OnDatabase(t *testing.T) { diff --git a/pkg/resources/grant_privileges_to_share_identifier.go b/pkg/resources/grant_privileges_to_share_identifier.go index 7305913739..b5f396786e 100644 --- a/pkg/resources/grant_privileges_to_share_identifier.go +++ b/pkg/resources/grant_privileges_to_share_identifier.go @@ -2,9 +2,10 @@ package resources import ( "fmt" + "strings" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" - "strings" ) type ShareGrantKind string diff --git a/pkg/resources/grant_privileges_to_share_identifier_test.go b/pkg/resources/grant_privileges_to_share_identifier_test.go index 62c50118dc..e7eb5f89c3 100644 --- a/pkg/resources/grant_privileges_to_share_identifier_test.go +++ b/pkg/resources/grant_privileges_to_share_identifier_test.go @@ -1,9 +1,10 @@ package resources import ( + "testing" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" "github.com/stretchr/testify/assert" - "testing" ) func TestParseGrantPrivilegesToShareId(t *testing.T) { @@ -43,7 +44,7 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { // Kind: OnFunctionShareGrantKind, // Identifier: sdk.NewSchemaObjectIdentifier("on-database-name", "on-schema-name", "on-function-name(INT, VARCHAR)"), // }, - //}, + // }, { Name: "grant privileges on table to share", Identifier: `account-name."share-name"|EVOLVE SCHEMA|OnTable|"on-database-name"."on-schema-name"."on-table-name"`, @@ -172,7 +173,7 @@ func TestGrantPrivilegesToShareIdString(t *testing.T) { // Identifier: sdk.NewSchemaObjectIdentifier("database-name", "schema-name", "function-name(INT, VARCHAR)"), // }, // Expected: `account-name."share-name"|USAGE|OnFunction|"database-name"."schema-name".\"function-name(INT, VARCHAR)\"`, - //}, + // }, { Name: "grant privileges on table to share", Identifier: GrantPrivilegesToShareId{ diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf index a239c79ba6..df7747fd27 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf @@ -3,7 +3,7 @@ resource "snowflake_database" "test" { } resource "snowflake_schema" "test" { - name = var.schema + name = var.schema database = snowflake_database.test.name } @@ -12,15 +12,15 @@ resource "snowflake_share" "test" { } resource "snowflake_grant_privileges_to_share" "test_setup" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name - privileges = ["USAGE"] + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = ["USAGE"] database_name = snowflake_database.test.name } resource "snowflake_grant_privileges_to_share" "test" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name - privileges = var.privileges + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = var.privileges all_tables_in_schema = "\"${snowflake_schema.test.database}\".\"${snowflake_schema.test.name}\"" } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/test.tf index a5632da6e2..e402a617d4 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/test.tf @@ -3,7 +3,7 @@ resource "snowflake_database" "test" { } resource "snowflake_schema" "test" { - name = var.schema + name = var.schema database = snowflake_database.test.name } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf index 381f10300f..7c1e3fcd48 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf @@ -7,8 +7,8 @@ resource "snowflake_share" "test" { } resource "snowflake_grant_privileges_to_share" "test" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name - privileges = var.privileges + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = var.privileges database_name = snowflake_database.test.name } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf index fa0998dfc1..04d088cea5 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf @@ -3,7 +3,7 @@ resource "snowflake_database" "test" { } resource "snowflake_schema" "test" { - name = var.schema + name = var.schema database = snowflake_database.test.name } @@ -12,15 +12,15 @@ resource "snowflake_share" "test" { } resource "snowflake_grant_privileges_to_share" "test_setup" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name - privileges = ["USAGE"] + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = ["USAGE"] database_name = snowflake_database.test.name } resource "snowflake_grant_privileges_to_share" "test" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name - privileges = var.privileges + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = var.privileges schema_name = "\"${snowflake_schema.test.database}\".\"${snowflake_schema.test.name}\"" } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/test.tf index a5632da6e2..e402a617d4 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/test.tf @@ -3,7 +3,7 @@ resource "snowflake_database" "test" { } resource "snowflake_schema" "test" { - name = var.schema + name = var.schema database = snowflake_database.test.name } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf index e81fc7578f..669670bf29 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf @@ -3,14 +3,14 @@ resource "snowflake_database" "test" { } resource "snowflake_schema" "test" { - name = var.schema + name = var.schema database = snowflake_database.test.name } resource "snowflake_table" "test" { - name = var.table_name + name = var.table_name database = snowflake_database.test.name - schema = snowflake_schema.test.name + schema = snowflake_schema.test.name column { name = "id" type = "NUMBER(38,0)" @@ -22,9 +22,9 @@ resource "snowflake_share" "test" { } resource "snowflake_grant_privileges_to_share" "test_setup" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name - privileges = ["USAGE"] + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = ["USAGE"] database_name = snowflake_database.test.name } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/test.tf index d0912b5034..f57de76855 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/test.tf @@ -3,14 +3,14 @@ resource "snowflake_database" "test" { } resource "snowflake_schema" "test" { - name = var.schema + name = var.schema database = snowflake_database.test.name } resource "snowflake_table" "test" { - name = var.table_name + name = var.table_name database = snowflake_database.test.name - schema = snowflake_schema.test.name + schema = snowflake_schema.test.name column { name = "id" type = "NUMBER(38,0)" diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf index 076c4371d2..d37acb9726 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf @@ -3,14 +3,14 @@ resource "snowflake_database" "test" { } resource "snowflake_schema" "test" { - name = var.schema + name = var.schema database = snowflake_database.test.name } resource "snowflake_tag" "test" { - name = var.tag_name + name = var.tag_name database = snowflake_database.test.name - schema = snowflake_schema.test.name + schema = snowflake_schema.test.name } resource "snowflake_share" "test" { @@ -18,9 +18,9 @@ resource "snowflake_share" "test" { } resource "snowflake_grant_privileges_to_share" "test_setup" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name - privileges = ["USAGE"] + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = ["USAGE"] database_name = snowflake_database.test.name } @@ -28,5 +28,5 @@ resource "snowflake_grant_privileges_to_share" "test" { depends_on = [snowflake_share.test] share_name = var.share_account_name privileges = var.privileges - tag_name = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_tag.test.name}\"" + tag_name = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_tag.test.name}\"" } \ No newline at end of file diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/test.tf index 339c360865..e15ad73344 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/test.tf @@ -3,14 +3,14 @@ resource "snowflake_database" "test" { } resource "snowflake_schema" "test" { - name = var.schema + name = var.schema database = snowflake_database.test.name } resource "snowflake_tag" "test" { - name = var.tag_name + name = var.tag_name database = snowflake_database.test.name - schema = snowflake_schema.test.name + schema = snowflake_schema.test.name } resource "snowflake_share" "test" { diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf index 3f2cf1e60f..2568830375 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf @@ -3,14 +3,14 @@ resource "snowflake_database" "test" { } resource "snowflake_schema" "test" { - name = var.schema + name = var.schema database = snowflake_database.test.name } resource "snowflake_table" "test" { - name = var.table_name + name = var.table_name database = snowflake_database.test.name - schema = snowflake_schema.test.name + schema = snowflake_schema.test.name column { name = "id" type = "NUMBER(38,0)" @@ -19,8 +19,8 @@ resource "snowflake_table" "test" { resource "snowflake_view" "test" { name = var.view_name - database = snowflake_database.test.name - schema = snowflake_schema.test.name + database = snowflake_database.test.name + schema = snowflake_schema.test.name is_secure = true statement = "select \"id\" from \"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_table.test.name}\"" } @@ -30,9 +30,9 @@ resource "snowflake_share" "test" { } resource "snowflake_grant_privileges_to_share" "test_setup" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name - privileges = ["USAGE"] + depends_on = [snowflake_share.test] + share_name = var.share_account_name + privileges = ["USAGE"] database_name = snowflake_database.test.name } @@ -40,5 +40,5 @@ resource "snowflake_grant_privileges_to_share" "test" { depends_on = [snowflake_share.test] share_name = var.share_account_name privileges = var.privileges - view_name = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_view.test.name}\"" + view_name = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_view.test.name}\"" } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/test.tf index 75ab564802..16cc8ac15f 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/test.tf @@ -3,14 +3,14 @@ resource "snowflake_database" "test" { } resource "snowflake_schema" "test" { - name = var.schema + name = var.schema database = snowflake_database.test.name } resource "snowflake_table" "test" { - name = var.table_name + name = var.table_name database = snowflake_database.test.name - schema = snowflake_schema.test.name + schema = snowflake_schema.test.name column { name = "id" type = "NUMBER(38,0)" @@ -19,8 +19,8 @@ resource "snowflake_table" "test" { resource "snowflake_view" "test" { name = var.view_name - database = snowflake_database.test.name - schema = snowflake_schema.test.name + database = snowflake_database.test.name + schema = snowflake_schema.test.name is_secure = true statement = "select \"id\" from \"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_table.test.name}\"" } diff --git a/pkg/sdk/grants_test.go b/pkg/sdk/grants_test.go index 56dc5c7c17..c7d23c1cb5 100644 --- a/pkg/sdk/grants_test.go +++ b/pkg/sdk/grants_test.go @@ -868,7 +868,7 @@ func TestRevokePrivilegeFromShare(t *testing.T) { }) // TODO: This one throws an error - //t.Run("on all views", func(t *testing.T) { + // t.Run("on all views", func(t *testing.T) { // otherID := RandomDatabaseObjectIdentifier() // opts := &revokePrivilegeFromShareOptions{ // privilege: ObjectPrivilegeUsage, @@ -880,7 +880,7 @@ func TestRevokePrivilegeFromShare(t *testing.T) { // from: id, // } // assertOptsValidAndSQLEquals(t, opts, "REVOKE USAGE ON ALL VIEWS IN SCHEMA %s FROM SHARE %s", otherID.FullyQualifiedName(), id.FullyQualifiedName()) - //}) + // }) } func TestGrants_GrantOwnership(t *testing.T) { diff --git a/pkg/sdk/testint/grants_integration_test.go b/pkg/sdk/testint/grants_integration_test.go index fff2098d04..90e8d1a539 100644 --- a/pkg/sdk/testint/grants_integration_test.go +++ b/pkg/sdk/testint/grants_integration_test.go @@ -1,11 +1,12 @@ package testint import ( + "testing" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/internal/collections" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "testing" ) func TestInt_GrantAndRevokePrivilegesToAccountRole(t *testing.T) { @@ -424,7 +425,7 @@ func TestInt_GrantPrivilegeToShare(t *testing.T) { assert.Equal(t, onId.FullyQualifiedName(), shareGrant.Name.FullyQualifiedName()) } - t.Run("with options - multiple privileges", func(t *testing.T) { + t.Run("with options", func(t *testing.T) { err := client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ Database: testDb(t).ID(), }, shareTest.ID()) @@ -440,7 +441,7 @@ func TestInt_GrantPrivilegeToShare(t *testing.T) { table, tableCleanup := createTable(t, client, testDb(t), testSchema(t)) t.Cleanup(tableCleanup) - err = client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeEvolveSchema, sdk.ObjectPrivilegeSelect}, &sdk.ShareGrantOn{ + err = client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeSelect}, &sdk.ShareGrantOn{ Table: &sdk.OnTable{ AllInSchema: testSchema(t).ID(), }, @@ -458,7 +459,7 @@ func TestInt_GrantPrivilegeToShare(t *testing.T) { require.NoError(t, err) assertGrant(t, grants, table.ID(), sdk.ObjectPrivilegeSelect) - err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeEvolveSchema, sdk.ObjectPrivilegeSelect}, &sdk.ShareGrantOn{ + err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeSelect}, &sdk.ShareGrantOn{ Table: &sdk.OnTable{ AllInSchema: testSchema(t).ID(), }, From 7a97d224e7da9b69e8790d4af0d3df8ac1a73f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Tue, 30 Jan 2024 15:58:44 +0100 Subject: [PATCH 5/7] wip --- docs/resources/grant_privileges_to_share.md | 12 ++- .../resource.tf | 12 ++- pkg/resources/grant_privileges_to_share.go | 4 +- ...ant_privileges_to_share_acceptance_test.go | 75 +++---------------- .../grant_privileges_to_share_identifier.go | 6 +- ...ant_privileges_to_share_identifier_test.go | 74 +++++++++--------- .../OnAllTablesInSchema/test.tf | 6 +- .../OnAllTablesInSchema/variables.tf | 4 - .../OnDatabase/test.tf | 3 +- .../OnDatabase/variables.tf | 4 - .../OnSchema/test.tf | 6 +- .../OnSchema/variables.tf | 4 - .../OnTable/test.tf | 6 +- .../OnTable/variables.tf | 4 - .../OnTag/test.tf | 6 +- .../OnTag/variables.tf | 4 - .../OnView/test.tf | 6 +- .../OnView/variables.tf | 4 - 18 files changed, 80 insertions(+), 160 deletions(-) diff --git a/docs/resources/grant_privileges_to_share.md b/docs/resources/grant_privileges_to_share.md index 24945ffa6e..1eb5b4799d 100644 --- a/docs/resources/grant_privileges_to_share.md +++ b/docs/resources/grant_privileges_to_share.md @@ -23,7 +23,7 @@ resource "snowflake_grant_privileges_to_share" "example" { on_database = snowflake_database.example.name } -## ID: "\"account_name\".\"share_name\"|USAGE|OnDatabase|\"database_name\"" +## ID: "\"share_name\"|USAGE|OnDatabase|\"database_name\"" ################################## ### on schema @@ -35,7 +35,7 @@ resource "snowflake_grant_privileges_to_share" "example" { on_schema = "${snowflake_database.example.name}.${snowflake_schema.example.name}" } -## ID: "\"account_name\".\"share_name\"|USAGE|OnSchema|\"database_name\".\"schema_name\"" +## ID: "\"share_name\"|USAGE|OnSchema|\"database_name\".\"schema_name\"" ################################## ### on table @@ -47,7 +47,7 @@ resource "snowflake_grant_privileges_to_share" "example" { on_table = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_table.example.name}" } -## ID: "\"account_name\".\"share_name\"|Select|OnTable|\"database_name\".\"schema_name\".\"table_name\"" +## ID: "\"share_name\"|SELECT|OnTable|\"database_name\".\"schema_name\".\"table_name\"" ################################## ### on all tables in schema @@ -59,6 +59,8 @@ resource "snowflake_grant_privileges_to_share" "example" { on_all_tables_in_schema = "${snowflake_database.example.name}.${snowflake_schema.example.name}" } +## ID: "\"share_name\"|SELECT|OnAllTablesInSchema|\"database_name\".\"schema_name\"" + ################################## ### on tag ################################## @@ -69,6 +71,8 @@ resource "snowflake_grant_privileges_to_share" "example" { on_tag = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_tag.example.name}" } +## ID: "\"share_name\"|READ|OnTag|\"database_name\".\"schema_name\".\"tag_name\"" + ################################## ### on view ################################## @@ -78,6 +82,8 @@ resource "snowflake_grant_privileges_to_share" "example" { privileges = ["SELECT"] on_view = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_view.example.name}" } + +## ID: "\"share_name\"|SELECT|OnView|\"database_name\".\"schema_name\".\"view_name\"" ``` diff --git a/examples/resources/snowflake_grant_privileges_to_share/resource.tf b/examples/resources/snowflake_grant_privileges_to_share/resource.tf index 6ca4ef79b5..f070a0b5ba 100644 --- a/examples/resources/snowflake_grant_privileges_to_share/resource.tf +++ b/examples/resources/snowflake_grant_privileges_to_share/resource.tf @@ -8,7 +8,7 @@ resource "snowflake_grant_privileges_to_share" "example" { on_database = snowflake_database.example.name } -## ID: "\"account_name\".\"share_name\"|USAGE|OnDatabase|\"database_name\"" +## ID: "\"share_name\"|USAGE|OnDatabase|\"database_name\"" ################################## ### on schema @@ -20,7 +20,7 @@ resource "snowflake_grant_privileges_to_share" "example" { on_schema = "${snowflake_database.example.name}.${snowflake_schema.example.name}" } -## ID: "\"account_name\".\"share_name\"|USAGE|OnSchema|\"database_name\".\"schema_name\"" +## ID: "\"share_name\"|USAGE|OnSchema|\"database_name\".\"schema_name\"" ################################## ### on table @@ -32,7 +32,7 @@ resource "snowflake_grant_privileges_to_share" "example" { on_table = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_table.example.name}" } -## ID: "\"account_name\".\"share_name\"|Select|OnTable|\"database_name\".\"schema_name\".\"table_name\"" +## ID: "\"share_name\"|SELECT|OnTable|\"database_name\".\"schema_name\".\"table_name\"" ################################## ### on all tables in schema @@ -44,6 +44,8 @@ resource "snowflake_grant_privileges_to_share" "example" { on_all_tables_in_schema = "${snowflake_database.example.name}.${snowflake_schema.example.name}" } +## ID: "\"share_name\"|SELECT|OnAllTablesInSchema|\"database_name\".\"schema_name\"" + ################################## ### on tag ################################## @@ -54,6 +56,8 @@ resource "snowflake_grant_privileges_to_share" "example" { on_tag = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_tag.example.name}" } +## ID: "\"share_name\"|READ|OnTag|\"database_name\".\"schema_name\".\"tag_name\"" + ################################## ### on view ################################## @@ -63,3 +67,5 @@ resource "snowflake_grant_privileges_to_share" "example" { privileges = ["SELECT"] on_view = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_view.example.name}" } + +## ID: "\"share_name\"|SELECT|OnView|\"database_name\".\"schema_name\".\"view_name\"" diff --git a/pkg/resources/grant_privileges_to_share.go b/pkg/resources/grant_privileges_to_share.go index 8cb2ed924c..64f9fabae3 100644 --- a/pkg/resources/grant_privileges_to_share.go +++ b/pkg/resources/grant_privileges_to_share.go @@ -114,7 +114,7 @@ func ImportGrantPrivilegesToShare() func(ctx context.Context, d *schema.Resource if err != nil { return nil, err } - if err := d.Set("share_name", id.ShareName.FullyQualifiedName()); err != nil { + if err := d.Set("share_name", id.ShareName.Name()); err != nil { return nil, err } if err := d.Set("privileges", id.Privileges); err != nil { @@ -355,7 +355,7 @@ func ReadGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, met func createGrantPrivilegesToShareIdFromSchema(d *schema.ResourceData) *GrantPrivilegesToShareId { id := new(GrantPrivilegesToShareId) - id.ShareName = sdk.NewExternalObjectIdentifierFromFullyQualifiedName(d.Get("share_name").(string)) + id.ShareName = sdk.NewAccountObjectIdentifier(d.Get("share_name").(string)) id.Privileges = expandStringList(d.Get("privileges").(*schema.Set).List()) databaseName, databaseNameOk := d.GetOk("database_name") diff --git a/pkg/resources/grant_privileges_to_share_acceptance_test.go b/pkg/resources/grant_privileges_to_share_acceptance_test.go index 732eeb6109..1dd636446f 100644 --- a/pkg/resources/grant_privileges_to_share_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_share_acceptance_test.go @@ -14,26 +14,18 @@ import ( "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-plugin-testing/tfversion" - "github.com/stretchr/testify/require" ) func TestAcc_GrantPrivilegesToShare_OnDatabase(t *testing.T) { databaseName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) - client, err := sdk.NewDefaultClient() - require.NoError(t, err) - currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) - require.NoError(t, err) - - shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ "share_name": config.StringVariable(shareName.Name()), "database": config.StringVariable(databaseName.Name()), } if withGrant { - variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) variables["privileges"] = config.ListVariable( config.StringVariable(sdk.ObjectPrivilegeUsage.String()), ) @@ -53,7 +45,7 @@ func TestAcc_GrantPrivilegesToShare_OnDatabase(t *testing.T) { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeUsage.String()), resource.TestCheckResourceAttr(resourceName, "database_name", databaseName.Name()), @@ -80,12 +72,6 @@ func TestAcc_GrantPrivilegesToShare_OnSchema(t *testing.T) { schemaName := sdk.NewDatabaseObjectIdentifier(databaseName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) - client, err := sdk.NewDefaultClient() - require.NoError(t, err) - currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) - require.NoError(t, err) - - shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ "share_name": config.StringVariable(shareName.Name()), @@ -93,7 +79,6 @@ func TestAcc_GrantPrivilegesToShare_OnSchema(t *testing.T) { "schema": config.StringVariable(schemaName.Name()), } if withGrant { - variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) variables["privileges"] = config.ListVariable( config.StringVariable(sdk.ObjectPrivilegeUsage.String()), ) @@ -113,7 +98,7 @@ func TestAcc_GrantPrivilegesToShare_OnSchema(t *testing.T) { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnSchema"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeUsage.String()), resource.TestCheckResourceAttr(resourceName, "schema_name", schemaName.FullyQualifiedName()), @@ -141,12 +126,6 @@ func TestAcc_GrantPrivilegesToShare_OnTable(t *testing.T) { tableName := sdk.NewSchemaObjectIdentifier(databaseName.Name(), schemaName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) - client, err := sdk.NewDefaultClient() - require.NoError(t, err) - currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) - require.NoError(t, err) - - shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ "share_name": config.StringVariable(shareName.Name()), @@ -155,7 +134,6 @@ func TestAcc_GrantPrivilegesToShare_OnTable(t *testing.T) { "table_name": config.StringVariable(tableName.Name()), } if withGrant { - variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) variables["privileges"] = config.ListVariable( config.StringVariable(sdk.ObjectPrivilegeSelect.String()), ) @@ -175,7 +153,7 @@ func TestAcc_GrantPrivilegesToShare_OnTable(t *testing.T) { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnTable"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeSelect.String()), resource.TestCheckResourceAttr(resourceName, "table_name", tableName.FullyQualifiedName()), @@ -202,12 +180,6 @@ func TestAcc_GrantPrivilegesToShare_OnAllTablesInSchema(t *testing.T) { schemaName := sdk.NewDatabaseObjectIdentifier(databaseName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) - client, err := sdk.NewDefaultClient() - require.NoError(t, err) - currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) - require.NoError(t, err) - - shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ "share_name": config.StringVariable(shareName.Name()), @@ -215,7 +187,6 @@ func TestAcc_GrantPrivilegesToShare_OnAllTablesInSchema(t *testing.T) { "schema": config.StringVariable(schemaName.Name()), } if withGrant { - variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) variables["privileges"] = config.ListVariable( config.StringVariable(sdk.ObjectPrivilegeSelect.String()), ) @@ -235,7 +206,7 @@ func TestAcc_GrantPrivilegesToShare_OnAllTablesInSchema(t *testing.T) { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeSelect.String()), resource.TestCheckResourceAttr(resourceName, "all_tables_in_schema", schemaName.FullyQualifiedName()), @@ -264,12 +235,6 @@ func TestAcc_GrantPrivilegesToShare_OnView(t *testing.T) { viewName := sdk.NewSchemaObjectIdentifier(databaseName.Name(), schemaName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) - client, err := sdk.NewDefaultClient() - require.NoError(t, err) - currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) - require.NoError(t, err) - - shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ "share_name": config.StringVariable(shareName.Name()), @@ -279,7 +244,6 @@ func TestAcc_GrantPrivilegesToShare_OnView(t *testing.T) { "view_name": config.StringVariable(viewName.Name()), } if withGrant { - variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) variables["privileges"] = config.ListVariable( config.StringVariable(sdk.ObjectPrivilegeSelect.String()), ) @@ -299,7 +263,7 @@ func TestAcc_GrantPrivilegesToShare_OnView(t *testing.T) { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnView"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeSelect.String()), resource.TestCheckResourceAttr(resourceName, "view_name", viewName.FullyQualifiedName()), @@ -327,12 +291,6 @@ func TestAcc_GrantPrivilegesToShare_OnTag(t *testing.T) { tagName := sdk.NewSchemaObjectIdentifier(databaseName.Name(), schemaName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) - client, err := sdk.NewDefaultClient() - require.NoError(t, err) - currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) - require.NoError(t, err) - - shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ "share_name": config.StringVariable(shareName.Name()), @@ -341,7 +299,6 @@ func TestAcc_GrantPrivilegesToShare_OnTag(t *testing.T) { "tag_name": config.StringVariable(tagName.Name()), } if withGrant { - variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) variables["privileges"] = config.ListVariable( config.StringVariable(sdk.ObjectPrivilegeRead.String()), ) @@ -361,7 +318,7 @@ func TestAcc_GrantPrivilegesToShare_OnTag(t *testing.T) { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnTag"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeRead.String()), resource.TestCheckResourceAttr(resourceName, "tag_name", tagName.FullyQualifiedName()), @@ -387,19 +344,12 @@ func TestAcc_GrantPrivilegesToShare_OnPrivilegeUpdate(t *testing.T) { databaseName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) - client, err := sdk.NewDefaultClient() - require.NoError(t, err) - currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) - require.NoError(t, err) - - shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) configVariables := func(withGrant bool, privileges []sdk.ObjectPrivilege) config.Variables { variables := config.Variables{ "share_name": config.StringVariable(shareName.Name()), "database": config.StringVariable(databaseName.Name()), } if withGrant { - variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) if len(privileges) > 0 { configPrivileges := make([]config.Variable, len(privileges)) for i, privilege := range privileges { @@ -425,7 +375,7 @@ func TestAcc_GrantPrivilegesToShare_OnPrivilegeUpdate(t *testing.T) { sdk.ObjectPrivilegeReferenceUsage, }), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeReferenceUsage.String()), resource.TestCheckResourceAttr(resourceName, "database_name", databaseName.Name()), @@ -437,7 +387,7 @@ func TestAcc_GrantPrivilegesToShare_OnPrivilegeUpdate(t *testing.T) { sdk.ObjectPrivilegeUsage, }), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeUsage.String()), resource.TestCheckResourceAttr(resourceName, "database_name", databaseName.Name()), @@ -465,19 +415,12 @@ func TestAcc_GrantPrivilegesToShare_OnDatabaseWithReferenceUsagePrivilege(t *tes databaseName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) - client, err := sdk.NewDefaultClient() - require.NoError(t, err) - currentAccount, err := client.ContextFunctions.CurrentAccount(context.Background()) - require.NoError(t, err) - - shareAccountName := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(fmt.Sprintf("%s.%s", currentAccount, shareName.Name())) configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ "share_name": config.StringVariable(shareName.Name()), "database": config.StringVariable(databaseName.Name()), } if withGrant { - variables["share_account_name"] = config.StringVariable(shareAccountName.FullyQualifiedName()) variables["privileges"] = config.ListVariable( config.StringVariable(sdk.ObjectPrivilegeReferenceUsage.String()), ) @@ -497,7 +440,7 @@ func TestAcc_GrantPrivilegesToShare_OnDatabaseWithReferenceUsagePrivilege(t *tes ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareAccountName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeReferenceUsage.String()), resource.TestCheckResourceAttr(resourceName, "database_name", databaseName.Name()), diff --git a/pkg/resources/grant_privileges_to_share_identifier.go b/pkg/resources/grant_privileges_to_share_identifier.go index b5f396786e..e287d5884d 100644 --- a/pkg/resources/grant_privileges_to_share_identifier.go +++ b/pkg/resources/grant_privileges_to_share_identifier.go @@ -22,7 +22,7 @@ const ( ) type GrantPrivilegesToShareId struct { - ShareName sdk.ExternalObjectIdentifier + ShareName sdk.AccountObjectIdentifier Privileges []string Kind ShareGrantKind Identifier sdk.ObjectIdentifier @@ -42,10 +42,10 @@ func ParseGrantPrivilegesToShareId(idString string) (GrantPrivilegesToShareId, e parts := strings.Split(idString, helpers.IDDelimiter) if len(parts) != 4 { - return grantPrivilegesToShareId, sdk.NewError(fmt.Sprintf(`snowflake_grant_privileges_to_share id is composed out of 4 parts ".|||", but got %d parts: %v`, len(parts), parts)) + return grantPrivilegesToShareId, sdk.NewError(fmt.Sprintf(`snowflake_grant_privileges_to_share id is composed out of 4 parts "|||", but got %d parts: %v`, len(parts), parts)) } - grantPrivilegesToShareId.ShareName = sdk.NewExternalObjectIdentifierFromFullyQualifiedName(parts[0]) + grantPrivilegesToShareId.ShareName = sdk.NewAccountObjectIdentifier(parts[0]) privileges := strings.Split(parts[1], ",") if len(privileges) == 0 || (len(privileges) == 1 && privileges[0] == "") { return grantPrivilegesToShareId, sdk.NewError(fmt.Sprintf(`invalid Privileges value: %s, should be comma separated list of privileges`, privileges)) diff --git a/pkg/resources/grant_privileges_to_share_identifier_test.go b/pkg/resources/grant_privileges_to_share_identifier_test.go index e7eb5f89c3..d892d2800d 100644 --- a/pkg/resources/grant_privileges_to_share_identifier_test.go +++ b/pkg/resources/grant_privileges_to_share_identifier_test.go @@ -16,9 +16,9 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { }{ { Name: "grant privileges on database to share", - Identifier: `account-name."share-name"|REFERENCE_USAGE|OnDatabase|"on-database-name"`, + Identifier: `"share-name"|REFERENCE_USAGE|OnDatabase|"on-database-name"`, Expected: GrantPrivilegesToShareId{ - ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + ShareName: sdk.NewAccountObjectIdentifier("share-name"), Privileges: []string{"REFERENCE_USAGE"}, Kind: OnDatabaseShareGrantKind, Identifier: sdk.NewAccountObjectIdentifier("on-database-name"), @@ -26,9 +26,9 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { }, { Name: "grant privileges on schema to share", - Identifier: `account-name."share-name"|USAGE|OnSchema|"on-database-name"."on-schema-name"`, + Identifier: `"share-name"|USAGE|OnSchema|"on-database-name"."on-schema-name"`, Expected: GrantPrivilegesToShareId{ - ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + ShareName: sdk.NewAccountObjectIdentifier("share-name"), Privileges: []string{"USAGE"}, Kind: OnSchemaShareGrantKind, Identifier: sdk.NewDatabaseObjectIdentifier("on-database-name", "on-schema-name"), @@ -37,9 +37,9 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { // TODO(SNOW-1021686): This is wrong and should be fixed (function's last part of identifier cannot be enclosed with quotes like that) //{ // Name: "grant privileges on function to share", - // Identifier: `account-name."share-name"|USAGE|OnFunction|"on-database-name"."on-schema-name".on-function-name(INT, VARCHAR)`, + // Identifier: `"share-name"|USAGE|OnFunction|"on-database-name"."on-schema-name".on-function-name(INT, VARCHAR)`, // Expected: GrantPrivilegesToShareId{ - // ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + // ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("share-name"), // Privileges: []string{"USAGE"}, // Kind: OnFunctionShareGrantKind, // Identifier: sdk.NewSchemaObjectIdentifier("on-database-name", "on-schema-name", "on-function-name(INT, VARCHAR)"), @@ -47,9 +47,9 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { // }, { Name: "grant privileges on table to share", - Identifier: `account-name."share-name"|EVOLVE SCHEMA|OnTable|"on-database-name"."on-schema-name"."on-table-name"`, + Identifier: `"share-name"|EVOLVE SCHEMA|OnTable|"on-database-name"."on-schema-name"."on-table-name"`, Expected: GrantPrivilegesToShareId{ - ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + ShareName: sdk.NewAccountObjectIdentifier("share-name"), Privileges: []string{"EVOLVE SCHEMA"}, Kind: OnTableShareGrantKind, Identifier: sdk.NewSchemaObjectIdentifier("on-database-name", "on-schema-name", "on-table-name"), @@ -57,9 +57,9 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { }, { Name: "grant privileges on all tables in schema to share", - Identifier: `account-name."share-name"|EVOLVE SCHEMA,SELECT|OnAllTablesInSchema|"on-database-name"."on-schema-name"`, + Identifier: `"share-name"|EVOLVE SCHEMA,SELECT|OnAllTablesInSchema|"on-database-name"."on-schema-name"`, Expected: GrantPrivilegesToShareId{ - ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + ShareName: sdk.NewAccountObjectIdentifier("share-name"), Privileges: []string{"EVOLVE SCHEMA", "SELECT"}, Kind: OnAllTablesInSchemaShareGrantKind, Identifier: sdk.NewDatabaseObjectIdentifier("on-database-name", "on-schema-name"), @@ -67,19 +67,19 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { }, { Name: "grant privileges on tag to share", - Identifier: `account-name."share-name"|READ|OnTag|"on-tag-name"`, + Identifier: `"share-name"|READ|OnTag|"database-name"."schema-name"."on-tag-name"`, Expected: GrantPrivilegesToShareId{ - ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + ShareName: sdk.NewAccountObjectIdentifier("share-name"), Privileges: []string{"READ"}, Kind: OnTagShareGrantKind, - Identifier: sdk.NewAccountObjectIdentifier("on-tag-name"), + Identifier: sdk.NewSchemaObjectIdentifier("database-name", "schema-name", "on-tag-name"), }, }, { Name: "grant privileges on view to share", - Identifier: `account-name."share-name"|READ|OnView|"on-database-name"."on-schema-name"."on-view-name"`, + Identifier: `"share-name"|READ|OnView|"on-database-name"."on-schema-name"."on-view-name"`, Expected: GrantPrivilegesToShareId{ - ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + ShareName: sdk.NewAccountObjectIdentifier("share-name"), Privileges: []string{"READ"}, Kind: OnViewShareGrantKind, Identifier: sdk.NewSchemaObjectIdentifier("on-database-name", "on-schema-name", "on-view-name"), @@ -87,37 +87,37 @@ func TestParseGrantPrivilegesToShareId(t *testing.T) { }, { Name: "validation: not enough parts", - Identifier: `account-name."share-name"|SELECT|OnDatabase`, - Error: `snowflake_grant_privileges_to_share id is composed out of 4 parts ".|||", but got 3 parts: [account-name."share-name" SELECT OnDatabase]`, + Identifier: `"share-name"|SELECT|OnDatabase`, + Error: `snowflake_grant_privileges_to_share id is composed out of 4 parts "|||", but got 3 parts: ["share-name" SELECT OnDatabase]`, }, { Name: "validation: empty privileges", - Identifier: `account-name."share-name"||OnDatabase|"database-name"`, + Identifier: `"share-name"||OnDatabase|"database-name"`, Error: `invalid Privileges value: [], should be comma separated list of privileges`, }, { Name: "validation: unsupported kind", - Identifier: `account-name."share-name"|SELECT|OnSomething|"object-name"`, + Identifier: `"share-name"|SELECT|OnSomething|"object-name"`, Error: `unexpected share grant kind: OnSomething`, }, { Name: "validation: invalid identifier", - Identifier: `account-name."share-name"|SELECT|OnDatabase|one.two.three.four.five.six.seven.eight.nine.ten`, + Identifier: `"share-name"|SELECT|OnDatabase|one.two.three.four.five.six.seven.eight.nine.ten`, Error: `unable to classify identifier: one.two.three.four.five.six.seven.eight.nine.ten`, }, { Name: "validation: invalid account object identifier", - Identifier: `account-name."share-name"|SELECT|OnDatabase|one.two`, + Identifier: `"share-name"|SELECT|OnDatabase|one.two`, Error: `invalid identifier, expected fully qualified name of account object: , but instead got: .`, }, { Name: "validation: invalid database object identifier", - Identifier: `account-name."share-name"|SELECT|OnSchema|one.two.three`, + Identifier: `"share-name"|SELECT|OnSchema|one.two.three`, Error: `invalid identifier, expected fully qualified name of database object: ., but instead got: ..`, }, { Name: "validation: invalid schema object identifier", - Identifier: `account-name."share-name"|SELECT|OnTable|one`, + Identifier: `"share-name"|SELECT|OnTable|one`, Error: `invalid identifier, expected fully qualified name of schema object: .., but instead got: `, }, } @@ -146,73 +146,73 @@ func TestGrantPrivilegesToShareIdString(t *testing.T) { { Name: "grant privileges on database to share", Identifier: GrantPrivilegesToShareId{ - ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + ShareName: sdk.NewAccountObjectIdentifier("share-name"), Privileges: []string{"REFERENCE_USAGE"}, Kind: OnDatabaseShareGrantKind, Identifier: sdk.NewAccountObjectIdentifier("database-name"), }, - Expected: `account-name."share-name"|REFERENCE_USAGE|OnDatabase|"database-name"`, + Expected: `"share-name"|REFERENCE_USAGE|OnDatabase|"database-name"`, }, { Name: "grant privileges on schema to share", Identifier: GrantPrivilegesToShareId{ - ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + ShareName: sdk.NewAccountObjectIdentifier("share-name"), Privileges: []string{"USAGE"}, Kind: OnSchemaShareGrantKind, Identifier: sdk.NewDatabaseObjectIdentifier("database-name", "schema-name"), }, - Expected: `account-name."share-name"|USAGE|OnSchema|"database-name"."schema-name"`, + Expected: `"share-name"|USAGE|OnSchema|"database-name"."schema-name"`, }, // TODO(SNOW-1021686): This is wrong and should be fixed (function's last part of identifier cannot be enclosed with quotes like that) //{ // Name: "grant privileges on function to share", // Identifier: GrantPrivilegesToShareId{ - // ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + // ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("share-name"), // Privileges: []string{"USAGE"}, // Kind: OnFunctionShareGrantKind, // Identifier: sdk.NewSchemaObjectIdentifier("database-name", "schema-name", "function-name(INT, VARCHAR)"), // }, - // Expected: `account-name."share-name"|USAGE|OnFunction|"database-name"."schema-name".\"function-name(INT, VARCHAR)\"`, + // Expected: `"share-name"|USAGE|OnFunction|"database-name"."schema-name".\"function-name(INT, VARCHAR)\"`, // }, { Name: "grant privileges on table to share", Identifier: GrantPrivilegesToShareId{ - ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + ShareName: sdk.NewAccountObjectIdentifier("share-name"), Privileges: []string{"EVOLVE SCHEMA", "SELECT"}, Kind: OnTableShareGrantKind, Identifier: sdk.NewSchemaObjectIdentifier("database-name", "schema-name", "table-name"), }, - Expected: `account-name."share-name"|EVOLVE SCHEMA,SELECT|OnTable|"database-name"."schema-name"."table-name"`, + Expected: `"share-name"|EVOLVE SCHEMA,SELECT|OnTable|"database-name"."schema-name"."table-name"`, }, { Name: "grant privileges on all tables in schema to share", Identifier: GrantPrivilegesToShareId{ - ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + ShareName: sdk.NewAccountObjectIdentifier("share-name"), Privileges: []string{"EVOLVE SCHEMA", "SELECT"}, Kind: OnAllTablesInSchemaShareGrantKind, Identifier: sdk.NewDatabaseObjectIdentifier("database-name", "schema-name"), }, - Expected: `account-name."share-name"|EVOLVE SCHEMA,SELECT|OnAllTablesInSchema|"database-name"."schema-name"`, + Expected: `"share-name"|EVOLVE SCHEMA,SELECT|OnAllTablesInSchema|"database-name"."schema-name"`, }, { Name: "grant privileges on tag to share", Identifier: GrantPrivilegesToShareId{ - ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + ShareName: sdk.NewAccountObjectIdentifier("share-name"), Privileges: []string{"READ"}, Kind: OnTagShareGrantKind, Identifier: sdk.NewAccountObjectIdentifier("tag-name"), }, - Expected: `account-name."share-name"|READ|OnTag|"tag-name"`, + Expected: `"share-name"|READ|OnTag|"tag-name"`, }, { Name: "grant privileges on view to share", Identifier: GrantPrivilegesToShareId{ - ShareName: sdk.NewExternalObjectIdentifierFromFullyQualifiedName("account-name.share-name"), + ShareName: sdk.NewAccountObjectIdentifier("share-name"), Privileges: []string{"SELECT"}, Kind: OnViewShareGrantKind, Identifier: sdk.NewSchemaObjectIdentifier("database-name", "schema-name", "view-name"), }, - Expected: `account-name."share-name"|SELECT|OnView|"database-name"."schema-name"."view-name"`, + Expected: `"share-name"|SELECT|OnView|"database-name"."schema-name"."view-name"`, }, } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf index df7747fd27..1d5fafef9c 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf @@ -12,15 +12,13 @@ resource "snowflake_share" "test" { } resource "snowflake_grant_privileges_to_share" "test_setup" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name + share_name = snowflake_share.test.name privileges = ["USAGE"] database_name = snowflake_database.test.name } resource "snowflake_grant_privileges_to_share" "test" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name + share_name = snowflake_share.test.name privileges = var.privileges all_tables_in_schema = "\"${snowflake_schema.test.database}\".\"${snowflake_schema.test.name}\"" } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/variables.tf index f495d7e38e..b44e81d500 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/variables.tf @@ -2,10 +2,6 @@ variable "share_name" { type = string } -variable "share_account_name" { - type = string -} - variable "privileges" { type = list(string) } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf index 7c1e3fcd48..43f2f988fc 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf @@ -7,8 +7,7 @@ resource "snowflake_share" "test" { } resource "snowflake_grant_privileges_to_share" "test" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name + share_name = snowflake_share.test.name privileges = var.privileges database_name = snowflake_database.test.name } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/variables.tf index bacc3a486c..84db64fb9b 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/variables.tf @@ -2,10 +2,6 @@ variable "share_name" { type = string } -variable "share_account_name" { - type = string -} - variable "privileges" { type = list(string) } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf index 04d088cea5..0bfea3adfe 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf @@ -12,15 +12,13 @@ resource "snowflake_share" "test" { } resource "snowflake_grant_privileges_to_share" "test_setup" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name + share_name = snowflake_share.test.name privileges = ["USAGE"] database_name = snowflake_database.test.name } resource "snowflake_grant_privileges_to_share" "test" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name + share_name = snowflake_share.test.name privileges = var.privileges schema_name = "\"${snowflake_schema.test.database}\".\"${snowflake_schema.test.name}\"" } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/variables.tf index f495d7e38e..b44e81d500 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/variables.tf @@ -2,10 +2,6 @@ variable "share_name" { type = string } -variable "share_account_name" { - type = string -} - variable "privileges" { type = list(string) } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf index 669670bf29..d833622e53 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf @@ -22,15 +22,13 @@ resource "snowflake_share" "test" { } resource "snowflake_grant_privileges_to_share" "test_setup" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name + share_name = snowflake_share.test.name privileges = ["USAGE"] database_name = snowflake_database.test.name } resource "snowflake_grant_privileges_to_share" "test" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name + share_name = snowflake_share.test.name privileges = var.privileges table_name = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_table.test.name}\"" } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/variables.tf index 64ca684b83..f6dd8e75b7 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/variables.tf @@ -2,10 +2,6 @@ variable "share_name" { type = string } -variable "share_account_name" { - type = string -} - variable "privileges" { type = list(string) } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf index d37acb9726..59543b37c4 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf @@ -18,15 +18,13 @@ resource "snowflake_share" "test" { } resource "snowflake_grant_privileges_to_share" "test_setup" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name + share_name = snowflake_share.test.name privileges = ["USAGE"] database_name = snowflake_database.test.name } resource "snowflake_grant_privileges_to_share" "test" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name + share_name = snowflake_share.test.name privileges = var.privileges tag_name = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_tag.test.name}\"" } \ No newline at end of file diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/variables.tf index c6c6856eab..f5575b9359 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/variables.tf @@ -2,10 +2,6 @@ variable "share_name" { type = string } -variable "share_account_name" { - type = string -} - variable "privileges" { type = list(string) } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf index 2568830375..60e0d393ec 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf @@ -30,15 +30,13 @@ resource "snowflake_share" "test" { } resource "snowflake_grant_privileges_to_share" "test_setup" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name + share_name = snowflake_share.test.name privileges = ["USAGE"] database_name = snowflake_database.test.name } resource "snowflake_grant_privileges_to_share" "test" { - depends_on = [snowflake_share.test] - share_name = var.share_account_name + share_name = snowflake_share.test.name privileges = var.privileges view_name = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_view.test.name}\"" } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/variables.tf index 9300773331..20162fb361 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/variables.tf @@ -2,10 +2,6 @@ variable "share_name" { type = string } -variable "share_account_name" { - type = string -} - variable "privileges" { type = list(string) } From d1be66948f9c3c534661e3154ef4e47f9989f7da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Wed, 31 Jan 2024 14:31:21 +0100 Subject: [PATCH 6/7] changes after review --- docs/resources/grant_privileges_to_share.md | 28 ++-- .../resource.tf | 12 +- pkg/resources/grant_privileges_to_share.go | 101 ++++++------ ...ant_privileges_to_share_acceptance_test.go | 146 ++++++++++++------ .../grant_privileges_to_share_identifier.go | 2 +- .../NoOnOption/test.tf | 8 + .../NoOnOption/variables.tf | 7 + .../OnAllTablesInSchema/test.tf | 14 +- .../OnAllTablesInSchema/variables.tf | 2 +- .../OnAllTablesInSchema_NoGrant/test.tf | 2 +- .../OnAllTablesInSchema_NoGrant/variables.tf | 2 +- .../OnDatabase/test.tf | 8 +- .../OnDatabase/variables.tf | 2 +- .../OnDatabase_NoGrant/test.tf | 2 +- .../OnDatabase_NoGrant/variables.tf | 2 +- .../OnDatabase_NoPrivileges/test.tf | 12 ++ .../OnDatabase_NoPrivileges/variables.tf | 7 + .../OnSchema/test.tf | 14 +- .../OnSchema/variables.tf | 2 +- .../OnSchema_NoGrant/test.tf | 2 +- .../OnSchema_NoGrant/variables.tf | 2 +- .../OnTable/test.tf | 14 +- .../OnTable/variables.tf | 4 +- .../OnTable_NoGrant/test.tf | 4 +- .../OnTable_NoGrant/variables.tf | 4 +- .../OnTag/test.tf | 14 +- .../OnTag/variables.tf | 4 +- .../OnTag_NoGrant/test.tf | 4 +- .../OnTag_NoGrant/variables.tf | 4 +- .../OnView/test.tf | 16 +- .../OnView/variables.tf | 6 +- .../OnView_NoGrant/test.tf | 4 +- .../OnView_NoGrant/variables.tf | 6 +- pkg/sdk/grants_test.go | 19 +-- 34 files changed, 280 insertions(+), 200 deletions(-) create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/NoOnOption/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/NoOnOption/variables.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoPrivileges/test.tf create mode 100644 pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoPrivileges/variables.tf diff --git a/docs/resources/grant_privileges_to_share.md b/docs/resources/grant_privileges_to_share.md index 1eb5b4799d..ea241bddd6 100644 --- a/docs/resources/grant_privileges_to_share.md +++ b/docs/resources/grant_privileges_to_share.md @@ -18,7 +18,7 @@ description: |- ################################## resource "snowflake_grant_privileges_to_share" "example" { - share_name = snowflake_share.example.name + to_share = snowflake_share.example.name privileges = ["USAGE"] on_database = snowflake_database.example.name } @@ -30,7 +30,7 @@ resource "snowflake_grant_privileges_to_share" "example" { ################################## resource "snowflake_grant_privileges_to_share" "example" { - share_name = snowflake_share.example.name + to_share = snowflake_share.example.name privileges = ["USAGE"] on_schema = "${snowflake_database.example.name}.${snowflake_schema.example.name}" } @@ -42,7 +42,7 @@ resource "snowflake_grant_privileges_to_share" "example" { ################################## resource "snowflake_grant_privileges_to_share" "example" { - share_name = snowflake_share.example.name + to_share = snowflake_share.example.name privileges = ["SELECT"] on_table = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_table.example.name}" } @@ -54,7 +54,7 @@ resource "snowflake_grant_privileges_to_share" "example" { ################################## resource "snowflake_grant_privileges_to_share" "example" { - share_name = snowflake_share.example.name + to_share = snowflake_share.example.name privileges = ["SELECT"] on_all_tables_in_schema = "${snowflake_database.example.name}.${snowflake_schema.example.name}" } @@ -66,7 +66,7 @@ resource "snowflake_grant_privileges_to_share" "example" { ################################## resource "snowflake_grant_privileges_to_share" "example" { - share_name = snowflake_share.example.name + to_share = snowflake_share.example.name privileges = ["READ"] on_tag = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_tag.example.name}" } @@ -78,7 +78,7 @@ resource "snowflake_grant_privileges_to_share" "example" { ################################## resource "snowflake_grant_privileges_to_share" "example" { - share_name = snowflake_share.example.name + to_share = snowflake_share.example.name privileges = ["SELECT"] on_view = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_view.example.name}" } @@ -91,17 +91,17 @@ resource "snowflake_grant_privileges_to_share" "example" { ### Required -- `privileges` (Set of String) The privileges to grant on the share. -- `share_name` (String) The fully qualified name of the share on which privileges will be granted. +- `privileges` (Set of String) The privileges to grant on the share. See available list of privileges: https://docs.snowflake.com/en/sql-reference/sql/grant-privilege-share#syntax +- `to_share` (String) The fully qualified name of the share on which privileges will be granted. ### Optional -- `all_tables_in_schema` (String) The fully qualified identifier for the schema for which the specified privilege will be granted for all tables. -- `database_name` (String) The fully qualified name of the database on which privileges will be granted. -- `schema_name` (String) The fully qualified name of the schema on which privileges will be granted. -- `table_name` (String) The fully qualified name of the table on which privileges will be granted. -- `tag_name` (String) The fully qualified name of the tag on which privileges will be granted. -- `view_name` (String) The fully qualified name of the view on which privileges will be granted. +- `on_all_tables_in_schema` (String) The fully qualified identifier for the schema for which the specified privilege will be granted for all tables. +- `on_database` (String) The fully qualified name of the database on which privileges will be granted. +- `on_schema` (String) The fully qualified name of the schema on which privileges will be granted. +- `on_table` (String) The fully qualified name of the table on which privileges will be granted. +- `on_tag` (String) The fully qualified name of the tag on which privileges will be granted. +- `on_view` (String) The fully qualified name of the view on which privileges will be granted. ### Read-Only diff --git a/examples/resources/snowflake_grant_privileges_to_share/resource.tf b/examples/resources/snowflake_grant_privileges_to_share/resource.tf index f070a0b5ba..a213e6cc8f 100644 --- a/examples/resources/snowflake_grant_privileges_to_share/resource.tf +++ b/examples/resources/snowflake_grant_privileges_to_share/resource.tf @@ -3,7 +3,7 @@ ################################## resource "snowflake_grant_privileges_to_share" "example" { - share_name = snowflake_share.example.name + to_share = snowflake_share.example.name privileges = ["USAGE"] on_database = snowflake_database.example.name } @@ -15,7 +15,7 @@ resource "snowflake_grant_privileges_to_share" "example" { ################################## resource "snowflake_grant_privileges_to_share" "example" { - share_name = snowflake_share.example.name + to_share = snowflake_share.example.name privileges = ["USAGE"] on_schema = "${snowflake_database.example.name}.${snowflake_schema.example.name}" } @@ -27,7 +27,7 @@ resource "snowflake_grant_privileges_to_share" "example" { ################################## resource "snowflake_grant_privileges_to_share" "example" { - share_name = snowflake_share.example.name + to_share = snowflake_share.example.name privileges = ["SELECT"] on_table = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_table.example.name}" } @@ -39,7 +39,7 @@ resource "snowflake_grant_privileges_to_share" "example" { ################################## resource "snowflake_grant_privileges_to_share" "example" { - share_name = snowflake_share.example.name + to_share = snowflake_share.example.name privileges = ["SELECT"] on_all_tables_in_schema = "${snowflake_database.example.name}.${snowflake_schema.example.name}" } @@ -51,7 +51,7 @@ resource "snowflake_grant_privileges_to_share" "example" { ################################## resource "snowflake_grant_privileges_to_share" "example" { - share_name = snowflake_share.example.name + to_share = snowflake_share.example.name privileges = ["READ"] on_tag = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_tag.example.name}" } @@ -63,7 +63,7 @@ resource "snowflake_grant_privileges_to_share" "example" { ################################## resource "snowflake_grant_privileges_to_share" "example" { - share_name = snowflake_share.example.name + to_share = snowflake_share.example.name privileges = ["SELECT"] on_view = "${snowflake_database.example.name}.${snowflake_schema.example.name}.${snowflake_view.example.name}" } diff --git a/pkg/resources/grant_privileges_to_share.go b/pkg/resources/grant_privileges_to_share.go index 64f9fabae3..bfdb865d41 100644 --- a/pkg/resources/grant_privileges_to_share.go +++ b/pkg/resources/grant_privileges_to_share.go @@ -13,29 +13,30 @@ import ( ) var grantPrivilegesToShareGrantExactlyOneOfValidation = []string{ - "database_name", - "schema_name", - // "function_name", - "table_name", - "all_tables_in_schema", - "tag_name", - "view_name", + "on_database", + "on_schema", + // TODO(SNOW-990811): "function_name", + "on_table", + "on_all_tables_in_schema", + "on_tag", + "on_view", } var grantPrivilegesToShareSchema = map[string]*schema.Schema{ - "share_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "The fully qualified name of the share on which privileges will be granted.", + "to_share": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The fully qualified name of the share on which privileges will be granted.", + ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](), }, "privileges": { Type: schema.TypeSet, Required: true, - Description: "The privileges to grant on the share.", + Description: "The privileges to grant on the share. See available list of privileges: https://docs.snowflake.com/en/sql-reference/sql/grant-privilege-share#syntax", Elem: &schema.Schema{Type: schema.TypeString}, }, - "database_name": { + "on_database": { Type: schema.TypeString, Optional: true, ForceNew: true, @@ -43,7 +44,7 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](), ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, }, - "schema_name": { + "on_schema": { Type: schema.TypeString, Optional: true, ForceNew: true, @@ -60,7 +61,7 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ // ValidateDiagFunc: IsValidIdentifier[sdk.FunctionIdentifier](), // ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, // }, - "table_name": { + "on_table": { Type: schema.TypeString, Optional: true, ForceNew: true, @@ -68,7 +69,7 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ ValidateDiagFunc: IsValidIdentifier[sdk.SchemaObjectIdentifier](), ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, }, - "all_tables_in_schema": { + "on_all_tables_in_schema": { Type: schema.TypeString, Optional: true, ForceNew: true, @@ -76,7 +77,7 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ ValidateDiagFunc: IsValidIdentifier[sdk.DatabaseObjectIdentifier](), ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, }, - "tag_name": { + "on_tag": { Type: schema.TypeString, Optional: true, ForceNew: true, @@ -84,7 +85,7 @@ var grantPrivilegesToShareSchema = map[string]*schema.Schema{ ValidateDiagFunc: IsValidIdentifier[sdk.SchemaObjectIdentifier](), ExactlyOneOf: grantPrivilegesToShareGrantExactlyOneOfValidation, }, - "view_name": { + "on_view": { Type: schema.TypeString, Optional: true, ForceNew: true, @@ -114,7 +115,7 @@ func ImportGrantPrivilegesToShare() func(ctx context.Context, d *schema.Resource if err != nil { return nil, err } - if err := d.Set("share_name", id.ShareName.Name()); err != nil { + if err := d.Set("to_share", id.ShareName.Name()); err != nil { return nil, err } if err := d.Set("privileges", id.Privileges); err != nil { @@ -123,31 +124,31 @@ func ImportGrantPrivilegesToShare() func(ctx context.Context, d *schema.Resource switch id.Kind { case OnDatabaseShareGrantKind: - if err := d.Set("database_name", id.Identifier.Name()); err != nil { + if err := d.Set("on_database", id.Identifier.Name()); err != nil { return nil, err } case OnSchemaShareGrantKind: - if err := d.Set("schema_name", id.Identifier.FullyQualifiedName()); err != nil { + if err := d.Set("on_schema", id.Identifier.FullyQualifiedName()); err != nil { return nil, err } - // case OnFunctionShareGrantKind: + // TODO(SNOW-990811) case OnFunctionShareGrantKind: // if err := d.Set("function_name", id.Identifier.FullyQualifiedName()); err != nil { // return nil, err // } case OnTableShareGrantKind: - if err := d.Set("table_name", id.Identifier.FullyQualifiedName()); err != nil { + if err := d.Set("on_table", id.Identifier.FullyQualifiedName()); err != nil { return nil, err } case OnAllTablesInSchemaShareGrantKind: - if err := d.Set("all_tables_in_schema", id.Identifier.FullyQualifiedName()); err != nil { + if err := d.Set("on_all_tables_in_schema", id.Identifier.FullyQualifiedName()); err != nil { return nil, err } case OnTagShareGrantKind: - if err := d.Set("tag_name", id.Identifier.FullyQualifiedName()); err != nil { + if err := d.Set("on_tag", id.Identifier.FullyQualifiedName()); err != nil { return nil, err } case OnViewShareGrantKind: - if err := d.Set("view_name", id.Identifier.FullyQualifiedName()); err != nil { + if err := d.Set("on_view", id.Identifier.FullyQualifiedName()); err != nil { return nil, err } } @@ -194,9 +195,9 @@ func UpdateGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, m } if d.HasChange("privileges") { - before, after := d.GetChange("privileges") - privilegesBeforeChange := expandStringList(before.(*schema.Set).List()) - privilegesAfterChange := expandStringList(after.(*schema.Set).List()) + oldPrivileges, newPrivileges := d.GetChange("privileges") + privilegesBeforeChange := expandStringList(oldPrivileges.(*schema.Set).List()) + privilegesAfterChange := expandStringList(newPrivileges.(*schema.Set).List()) var privilegesToAdd, privilegesToRemove []sdk.ObjectPrivilege @@ -328,14 +329,16 @@ func ReadGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, met if !slices.Contains(id.Privileges, grant.Privilege) { continue } - if grant.GranteeName.Name() == id.ShareName.Name() { // TODO: id.ShareName should be outside resource identifier (forgot the name) + if grant.GranteeName.Name() == id.ShareName.Name() { if grantedOn == grant.GrantedOn { privileges = append(privileges, grant.Privilege) } } } - // It's a pseudo-role, so we have to append it whenever it's specified in the configuration + // REFERENCE_USAGE is a special pseudo-privilege that you can grant or revoke, + // but it won't show up when querying privileges (not returned by show grants ... query). + // That's why we have to check it manually outside the loop and append it whenever it's specified in the configuration. if slices.Contains(id.Privileges, sdk.ObjectPrivilegeReferenceUsage.String()) { privileges = append(privileges, sdk.ObjectPrivilegeReferenceUsage.String()) } @@ -355,16 +358,16 @@ func ReadGrantPrivilegesToShare(ctx context.Context, d *schema.ResourceData, met func createGrantPrivilegesToShareIdFromSchema(d *schema.ResourceData) *GrantPrivilegesToShareId { id := new(GrantPrivilegesToShareId) - id.ShareName = sdk.NewAccountObjectIdentifier(d.Get("share_name").(string)) + id.ShareName = sdk.NewAccountObjectIdentifier(d.Get("to_share").(string)) id.Privileges = expandStringList(d.Get("privileges").(*schema.Set).List()) - databaseName, databaseNameOk := d.GetOk("database_name") - schemaName, schemaNameOk := d.GetOk("schema_name") - // functionName, functionNameOk := d.GetOk("function_name") - tableName, tableNameOk := d.GetOk("table_name") - allTablesInSchema, allTablesInSchemaOk := d.GetOk("all_tables_in_schema") - tagName, tagNameOk := d.GetOk("tag_name") - viewName, viewNameOk := d.GetOk("view_name") + databaseName, databaseNameOk := d.GetOk("on_database") + schemaName, schemaNameOk := d.GetOk("on_schema") + // TODO(SNOW-990811) functionName, functionNameOk := d.GetOk("function_name") + tableName, tableNameOk := d.GetOk("on_table") + allTablesInSchema, allTablesInSchemaOk := d.GetOk("on_all_tables_in_schema") + tagName, tagNameOk := d.GetOk("on_tag") + viewName, viewNameOk := d.GetOk("on_view") switch { case databaseNameOk: @@ -373,7 +376,7 @@ func createGrantPrivilegesToShareIdFromSchema(d *schema.ResourceData) *GrantPriv case schemaNameOk: id.Kind = OnSchemaShareGrantKind id.Identifier = sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(schemaName.(string)) - // case functionNameOk: + // TODO(SNOW-990811) case functionNameOk: // id.Kind = OnFunctionShareGrantKind // id.Identifier = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(functionName.(string)) case tableNameOk: @@ -405,20 +408,20 @@ func getObjectPrivilegesFromSchema(d *schema.ResourceData) []sdk.ObjectPrivilege func getShareGrantOn(d *schema.ResourceData) *sdk.ShareGrantOn { grantOn := new(sdk.ShareGrantOn) - databaseName, databaseNameOk := d.GetOk("database_name") - schemaName, schemaNameOk := d.GetOk("schema_name") - // functionName, functionNameOk := d.GetOk("table_name") - tableName, tableNameOk := d.GetOk("table_name") - allTablesInSchema, allTablesInSchemaOk := d.GetOk("all_tables_in_schema") - tagName, tagNameOk := d.GetOk("tag_name") - viewName, viewNameOk := d.GetOk("view_name") + databaseName, databaseNameOk := d.GetOk("on_database") + schemaName, schemaNameOk := d.GetOk("on_schema") + // TODO(SNOW-990811) functionName, functionNameOk := d.GetOk("on_function") + tableName, tableNameOk := d.GetOk("on_table") + allTablesInSchema, allTablesInSchemaOk := d.GetOk("on_all_tables_in_schema") + tagName, tagNameOk := d.GetOk("on_tag") + viewName, viewNameOk := d.GetOk("on_view") switch { case len(databaseName.(string)) > 0 && databaseNameOk: grantOn.Database = sdk.NewAccountObjectIdentifierFromFullyQualifiedName(databaseName.(string)) case len(schemaName.(string)) > 0 && schemaNameOk: grantOn.Schema = sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(schemaName.(string)) - // case len(functionName.(string)) > 0 && functionNameOk: + // TODO(SNOW-990811) case len(functionName.(string)) > 0 && functionNameOk: // grantOn.Function = sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(functionName.(string)) case len(tableName.(string)) > 0 && tableNameOk: grantOn.Table = &sdk.OnTable{ diff --git a/pkg/resources/grant_privileges_to_share_acceptance_test.go b/pkg/resources/grant_privileges_to_share_acceptance_test.go index 1dd636446f..35d52fc0e4 100644 --- a/pkg/resources/grant_privileges_to_share_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_share_acceptance_test.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "fmt" + "regexp" "strings" "testing" @@ -22,8 +23,8 @@ func TestAcc_GrantPrivilegesToShare_OnDatabase(t *testing.T) { configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ - "share_name": config.StringVariable(shareName.Name()), - "database": config.StringVariable(databaseName.Name()), + "to_share": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), } if withGrant { variables["privileges"] = config.ListVariable( @@ -45,10 +46,10 @@ func TestAcc_GrantPrivilegesToShare_OnDatabase(t *testing.T) { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), + resource.TestCheckResourceAttr(resourceName, "to_share", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeUsage.String()), - resource.TestCheckResourceAttr(resourceName, "database_name", databaseName.Name()), + resource.TestCheckResourceAttr(resourceName, "on_database", databaseName.Name()), ), }, { @@ -74,9 +75,9 @@ func TestAcc_GrantPrivilegesToShare_OnSchema(t *testing.T) { configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ - "share_name": config.StringVariable(shareName.Name()), - "database": config.StringVariable(databaseName.Name()), - "schema": config.StringVariable(schemaName.Name()), + "to_share": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + "schema": config.StringVariable(schemaName.Name()), } if withGrant { variables["privileges"] = config.ListVariable( @@ -98,10 +99,10 @@ func TestAcc_GrantPrivilegesToShare_OnSchema(t *testing.T) { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnSchema"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), + resource.TestCheckResourceAttr(resourceName, "to_share", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeUsage.String()), - resource.TestCheckResourceAttr(resourceName, "schema_name", schemaName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "on_schema", schemaName.FullyQualifiedName()), ), }, { @@ -120,6 +121,8 @@ func TestAcc_GrantPrivilegesToShare_OnSchema(t *testing.T) { }) } +// TODO(SNOW-1021686): Add on_function test + func TestAcc_GrantPrivilegesToShare_OnTable(t *testing.T) { databaseName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) schemaName := sdk.NewDatabaseObjectIdentifier(databaseName.Name(), strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) @@ -128,10 +131,10 @@ func TestAcc_GrantPrivilegesToShare_OnTable(t *testing.T) { configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ - "share_name": config.StringVariable(shareName.Name()), - "database": config.StringVariable(databaseName.Name()), - "schema": config.StringVariable(schemaName.Name()), - "table_name": config.StringVariable(tableName.Name()), + "to_share": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + "schema": config.StringVariable(schemaName.Name()), + "on_table": config.StringVariable(tableName.Name()), } if withGrant { variables["privileges"] = config.ListVariable( @@ -153,10 +156,10 @@ func TestAcc_GrantPrivilegesToShare_OnTable(t *testing.T) { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnTable"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), + resource.TestCheckResourceAttr(resourceName, "to_share", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeSelect.String()), - resource.TestCheckResourceAttr(resourceName, "table_name", tableName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "on_table", tableName.FullyQualifiedName()), ), }, { @@ -182,9 +185,9 @@ func TestAcc_GrantPrivilegesToShare_OnAllTablesInSchema(t *testing.T) { configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ - "share_name": config.StringVariable(shareName.Name()), - "database": config.StringVariable(databaseName.Name()), - "schema": config.StringVariable(schemaName.Name()), + "to_share": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + "schema": config.StringVariable(schemaName.Name()), } if withGrant { variables["privileges"] = config.ListVariable( @@ -206,10 +209,10 @@ func TestAcc_GrantPrivilegesToShare_OnAllTablesInSchema(t *testing.T) { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), + resource.TestCheckResourceAttr(resourceName, "to_share", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeSelect.String()), - resource.TestCheckResourceAttr(resourceName, "all_tables_in_schema", schemaName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "on_all_tables_in_schema", schemaName.FullyQualifiedName()), ), }, { @@ -237,11 +240,11 @@ func TestAcc_GrantPrivilegesToShare_OnView(t *testing.T) { configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ - "share_name": config.StringVariable(shareName.Name()), - "database": config.StringVariable(databaseName.Name()), - "schema": config.StringVariable(schemaName.Name()), - "table_name": config.StringVariable(tableName.Name()), - "view_name": config.StringVariable(viewName.Name()), + "to_share": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + "schema": config.StringVariable(schemaName.Name()), + "on_table": config.StringVariable(tableName.Name()), + "on_view": config.StringVariable(viewName.Name()), } if withGrant { variables["privileges"] = config.ListVariable( @@ -263,10 +266,10 @@ func TestAcc_GrantPrivilegesToShare_OnView(t *testing.T) { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnView"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), + resource.TestCheckResourceAttr(resourceName, "to_share", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeSelect.String()), - resource.TestCheckResourceAttr(resourceName, "view_name", viewName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "on_view", viewName.FullyQualifiedName()), ), }, { @@ -293,10 +296,10 @@ func TestAcc_GrantPrivilegesToShare_OnTag(t *testing.T) { configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ - "share_name": config.StringVariable(shareName.Name()), - "database": config.StringVariable(databaseName.Name()), - "schema": config.StringVariable(schemaName.Name()), - "tag_name": config.StringVariable(tagName.Name()), + "to_share": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + "schema": config.StringVariable(schemaName.Name()), + "on_tag": config.StringVariable(tagName.Name()), } if withGrant { variables["privileges"] = config.ListVariable( @@ -318,10 +321,10 @@ func TestAcc_GrantPrivilegesToShare_OnTag(t *testing.T) { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnTag"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), + resource.TestCheckResourceAttr(resourceName, "to_share", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeRead.String()), - resource.TestCheckResourceAttr(resourceName, "tag_name", tagName.FullyQualifiedName()), + resource.TestCheckResourceAttr(resourceName, "on_tag", tagName.FullyQualifiedName()), ), }, { @@ -346,8 +349,8 @@ func TestAcc_GrantPrivilegesToShare_OnPrivilegeUpdate(t *testing.T) { configVariables := func(withGrant bool, privileges []sdk.ObjectPrivilege) config.Variables { variables := config.Variables{ - "share_name": config.StringVariable(shareName.Name()), - "database": config.StringVariable(databaseName.Name()), + "to_share": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), } if withGrant { if len(privileges) > 0 { @@ -375,10 +378,10 @@ func TestAcc_GrantPrivilegesToShare_OnPrivilegeUpdate(t *testing.T) { sdk.ObjectPrivilegeReferenceUsage, }), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), + resource.TestCheckResourceAttr(resourceName, "to_share", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeReferenceUsage.String()), - resource.TestCheckResourceAttr(resourceName, "database_name", databaseName.Name()), + resource.TestCheckResourceAttr(resourceName, "on_database", databaseName.Name()), ), }, { @@ -387,10 +390,10 @@ func TestAcc_GrantPrivilegesToShare_OnPrivilegeUpdate(t *testing.T) { sdk.ObjectPrivilegeUsage, }), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), + resource.TestCheckResourceAttr(resourceName, "to_share", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeUsage.String()), - resource.TestCheckResourceAttr(resourceName, "database_name", databaseName.Name()), + resource.TestCheckResourceAttr(resourceName, "on_database", databaseName.Name()), ), }, { @@ -417,8 +420,8 @@ func TestAcc_GrantPrivilegesToShare_OnDatabaseWithReferenceUsagePrivilege(t *tes configVariables := func(withGrant bool) config.Variables { variables := config.Variables{ - "share_name": config.StringVariable(shareName.Name()), - "database": config.StringVariable(databaseName.Name()), + "to_share": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), } if withGrant { variables["privileges"] = config.ListVariable( @@ -440,10 +443,10 @@ func TestAcc_GrantPrivilegesToShare_OnDatabaseWithReferenceUsagePrivilege(t *tes ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase"), ConfigVariables: configVariables(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "share_name", shareName.Name()), + resource.TestCheckResourceAttr(resourceName, "to_share", shareName.Name()), resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"), resource.TestCheckResourceAttr(resourceName, "privileges.0", sdk.ObjectPrivilegeReferenceUsage.String()), - resource.TestCheckResourceAttr(resourceName, "database_name", databaseName.Name()), + resource.TestCheckResourceAttr(resourceName, "on_database", databaseName.Name()), ), }, { @@ -462,6 +465,61 @@ func TestAcc_GrantPrivilegesToShare_OnDatabaseWithReferenceUsagePrivilege(t *tes }) } +func TestAcc_GrantPrivilegesToShare_NoPrivileges(t *testing.T) { + databaseName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + + configVariables := func() config.Variables { + return config.Variables{ + "to_share": config.StringVariable(shareName.Name()), + "database": config.StringVariable(databaseName.Name()), + } + } + + 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{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/OnDatabase_NoPrivileges"), + ConfigVariables: configVariables(), + ExpectError: regexp.MustCompile(`The argument "privileges" is required, but no definition was found.`), + }, + }, + }) +} + +func TestAcc_GrantPrivilegesToShare_NoOnOption(t *testing.T) { + shareName := sdk.NewAccountObjectIdentifier(strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))) + + configVariables := func() config.Variables { + return config.Variables{ + "to_share": config.StringVariable(shareName.Name()), + "privileges": config.ListVariable( + config.StringVariable(sdk.ObjectPrivilegeReferenceUsage.String()), + ), + } + } + + 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{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToShare/NoOnOption"), + ConfigVariables: configVariables(), + ExpectError: regexp.MustCompile(`Invalid combination of arguments`), + }, + }, + }) +} + func testAccCheckSharePrivilegesRevoked() func(*terraform.State) error { return func(state *terraform.State) error { for _, rs := range state.RootModule().Resources { @@ -472,7 +530,7 @@ func testAccCheckSharePrivilegesRevoked() func(*terraform.State) error { client := sdk.NewClientFromDB(db) ctx := context.Background() - id := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(rs.Primary.Attributes["share_name"]) + id := sdk.NewExternalObjectIdentifierFromFullyQualifiedName(rs.Primary.Attributes["to_share"]) grants, err := client.Grants.Show(ctx, &sdk.ShowGrantOptions{ To: &sdk.ShowGrantsTo{ Share: sdk.NewAccountObjectIdentifier(id.Name()), diff --git a/pkg/resources/grant_privileges_to_share_identifier.go b/pkg/resources/grant_privileges_to_share_identifier.go index e287d5884d..744facc1b2 100644 --- a/pkg/resources/grant_privileges_to_share_identifier.go +++ b/pkg/resources/grant_privileges_to_share_identifier.go @@ -79,7 +79,7 @@ func ParseGrantPrivilegesToShareId(idString string) (GrantPrivilegesToShareId, e getExpectedIdentifierRepresentationFromParam(id), ) } - case OnTableShareGrantKind, OnViewShareGrantKind, OnTagShareGrantKind: // , OnFunctionShareGrantKind: + case OnTableShareGrantKind, OnViewShareGrantKind, OnTagShareGrantKind: // TODO(SNOW-1021686) , OnFunctionShareGrantKind: if typedIdentifier, ok := id.(sdk.SchemaObjectIdentifier); ok { grantPrivilegesToShareId.Identifier = typedIdentifier } else { diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/NoOnOption/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/NoOnOption/test.tf new file mode 100644 index 0000000000..12a5632170 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/NoOnOption/test.tf @@ -0,0 +1,8 @@ +resource "snowflake_share" "test" { + name = var.to_share +} + +resource "snowflake_grant_privileges_to_share" "test" { + to_share = snowflake_share.test.name + privileges = var.privileges +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/NoOnOption/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/NoOnOption/variables.tf new file mode 100644 index 0000000000..cf7961587f --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/NoOnOption/variables.tf @@ -0,0 +1,7 @@ +variable "to_share" { + type = string +} + +variable "privileges" { + type = list(string) +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf index 1d5fafef9c..1805c18714 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/test.tf @@ -8,17 +8,17 @@ resource "snowflake_schema" "test" { } resource "snowflake_share" "test" { - name = var.share_name + name = var.to_share } resource "snowflake_grant_privileges_to_share" "test_setup" { - share_name = snowflake_share.test.name - privileges = ["USAGE"] - database_name = snowflake_database.test.name + to_share = snowflake_share.test.name + privileges = ["USAGE"] + on_database = snowflake_database.test.name } resource "snowflake_grant_privileges_to_share" "test" { - share_name = snowflake_share.test.name - privileges = var.privileges - all_tables_in_schema = "\"${snowflake_schema.test.database}\".\"${snowflake_schema.test.name}\"" + to_share = snowflake_share.test.name + privileges = var.privileges + on_all_tables_in_schema = "\"${snowflake_schema.test.database}\".\"${snowflake_schema.test.name}\"" } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/variables.tf index b44e81d500..f0753857d4 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema/variables.tf @@ -1,4 +1,4 @@ -variable "share_name" { +variable "to_share" { type = string } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/test.tf index e402a617d4..beb3470c6a 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/test.tf @@ -8,5 +8,5 @@ resource "snowflake_schema" "test" { } resource "snowflake_share" "test" { - name = var.share_name + name = var.to_share } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/variables.tf index ba53fb83e8..f5a1391a49 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnAllTablesInSchema_NoGrant/variables.tf @@ -1,4 +1,4 @@ -variable "share_name" { +variable "to_share" { type = string } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf index 43f2f988fc..b4fa3ebc17 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/test.tf @@ -3,11 +3,11 @@ resource "snowflake_database" "test" { } resource "snowflake_share" "test" { - name = var.share_name + name = var.to_share } resource "snowflake_grant_privileges_to_share" "test" { - share_name = snowflake_share.test.name - privileges = var.privileges - database_name = snowflake_database.test.name + to_share = snowflake_share.test.name + privileges = var.privileges + on_database = snowflake_database.test.name } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/variables.tf index 84db64fb9b..8f3b5923f0 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase/variables.tf @@ -1,4 +1,4 @@ -variable "share_name" { +variable "to_share" { type = string } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/test.tf index 0e0031f5ec..50bdc08e8d 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/test.tf @@ -3,5 +3,5 @@ resource "snowflake_database" "test" { } resource "snowflake_share" "test" { - name = var.share_name + name = var.to_share } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/variables.tf index 45e63e3a7d..405daac5da 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoGrant/variables.tf @@ -1,4 +1,4 @@ -variable "share_name" { +variable "to_share" { type = string } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoPrivileges/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoPrivileges/test.tf new file mode 100644 index 0000000000..6026bc53b1 --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoPrivileges/test.tf @@ -0,0 +1,12 @@ +resource "snowflake_database" "test" { + name = var.database +} + +resource "snowflake_share" "test" { + name = var.to_share +} + +resource "snowflake_grant_privileges_to_share" "test" { + to_share = snowflake_share.test.name + on_database = snowflake_database.test.name +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoPrivileges/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoPrivileges/variables.tf new file mode 100644 index 0000000000..405daac5da --- /dev/null +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnDatabase_NoPrivileges/variables.tf @@ -0,0 +1,7 @@ +variable "to_share" { + type = string +} + +variable "database" { + type = string +} diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf index 0bfea3adfe..6fedcefe97 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/test.tf @@ -8,17 +8,17 @@ resource "snowflake_schema" "test" { } resource "snowflake_share" "test" { - name = var.share_name + name = var.to_share } resource "snowflake_grant_privileges_to_share" "test_setup" { - share_name = snowflake_share.test.name - privileges = ["USAGE"] - database_name = snowflake_database.test.name + to_share = snowflake_share.test.name + privileges = ["USAGE"] + on_database = snowflake_database.test.name } resource "snowflake_grant_privileges_to_share" "test" { - share_name = snowflake_share.test.name - privileges = var.privileges - schema_name = "\"${snowflake_schema.test.database}\".\"${snowflake_schema.test.name}\"" + to_share = snowflake_share.test.name + privileges = var.privileges + on_schema = "\"${snowflake_schema.test.database}\".\"${snowflake_schema.test.name}\"" } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/variables.tf index b44e81d500..f0753857d4 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema/variables.tf @@ -1,4 +1,4 @@ -variable "share_name" { +variable "to_share" { type = string } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/test.tf index e402a617d4..beb3470c6a 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/test.tf @@ -8,5 +8,5 @@ resource "snowflake_schema" "test" { } resource "snowflake_share" "test" { - name = var.share_name + name = var.to_share } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/variables.tf index ba53fb83e8..f5a1391a49 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnSchema_NoGrant/variables.tf @@ -1,4 +1,4 @@ -variable "share_name" { +variable "to_share" { type = string } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf index d833622e53..58e3beddbf 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/test.tf @@ -8,7 +8,7 @@ resource "snowflake_schema" "test" { } resource "snowflake_table" "test" { - name = var.table_name + name = var.on_table database = snowflake_database.test.name schema = snowflake_schema.test.name column { @@ -18,17 +18,17 @@ resource "snowflake_table" "test" { } resource "snowflake_share" "test" { - name = var.share_name + name = var.to_share } resource "snowflake_grant_privileges_to_share" "test_setup" { - share_name = snowflake_share.test.name - privileges = ["USAGE"] - database_name = snowflake_database.test.name + to_share = snowflake_share.test.name + privileges = ["USAGE"] + on_database = snowflake_database.test.name } resource "snowflake_grant_privileges_to_share" "test" { - share_name = snowflake_share.test.name + to_share = snowflake_share.test.name privileges = var.privileges - table_name = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_table.test.name}\"" + on_table = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_table.test.name}\"" } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/variables.tf index f6dd8e75b7..c4968d159c 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable/variables.tf @@ -1,4 +1,4 @@ -variable "share_name" { +variable "to_share" { type = string } @@ -14,6 +14,6 @@ variable "schema" { type = string } -variable "table_name" { +variable "on_table" { type = string } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/test.tf index f57de76855..9b65cdd148 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/test.tf @@ -8,7 +8,7 @@ resource "snowflake_schema" "test" { } resource "snowflake_table" "test" { - name = var.table_name + name = var.on_table database = snowflake_database.test.name schema = snowflake_schema.test.name column { @@ -18,5 +18,5 @@ resource "snowflake_table" "test" { } resource "snowflake_share" "test" { - name = var.share_name + name = var.to_share } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/variables.tf index d5ef54ae92..29606a0a04 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTable_NoGrant/variables.tf @@ -1,4 +1,4 @@ -variable "share_name" { +variable "to_share" { type = string } @@ -10,6 +10,6 @@ variable "schema" { type = string } -variable "table_name" { +variable "on_table" { type = string } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf index 59543b37c4..728b944946 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/test.tf @@ -8,23 +8,23 @@ resource "snowflake_schema" "test" { } resource "snowflake_tag" "test" { - name = var.tag_name + name = var.on_tag database = snowflake_database.test.name schema = snowflake_schema.test.name } resource "snowflake_share" "test" { - name = var.share_name + name = var.to_share } resource "snowflake_grant_privileges_to_share" "test_setup" { - share_name = snowflake_share.test.name - privileges = ["USAGE"] - database_name = snowflake_database.test.name + to_share = snowflake_share.test.name + privileges = ["USAGE"] + on_database = snowflake_database.test.name } resource "snowflake_grant_privileges_to_share" "test" { - share_name = snowflake_share.test.name + to_share = snowflake_share.test.name privileges = var.privileges - tag_name = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_tag.test.name}\"" + on_tag = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_tag.test.name}\"" } \ No newline at end of file diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/variables.tf index f5575b9359..336fc788e2 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag/variables.tf @@ -1,4 +1,4 @@ -variable "share_name" { +variable "to_share" { type = string } @@ -14,6 +14,6 @@ variable "schema" { type = string } -variable "tag_name" { +variable "on_tag" { type = string } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/test.tf index e15ad73344..58f711ee44 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/test.tf @@ -8,11 +8,11 @@ resource "snowflake_schema" "test" { } resource "snowflake_tag" "test" { - name = var.tag_name + name = var.on_tag database = snowflake_database.test.name schema = snowflake_schema.test.name } resource "snowflake_share" "test" { - name = var.share_name + name = var.to_share } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/variables.tf index 6f7e3979ae..af41461f2a 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnTag_NoGrant/variables.tf @@ -1,4 +1,4 @@ -variable "share_name" { +variable "to_share" { type = string } @@ -10,6 +10,6 @@ variable "schema" { type = string } -variable "tag_name" { +variable "on_tag" { type = string } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf index 60e0d393ec..5c504320f9 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/test.tf @@ -8,7 +8,7 @@ resource "snowflake_schema" "test" { } resource "snowflake_table" "test" { - name = var.table_name + name = var.on_table database = snowflake_database.test.name schema = snowflake_schema.test.name column { @@ -18,7 +18,7 @@ resource "snowflake_table" "test" { } resource "snowflake_view" "test" { - name = var.view_name + name = var.on_view database = snowflake_database.test.name schema = snowflake_schema.test.name is_secure = true @@ -26,17 +26,17 @@ resource "snowflake_view" "test" { } resource "snowflake_share" "test" { - name = var.share_name + name = var.to_share } resource "snowflake_grant_privileges_to_share" "test_setup" { - share_name = snowflake_share.test.name - privileges = ["USAGE"] - database_name = snowflake_database.test.name + to_share = snowflake_share.test.name + privileges = ["USAGE"] + on_database = snowflake_database.test.name } resource "snowflake_grant_privileges_to_share" "test" { - share_name = snowflake_share.test.name + to_share = snowflake_share.test.name privileges = var.privileges - view_name = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_view.test.name}\"" + on_view = "\"${snowflake_database.test.name}\".\"${snowflake_schema.test.name}\".\"${snowflake_view.test.name}\"" } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/variables.tf index 20162fb361..84cd501eb9 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView/variables.tf @@ -1,4 +1,4 @@ -variable "share_name" { +variable "to_share" { type = string } @@ -14,10 +14,10 @@ variable "schema" { type = string } -variable "table_name" { +variable "on_table" { type = string } -variable "view_name" { +variable "on_view" { type = string } diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/test.tf index 16cc8ac15f..91137560e5 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/test.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/test.tf @@ -8,7 +8,7 @@ resource "snowflake_schema" "test" { } resource "snowflake_table" "test" { - name = var.table_name + name = var.on_table database = snowflake_database.test.name schema = snowflake_schema.test.name column { @@ -18,7 +18,7 @@ resource "snowflake_table" "test" { } resource "snowflake_view" "test" { - name = var.view_name + name = var.on_view database = snowflake_database.test.name schema = snowflake_schema.test.name is_secure = true diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/variables.tf index 7a36d7147d..6800bf8359 100644 --- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/variables.tf +++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToShare/OnView_NoGrant/variables.tf @@ -1,4 +1,4 @@ -variable "share_name" { +variable "to_share" { type = string } @@ -10,10 +10,10 @@ variable "schema" { type = string } -variable "table_name" { +variable "on_table" { type = string } -variable "view_name" { +variable "on_view" { type = string } diff --git a/pkg/sdk/grants_test.go b/pkg/sdk/grants_test.go index c7d23c1cb5..69ccf6b44c 100644 --- a/pkg/sdk/grants_test.go +++ b/pkg/sdk/grants_test.go @@ -864,23 +864,8 @@ func TestRevokePrivilegeFromShare(t *testing.T) { }, from: id, } - assertOptsValidAndSQLEquals(t, opts, "REVOKE READ ON TAG \"database-name\".\"schema-name\".\"tag-name\" FROM SHARE %s", id.FullyQualifiedName()) - }) - - // TODO: This one throws an error - // t.Run("on all views", func(t *testing.T) { - // otherID := RandomDatabaseObjectIdentifier() - // opts := &revokePrivilegeFromShareOptions{ - // privilege: ObjectPrivilegeUsage, - // On: &RevokePrivilegeFromShareOn{ - // View: &OnView{ - // AllInSchema: otherID, - // }, - // }, - // from: id, - // } - // assertOptsValidAndSQLEquals(t, opts, "REVOKE USAGE ON ALL VIEWS IN SCHEMA %s FROM SHARE %s", otherID.FullyQualifiedName(), id.FullyQualifiedName()) - // }) + assertOptsValidAndSQLEquals(t, opts, "REVOKE READ ON TAG \"database-name\".\"schema-name\".\"tag-name\" FROM SHARE %s", id.FullyQualifiedName()) + }) } func TestGrants_GrantOwnership(t *testing.T) { From 7665938ac46057c1487c19e015212f39a87c8e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Thu, 1 Feb 2024 10:44:18 +0100 Subject: [PATCH 7/7] add documentation --- docs/resources/grant_privileges_to_share.md | 34 ++++++++++++ .../grant_privileges_to_share.md.tmpl | 53 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 templates/resources/grant_privileges_to_share.md.tmpl diff --git a/docs/resources/grant_privileges_to_share.md b/docs/resources/grant_privileges_to_share.md index ea241bddd6..0beac830ba 100644 --- a/docs/resources/grant_privileges_to_share.md +++ b/docs/resources/grant_privileges_to_share.md @@ -6,6 +6,8 @@ description: |- --- +~> **Note** This is a preview resource. It's ready for general use. In case of any errors, please file an issue in our GitHub repository. + # snowflake_grant_privileges_to_share (Resource) @@ -106,3 +108,35 @@ resource "snowflake_grant_privileges_to_share" "example" { ### Read-Only - `id` (String) The ID of this resource. + +## Import + +~> **Note** All the ..._name parts should be fully qualified names, e.g. for database object it is `"".""` + +Import is supported using the following syntax: + +`terraform import "|||"` + +where: +- share_name - fully qualified identifier +- privileges - list of privileges, comma separated. See the available privileges for given object types: https://docs.snowflake.com/en/sql-reference/sql/grant-privilege-share#syntax +- grant_type - enum +- grant_identifier - fully qualified identifier + +### OnDatabase +`terraform import "||OnDatabase|"` + +### OnSchema +`terraform import "||OnSchema|."` + +### OnTable +`terraform import "||OnTable|.."` + +### OnSchema +`terraform import "||OnAllTablesInSchema|."` + +### OnTag +`terraform import "||OnTag|.."` + +### OnView +`terraform import "||OnView|.."` diff --git a/templates/resources/grant_privileges_to_share.md.tmpl b/templates/resources/grant_privileges_to_share.md.tmpl new file mode 100644 index 0000000000..f2639461b1 --- /dev/null +++ b/templates/resources/grant_privileges_to_share.md.tmpl @@ -0,0 +1,53 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +~> **Note** This is a preview resource. It's ready for general use. In case of any errors, please file an issue in our GitHub repository. + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +{{ if .HasExample -}} +## Example Usage + +{{ tffile (printf "examples/resources/%s/resource.tf" .Name)}} +{{- end }} + +{{ .SchemaMarkdown | trimspace }} + +## Import + +~> **Note** All the ..._name parts should be fully qualified names, e.g. for database object it is `"".""` + +Import is supported using the following syntax: + +`terraform import "|||"` + +where: +- share_name - fully qualified identifier +- privileges - list of privileges, comma separated. See the available privileges for given object types: https://docs.snowflake.com/en/sql-reference/sql/grant-privilege-share#syntax +- grant_type - enum +- grant_identifier - fully qualified identifier + +### OnDatabase +`terraform import "||OnDatabase|"` + +### OnSchema +`terraform import "||OnSchema|."` + +### OnTable +`terraform import "||OnTable|.."` + +### OnSchema +`terraform import "||OnAllTablesInSchema|."` + +### OnTag +`terraform import "||OnTag|.."` + +### OnView +`terraform import "||OnView|.."`