From 4f4c4a4fcb91725a55726c03429745bbf95fd642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Cie=C5=9Blak?= Date: Mon, 11 Dec 2023 16:18:05 +0100 Subject: [PATCH] fix: Add missing parameters (#2250) --- docs/resources/grant_privileges_to_role.md | 8 ++-- pkg/resources/grant_privileges_to_role.go | 14 +++++-- ...rant_privileges_to_role_acceptance_test.go | 38 +++++++++++++++++++ pkg/sdk/grants.go | 1 + pkg/sdk/grants_test.go | 16 ++++++++ pkg/sdk/grants_validations.go | 4 +- pkg/sdk/object_types.go | 6 +++ pkg/sdk/privileges.go | 15 ++++++++ 8 files changed, 92 insertions(+), 10 deletions(-) diff --git a/docs/resources/grant_privileges_to_role.md b/docs/resources/grant_privileges_to_role.md index 9fdc69a5c2..6bfeb3ccbe 100644 --- a/docs/resources/grant_privileges_to_role.md +++ b/docs/resources/grant_privileges_to_role.md @@ -199,7 +199,7 @@ resource "snowflake_grant_privileges_to_role" "g14" { Required: - `object_name` (String) The fully qualified name of the object on which privileges will be granted. -- `object_type` (String) The object type of the account object on which privileges will be granted. Valid values are: USER | RESOURCE MONITOR | WAREHOUSE | DATABASE | INTEGRATION | FAILOVER GROUP | REPLICATION GROUP +- `object_type` (String) The object type of the account object on which privileges will be granted. Valid values are: USER | RESOURCE MONITOR | WAREHOUSE | DATABASE | INTEGRATION | FAILOVER GROUP | REPLICATION GROUP | EXTERNAL VOLUME @@ -220,14 +220,14 @@ Optional: - `all` (Block List, Max: 1) Configures the privilege to be granted on all objects in eihter a database or schema. (see [below for nested schema](#nestedblock--on_schema_object--all)) - `future` (Block List, Max: 1) Configures the privilege to be granted on future objects in eihter a database or schema. (see [below for nested schema](#nestedblock--on_schema_object--future)) - `object_name` (String) The fully qualified name of the object on which privileges will be granted. -- `object_type` (String) The object type of the schema object on which privileges will be granted. Valid values are: ALERT | DYNAMIC TABLE | EVENT TABLE | FILE FORMAT | FUNCTION | PROCEDURE | SECRET | SEQUENCE | PIPE | MASKING POLICY | PASSWORD POLICY | ROW ACCESS POLICY | SESSION POLICY | TAG | STAGE | STREAM | TABLE | EXTERNAL TABLE | TASK | VIEW | MATERIALIZED VIEW +- `object_type` (String) The object type of the schema object on which privileges will be granted. Valid values are: ALERT | DYNAMIC TABLE | EVENT TABLE | FILE FORMAT | FUNCTION | ICEBERG TABLE | PROCEDURE | SECRET | SEQUENCE | PIPE | MASKING POLICY | PASSWORD POLICY | ROW ACCESS POLICY | SESSION POLICY | TAG | STAGE | STREAM | TABLE | EXTERNAL TABLE | TASK | VIEW | MATERIALIZED VIEW ### Nested Schema for `on_schema_object.all` Required: -- `object_type_plural` (String) The plural object type of the schema object on which privileges will be granted. Valid values are: ALERTS | DYNAMIC TABLES | EVENT TABLES | FILE FORMATS | FUNCTIONS | PROCEDURES | SECRETS | SEQUENCES | PIPES | MASKING POLICIES | PASSWORD POLICIES | ROW ACCESS POLICIES | SESSION POLICIES | TAGS | STAGES | STREAMS | TABLES | EXTERNAL TABLES | TASKS | VIEWS | MATERIALIZED VIEWS +- `object_type_plural` (String) The plural object type of the schema object on which privileges will be granted. Valid values are: ALERTS | DYNAMIC TABLES | EVENT TABLES | FILE FORMATS | FUNCTIONS | ICEBERG TABLES | PROCEDURES | SECRETS | SEQUENCES | PIPES | MASKING POLICIES | PASSWORD POLICIES | ROW ACCESS POLICIES | SESSION POLICIES | TAGS | STAGES | STREAMS | TABLES | EXTERNAL TABLES | TASKS | VIEWS | MATERIALIZED VIEWS Optional: @@ -240,7 +240,7 @@ Optional: Required: -- `object_type_plural` (String) The plural object type of the schema object on which privileges will be granted. Valid values are: ALERTS | DYNAMIC TABLES | EVENT TABLES | FILE FORMATS | FUNCTIONS | PROCEDURES | SECRETS | SEQUENCES | PIPES | MASKING POLICIES | PASSWORD POLICIES | ROW ACCESS POLICIES | SESSION POLICIES | TAGS | STAGES | STREAMS | TABLES | EXTERNAL TABLES | TASKS | VIEWS | MATERIALIZED VIEWS +- `object_type_plural` (String) The plural object type of the schema object on which privileges will be granted. Valid values are: ALERTS | DYNAMIC TABLES | EVENT TABLES | FILE FORMATS | FUNCTIONS | ICEBERG TABLES | PROCEDURES | SECRETS | SEQUENCES | PIPES | MASKING POLICIES | PASSWORD POLICIES | ROW ACCESS POLICIES | SESSION POLICIES | TAGS | STAGES | STREAMS | TABLES | EXTERNAL TABLES | TASKS | VIEWS | MATERIALIZED VIEWS Optional: diff --git a/pkg/resources/grant_privileges_to_role.go b/pkg/resources/grant_privileges_to_role.go index e8a08d4d1c..33078163bc 100644 --- a/pkg/resources/grant_privileges_to_role.go +++ b/pkg/resources/grant_privileges_to_role.go @@ -56,7 +56,7 @@ var grantPrivilegesToRoleSchema = map[string]*schema.Schema{ "object_type": { Type: schema.TypeString, Required: true, - Description: "The object type of the account object on which privileges will be granted. Valid values are: USER | RESOURCE MONITOR | WAREHOUSE | DATABASE | INTEGRATION | FAILOVER GROUP | REPLICATION GROUP", + Description: "The object type of the account object on which privileges will be granted. Valid values are: USER | RESOURCE MONITOR | WAREHOUSE | DATABASE | INTEGRATION | FAILOVER GROUP | REPLICATION GROUP | EXTERNAL VOLUME", ValidateFunc: validation.StringInSlice([]string{ "USER", "RESOURCE MONITOR", @@ -65,6 +65,7 @@ var grantPrivilegesToRoleSchema = map[string]*schema.Schema{ "INTEGRATION", "FAILOVER GROUP", "REPLICATION GROUP", + "EXTERNAL VOLUME", }, true), }, "object_name": { @@ -120,7 +121,7 @@ var grantPrivilegesToRoleSchema = map[string]*schema.Schema{ "object_type": { Type: schema.TypeString, Optional: true, - Description: "The object type of the schema object on which privileges will be granted. Valid values are: ALERT | DYNAMIC TABLE | EVENT TABLE | FILE FORMAT | FUNCTION | PROCEDURE | SECRET | SEQUENCE | PIPE | MASKING POLICY | PASSWORD POLICY | ROW ACCESS POLICY | SESSION POLICY | TAG | STAGE | STREAM | TABLE | EXTERNAL TABLE | TASK | VIEW | MATERIALIZED VIEW", + Description: "The object type of the schema object on which privileges will be granted. Valid values are: ALERT | DYNAMIC TABLE | EVENT TABLE | FILE FORMAT | FUNCTION | ICEBERG TABLE | PROCEDURE | SECRET | SEQUENCE | PIPE | MASKING POLICY | PASSWORD POLICY | ROW ACCESS POLICY | SESSION POLICY | TAG | STAGE | STREAM | TABLE | EXTERNAL TABLE | TASK | VIEW | MATERIALIZED VIEW", RequiredWith: []string{"on_schema_object.0.object_name"}, ConflictsWith: []string{"on_schema_object.0.all", "on_schema_object.0.future"}, ForceNew: true, @@ -130,6 +131,7 @@ var grantPrivilegesToRoleSchema = map[string]*schema.Schema{ "EVENT TABLE", "FILE FORMAT", "FUNCTION", + "ICEBERG TABLE", "PROCEDURE", "SECRET", "SEQUENCE", @@ -167,7 +169,7 @@ var grantPrivilegesToRoleSchema = map[string]*schema.Schema{ "object_type_plural": { Type: schema.TypeString, Required: true, - Description: "The plural object type of the schema object on which privileges will be granted. Valid values are: ALERTS | DYNAMIC TABLES | EVENT TABLES | FILE FORMATS | FUNCTIONS | PROCEDURES | SECRETS | SEQUENCES | PIPES | MASKING POLICIES | PASSWORD POLICIES | ROW ACCESS POLICIES | SESSION POLICIES | TAGS | STAGES | STREAMS | TABLES | EXTERNAL TABLES | TASKS | VIEWS | MATERIALIZED VIEWS", + Description: "The plural object type of the schema object on which privileges will be granted. Valid values are: ALERTS | DYNAMIC TABLES | EVENT TABLES | FILE FORMATS | FUNCTIONS | ICEBERG TABLES | PROCEDURES | SECRETS | SEQUENCES | PIPES | MASKING POLICIES | PASSWORD POLICIES | ROW ACCESS POLICIES | SESSION POLICIES | TAGS | STAGES | STREAMS | TABLES | EXTERNAL TABLES | TASKS | VIEWS | MATERIALIZED VIEWS", ForceNew: true, ValidateFunc: validation.StringInSlice([]string{ "ALERTS", @@ -175,6 +177,7 @@ var grantPrivilegesToRoleSchema = map[string]*schema.Schema{ "EVENT TABLES", "FILE FORMATS", "FUNCTIONS", + "ICEBERG TABLES", "PROCEDURES", "SECRETS", "SEQUENCES", @@ -221,7 +224,7 @@ var grantPrivilegesToRoleSchema = map[string]*schema.Schema{ "object_type_plural": { Type: schema.TypeString, Required: true, - Description: "The plural object type of the schema object on which privileges will be granted. Valid values are: ALERTS | DYNAMIC TABLES | EVENT TABLES | FILE FORMATS | FUNCTIONS | PROCEDURES | SECRETS | SEQUENCES | PIPES | MASKING POLICIES | PASSWORD POLICIES | ROW ACCESS POLICIES | SESSION POLICIES | TAGS | STAGES | STREAMS | TABLES | EXTERNAL TABLES | TASKS | VIEWS | MATERIALIZED VIEWS", + Description: "The plural object type of the schema object on which privileges will be granted. Valid values are: ALERTS | DYNAMIC TABLES | EVENT TABLES | FILE FORMATS | FUNCTIONS | ICEBERG TABLES | PROCEDURES | SECRETS | SEQUENCES | PIPES | MASKING POLICIES | PASSWORD POLICIES | ROW ACCESS POLICIES | SESSION POLICIES | TAGS | STAGES | STREAMS | TABLES | EXTERNAL TABLES | TASKS | VIEWS | MATERIALIZED VIEWS", ForceNew: true, ValidateFunc: validation.StringInSlice([]string{ "ALERTS", @@ -229,6 +232,7 @@ var grantPrivilegesToRoleSchema = map[string]*schema.Schema{ "EVENT TABLES", "FILE FORMATS", "FUNCTIONS", + "ICEBERG TABLES", "PROCEDURES", "SECRETS", "SEQUENCES", @@ -730,6 +734,8 @@ func configureAccountRoleGrantPrivilegeOptions(d *schema.ResourceData, privilege on.AccountObject.User = &objectID case sdk.ObjectTypeWarehouse: on.AccountObject.Warehouse = &objectID + case sdk.ObjectTypeExternalVolume: + on.AccountObject.ExternalVolume = &objectID default: return nil, nil, fmt.Errorf("invalid object type %s", objectType) } diff --git a/pkg/resources/grant_privileges_to_role_acceptance_test.go b/pkg/resources/grant_privileges_to_role_acceptance_test.go index 52e5cd0512..2d6b20be8a 100644 --- a/pkg/resources/grant_privileges_to_role_acceptance_test.go +++ b/pkg/resources/grant_privileges_to_role_acceptance_test.go @@ -5,6 +5,9 @@ import ( "strings" "testing" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" + "github.com/hashicorp/terraform-plugin-testing/tfversion" + acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" @@ -861,3 +864,38 @@ func TestAcc_GrantPrivilegesToRole_onSchemaObject_futureInDatabase_externalTable }, }) } + +func TestAcc_GrantPrivilegesToRole_onSchemaObject_futureIcebergTables(t *testing.T) { + 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{ + { + Config: fmt.Sprintf(` +resource "snowflake_role" "role" { + name = "TEST_ROLE_123" +} + +resource "snowflake_grant_privileges_to_role" "grant" { + role_name = snowflake_role.role.name + privileges = ["SELECT"] + on_schema_object { + future { + object_type_plural = "ICEBERG TABLES" + in_schema = "\"%s\".\"%s\"" + } + } +} +`, acc.TestDatabaseName, acc.TestSchemaName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("snowflake_grant_privileges_to_role.grant", "on_schema_object.#", "1"), + resource.TestCheckResourceAttr("snowflake_grant_privileges_to_role.grant", "on_schema_object.0.future.#", "1"), + resource.TestCheckResourceAttr("snowflake_grant_privileges_to_role.grant", "on_schema_object.0.future.0.object_type_plural", string(sdk.PluralObjectTypeIcebergTables)), + ), + }, + }, + }) +} diff --git a/pkg/sdk/grants.go b/pkg/sdk/grants.go index b9af33ecfa..f4dc79fcb4 100644 --- a/pkg/sdk/grants.go +++ b/pkg/sdk/grants.go @@ -52,6 +52,7 @@ type GrantOnAccountObject struct { Integration *AccountObjectIdentifier `ddl:"identifier" sql:"INTEGRATION"` FailoverGroup *AccountObjectIdentifier `ddl:"identifier" sql:"FAILOVER GROUP"` ReplicationGroup *AccountObjectIdentifier `ddl:"identifier" sql:"REPLICATION GROUP"` + ExternalVolume *AccountObjectIdentifier `ddl:"identifier" sql:"EXTERNAL VOLUME"` } type GrantOnSchema struct { diff --git a/pkg/sdk/grants_test.go b/pkg/sdk/grants_test.go index 3c8b0825a9..927c954bcd 100644 --- a/pkg/sdk/grants_test.go +++ b/pkg/sdk/grants_test.go @@ -35,6 +35,22 @@ func TestGrantPrivilegesToAccountRole(t *testing.T) { } assertOptsValidAndSQLEquals(t, opts, `GRANT ALL PRIVILEGES ON DATABASE "db1" TO ROLE "role1"`) }) + + t.Run("on account object - external volume", func(t *testing.T) { + opts := &GrantPrivilegesToAccountRoleOptions{ + privileges: &AccountRoleGrantPrivileges{ + AllPrivileges: Bool(true), + }, + on: &AccountRoleGrantOn{ + AccountObject: &GrantOnAccountObject{ + ExternalVolume: Pointer(NewAccountObjectIdentifier("ex volume")), + }, + }, + accountRole: NewAccountObjectIdentifier("role1"), + } + assertOptsValidAndSQLEquals(t, opts, `GRANT ALL PRIVILEGES ON EXTERNAL VOLUME "ex volume" TO ROLE "role1"`) + }) + t.Run("on schema", func(t *testing.T) { opts := &GrantPrivilegesToAccountRoleOptions{ privileges: &AccountRoleGrantPrivileges{ diff --git a/pkg/sdk/grants_validations.go b/pkg/sdk/grants_validations.go index a66029ac63..694dbbad91 100644 --- a/pkg/sdk/grants_validations.go +++ b/pkg/sdk/grants_validations.go @@ -72,8 +72,8 @@ func (v *AccountRoleGrantOn) validate() error { } func (v *GrantOnAccountObject) validate() error { - if !exactlyOneValueSet(v.User, v.ResourceMonitor, v.Warehouse, v.Database, v.Integration, v.FailoverGroup, v.ReplicationGroup) { - return errExactlyOneOf("GrantOnAccountObject", "User", "ResourceMonitor", "Warehouse", "Database", "Integration", "FailoverGroup", "ReplicationGroup") + if !exactlyOneValueSet(v.User, v.ResourceMonitor, v.Warehouse, v.Database, v.Integration, v.FailoverGroup, v.ReplicationGroup, v.ExternalVolume) { + return errExactlyOneOf("GrantOnAccountObject", "User", "ResourceMonitor", "Warehouse", "Database", "Integration", "FailoverGroup", "ReplicationGroup", "ExternalVolume") } return nil } diff --git a/pkg/sdk/object_types.go b/pkg/sdk/object_types.go index 44363d0afb..b59ea64da5 100644 --- a/pkg/sdk/object_types.go +++ b/pkg/sdk/object_types.go @@ -59,6 +59,8 @@ const ( ObjectTypeApplicationRole ObjectType = "APPLICATION ROLE" ObjectTypeStreamlit ObjectType = "STREAMLIT" ObjectTypeColumn ObjectType = "COLUMN" + ObjectTypeIcebergTable ObjectType = "ICEBERG TABLE" + ObjectTypeExternalVolume ObjectType = "EXTERNAL VOLUME" ) func (o ObjectType) String() string { @@ -109,6 +111,8 @@ func objectTypeSingularToPluralMap() map[ObjectType]PluralObjectType { ObjectTypeApplicationPackage: PluralObjectTypeApplicationPackages, ObjectTypeApplicationRole: PluralObjectTypeApplicationRoles, ObjectTypeStreamlit: PluralObjectTypeStreamlits, + ObjectTypeIcebergTable: PluralObjectTypeIcebergTables, + ObjectTypeExternalVolume: PluralObjectTypeExternalVolumes, } } @@ -199,6 +203,8 @@ const ( PluralObjectTypeApplicationPackages PluralObjectType = "APPLICATION PACKAGES" PluralObjectTypeApplicationRoles PluralObjectType = "APPLICATION ROLES" PluralObjectTypeStreamlits PluralObjectType = "STREAMLITS" + PluralObjectTypeIcebergTables PluralObjectType = "ICEBERG TABLES" + PluralObjectTypeExternalVolumes PluralObjectType = "EXTERNAL VOLUMES" ) func (p PluralObjectType) String() string { diff --git a/pkg/sdk/privileges.go b/pkg/sdk/privileges.go index d4eb5958d9..47bb95a520 100644 --- a/pkg/sdk/privileges.go +++ b/pkg/sdk/privileges.go @@ -13,6 +13,7 @@ const ( GlobalPrivilegeCreateFailoverGroup GlobalPrivilege = "CREATE FAILOVER GROUP" GlobalPrivilegeCreateIntegration GlobalPrivilege = "CREATE INTEGRATION" GlobalPrivilegeCreateNetworkPolicy GlobalPrivilege = "CREATE NETWORK POLICY" + GlobalPrivilegeCreateExternalVolume GlobalPrivilege = "CREATE EXTERNAL VOLUME" GlobalPrivilegeCreateReplicationGroup GlobalPrivilege = "CREATE REPLICATION GROUP" GlobalPrivilegeCreateRole GlobalPrivilege = "CREATE ROLE" GlobalPrivilegeCreateShare GlobalPrivilege = "CREATE SHARE" @@ -71,6 +72,9 @@ const ( AccountObjectPrivilegeMonitor AccountObjectPrivilege = "MONITOR" AccountObjectPrivilegeUsage AccountObjectPrivilege = "USAGE" + // -- For EXTERNAL VOLUME + // AccountObjectPrivilegeUsage AccountObjectPrivilege = "USAGE" (duplicate) + // -- For FAILOVER GROUP // { FAILOVER | MODIFY | MONITOR | REPLICATE } [ , ... ] AccountObjectPrivilegeFailover AccountObjectPrivilege = "FAILOVER" @@ -126,11 +130,13 @@ const ( [ , ... ] */ SchemaPrivilegeAddSearchOptimization SchemaPrivilege = "ADD SEARCH OPTIMIZATION" + SchemaPrivilegeApplyBudget SchemaPrivilege = "APPLYBUDGET" SchemaPrivilegeCreateAlert SchemaPrivilege = "CREATE ALERT" SchemaPrivilegeCreateDynamicTable SchemaPrivilege = "CREATE DYNAMIC TABLE" SchemaPrivilegeCreateExternalTable SchemaPrivilege = "CREATE EXTERNAL TABLE" SchemaPrivilegeCreateFileFormat SchemaPrivilege = "CREATE FILE FORMAT" SchemaPrivilegeCreateFunction SchemaPrivilege = "CREATE FUNCTION" + SchemaPrivilegeCreateIcebergTable SchemaPrivilege = "CREATE ICEBERG TABLE" SchemaPrivilegeCreateMaterializedView SchemaPrivilege = "CREATE MATERIALIZED VIEW" SchemaPrivilegeCreatePipe SchemaPrivilege = "CREATE PIPE" SchemaPrivilegeCreateProcedure SchemaPrivilege = "CREATE PROCEDURE" @@ -178,6 +184,15 @@ const ( // USAGE [ , ... ] SchemaObjectPrivilegeUsage SchemaObjectPrivilege = "USAGE" + // -- For ICEBERG TABLE + SchemaObjectPrivilegeApplyBudget SchemaObjectPrivilege = "APPLYBUDGET" + //SchemaObjectPrivilegeDelete SchemaObjectPrivilege = "DELETE" (duplicate) + //SchemaObjectPrivilegeInsert SchemaObjectPrivilege = "INSERT" (duplicate) + //SchemaObjectPrivilegeReferences SchemaObjectPrivilege = "REFERENCES" (duplicate) + //SchemaObjectPrivilegeSelect SchemaObjectPrivilege = "SELECT" (duplicate) + //SchemaObjectPrivilegeTruncate SchemaObjectPrivilege = "Truncate" (duplicate) + //SchemaObjectPrivilegeUpdate SchemaObjectPrivilege = "Update" (duplicate) + // -- For PIPE // { MONITOR | OPERATE } [ , ... ] SchemaObjectPrivilegeMonitor SchemaObjectPrivilege = "MONITOR"