diff --git a/docs/resources/grant_privileges_to_account_role.md b/docs/resources/grant_privileges_to_account_role.md
index 64af3480f7..9358449ece 100644
--- a/docs/resources/grant_privileges_to_account_role.md
+++ b/docs/resources/grant_privileges_to_account_role.md
@@ -300,16 +300,16 @@ Optional:
Optional:
- `all` (Block List, Max: 1) Configures the privilege to be granted on all objects in either 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 all objects in either a database or schema. (see [below for nested schema](#nestedblock--on_schema_object--future))
+- `future` (Block List, Max: 1) Configures the privilege to be granted on future objects in either 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 | NETWORK RULE | PACKAGES POLICY | ICEBERG TABLE
+- `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 | NETWORK RULE | PACKAGES POLICY | STREAMLIT | ICEBERG TABLE
### 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 | NETWORK RULES | PACKAGES POLICIES | ICEBERG TABLES
+- `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 | NETWORK RULES | PACKAGES POLICIES | STREAMLITS | ICEBERG TABLES.
Optional:
@@ -322,13 +322,16 @@ 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 | NETWORK RULES | PACKAGES POLICIES | ICEBERG TABLES
+- `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 | NETWORK RULES | PACKAGES POLICIES | ICEBERG TABLES.
Optional:
- `in_database` (String)
- `in_schema` (String)
+## Known limitations
+- Setting the `CREATE SNOWFLAKE.ML.ANOMALY_DETECTION` or `CREATE SNOWFLAKE.ML.FORECAST` privileges on schema results in a permadiff because of the probably incorrect Snowflake's behavior of `SHOW GRANTS ON `. More in the [comment](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2651#issuecomment-2022634952).
+
## Import
~> **Note** All the ..._name parts should be fully qualified names (where every part is quoted), e.g. for schema object it is `""."".""`
diff --git a/docs/resources/grant_privileges_to_database_role.md b/docs/resources/grant_privileges_to_database_role.md
index e853927cc6..b3e8b16564 100644
--- a/docs/resources/grant_privileges_to_database_role.md
+++ b/docs/resources/grant_privileges_to_database_role.md
@@ -206,14 +206,14 @@ Optional:
- `all` (Block List, Max: 1) Configures the privilege to be granted on all objects in either 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 either 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 | NETWORK RULE | PACKAGES POLICY | ICEBERG TABLE
+- `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 | NETWORK RULE | PACKAGES POLICY | STREAMLIT | ICEBERG TABLE
### 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 | NETWORK RULES | PACKAGES POLICIES | ICEBERG TABLES
+- `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 | NETWORK RULES | PACKAGES POLICIES | STREAMLITS | ICEBERG TABLES.
Optional:
@@ -226,7 +226,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 | NETWORK RULES | PACKAGES POLICIES | ICEBERG TABLES
+- `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 | NETWORK RULES | PACKAGES POLICIES | ICEBERG TABLES.
Optional:
diff --git a/docs/resources/grant_privileges_to_role.md b/docs/resources/grant_privileges_to_role.md
index f6983d3de4..2275a332cc 100644
--- a/docs/resources/grant_privileges_to_role.md
+++ b/docs/resources/grant_privileges_to_role.md
@@ -219,14 +219,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 | 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
+- `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 | NETWORK RULE | PACKAGES POLICY | STREAMLIT | ICEBERG TABLE
### 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 | 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
+- `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 | NETWORK RULES | PACKAGES POLICIES | STREAMLITS | ICEBERG TABLES
Optional:
@@ -239,7 +239,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 | 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
+- `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 | NETWORK RULES | PACKAGES POLICIES | ICEBERG TABLES
Optional:
diff --git a/docs/resources/grant_privileges_to_share.md b/docs/resources/grant_privileges_to_share.md
index a9e4c07377..6fa78c3e08 100644
--- a/docs/resources/grant_privileges_to_share.md
+++ b/docs/resources/grant_privileges_to_share.md
@@ -119,6 +119,9 @@ resource "snowflake_grant_privileges_to_share" "example" {
- `id` (String) The ID of this resource.
+## Known limitations
+- Setting the `CREATE SNOWFLAKE.ML.ANOMALY_DETECTION` or `CREATE SNOWFLAKE.ML.FORECAST` privileges on schema results in a permadiff because of the probably incorrect Snowflake's behavior of `SHOW GRANTS ON `. More in the [comment](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2651#issuecomment-2022634952).
+
## Import
~> **Note** All the ..._name parts should be fully qualified names, e.g. for database object it is `"".""`
diff --git a/pkg/resources/grant_helpers.go b/pkg/resources/grant_helpers.go
index d4d6afeaa5..6217041957 100644
--- a/pkg/resources/grant_helpers.go
+++ b/pkg/resources/grant_helpers.go
@@ -7,12 +7,9 @@ import (
"time"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider"
-
- "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/snowflake"
"github.com/hashicorp/go-cty/cty"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
-
- "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/snowflake"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/jmoiron/sqlx"
"github.com/snowflakedb/gosnowflake"
@@ -411,62 +408,3 @@ func isNotOwnershipGrant() func(value any, path cty.Path) diag.Diagnostics {
return diags
}
}
-
-func ValidGrantedObjectType() schema.SchemaValidateDiagFunc {
- return StringInSlice([]string{
- sdk.ObjectTypeAlert.String(),
- sdk.ObjectTypeDynamicTable.String(),
- sdk.ObjectTypeEventTable.String(),
- sdk.ObjectTypeFileFormat.String(),
- sdk.ObjectTypeFunction.String(),
- sdk.ObjectTypeProcedure.String(),
- sdk.ObjectTypeSecret.String(),
- sdk.ObjectTypeSequence.String(),
- sdk.ObjectTypePipe.String(),
- sdk.ObjectTypeMaskingPolicy.String(),
- sdk.ObjectTypePasswordPolicy.String(),
- sdk.ObjectTypeRowAccessPolicy.String(),
- sdk.ObjectTypeSessionPolicy.String(),
- sdk.ObjectTypeTag.String(),
- sdk.ObjectTypeStage.String(),
- sdk.ObjectTypeStream.String(),
- sdk.ObjectTypeTable.String(),
- sdk.ObjectTypeExternalTable.String(),
- sdk.ObjectTypeTask.String(),
- sdk.ObjectTypeView.String(),
- sdk.ObjectTypeMaterializedView.String(),
- sdk.ObjectTypeNetworkRule.String(),
- sdk.ObjectTypePackagesPolicy.String(),
- sdk.ObjectTypeIcebergTable.String(),
- }, true)
-}
-
-func ValidGrantedPluralObjectType() schema.SchemaValidateDiagFunc {
- return StringInSlice(
- []string{
- sdk.PluralObjectTypeAlerts.String(),
- sdk.PluralObjectTypeDynamicTables.String(),
- sdk.PluralObjectTypeEventTables.String(),
- sdk.PluralObjectTypeFileFormats.String(),
- sdk.PluralObjectTypeFunctions.String(),
- sdk.PluralObjectTypeProcedures.String(),
- sdk.PluralObjectTypeSecrets.String(),
- sdk.PluralObjectTypeSequences.String(),
- sdk.PluralObjectTypePipes.String(),
- sdk.PluralObjectTypeMaskingPolicies.String(),
- sdk.PluralObjectTypePasswordPolicies.String(),
- sdk.PluralObjectTypeRowAccessPolicies.String(),
- sdk.PluralObjectTypeSessionPolicies.String(),
- sdk.PluralObjectTypeTags.String(),
- sdk.PluralObjectTypeStages.String(),
- sdk.PluralObjectTypeStreams.String(),
- sdk.PluralObjectTypeTables.String(),
- sdk.PluralObjectTypeExternalTables.String(),
- sdk.PluralObjectTypeTasks.String(),
- sdk.PluralObjectTypeViews.String(),
- sdk.PluralObjectTypeMaterializedViews.String(),
- sdk.PluralObjectTypeNetworkRules.String(),
- sdk.PluralObjectTypePackagesPolicies.String(),
- sdk.PluralObjectTypeIcebergTables.String(),
- }, true)
-}
diff --git a/pkg/resources/grant_privileges_to_account_role.go b/pkg/resources/grant_privileges_to_account_role.go
index 80dd3ebe6d..99c2f322cc 100644
--- a/pkg/resources/grant_privileges_to_account_role.go
+++ b/pkg/resources/grant_privileges_to_account_role.go
@@ -196,7 +196,7 @@ var grantPrivilegesToAccountRoleSchema = map[string]*schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: 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 | NETWORK RULE | PACKAGES POLICY | ICEBERG TABLE",
+ Description: fmt.Sprintf("The object type of the schema object on which privileges will be granted. Valid values are: %s", strings.Join(sdk.ValidGrantToObjectTypesString, " | ")),
RequiredWith: []string{
"on_schema_object.0.object_name",
},
@@ -204,7 +204,7 @@ var grantPrivilegesToAccountRoleSchema = map[string]*schema.Schema{
"on_schema_object.0.all",
"on_schema_object.0.future",
},
- ValidateDiagFunc: ValidGrantedObjectType(),
+ ValidateDiagFunc: StringInSlice(sdk.ValidGrantToObjectTypesString, true),
},
"object_name": {
Type: schema.TypeString,
@@ -228,7 +228,7 @@ var grantPrivilegesToAccountRoleSchema = map[string]*schema.Schema{
Description: "Configures the privilege to be granted on all objects in either a database or schema.",
MaxItems: 1,
Elem: &schema.Resource{
- Schema: grantPrivilegesOnAccountRoleBulkOperationSchema,
+ Schema: getGrantPrivilegesOnAccountRoleBulkOperationSchema(sdk.ValidGrantToPluralObjectTypesString),
},
ConflictsWith: []string{
"on_schema_object.0.object_type",
@@ -243,10 +243,10 @@ var grantPrivilegesToAccountRoleSchema = map[string]*schema.Schema{
Type: schema.TypeList,
Optional: true,
ForceNew: true,
- Description: "Configures the privilege to be granted on all objects in either a database or schema.",
+ Description: "Configures the privilege to be granted on future objects in either a database or schema.",
MaxItems: 1,
Elem: &schema.Resource{
- Schema: grantPrivilegesOnAccountRoleBulkOperationSchema,
+ Schema: getGrantPrivilegesOnAccountRoleBulkOperationSchema(sdk.ValidGrantToFuturePluralObjectTypesString),
},
ConflictsWith: []string{
"on_schema_object.0.object_type",
@@ -262,26 +262,28 @@ var grantPrivilegesToAccountRoleSchema = map[string]*schema.Schema{
},
}
-var grantPrivilegesOnAccountRoleBulkOperationSchema = map[string]*schema.Schema{
- "object_type_plural": {
- Type: schema.TypeString,
- Required: true,
- ForceNew: 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 | NETWORK RULES | PACKAGES POLICIES | ICEBERG TABLES",
- ValidateDiagFunc: ValidGrantedPluralObjectType(),
- },
- "in_database": {
- Type: schema.TypeString,
- Optional: true,
- ForceNew: true,
- ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](),
- },
- "in_schema": {
- Type: schema.TypeString,
- Optional: true,
- ForceNew: true,
- ValidateDiagFunc: IsValidIdentifier[sdk.DatabaseObjectIdentifier](),
- },
+func getGrantPrivilegesOnAccountRoleBulkOperationSchema(validGrantToObjectTypes []string) map[string]*schema.Schema {
+ return map[string]*schema.Schema{
+ "object_type_plural": {
+ Type: schema.TypeString,
+ Required: true,
+ ForceNew: true,
+ Description: fmt.Sprintf("The plural object type of the schema object on which privileges will be granted. Valid values are: %s.", strings.Join(validGrantToObjectTypes, " | ")),
+ ValidateDiagFunc: StringInSlice(validGrantToObjectTypes, true),
+ },
+ "in_database": {
+ Type: schema.TypeString,
+ Optional: true,
+ ForceNew: true,
+ ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](),
+ },
+ "in_schema": {
+ Type: schema.TypeString,
+ Optional: true,
+ ForceNew: true,
+ ValidateDiagFunc: IsValidIdentifier[sdk.DatabaseObjectIdentifier](),
+ },
+ }
}
func GrantPrivilegesToAccountRole() *schema.Resource {
diff --git a/pkg/resources/grant_privileges_to_account_role_acceptance_test.go b/pkg/resources/grant_privileges_to_account_role_acceptance_test.go
index eca421b9f8..bda96ed19d 100644
--- a/pkg/resources/grant_privileges_to_account_role_acceptance_test.go
+++ b/pkg/resources/grant_privileges_to_account_role_acceptance_test.go
@@ -469,8 +469,9 @@ func TestAcc_GrantPrivilegesToAccountRole_OnSchemaObject_OnAll_InDatabase(t *tes
config.StringVariable(string(sdk.SchemaObjectPrivilegeInsert)),
config.StringVariable(string(sdk.SchemaObjectPrivilegeUpdate)),
),
- "database": config.StringVariable(databaseName),
- "with_grant_option": config.BoolVariable(false),
+ "database": config.StringVariable(databaseName),
+ "object_type_plural": config.StringVariable(sdk.PluralObjectTypeTables.String()),
+ "with_grant_option": config.BoolVariable(false),
}
resourceName := "snowflake_grant_privileges_to_account_role.test"
@@ -569,8 +570,9 @@ func TestAcc_GrantPrivilegesToAccountRole_OnSchemaObject_OnFuture_InDatabase(t *
config.StringVariable(string(sdk.SchemaObjectPrivilegeInsert)),
config.StringVariable(string(sdk.SchemaObjectPrivilegeUpdate)),
),
- "database": config.StringVariable(databaseName),
- "with_grant_option": config.BoolVariable(false),
+ "database": config.StringVariable(databaseName),
+ "object_type_plural": config.StringVariable(sdk.PluralObjectTypeTables.String()),
+ "with_grant_option": config.BoolVariable(false),
}
resourceName := "snowflake_grant_privileges_to_account_role.test"
@@ -610,6 +612,83 @@ func TestAcc_GrantPrivilegesToAccountRole_OnSchemaObject_OnFuture_InDatabase(t *
})
}
+// TODO [SNOW-1272222]: fix the test when it starts working on Snowflake side
+func TestAcc_GrantPrivilegesToAccountRole_OnSchemaObject_OnFuture_Streamlits_InDatabase(t *testing.T) {
+ t.Skip("Fix after it starts working on Snowflake side, reference: SNOW-1272222")
+ name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
+ roleName := sdk.NewAccountObjectIdentifier(name).FullyQualifiedName()
+ databaseName := sdk.NewAccountObjectIdentifier(acc.TestDatabaseName).FullyQualifiedName()
+ configVariables := config.Variables{
+ "name": config.StringVariable(roleName),
+ "privileges": config.ListVariable(
+ config.StringVariable(string(sdk.SchemaObjectPrivilegeUsage)),
+ ),
+ "database": config.StringVariable(databaseName),
+ "object_type_plural": config.StringVariable(sdk.PluralObjectTypeStreamlits.String()),
+ "with_grant_option": config.BoolVariable(false),
+ }
+
+ resource.Test(t, resource.TestCase{
+ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
+ PreCheck: func() { acc.TestAccPreCheck(t) },
+ TerraformVersionChecks: []tfversion.TerraformVersionCheck{
+ tfversion.RequireAbove(tfversion.Version1_5_0),
+ },
+ CheckDestroy: testAccCheckAccountRolePrivilegesRevoked(name),
+ Steps: []resource.TestStep{
+ {
+ PreConfig: func() { createAccountRoleOutsideTerraform(t, name) },
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnFuture_InDatabase"),
+ ConfigVariables: configVariables,
+ ExpectError: regexp.MustCompile("Unsupported feature 'STREAMLIT'"),
+ },
+ },
+ })
+}
+
+func TestAcc_GrantPrivilegesToAccountRole_OnSchemaObject_OnAll_Streamlits_InDatabase(t *testing.T) {
+ name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
+ roleName := sdk.NewAccountObjectIdentifier(name).FullyQualifiedName()
+ databaseName := sdk.NewAccountObjectIdentifier(acc.TestDatabaseName).FullyQualifiedName()
+ configVariables := config.Variables{
+ "name": config.StringVariable(roleName),
+ "privileges": config.ListVariable(
+ config.StringVariable(string(sdk.SchemaObjectPrivilegeUsage)),
+ ),
+ "database": config.StringVariable(databaseName),
+ "object_type_plural": config.StringVariable(sdk.PluralObjectTypeStreamlits.String()),
+ "with_grant_option": config.BoolVariable(false),
+ }
+ resourceName := "snowflake_grant_privileges_to_account_role.test"
+
+ resource.Test(t, resource.TestCase{
+ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
+ PreCheck: func() { acc.TestAccPreCheck(t) },
+ TerraformVersionChecks: []tfversion.TerraformVersionCheck{
+ tfversion.RequireAbove(tfversion.Version1_5_0),
+ },
+ CheckDestroy: testAccCheckAccountRolePrivilegesRevoked(name),
+ Steps: []resource.TestStep{
+ {
+ PreConfig: func() { createAccountRoleOutsideTerraform(t, name) },
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnAll_InDatabase"),
+ ConfigVariables: configVariables,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, "account_role_name", roleName),
+ resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"),
+ resource.TestCheckResourceAttr(resourceName, "privileges.0", string(sdk.SchemaObjectPrivilegeUsage)),
+ resource.TestCheckResourceAttr(resourceName, "on_schema_object.#", "1"),
+ resource.TestCheckResourceAttr(resourceName, "on_schema_object.0.all.#", "1"),
+ resource.TestCheckResourceAttr(resourceName, "on_schema_object.0.all.0.object_type_plural", string(sdk.PluralObjectTypeStreamlits)),
+ resource.TestCheckResourceAttr(resourceName, "on_schema_object.0.all.0.in_database", databaseName),
+ resource.TestCheckResourceAttr(resourceName, "with_grant_option", "false"),
+ resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|USAGE|OnSchemaObject|OnAll|STREAMLITS|InDatabase|%s", roleName, databaseName)),
+ ),
+ },
+ },
+ })
+}
+
func TestAcc_GrantPrivilegesToAccountRole_UpdatePrivileges(t *testing.T) {
name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
roleName := sdk.NewAccountObjectIdentifier(name).FullyQualifiedName()
@@ -1059,6 +1138,58 @@ func TestAcc_GrantPrivilegesToAccountRole_OnExternalVolume(t *testing.T) {
})
}
+// proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2651
+// TODO [SNOW-1270457]: This seems to be a Snowflake error, we are waiting for the confirmation. Alter the test when the behavior is fixed. Update the resource documentation (section known issues).
+func TestAcc_GrantPrivilegesToAccountRole_MLPrivileges(t *testing.T) {
+ name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
+ roleName := sdk.NewAccountObjectIdentifier(name).FullyQualifiedName()
+ configVariables := config.Variables{
+ "name": config.StringVariable(roleName),
+ "privileges": config.ListVariable(
+ config.StringVariable(string(sdk.SchemaPrivilegeCreateSnowflakeMlAnomalyDetection)),
+ config.StringVariable(string(sdk.SchemaPrivilegeCreateSnowflakeMlForecast)),
+ ),
+ "database": config.StringVariable(acc.TestDatabaseName),
+ "schema": config.StringVariable(acc.TestSchemaName),
+ "with_grant_option": config.BoolVariable(false),
+ }
+ resourceName := "snowflake_grant_privileges_to_account_role.test"
+
+ schemaName := sdk.NewDatabaseObjectIdentifier(acc.TestDatabaseName, acc.TestSchemaName).FullyQualifiedName()
+
+ resource.Test(t, resource.TestCase{
+ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
+ PreCheck: func() { acc.TestAccPreCheck(t) },
+ TerraformVersionChecks: []tfversion.TerraformVersionCheck{
+ tfversion.RequireAbove(tfversion.Version1_5_0),
+ },
+ CheckDestroy: testAccCheckAccountRolePrivilegesRevoked(name),
+ Steps: []resource.TestStep{
+ {
+ PreConfig: func() { createAccountRoleOutsideTerraform(t, name) },
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToAccountRole/OnSchema"),
+ ConfigVariables: configVariables,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, "account_role_name", roleName),
+ resource.TestCheckResourceAttr(resourceName, "privileges.#", "2"),
+ resource.TestCheckResourceAttr(resourceName, "privileges.0", string(sdk.SchemaPrivilegeCreateSnowflakeMlAnomalyDetection)),
+ resource.TestCheckResourceAttr(resourceName, "privileges.1", string(sdk.SchemaPrivilegeCreateSnowflakeMlForecast)),
+ resource.TestCheckResourceAttr(resourceName, "on_schema.#", "1"),
+ resource.TestCheckResourceAttr(resourceName, "on_schema.0.schema_name", schemaName),
+ resource.TestCheckResourceAttr(resourceName, "with_grant_option", "false"),
+ resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|CREATE SNOWFLAKE.ML.ANOMALY_DETECTION,CREATE SNOWFLAKE.ML.FORECAST|OnSchema|OnSchema|%s", roleName, schemaName)),
+ ),
+ ExpectNonEmptyPlan: true,
+ ConfigPlanChecks: resource.ConfigPlanChecks{
+ PostApplyPostRefresh: []plancheck.PlanCheck{
+ plancheck.ExpectNonEmptyPlan(),
+ },
+ },
+ },
+ },
+ })
+}
+
// proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2459 is fixed
func TestAcc_GrantPrivilegesToAccountRole_ChangeWithGrantOptionsOutsideOfTerraform_WithGrantOptions(t *testing.T) {
name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
diff --git a/pkg/resources/grant_privileges_to_database_role.go b/pkg/resources/grant_privileges_to_database_role.go
index f89a3e676a..8dd80b907b 100644
--- a/pkg/resources/grant_privileges_to_database_role.go
+++ b/pkg/resources/grant_privileges_to_database_role.go
@@ -5,6 +5,7 @@ import (
"fmt"
"log"
"slices"
+ "strings"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider"
@@ -147,7 +148,7 @@ var grantPrivilegesToDatabaseRoleSchema = map[string]*schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: 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 | NETWORK RULE | PACKAGES POLICY | ICEBERG TABLE",
+ Description: fmt.Sprintf("The object type of the schema object on which privileges will be granted. Valid values are: %s", strings.Join(sdk.ValidGrantToObjectTypesString, " | ")),
RequiredWith: []string{
"on_schema_object.0.object_name",
},
@@ -155,7 +156,7 @@ var grantPrivilegesToDatabaseRoleSchema = map[string]*schema.Schema{
"on_schema_object.0.all",
"on_schema_object.0.future",
},
- ValidateDiagFunc: ValidGrantedObjectType(),
+ ValidateDiagFunc: StringInSlice(sdk.ValidGrantToObjectTypesString, true),
},
"object_name": {
Type: schema.TypeString,
@@ -179,7 +180,7 @@ var grantPrivilegesToDatabaseRoleSchema = map[string]*schema.Schema{
Description: "Configures the privilege to be granted on all objects in either a database or schema.",
MaxItems: 1,
Elem: &schema.Resource{
- Schema: grantPrivilegesOnDatabaseRoleBulkOperationSchema,
+ Schema: getGrantPrivilegesOnDatabaseRoleBulkOperationSchema(sdk.ValidGrantToPluralObjectTypesString),
},
ConflictsWith: []string{
"on_schema_object.0.object_type",
@@ -197,7 +198,7 @@ var grantPrivilegesToDatabaseRoleSchema = map[string]*schema.Schema{
Description: "Configures the privilege to be granted on future objects in either a database or schema.",
MaxItems: 1,
Elem: &schema.Resource{
- Schema: grantPrivilegesOnDatabaseRoleBulkOperationSchema,
+ Schema: getGrantPrivilegesOnDatabaseRoleBulkOperationSchema(sdk.ValidGrantToFuturePluralObjectTypesString),
},
ConflictsWith: []string{
"on_schema_object.0.object_type",
@@ -213,28 +214,30 @@ var grantPrivilegesToDatabaseRoleSchema = map[string]*schema.Schema{
},
}
-var grantPrivilegesOnDatabaseRoleBulkOperationSchema = map[string]*schema.Schema{
- "object_type_plural": {
- Type: schema.TypeString,
- Required: true,
- ForceNew: 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 | NETWORK RULES | PACKAGES POLICIES | ICEBERG TABLES",
- ValidateDiagFunc: ValidGrantedPluralObjectType(),
- },
- "in_database": {
- Type: schema.TypeString,
- Optional: true,
- ForceNew: true,
- Description: "The fully qualified name of the database.",
- ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](),
- },
- "in_schema": {
- Type: schema.TypeString,
- Optional: true,
- ForceNew: true,
- Description: "The fully qualified name of the schema.",
- ValidateDiagFunc: IsValidIdentifier[sdk.DatabaseObjectIdentifier](),
- },
+func getGrantPrivilegesOnDatabaseRoleBulkOperationSchema(validGrantToObjectTypes []string) map[string]*schema.Schema {
+ return map[string]*schema.Schema{
+ "object_type_plural": {
+ Type: schema.TypeString,
+ Required: true,
+ ForceNew: true,
+ Description: fmt.Sprintf("The plural object type of the schema object on which privileges will be granted. Valid values are: %s.", strings.Join(validGrantToObjectTypes, " | ")),
+ ValidateDiagFunc: StringInSlice(validGrantToObjectTypes, true),
+ },
+ "in_database": {
+ Type: schema.TypeString,
+ Optional: true,
+ ForceNew: true,
+ Description: "The fully qualified name of the database.",
+ ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](),
+ },
+ "in_schema": {
+ Type: schema.TypeString,
+ Optional: true,
+ ForceNew: true,
+ Description: "The fully qualified name of the schema.",
+ ValidateDiagFunc: IsValidIdentifier[sdk.DatabaseObjectIdentifier](),
+ },
+ }
}
func GrantPrivilegesToDatabaseRole() *schema.Resource {
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 de437083f8..bbb478b486 100644
--- a/pkg/resources/grant_privileges_to_database_role_acceptance_test.go
+++ b/pkg/resources/grant_privileges_to_database_role_acceptance_test.go
@@ -385,8 +385,9 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnSchemaObject_OnAll_InDatabase(t *te
config.StringVariable(string(sdk.SchemaObjectPrivilegeInsert)),
config.StringVariable(string(sdk.SchemaObjectPrivilegeUpdate)),
),
- "database": config.StringVariable(acc.TestDatabaseName),
- "with_grant_option": config.BoolVariable(false),
+ "database": config.StringVariable(acc.TestDatabaseName),
+ "object_type_plural": config.StringVariable(sdk.PluralObjectTypeTables.String()),
+ "with_grant_option": config.BoolVariable(false),
}
resourceName := "snowflake_grant_privileges_to_database_role.test"
@@ -487,8 +488,9 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnSchemaObject_OnFuture_InDatabase(t
config.StringVariable(string(sdk.SchemaObjectPrivilegeInsert)),
config.StringVariable(string(sdk.SchemaObjectPrivilegeUpdate)),
),
- "database": config.StringVariable(acc.TestDatabaseName),
- "with_grant_option": config.BoolVariable(false),
+ "database": config.StringVariable(acc.TestDatabaseName),
+ "object_type_plural": config.StringVariable(sdk.PluralObjectTypeTables.String()),
+ "with_grant_option": config.BoolVariable(false),
}
resourceName := "snowflake_grant_privileges_to_database_role.test"
@@ -531,6 +533,82 @@ func TestAcc_GrantPrivilegesToDatabaseRole_OnSchemaObject_OnFuture_InDatabase(t
})
}
+// TODO [SNOW-1272222]: fix the test when it starts working on Snowflake side
+func TestAcc_GrantPrivilegesToDatabaseRole_OnSchemaObject_OnFuture_Streamlits_InDatabase(t *testing.T) {
+ t.Skip("Fix after it starts working on Snowflake side, reference: SNOW-1272222")
+ name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
+ configVariables := config.Variables{
+ "name": config.StringVariable(name),
+ "privileges": config.ListVariable(
+ config.StringVariable(string(sdk.SchemaObjectPrivilegeUsage)),
+ ),
+ "database": config.StringVariable(acc.TestDatabaseName),
+ "object_type_plural": config.StringVariable(sdk.PluralObjectTypeStreamlits.String()),
+ "with_grant_option": config.BoolVariable(false),
+ }
+
+ resource.Test(t, resource.TestCase{
+ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
+ PreCheck: func() { acc.TestAccPreCheck(t) },
+ TerraformVersionChecks: []tfversion.TerraformVersionCheck{
+ tfversion.RequireAbove(tfversion.Version1_5_0),
+ },
+ CheckDestroy: testAccCheckDatabaseRolePrivilegesRevoked,
+ Steps: []resource.TestStep{
+ {
+ PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) },
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnFuture_InDatabase"),
+ ConfigVariables: configVariables,
+ ExpectError: regexp.MustCompile("Unsupported feature 'STREAMLIT'"),
+ },
+ },
+ })
+}
+
+func TestAcc_GrantPrivilegesToDatabaseRole_OnSchemaObject_OnAll_Streamlits_InDatabase(t *testing.T) {
+ name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
+ configVariables := config.Variables{
+ "name": config.StringVariable(name),
+ "privileges": config.ListVariable(
+ config.StringVariable(string(sdk.SchemaObjectPrivilegeUsage)),
+ ),
+ "database": config.StringVariable(acc.TestDatabaseName),
+ "object_type_plural": config.StringVariable(sdk.PluralObjectTypeStreamlits.String()),
+ "with_grant_option": config.BoolVariable(false),
+ }
+ resourceName := "snowflake_grant_privileges_to_database_role.test"
+
+ databaseRoleName := sdk.NewDatabaseObjectIdentifier(acc.TestDatabaseName, name).FullyQualifiedName()
+ databaseName := sdk.NewAccountObjectIdentifier(acc.TestDatabaseName).FullyQualifiedName()
+
+ resource.Test(t, resource.TestCase{
+ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
+ PreCheck: func() { acc.TestAccPreCheck(t) },
+ TerraformVersionChecks: []tfversion.TerraformVersionCheck{
+ tfversion.RequireAbove(tfversion.Version1_5_0),
+ },
+ CheckDestroy: testAccCheckAccountRolePrivilegesRevoked(name),
+ Steps: []resource.TestStep{
+ {
+ PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) },
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnAll_InDatabase"),
+ ConfigVariables: configVariables,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, "database_role_name", databaseRoleName),
+ resource.TestCheckResourceAttr(resourceName, "privileges.#", "1"),
+ resource.TestCheckResourceAttr(resourceName, "privileges.0", string(sdk.SchemaObjectPrivilegeUsage)),
+ resource.TestCheckResourceAttr(resourceName, "on_schema_object.#", "1"),
+ resource.TestCheckResourceAttr(resourceName, "on_schema_object.0.all.#", "1"),
+ resource.TestCheckResourceAttr(resourceName, "on_schema_object.0.all.0.object_type_plural", string(sdk.PluralObjectTypeStreamlits)),
+ resource.TestCheckResourceAttr(resourceName, "on_schema_object.0.all.0.in_database", databaseName),
+ resource.TestCheckResourceAttr(resourceName, "with_grant_option", "false"),
+ resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|USAGE|OnSchemaObject|OnAll|STREAMLITS|InDatabase|%s", databaseRoleName, databaseName)),
+ ),
+ },
+ },
+ })
+}
+
func TestAcc_GrantPrivilegesToDatabaseRole_UpdatePrivileges(t *testing.T) {
name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
configVariables := func(allPrivileges bool, privileges []sdk.AccountObjectPrivilege) config.Variables {
@@ -799,6 +877,58 @@ func TestAcc_GrantPrivilegesToDatabaseRole_AlwaysApply(t *testing.T) {
})
}
+// proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2651
+// TODO [SNOW-1270457]: This seems to be a Snowflake error, we are waiting for the confirmation. Alter the test when the behavior is fixed. Update the resource documentation (section known issues).
+func TestAcc_GrantPrivilegesToDatabaseRole_MLPrivileges(t *testing.T) {
+ name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
+ configVariables := config.Variables{
+ "name": config.StringVariable(name),
+ "privileges": config.ListVariable(
+ config.StringVariable(string(sdk.SchemaPrivilegeCreateSnowflakeMlAnomalyDetection)),
+ config.StringVariable(string(sdk.SchemaPrivilegeCreateSnowflakeMlForecast)),
+ ),
+ "database": config.StringVariable(acc.TestDatabaseName),
+ "schema": config.StringVariable(acc.TestSchemaName),
+ "with_grant_option": config.BoolVariable(false),
+ }
+ resourceName := "snowflake_grant_privileges_to_database_role.test"
+
+ databaseRoleName := sdk.NewDatabaseObjectIdentifier(acc.TestDatabaseName, name).FullyQualifiedName()
+ schemaName := sdk.NewDatabaseObjectIdentifier(acc.TestDatabaseName, acc.TestSchemaName).FullyQualifiedName()
+
+ resource.Test(t, resource.TestCase{
+ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
+ PreCheck: func() { acc.TestAccPreCheck(t) },
+ TerraformVersionChecks: []tfversion.TerraformVersionCheck{
+ tfversion.RequireAbove(tfversion.Version1_5_0),
+ },
+ CheckDestroy: testAccCheckAccountRolePrivilegesRevoked(name),
+ Steps: []resource.TestStep{
+ {
+ PreConfig: func() { createDatabaseRoleOutsideTerraform(t, name) },
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_GrantPrivilegesToDatabaseRole/OnSchema"),
+ ConfigVariables: configVariables,
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, "database_role_name", databaseRoleName),
+ resource.TestCheckResourceAttr(resourceName, "privileges.#", "2"),
+ resource.TestCheckResourceAttr(resourceName, "privileges.0", string(sdk.SchemaPrivilegeCreateSnowflakeMlAnomalyDetection)),
+ resource.TestCheckResourceAttr(resourceName, "privileges.1", string(sdk.SchemaPrivilegeCreateSnowflakeMlForecast)),
+ resource.TestCheckResourceAttr(resourceName, "on_schema.#", "1"),
+ resource.TestCheckResourceAttr(resourceName, "on_schema.0.schema_name", schemaName),
+ resource.TestCheckResourceAttr(resourceName, "with_grant_option", "false"),
+ resource.TestCheckResourceAttr(resourceName, "id", fmt.Sprintf("%s|false|false|CREATE SNOWFLAKE.ML.ANOMALY_DETECTION,CREATE SNOWFLAKE.ML.FORECAST|OnSchema|OnSchema|%s", databaseRoleName, schemaName)),
+ ),
+ ExpectNonEmptyPlan: true,
+ ConfigPlanChecks: resource.ConfigPlanChecks{
+ PostApplyPostRefresh: []plancheck.PlanCheck{
+ plancheck.ExpectNonEmptyPlan(),
+ },
+ },
+ },
+ },
+ })
+}
+
// proves https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2459 is fixed
func TestAcc_GrantPrivilegesToDatabaseRole_ChangeWithGrantOptionsOutsideOfTerraform_WithGrantOptions(t *testing.T) {
name := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
diff --git a/pkg/resources/grant_privileges_to_role.go b/pkg/resources/grant_privileges_to_role.go
index 109385bb82..c54ed16fe3 100644
--- a/pkg/resources/grant_privileges_to_role.go
+++ b/pkg/resources/grant_privileges_to_role.go
@@ -130,11 +130,11 @@ 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 | 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",
+ Description: fmt.Sprintf("The object type of the schema object on which privileges will be granted. Valid values are: %s", strings.Join(sdk.ValidGrantToObjectTypesString, " | ")),
RequiredWith: []string{"on_schema_object.0.object_name"},
ConflictsWith: []string{"on_schema_object.0.all", "on_schema_object.0.future"},
ForceNew: true,
- ValidateDiagFunc: ValidGrantedObjectType(),
+ ValidateDiagFunc: StringInSlice(sdk.ValidGrantToObjectTypesString, true),
},
"object_name": {
Type: schema.TypeString,
@@ -156,9 +156,9 @@ 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 | 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",
+ Description: fmt.Sprintf("The plural object type of the schema object on which privileges will be granted. Valid values are: %s", strings.Join(sdk.ValidGrantToPluralObjectTypesString, " | ")),
ForceNew: true,
- ValidateDiagFunc: ValidGrantedPluralObjectType(),
+ ValidateDiagFunc: StringInSlice(sdk.ValidGrantToPluralObjectTypesString, true),
},
"in_database": {
Type: schema.TypeString,
@@ -190,9 +190,9 @@ 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 | 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",
+ Description: fmt.Sprintf("The plural object type of the schema object on which privileges will be granted. Valid values are: %s", strings.Join(sdk.ValidGrantToFuturePluralObjectTypesString, " | ")),
ForceNew: true,
- ValidateDiagFunc: ValidGrantedPluralObjectType(),
+ ValidateDiagFunc: StringInSlice(sdk.ValidGrantToFuturePluralObjectTypesString, true),
},
"in_database": {
Type: schema.TypeString,
diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnAll_InDatabase/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnAll_InDatabase/test.tf
index 7fa86e21f7..b787a89214 100644
--- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnAll_InDatabase/test.tf
+++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnAll_InDatabase/test.tf
@@ -5,7 +5,7 @@ resource "snowflake_grant_privileges_to_account_role" "test" {
on_schema_object {
all {
- object_type_plural = "TABLES"
+ object_type_plural = var.object_type_plural
in_database = var.database
}
}
diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnAll_InDatabase/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnAll_InDatabase/variables.tf
index 0e22e903d7..fde4549568 100644
--- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnAll_InDatabase/variables.tf
+++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnAll_InDatabase/variables.tf
@@ -10,6 +10,10 @@ variable "database" {
type = string
}
+variable "object_type_plural" {
+ type = string
+}
+
variable "with_grant_option" {
type = bool
}
diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnFuture_InDatabase/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnFuture_InDatabase/test.tf
index ed7804ce4b..4da613126e 100644
--- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnFuture_InDatabase/test.tf
+++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnFuture_InDatabase/test.tf
@@ -5,7 +5,7 @@ resource "snowflake_grant_privileges_to_account_role" "test" {
on_schema_object {
future {
- object_type_plural = "TABLES"
+ object_type_plural = var.object_type_plural
in_database = var.database
}
}
diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnFuture_InDatabase/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnFuture_InDatabase/variables.tf
index 0e22e903d7..fde4549568 100644
--- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnFuture_InDatabase/variables.tf
+++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToAccountRole/OnSchemaObject_OnFuture_InDatabase/variables.tf
@@ -10,6 +10,10 @@ variable "database" {
type = string
}
+variable "object_type_plural" {
+ type = string
+}
+
variable "with_grant_option" {
type = bool
}
diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnAll_InDatabase/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnAll_InDatabase/test.tf
index 230a702d23..75e38e11c6 100644
--- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnAll_InDatabase/test.tf
+++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnAll_InDatabase/test.tf
@@ -5,7 +5,7 @@ resource "snowflake_grant_privileges_to_database_role" "test" {
on_schema_object {
all {
- object_type_plural = "TABLES"
+ object_type_plural = var.object_type_plural
in_database = "\"${var.database}\""
}
}
diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnAll_InDatabase/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnAll_InDatabase/variables.tf
index 0e22e903d7..fde4549568 100644
--- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnAll_InDatabase/variables.tf
+++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnAll_InDatabase/variables.tf
@@ -10,6 +10,10 @@ variable "database" {
type = string
}
+variable "object_type_plural" {
+ type = string
+}
+
variable "with_grant_option" {
type = bool
}
diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnFuture_InDatabase/test.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnFuture_InDatabase/test.tf
index 3463a24a8f..42b8c2a0b1 100644
--- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnFuture_InDatabase/test.tf
+++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnFuture_InDatabase/test.tf
@@ -5,7 +5,7 @@ resource "snowflake_grant_privileges_to_database_role" "test" {
on_schema_object {
future {
- object_type_plural = "TABLES"
+ object_type_plural = var.object_type_plural
in_database = "\"${var.database}\""
}
}
diff --git a/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnFuture_InDatabase/variables.tf b/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnFuture_InDatabase/variables.tf
index 0e22e903d7..fde4549568 100644
--- a/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnFuture_InDatabase/variables.tf
+++ b/pkg/resources/testdata/TestAcc_GrantPrivilegesToDatabaseRole/OnSchemaObject_OnFuture_InDatabase/variables.tf
@@ -10,6 +10,10 @@ variable "database" {
type = string
}
+variable "object_type_plural" {
+ type = string
+}
+
variable "with_grant_option" {
type = bool
}
diff --git a/pkg/sdk/grants_validations.go b/pkg/sdk/grants_validations.go
index 1df10d643e..7b9e92f7c7 100644
--- a/pkg/sdk/grants_validations.go
+++ b/pkg/sdk/grants_validations.go
@@ -61,9 +61,44 @@ var validGrantOwnershipObjectTypes = []ObjectType{
ObjectTypeWarehouse,
}
+var validGrantToObjectTypes = []ObjectType{
+ ObjectTypeAlert,
+ ObjectTypeDynamicTable,
+ ObjectTypeEventTable,
+ ObjectTypeFileFormat,
+ ObjectTypeFunction,
+ ObjectTypeProcedure,
+ ObjectTypeSecret,
+ ObjectTypeSequence,
+ ObjectTypePipe,
+ ObjectTypeMaskingPolicy,
+ ObjectTypePasswordPolicy,
+ ObjectTypeRowAccessPolicy,
+ ObjectTypeSessionPolicy,
+ ObjectTypeTag,
+ ObjectTypeStage,
+ ObjectTypeStream,
+ ObjectTypeTable,
+ ObjectTypeExternalTable,
+ ObjectTypeTask,
+ ObjectTypeView,
+ ObjectTypeMaterializedView,
+ ObjectTypeNetworkRule,
+ ObjectTypePackagesPolicy,
+ ObjectTypeStreamlit,
+ ObjectTypeIcebergTable,
+}
+
+var invalidGrantToFutureObjectTypes = []ObjectType{
+ ObjectTypeStreamlit,
+}
+
var (
ValidGrantOwnershipObjectTypesString = make([]string, len(validGrantOwnershipObjectTypes))
ValidGrantOwnershipPluralObjectTypesString = make([]string, len(validGrantOwnershipObjectTypes))
+ ValidGrantToObjectTypesString = make([]string, len(validGrantToObjectTypes))
+ ValidGrantToPluralObjectTypesString = make([]string, len(validGrantToObjectTypes))
+ ValidGrantToFuturePluralObjectTypesString = make([]string, 0)
)
func init() {
@@ -71,6 +106,13 @@ func init() {
ValidGrantOwnershipObjectTypesString[i] = objectType.String()
ValidGrantOwnershipPluralObjectTypesString[i] = objectType.Plural().String()
}
+ for i, objectType := range validGrantToObjectTypes {
+ ValidGrantToObjectTypesString[i] = objectType.String()
+ ValidGrantToPluralObjectTypesString[i] = objectType.Plural().String()
+ if !slices.Contains(invalidGrantToFutureObjectTypes, objectType) {
+ ValidGrantToFuturePluralObjectTypesString = append(ValidGrantToFuturePluralObjectTypesString, objectType.Plural().String())
+ }
+ }
}
func (opts *GrantPrivilegesToAccountRoleOptions) validate() error {
diff --git a/pkg/sdk/testint/streamlits_integration_test.go b/pkg/sdk/testint/streamlits_integration_test.go
index 1680389baa..ace858a844 100644
--- a/pkg/sdk/testint/streamlits_integration_test.go
+++ b/pkg/sdk/testint/streamlits_integration_test.go
@@ -6,6 +6,7 @@ import (
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/internal/collections"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/internal/random"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -69,6 +70,139 @@ func TestInt_Streamlits(t *testing.T) {
assertStreamlit(t, id, comment, "")
})
+ // TODO [SNOW-1272222]: fix the test when it starts working on Snowflake side
+ t.Run("grant privilege to streamlits to role", func(t *testing.T) {
+ stage, cleanupStage := createStage(t, client, sdk.NewSchemaObjectIdentifier(TestDatabaseName, TestSchemaName, random.AlphaN(4)))
+ t.Cleanup(cleanupStage)
+
+ role, roleCleanup := createRole(t, client)
+ t.Cleanup(roleCleanup)
+
+ comment := random.StringN(4)
+ id := sdk.NewSchemaObjectIdentifier(databaseTest.Name, schemaTest.Name, random.StringN(4))
+ mainFile := "manifest.yml"
+ request := sdk.NewCreateStreamlitRequest(id, stage.Location(), mainFile).WithComment(&comment)
+ err := client.Streamlits.Create(ctx, request)
+ require.NoError(t, err)
+ t.Cleanup(cleanupStreamlitHandle(id))
+
+ assertStreamlit(t, id, comment, "")
+
+ privileges := &sdk.AccountRoleGrantPrivileges{
+ SchemaObjectPrivileges: []sdk.SchemaObjectPrivilege{sdk.SchemaObjectPrivilegeUsage},
+ }
+ on := &sdk.AccountRoleGrantOn{
+ SchemaObject: &sdk.GrantOnSchemaObject{
+ SchemaObject: &sdk.Object{
+ ObjectType: sdk.ObjectTypeStreamlit,
+ Name: id,
+ },
+ },
+ }
+ err = client.Grants.GrantPrivilegesToAccountRole(ctx, privileges, on, role.ID(), nil)
+ require.NoError(t, err)
+
+ grants, err := client.Grants.Show(ctx, &sdk.ShowGrantOptions{
+ To: &sdk.ShowGrantsTo{
+ Role: role.ID(),
+ },
+ })
+ require.NoError(t, err)
+ assert.Equal(t, 1, len(grants))
+ assert.Equal(t, sdk.SchemaObjectPrivilegeUsage.String(), grants[0].Privilege)
+ assert.Equal(t, id.FullyQualifiedName(), grants[0].Name.FullyQualifiedName())
+
+ on = &sdk.AccountRoleGrantOn{
+ SchemaObject: &sdk.GrantOnSchemaObject{
+ Future: &sdk.GrantOnSchemaObjectIn{
+ PluralObjectType: sdk.PluralObjectTypeStreamlits,
+ InDatabase: sdk.Pointer(sdk.NewAccountObjectIdentifier(TestDatabaseName)),
+ },
+ },
+ }
+ err = client.Grants.GrantPrivilegesToAccountRole(ctx, privileges, on, role.ID(), nil)
+ require.Error(t, err)
+ require.ErrorContains(t, err, "Unsupported feature 'STREAMLIT'")
+
+ on = &sdk.AccountRoleGrantOn{
+ SchemaObject: &sdk.GrantOnSchemaObject{
+ All: &sdk.GrantOnSchemaObjectIn{
+ PluralObjectType: sdk.PluralObjectTypeStreamlits,
+ InDatabase: sdk.Pointer(sdk.NewAccountObjectIdentifier(TestDatabaseName)),
+ },
+ },
+ }
+ err = client.Grants.GrantPrivilegesToAccountRole(ctx, privileges, on, role.ID(), nil)
+ require.NoError(t, err)
+ })
+
+ // TODO [SNOW-1272222]: fix the test when it starts working on Snowflake side
+ t.Run("grant privilege to streamlits to database role", func(t *testing.T) {
+ stage, cleanupStage := createStage(t, client, sdk.NewSchemaObjectIdentifier(TestDatabaseName, TestSchemaName, random.AlphaN(4)))
+ t.Cleanup(cleanupStage)
+
+ databaseRole, databaseRoleCleanup := createDatabaseRole(t, client, testDb(t))
+ t.Cleanup(databaseRoleCleanup)
+
+ databaseRoleId := sdk.NewDatabaseObjectIdentifier(testDb(t).Name, databaseRole.Name)
+
+ comment := random.StringN(4)
+ id := sdk.NewSchemaObjectIdentifier(databaseTest.Name, schemaTest.Name, random.StringN(4))
+ mainFile := "manifest.yml"
+ request := sdk.NewCreateStreamlitRequest(id, stage.Location(), mainFile).WithComment(&comment)
+ err := client.Streamlits.Create(ctx, request)
+ require.NoError(t, err)
+ t.Cleanup(cleanupStreamlitHandle(id))
+
+ assertStreamlit(t, id, comment, "")
+
+ privileges := &sdk.DatabaseRoleGrantPrivileges{
+ SchemaObjectPrivileges: []sdk.SchemaObjectPrivilege{sdk.SchemaObjectPrivilegeUsage},
+ }
+ on := &sdk.DatabaseRoleGrantOn{
+ SchemaObject: &sdk.GrantOnSchemaObject{
+ SchemaObject: &sdk.Object{
+ ObjectType: sdk.ObjectTypeStreamlit,
+ Name: id,
+ },
+ },
+ }
+ err = client.Grants.GrantPrivilegesToDatabaseRole(ctx, privileges, on, databaseRoleId, nil)
+ require.NoError(t, err)
+
+ grants, err := client.Grants.Show(ctx, &sdk.ShowGrantOptions{
+ To: &sdk.ShowGrantsTo{
+ DatabaseRole: databaseRoleId,
+ },
+ })
+ require.NoError(t, err)
+ // Expecting two grants because database role has usage on database by default
+ require.Equal(t, 2, len(grants))
+
+ on = &sdk.DatabaseRoleGrantOn{
+ SchemaObject: &sdk.GrantOnSchemaObject{
+ Future: &sdk.GrantOnSchemaObjectIn{
+ PluralObjectType: sdk.PluralObjectTypeStreamlits,
+ InDatabase: sdk.Pointer(sdk.NewAccountObjectIdentifier(TestDatabaseName)),
+ },
+ },
+ }
+ err = client.Grants.GrantPrivilegesToDatabaseRole(ctx, privileges, on, databaseRoleId, nil)
+ require.Error(t, err)
+ require.ErrorContains(t, err, "Unsupported feature 'STREAMLIT'")
+
+ on = &sdk.DatabaseRoleGrantOn{
+ SchemaObject: &sdk.GrantOnSchemaObject{
+ All: &sdk.GrantOnSchemaObjectIn{
+ PluralObjectType: sdk.PluralObjectTypeStreamlits,
+ InDatabase: sdk.Pointer(sdk.NewAccountObjectIdentifier(TestDatabaseName)),
+ },
+ },
+ }
+ err = client.Grants.GrantPrivilegesToDatabaseRole(ctx, privileges, on, databaseRoleId, nil)
+ require.NoError(t, err)
+ })
+
t.Run("alter streamlit: set", func(t *testing.T) {
stage, cleanupStage := createStage(t, client, sdk.NewSchemaObjectIdentifier(TestDatabaseName, TestSchemaName, random.AlphaN(4)))
t.Cleanup(cleanupStage)
diff --git a/templates/resources/grant_privileges_to_account_role.md.tmpl b/templates/resources/grant_privileges_to_account_role.md.tmpl
index f591bf021c..e12d772e80 100644
--- a/templates/resources/grant_privileges_to_account_role.md.tmpl
+++ b/templates/resources/grant_privileges_to_account_role.md.tmpl
@@ -29,6 +29,9 @@ description: |-
{{ .SchemaMarkdown | trimspace }}
+## Known limitations
+- Setting the `CREATE SNOWFLAKE.ML.ANOMALY_DETECTION` or `CREATE SNOWFLAKE.ML.FORECAST` privileges on schema results in a permadiff because of the probably incorrect Snowflake's behavior of `SHOW GRANTS ON `. More in the [comment](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2651#issuecomment-2022634952).
+
## Import
~> **Note** All the ..._name parts should be fully qualified names (where every part is quoted), e.g. for schema object it is `""."".""`
diff --git a/templates/resources/grant_privileges_to_share.md.tmpl b/templates/resources/grant_privileges_to_share.md.tmpl
index ebfe2a54df..2132602c86 100644
--- a/templates/resources/grant_privileges_to_share.md.tmpl
+++ b/templates/resources/grant_privileges_to_share.md.tmpl
@@ -24,6 +24,9 @@ description: |-
{{ .SchemaMarkdown | trimspace }}
+## Known limitations
+- Setting the `CREATE SNOWFLAKE.ML.ANOMALY_DETECTION` or `CREATE SNOWFLAKE.ML.FORECAST` privileges on schema results in a permadiff because of the probably incorrect Snowflake's behavior of `SHOW GRANTS ON `. More in the [comment](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2651#issuecomment-2022634952).
+
## Import
~> **Note** All the ..._name parts should be fully qualified names, e.g. for database object it is `"".""`