Skip to content

Commit

Permalink
feat: Fix issues 2651 2656 (#2659)
Browse files Browse the repository at this point in the history
- Prove errors with granting ML privileges (references: #2651):
  - currently the test only
  - known issues section added to the docs
  - the case will be followed up on Snowflake side
- Add possibility to grant privileges to STREAMLIT (references #2656):
  - moved the validations to SDK
  - descriptions made more general
- added tests inside SDK to prove that given streamlit an ALL works, but
the FUTURE results in error
- added tests on resources side (no tests added in old
snowflake_grant_privilege_to_role resource)
  - split ALL and FUTURE to have correct validation and description
  -  the case will be followed up on Snowflake side
  • Loading branch information
sfc-gh-asawicki committed Mar 28, 2024
1 parent 4a73721 commit 7fa09cc
Show file tree
Hide file tree
Showing 22 changed files with 550 additions and 142 deletions.
11 changes: 7 additions & 4 deletions docs/resources/grant_privileges_to_account_role.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

<a id="nestedblock--on_schema_object--all"></a>
### 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:

Expand All @@ -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 <object_type> <object_name>`. 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 `"<database_name>"."<schema_name>"."<object_name>"`
Expand Down
6 changes: 3 additions & 3 deletions docs/resources/grant_privileges_to_database_role.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

<a id="nestedblock--on_schema_object--all"></a>
### 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:

Expand All @@ -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:

Expand Down
6 changes: 3 additions & 3 deletions docs/resources/grant_privileges_to_role.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

<a id="nestedblock--on_schema_object--all"></a>
### 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:

Expand All @@ -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:

Expand Down
3 changes: 3 additions & 0 deletions docs/resources/grant_privileges_to_share.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <object_type> <object_name>`. 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 `"<database_name>"."<object_name>"`
Expand Down
64 changes: 1 addition & 63 deletions pkg/resources/grant_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
}
52 changes: 27 additions & 25 deletions pkg/resources/grant_privileges_to_account_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,15 +196,15 @@ 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",
},
ConflictsWith: []string{
"on_schema_object.0.all",
"on_schema_object.0.future",
},
ValidateDiagFunc: ValidGrantedObjectType(),
ValidateDiagFunc: StringInSlice(sdk.ValidGrantToObjectTypesString, true),
},
"object_name": {
Type: schema.TypeString,
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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 {
Expand Down
Loading

0 comments on commit 7fa09cc

Please sign in to comment.