diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md
index 8bbbc7fa7c..10279af5fe 100644
--- a/MIGRATION_GUIDE.md
+++ b/MIGRATION_GUIDE.md
@@ -6,6 +6,23 @@ across different versions.
## v0.94.x ➞ v0.95.0
+### *(breaking change)* database roles data source; field rename, schema structure changes, and adding missing filtering options
+
+- `database` renamed to `in_database`
+- Added `like` and `limit` filtering options
+- `SHOW DATABASE ROLES` output is now put inside `database_roles.*.show_output`. Here's the list of currently available fields:
+ - `created_on`
+ - `name`
+ - `is_default`
+ - `is_current`
+ - `is_inherited`
+ - `granted_to_roles`
+ - `granted_to_database_roles`
+ - `granted_database_roles`
+ - `owner`
+ - `comment`
+ - `owner_role_type`
+
### snowflake_view resource changes
New fields:
- `row_access_policy`
diff --git a/Makefile b/Makefile
index de4149be2e..c47bd5a031 100644
--- a/Makefile
+++ b/Makefile
@@ -156,10 +156,10 @@ clean-resource-show-output-assertions: ## Clean resource parameters assertions
generate-resource-model-builders: ## Generate resource model builders
go generate ./pkg/acceptance/bettertestspoc/config/model/generate.go
-clean-resource-model-builder: ## Clean resource model builders
+clean-resource-model-builders: ## Clean resource model builders
rm -f ./pkg/acceptance/bettertestspoc/config/model/*_gen.go
-clean-all-assertions-and-config-models: clean-snowflake-object-assertions clean-snowflake-object-parameters-assertions clean-resource-assertions clean-resource-parameters-assertions clean-resource-show-output-assertions clean-resource-model-builder ## clean all generated assertions and config models
+clean-all-assertions-and-config-models: clean-snowflake-object-assertions clean-snowflake-object-parameters-assertions clean-resource-assertions clean-resource-parameters-assertions clean-resource-show-output-assertions clean-resource-model-builders ## clean all generated assertions and config models
generate-all-assertions-and-config-models: generate-snowflake-object-assertions generate-snowflake-object-parameters-assertions generate-resource-assertions generate-resource-parameters-assertions generate-resource-show-output-assertions generate-resource-model-builders ## generate all assertions and config models
diff --git a/docs/data-sources/database_roles.md b/docs/data-sources/database_roles.md
index 4d3b7957f2..8298c3d9ad 100644
--- a/docs/data-sources/database_roles.md
+++ b/docs/data-sources/database_roles.md
@@ -5,6 +5,8 @@ description: |-
---
+!> **V1 release candidate** This data source was reworked and is a release candidate for the V1. We do not expect significant changes in it before the V1. We will welcome any feedback and adjust the data source if needed. Any errors reported will be resolved with a higher priority. We encourage checking this data source out before the V1 release. Please follow the [migration guide](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/MIGRATION_GUIDE.md#v0920--v0930) to use it.
+
# snowflake_database_roles (Data Source)
@@ -22,18 +24,50 @@ data "snowflake_database_roles" "db_roles" {
### Required
-- `database` (String) The database from which to return the database roles from.
+- `in_database` (String) The database from which to return the database roles from.
+
+### Optional
+
+- `like` (String) Filters the output with **case-insensitive** pattern, with support for SQL wildcard characters (`%` and `_`).
+- `limit` (Block List, Max: 1) Limits the number of rows returned. If the `limit.from` is set, then the limit wll start from the first element matched by the expression. The expression is only used to match with the first element, later on the elements are not matched by the prefix, but you can enforce a certain pattern with `starts_with` or `like`. (see [below for nested schema](#nestedblock--limit))
### Read-Only
-- `database_roles` (List of Object) Lists all the database roles in a specified database. (see [below for nested schema](#nestedatt--database_roles))
+- `database_roles` (List of Object) Holds the aggregated output of all database role details queries. (see [below for nested schema](#nestedatt--database_roles))
- `id` (String) The ID of this resource.
+
+### Nested Schema for `limit`
+
+Required:
+
+- `rows` (Number) The maximum number of rows to return.
+
+Optional:
+
+- `from` (String) Specifies a **case-sensitive** pattern that is used to match object name. After the first match, the limit on the number of rows will be applied.
+
+
### Nested Schema for `database_roles`
Read-Only:
+- `show_output` (List of Object) (see [below for nested schema](#nestedobjatt--database_roles--show_output))
+
+
+### Nested Schema for `database_roles.show_output`
+
+Read-Only:
+
- `comment` (String)
+- `created_on` (String)
+- `granted_database_roles` (Number)
+- `granted_to_database_roles` (Number)
+- `granted_to_roles` (Number)
+- `is_current` (Boolean)
+- `is_default` (Boolean)
+- `is_inherited` (Boolean)
- `name` (String)
- `owner` (String)
+- `owner_role_type` (String)
diff --git a/docs/resources/database_role.md b/docs/resources/database_role.md
index 6d6dd85817..613024f51e 100644
--- a/docs/resources/database_role.md
+++ b/docs/resources/database_role.md
@@ -5,6 +5,8 @@ description: |-
---
+!> **V1 release candidate** This resource was reworked and is a release candidate for the V1. We do not expect significant changes in it before the V1. We will welcome any feedback and adjust the resource if needed. Any errors reported will be resolved with a higher priority. We encourage checking this resource out before the V1 release.
+
# snowflake_database_role (Resource)
@@ -12,13 +14,16 @@ description: |-
## Example Usage
```terraform
-resource "snowflake_database_role" "db_role" {
- database = "database"
- name = "role_1"
- comment = "my db role"
+resource "snowflake_database" "test_database" {
+ name = "database_name"
}
-```
+resource "snowflake_database_role" "test_database_role" {
+ database = snowflake_database.test_database.fully_qualified_name
+ name = "database_role_name"
+ comment = "my database role"
+}
+```
-> **Note** Instead of using fully_qualified_name, you can reference objects managed outside Terraform by constructing a correct ID, consult [identifiers guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/identifiers#new-computed-fully-qualified-name-field-in-resources).
@@ -27,8 +32,8 @@ resource "snowflake_database_role" "db_role" {
### Required
-- `database` (String) The database in which to create the database role.
-- `name` (String) Specifies the identifier for the database role.
+- `database` (String) The database in which to create the database role. Due to technical limitations (read more [here](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/docs/technical-documentation/identifiers_rework_design_decisions.md#known-limitations-and-identifier-recommendations)), avoid using the following characters: `|`, `.`, `(`, `)`, `"`
+- `name` (String) Specifies the identifier for the database role. Due to technical limitations (read more [here](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/docs/technical-documentation/identifiers_rework_design_decisions.md#known-limitations-and-identifier-recommendations)), avoid using the following characters: `|`, `.`, `(`, `)`, `"`
### Optional
@@ -38,11 +43,29 @@ resource "snowflake_database_role" "db_role" {
- `fully_qualified_name` (String) Fully qualified name of the resource. For more information, see [object name resolution](https://docs.snowflake.com/en/sql-reference/name-resolution).
- `id` (String) The ID of this resource.
+- `show_output` (List of Object) Outputs the result of `SHOW DATABASE ROLES` for the given database role. Note that this value will be only recomputed whenever comment field changes. (see [below for nested schema](#nestedatt--show_output))
+
+
+### Nested Schema for `show_output`
+
+Read-Only:
+
+- `comment` (String)
+- `created_on` (String)
+- `granted_database_roles` (Number)
+- `granted_to_database_roles` (Number)
+- `granted_to_roles` (Number)
+- `is_current` (Boolean)
+- `is_default` (Boolean)
+- `is_inherited` (Boolean)
+- `name` (String)
+- `owner` (String)
+- `owner_role_type` (String)
## Import
Import is supported using the following syntax:
```shell
-terraform import snowflake_database_role.example 'dbName|roleName'
+terraform import snowflake_database_role.example '"".""'
```
diff --git a/examples/resources/snowflake_database_role/import.sh b/examples/resources/snowflake_database_role/import.sh
index b13ea1e783..256d054a74 100644
--- a/examples/resources/snowflake_database_role/import.sh
+++ b/examples/resources/snowflake_database_role/import.sh
@@ -1 +1 @@
-terraform import snowflake_database_role.example 'dbName|roleName'
+terraform import snowflake_database_role.example '"".""'
diff --git a/examples/resources/snowflake_database_role/resource.tf b/examples/resources/snowflake_database_role/resource.tf
index 4d061c88e5..7da683bbb7 100644
--- a/examples/resources/snowflake_database_role/resource.tf
+++ b/examples/resources/snowflake_database_role/resource.tf
@@ -1,5 +1,9 @@
-resource "snowflake_database_role" "db_role" {
- database = "database"
- name = "role_1"
- comment = "my db role"
+resource "snowflake_database" "test_database" {
+ name = "database_name"
+}
+
+resource "snowflake_database_role" "test_database_role" {
+ database = snowflake_database.test_database.fully_qualified_name
+ name = "database_role_name"
+ comment = "my database role"
}
diff --git a/pkg/acceptance/bettertestspoc/README.md b/pkg/acceptance/bettertestspoc/README.md
index f43ce258b0..3dca522056 100644
--- a/pkg/acceptance/bettertestspoc/README.md
+++ b/pkg/acceptance/bettertestspoc/README.md
@@ -1,4 +1,19 @@
# Better tests poc
+
+
+* [Better tests poc](#better-tests-poc)
+ * [How it works](#how-it-works)
+ * [Adding new resource assertions](#adding-new-resource-assertions)
+ * [Adding new resource show output assertions](#adding-new-resource-show-output-assertions)
+ * [Adding new resource parameters assertions](#adding-new-resource-parameters-assertions)
+ * [Adding new Snowflake object assertions](#adding-new-snowflake-object-assertions)
+ * [Adding new Snowflake object parameters assertions](#adding-new-snowflake-object-parameters-assertions)
+ * [Adding new resource config model builders](#adding-new-resource-config-model-builders)
+ * [Running the generators](#running-the-generators)
+ * [Example usage in practice](#example-usage-in-practice)
+ * [Known limitations/planned improvements](#known-limitationsplanned-improvements)
+
+
This package contains a quick implementation of helpers that should allow us a quicker, more pleasant, and more readable implementation of tests, mainly the acceptance ones.
It contains the following packages:
- `assert` - all the assertions reside here. Also, the utilities to build assertions for new objects. All the current assertions are generated. The currently supported assertions are:
@@ -326,3 +341,4 @@ func (w *WarehouseDatasourceShowOutputAssert) IsEmpty() {
- distinguish between different enum types (TODO left in `assert/resourceshowoutputassert/gen/templates.go`)
- support the rest of attribute types in config model builders (TODO left in `config/model/gen/model.go`)
- parametrize test client helper used - integration versus acceptance tests - this has to be changed in the generator too (TODO left in `assert/objectassert/user_snowflake_ext.go`)
+- Omit computed fields in the model (like FullyQualifiedName), because it doesn't make sense to set them
diff --git a/pkg/acceptance/bettertestspoc/assert/objectassert/database_role_snowflake_gen.go b/pkg/acceptance/bettertestspoc/assert/objectassert/database_role_snowflake_gen.go
new file mode 100644
index 0000000000..2fe7e08b85
--- /dev/null
+++ b/pkg/acceptance/bettertestspoc/assert/objectassert/database_role_snowflake_gen.go
@@ -0,0 +1,163 @@
+// Code generated by assertions generator; DO NOT EDIT.
+
+package objectassert
+
+import (
+ "fmt"
+ "testing"
+
+ acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance"
+
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
+)
+
+type DatabaseRoleAssert struct {
+ *assert.SnowflakeObjectAssert[sdk.DatabaseRole, sdk.DatabaseObjectIdentifier]
+}
+
+func DatabaseRole(t *testing.T, id sdk.DatabaseObjectIdentifier) *DatabaseRoleAssert {
+ t.Helper()
+ return &DatabaseRoleAssert{
+ assert.NewSnowflakeObjectAssertWithProvider(sdk.ObjectTypeDatabaseRole, id, acc.TestClient().DatabaseRole.Show),
+ }
+}
+
+func DatabaseRoleFromObject(t *testing.T, databaseRole *sdk.DatabaseRole) *DatabaseRoleAssert {
+ t.Helper()
+ return &DatabaseRoleAssert{
+ assert.NewSnowflakeObjectAssertWithObject(sdk.ObjectTypeDatabaseRole, databaseRole.ID(), databaseRole),
+ }
+}
+
+func (d *DatabaseRoleAssert) HasCreatedOn(expected string) *DatabaseRoleAssert {
+ d.AddAssertion(func(t *testing.T, o *sdk.DatabaseRole) error {
+ t.Helper()
+ if o.CreatedOn != expected {
+ return fmt.Errorf("expected created on: %v; got: %v", expected, o.CreatedOn)
+ }
+ return nil
+ })
+ return d
+}
+
+func (d *DatabaseRoleAssert) HasName(expected string) *DatabaseRoleAssert {
+ d.AddAssertion(func(t *testing.T, o *sdk.DatabaseRole) error {
+ t.Helper()
+ if o.Name != expected {
+ return fmt.Errorf("expected name: %v; got: %v", expected, o.Name)
+ }
+ return nil
+ })
+ return d
+}
+
+func (d *DatabaseRoleAssert) HasDatabaseName(expected string) *DatabaseRoleAssert {
+ d.AddAssertion(func(t *testing.T, o *sdk.DatabaseRole) error {
+ t.Helper()
+ if o.DatabaseName != expected {
+ return fmt.Errorf("expected database name: %v; got: %v", expected, o.DatabaseName)
+ }
+ return nil
+ })
+ return d
+}
+
+func (d *DatabaseRoleAssert) HasIsDefault(expected bool) *DatabaseRoleAssert {
+ d.AddAssertion(func(t *testing.T, o *sdk.DatabaseRole) error {
+ t.Helper()
+ if o.IsDefault != expected {
+ return fmt.Errorf("expected is default: %v; got: %v", expected, o.IsDefault)
+ }
+ return nil
+ })
+ return d
+}
+
+func (d *DatabaseRoleAssert) HasIsCurrent(expected bool) *DatabaseRoleAssert {
+ d.AddAssertion(func(t *testing.T, o *sdk.DatabaseRole) error {
+ t.Helper()
+ if o.IsCurrent != expected {
+ return fmt.Errorf("expected is current: %v; got: %v", expected, o.IsCurrent)
+ }
+ return nil
+ })
+ return d
+}
+
+func (d *DatabaseRoleAssert) HasIsInherited(expected bool) *DatabaseRoleAssert {
+ d.AddAssertion(func(t *testing.T, o *sdk.DatabaseRole) error {
+ t.Helper()
+ if o.IsInherited != expected {
+ return fmt.Errorf("expected is inherited: %v; got: %v", expected, o.IsInherited)
+ }
+ return nil
+ })
+ return d
+}
+
+func (d *DatabaseRoleAssert) HasGrantedToRoles(expected int) *DatabaseRoleAssert {
+ d.AddAssertion(func(t *testing.T, o *sdk.DatabaseRole) error {
+ t.Helper()
+ if o.GrantedToRoles != expected {
+ return fmt.Errorf("expected granted to roles: %v; got: %v", expected, o.GrantedToRoles)
+ }
+ return nil
+ })
+ return d
+}
+
+func (d *DatabaseRoleAssert) HasGrantedToDatabaseRoles(expected int) *DatabaseRoleAssert {
+ d.AddAssertion(func(t *testing.T, o *sdk.DatabaseRole) error {
+ t.Helper()
+ if o.GrantedToDatabaseRoles != expected {
+ return fmt.Errorf("expected granted to database roles: %v; got: %v", expected, o.GrantedToDatabaseRoles)
+ }
+ return nil
+ })
+ return d
+}
+
+func (d *DatabaseRoleAssert) HasGrantedDatabaseRoles(expected int) *DatabaseRoleAssert {
+ d.AddAssertion(func(t *testing.T, o *sdk.DatabaseRole) error {
+ t.Helper()
+ if o.GrantedDatabaseRoles != expected {
+ return fmt.Errorf("expected granted database roles: %v; got: %v", expected, o.GrantedDatabaseRoles)
+ }
+ return nil
+ })
+ return d
+}
+
+func (d *DatabaseRoleAssert) HasOwner(expected string) *DatabaseRoleAssert {
+ d.AddAssertion(func(t *testing.T, o *sdk.DatabaseRole) error {
+ t.Helper()
+ if o.Owner != expected {
+ return fmt.Errorf("expected owner: %v; got: %v", expected, o.Owner)
+ }
+ return nil
+ })
+ return d
+}
+
+func (d *DatabaseRoleAssert) HasComment(expected string) *DatabaseRoleAssert {
+ d.AddAssertion(func(t *testing.T, o *sdk.DatabaseRole) error {
+ t.Helper()
+ if o.Comment != expected {
+ return fmt.Errorf("expected comment: %v; got: %v", expected, o.Comment)
+ }
+ return nil
+ })
+ return d
+}
+
+func (d *DatabaseRoleAssert) HasOwnerRoleType(expected string) *DatabaseRoleAssert {
+ d.AddAssertion(func(t *testing.T, o *sdk.DatabaseRole) error {
+ t.Helper()
+ if o.OwnerRoleType != expected {
+ return fmt.Errorf("expected owner role type: %v; got: %v", expected, o.OwnerRoleType)
+ }
+ return nil
+ })
+ return d
+}
diff --git a/pkg/acceptance/bettertestspoc/assert/objectassert/gen/sdk_object_def.go b/pkg/acceptance/bettertestspoc/assert/objectassert/gen/sdk_object_def.go
index 47e1a3b2e4..65c3abf062 100644
--- a/pkg/acceptance/bettertestspoc/assert/objectassert/gen/sdk_object_def.go
+++ b/pkg/acceptance/bettertestspoc/assert/objectassert/gen/sdk_object_def.go
@@ -12,6 +12,11 @@ type SdkObjectDef struct {
}
var allStructs = []SdkObjectDef{
+ {
+ IdType: "sdk.DatabaseObjectIdentifier",
+ ObjectType: sdk.ObjectTypeDatabaseRole,
+ ObjectStruct: sdk.DatabaseRole{},
+ },
{
IdType: "sdk.AccountObjectIdentifier",
ObjectType: sdk.ObjectTypeUser,
diff --git a/pkg/acceptance/bettertestspoc/assert/resourceassert/database_role_resource_gen.go b/pkg/acceptance/bettertestspoc/assert/resourceassert/database_role_resource_gen.go
new file mode 100644
index 0000000000..09887b7326
--- /dev/null
+++ b/pkg/acceptance/bettertestspoc/assert/resourceassert/database_role_resource_gen.go
@@ -0,0 +1,77 @@
+// Code generated by assertions generator; DO NOT EDIT.
+
+package resourceassert
+
+import (
+ "testing"
+
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert"
+)
+
+type DatabaseRoleResourceAssert struct {
+ *assert.ResourceAssert
+}
+
+func DatabaseRoleResource(t *testing.T, name string) *DatabaseRoleResourceAssert {
+ t.Helper()
+
+ return &DatabaseRoleResourceAssert{
+ ResourceAssert: assert.NewResourceAssert(name, "resource"),
+ }
+}
+
+func ImportedDatabaseRoleResource(t *testing.T, id string) *DatabaseRoleResourceAssert {
+ t.Helper()
+
+ return &DatabaseRoleResourceAssert{
+ ResourceAssert: assert.NewImportedResourceAssert(id, "imported resource"),
+ }
+}
+
+///////////////////////////////////
+// Attribute value string checks //
+///////////////////////////////////
+
+func (d *DatabaseRoleResourceAssert) HasCommentString(expected string) *DatabaseRoleResourceAssert {
+ d.AddAssertion(assert.ValueSet("comment", expected))
+ return d
+}
+
+func (d *DatabaseRoleResourceAssert) HasDatabaseString(expected string) *DatabaseRoleResourceAssert {
+ d.AddAssertion(assert.ValueSet("database", expected))
+ return d
+}
+
+func (d *DatabaseRoleResourceAssert) HasFullyQualifiedNameString(expected string) *DatabaseRoleResourceAssert {
+ d.AddAssertion(assert.ValueSet("fully_qualified_name", expected))
+ return d
+}
+
+func (d *DatabaseRoleResourceAssert) HasNameString(expected string) *DatabaseRoleResourceAssert {
+ d.AddAssertion(assert.ValueSet("name", expected))
+ return d
+}
+
+////////////////////////////
+// Attribute empty checks //
+////////////////////////////
+
+func (d *DatabaseRoleResourceAssert) HasNoComment() *DatabaseRoleResourceAssert {
+ d.AddAssertion(assert.ValueNotSet("comment"))
+ return d
+}
+
+func (d *DatabaseRoleResourceAssert) HasNoDatabase() *DatabaseRoleResourceAssert {
+ d.AddAssertion(assert.ValueNotSet("database"))
+ return d
+}
+
+func (d *DatabaseRoleResourceAssert) HasNoFullyQualifiedName() *DatabaseRoleResourceAssert {
+ d.AddAssertion(assert.ValueNotSet("fully_qualified_name"))
+ return d
+}
+
+func (d *DatabaseRoleResourceAssert) HasNoName() *DatabaseRoleResourceAssert {
+ d.AddAssertion(assert.ValueNotSet("name"))
+ return d
+}
diff --git a/pkg/acceptance/bettertestspoc/assert/resourceassert/gen/resource_schema_def.go b/pkg/acceptance/bettertestspoc/assert/resourceassert/gen/resource_schema_def.go
index 746291bbec..6c803e714f 100644
--- a/pkg/acceptance/bettertestspoc/assert/resourceassert/gen/resource_schema_def.go
+++ b/pkg/acceptance/bettertestspoc/assert/resourceassert/gen/resource_schema_def.go
@@ -33,4 +33,8 @@ var allResourceSchemaDefs = []ResourceSchemaDef{
name: "View",
schema: resources.View().Schema,
},
+ {
+ name: "DatabaseRole",
+ schema: resources.DatabaseRole().Schema,
+ },
}
diff --git a/pkg/acceptance/bettertestspoc/assert/resourceassert/user_resource_gen.go b/pkg/acceptance/bettertestspoc/assert/resourceassert/user_resource_gen.go
index 2693a8e9d4..c491866e99 100644
--- a/pkg/acceptance/bettertestspoc/assert/resourceassert/user_resource_gen.go
+++ b/pkg/acceptance/bettertestspoc/assert/resourceassert/user_resource_gen.go
@@ -167,6 +167,11 @@ func (u *UserResourceAssert) HasFirstNameString(expected string) *UserResourceAs
return u
}
+func (u *UserResourceAssert) HasFullyQualifiedNameString(expected string) *UserResourceAssert {
+ u.AddAssertion(assert.ValueSet("fully_qualified_name", expected))
+ return u
+}
+
func (u *UserResourceAssert) HasGeographyOutputFormatString(expected string) *UserResourceAssert {
u.AddAssertion(assert.ValueSet("geography_output_format", expected))
return u
@@ -546,6 +551,11 @@ func (u *UserResourceAssert) HasNoFirstName() *UserResourceAssert {
return u
}
+func (u *UserResourceAssert) HasNoFullyQualifiedName() *UserResourceAssert {
+ u.AddAssertion(assert.ValueNotSet("fully_qualified_name"))
+ return u
+}
+
func (u *UserResourceAssert) HasNoGeographyOutputFormat() *UserResourceAssert {
u.AddAssertion(assert.ValueNotSet("geography_output_format"))
return u
diff --git a/pkg/acceptance/bettertestspoc/assert/resourceassert/warehouse_resource_gen.go b/pkg/acceptance/bettertestspoc/assert/resourceassert/warehouse_resource_gen.go
index fe8d54d8a1..c8eaa5f92b 100644
--- a/pkg/acceptance/bettertestspoc/assert/resourceassert/warehouse_resource_gen.go
+++ b/pkg/acceptance/bettertestspoc/assert/resourceassert/warehouse_resource_gen.go
@@ -52,6 +52,11 @@ func (w *WarehouseResourceAssert) HasEnableQueryAccelerationString(expected stri
return w
}
+func (w *WarehouseResourceAssert) HasFullyQualifiedNameString(expected string) *WarehouseResourceAssert {
+ w.AddAssertion(assert.ValueSet("fully_qualified_name", expected))
+ return w
+}
+
func (w *WarehouseResourceAssert) HasInitiallySuspendedString(expected string) *WarehouseResourceAssert {
w.AddAssertion(assert.ValueSet("initially_suspended", expected))
return w
@@ -136,6 +141,11 @@ func (w *WarehouseResourceAssert) HasNoEnableQueryAcceleration() *WarehouseResou
return w
}
+func (w *WarehouseResourceAssert) HasNoFullyQualifiedName() *WarehouseResourceAssert {
+ w.AddAssertion(assert.ValueNotSet("fully_qualified_name"))
+ return w
+}
+
func (w *WarehouseResourceAssert) HasNoInitiallySuspended() *WarehouseResourceAssert {
w.AddAssertion(assert.ValueNotSet("initially_suspended"))
return w
diff --git a/pkg/acceptance/bettertestspoc/assert/resourceshowoutputassert/database_role_show_output_gen.go b/pkg/acceptance/bettertestspoc/assert/resourceshowoutputassert/database_role_show_output_gen.go
new file mode 100644
index 0000000000..b4e699ca62
--- /dev/null
+++ b/pkg/acceptance/bettertestspoc/assert/resourceshowoutputassert/database_role_show_output_gen.go
@@ -0,0 +1,101 @@
+// Code generated by assertions generator; DO NOT EDIT.
+
+package resourceshowoutputassert
+
+import (
+ "testing"
+
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
+)
+
+// to ensure sdk package is used
+var _ = sdk.Object{}
+
+type DatabaseRoleShowOutputAssert struct {
+ *assert.ResourceAssert
+}
+
+func DatabaseRoleShowOutput(t *testing.T, name string) *DatabaseRoleShowOutputAssert {
+ t.Helper()
+
+ d := DatabaseRoleShowOutputAssert{
+ ResourceAssert: assert.NewResourceAssert(name, "show_output"),
+ }
+ d.AddAssertion(assert.ValueSet("show_output.#", "1"))
+ return &d
+}
+
+func ImportedDatabaseRoleShowOutput(t *testing.T, id string) *DatabaseRoleShowOutputAssert {
+ t.Helper()
+
+ d := DatabaseRoleShowOutputAssert{
+ ResourceAssert: assert.NewImportedResourceAssert(id, "show_output"),
+ }
+ d.AddAssertion(assert.ValueSet("show_output.#", "1"))
+ return &d
+}
+
+////////////////////////////
+// Attribute value checks //
+////////////////////////////
+
+func (d *DatabaseRoleShowOutputAssert) HasCreatedOn(expected string) *DatabaseRoleShowOutputAssert {
+ d.AddAssertion(assert.ResourceShowOutputValueSet("created_on", expected))
+ return d
+}
+
+func (d *DatabaseRoleShowOutputAssert) HasName(expected string) *DatabaseRoleShowOutputAssert {
+ d.AddAssertion(assert.ResourceShowOutputValueSet("name", expected))
+ return d
+}
+
+func (d *DatabaseRoleShowOutputAssert) HasDatabaseName(expected string) *DatabaseRoleShowOutputAssert {
+ d.AddAssertion(assert.ResourceShowOutputValueSet("database_name", expected))
+ return d
+}
+
+func (d *DatabaseRoleShowOutputAssert) HasIsDefault(expected bool) *DatabaseRoleShowOutputAssert {
+ d.AddAssertion(assert.ResourceShowOutputBoolValueSet("is_default", expected))
+ return d
+}
+
+func (d *DatabaseRoleShowOutputAssert) HasIsCurrent(expected bool) *DatabaseRoleShowOutputAssert {
+ d.AddAssertion(assert.ResourceShowOutputBoolValueSet("is_current", expected))
+ return d
+}
+
+func (d *DatabaseRoleShowOutputAssert) HasIsInherited(expected bool) *DatabaseRoleShowOutputAssert {
+ d.AddAssertion(assert.ResourceShowOutputBoolValueSet("is_inherited", expected))
+ return d
+}
+
+func (d *DatabaseRoleShowOutputAssert) HasGrantedToRoles(expected int) *DatabaseRoleShowOutputAssert {
+ d.AddAssertion(assert.ResourceShowOutputIntValueSet("granted_to_roles", expected))
+ return d
+}
+
+func (d *DatabaseRoleShowOutputAssert) HasGrantedToDatabaseRoles(expected int) *DatabaseRoleShowOutputAssert {
+ d.AddAssertion(assert.ResourceShowOutputIntValueSet("granted_to_database_roles", expected))
+ return d
+}
+
+func (d *DatabaseRoleShowOutputAssert) HasGrantedDatabaseRoles(expected int) *DatabaseRoleShowOutputAssert {
+ d.AddAssertion(assert.ResourceShowOutputIntValueSet("granted_database_roles", expected))
+ return d
+}
+
+func (d *DatabaseRoleShowOutputAssert) HasOwner(expected string) *DatabaseRoleShowOutputAssert {
+ d.AddAssertion(assert.ResourceShowOutputValueSet("owner", expected))
+ return d
+}
+
+func (d *DatabaseRoleShowOutputAssert) HasComment(expected string) *DatabaseRoleShowOutputAssert {
+ d.AddAssertion(assert.ResourceShowOutputValueSet("comment", expected))
+ return d
+}
+
+func (d *DatabaseRoleShowOutputAssert) HasOwnerRoleType(expected string) *DatabaseRoleShowOutputAssert {
+ d.AddAssertion(assert.ResourceShowOutputValueSet("owner_role_type", expected))
+ return d
+}
diff --git a/pkg/acceptance/bettertestspoc/config/model/database_role_model_gen.go b/pkg/acceptance/bettertestspoc/config/model/database_role_model_gen.go
new file mode 100644
index 0000000000..df3106e1cc
--- /dev/null
+++ b/pkg/acceptance/bettertestspoc/config/model/database_role_model_gen.go
@@ -0,0 +1,92 @@
+// Code generated by config model builder generator; DO NOT EDIT.
+
+package model
+
+import (
+ tfconfig "github.com/hashicorp/terraform-plugin-testing/config"
+
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/config"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources"
+)
+
+type DatabaseRoleModel struct {
+ Comment tfconfig.Variable `json:"comment,omitempty"`
+ Database tfconfig.Variable `json:"database,omitempty"`
+ FullyQualifiedName tfconfig.Variable `json:"fully_qualified_name,omitempty"`
+ Name tfconfig.Variable `json:"name,omitempty"`
+
+ *config.ResourceModelMeta
+}
+
+/////////////////////////////////////////////////
+// Basic builders (resource name and required) //
+/////////////////////////////////////////////////
+
+func DatabaseRole(
+ resourceName string,
+ database string,
+ name string,
+) *DatabaseRoleModel {
+ d := &DatabaseRoleModel{ResourceModelMeta: config.Meta(resourceName, resources.DatabaseRole)}
+ d.WithDatabase(database)
+ d.WithName(name)
+ return d
+}
+
+func DatabaseRoleWithDefaultMeta(
+ database string,
+ name string,
+) *DatabaseRoleModel {
+ d := &DatabaseRoleModel{ResourceModelMeta: config.DefaultMeta(resources.DatabaseRole)}
+ d.WithDatabase(database)
+ d.WithName(name)
+ return d
+}
+
+/////////////////////////////////
+// below all the proper values //
+/////////////////////////////////
+
+func (d *DatabaseRoleModel) WithComment(comment string) *DatabaseRoleModel {
+ d.Comment = tfconfig.StringVariable(comment)
+ return d
+}
+
+func (d *DatabaseRoleModel) WithDatabase(database string) *DatabaseRoleModel {
+ d.Database = tfconfig.StringVariable(database)
+ return d
+}
+
+func (d *DatabaseRoleModel) WithFullyQualifiedName(fullyQualifiedName string) *DatabaseRoleModel {
+ d.FullyQualifiedName = tfconfig.StringVariable(fullyQualifiedName)
+ return d
+}
+
+func (d *DatabaseRoleModel) WithName(name string) *DatabaseRoleModel {
+ d.Name = tfconfig.StringVariable(name)
+ return d
+}
+
+//////////////////////////////////////////
+// below it's possible to set any value //
+//////////////////////////////////////////
+
+func (d *DatabaseRoleModel) WithCommentValue(value tfconfig.Variable) *DatabaseRoleModel {
+ d.Comment = value
+ return d
+}
+
+func (d *DatabaseRoleModel) WithDatabaseValue(value tfconfig.Variable) *DatabaseRoleModel {
+ d.Database = value
+ return d
+}
+
+func (d *DatabaseRoleModel) WithFullyQualifiedNameValue(value tfconfig.Variable) *DatabaseRoleModel {
+ d.FullyQualifiedName = value
+ return d
+}
+
+func (d *DatabaseRoleModel) WithNameValue(value tfconfig.Variable) *DatabaseRoleModel {
+ d.Name = value
+ return d
+}
diff --git a/pkg/acceptance/bettertestspoc/config/model/gen/templates/definition.tmpl b/pkg/acceptance/bettertestspoc/config/model/gen/templates/definition.tmpl
index 274061be68..c61398e7dd 100644
--- a/pkg/acceptance/bettertestspoc/config/model/gen/templates/definition.tmpl
+++ b/pkg/acceptance/bettertestspoc/config/model/gen/templates/definition.tmpl
@@ -19,15 +19,17 @@ func {{ .Name }}(
resourceName string,
{{ range .Attributes -}}
{{- $attributeNameCamel := SnakeCaseToCamel .Name -}}
- {{ if .Required }}{{ FirstLetterLowercase $attributeNameCamel }} {{ .AttributeType }},{{ end }}
- {{- end }}
+ {{ if .Required -}}
+ {{ FirstLetterLowercase $attributeNameCamel }} {{ .AttributeType }},
+ {{ end }}
+ {{- end -}}
) *{{ $modelName }} {
{{ $modelVar }} := &{{ $modelName }}{ResourceModelMeta: config.Meta(resourceName, resources.{{ .Name }})}
{{ range .Attributes -}}
{{- $attributeNameCamel := SnakeCaseToCamel .Name -}}
- {{- if .Required -}}
+ {{ if .Required -}}
{{ $modelVar }}.With{{ $attributeNameCamel }}({{ FirstLetterLowercase $attributeNameCamel }})
- {{ end -}}
+ {{ end }}
{{- end -}}
return {{ $modelVar }}
}
@@ -35,15 +37,17 @@ func {{ .Name }}(
func {{ .Name }}WithDefaultMeta(
{{ range .Attributes -}}
{{- $attributeNameCamel := SnakeCaseToCamel .Name -}}
- {{ if .Required }}{{ FirstLetterLowercase $attributeNameCamel }} {{ .AttributeType }},{{ end }}
- {{- end }}
+ {{ if .Required -}}
+ {{ FirstLetterLowercase $attributeNameCamel }} {{ .AttributeType }},
+ {{ end }}
+ {{- end -}}
) *{{ $modelName }} {
{{ $modelVar }} := &{{ $modelName }}{ResourceModelMeta: config.DefaultMeta(resources.{{ .Name }})}
{{ range .Attributes -}}
{{- $attributeNameCamel := SnakeCaseToCamel .Name -}}
- {{- if .Required -}}
+ {{ if .Required -}}
{{ $modelVar }}.With{{ $attributeNameCamel }}({{ FirstLetterLowercase $attributeNameCamel }})
- {{ end -}}
+ {{ end }}
{{- end -}}
return {{ $modelVar }}
}
diff --git a/pkg/acceptance/bettertestspoc/config/model/user_model_gen.go b/pkg/acceptance/bettertestspoc/config/model/user_model_gen.go
index 8002163a6b..d24e499644 100644
--- a/pkg/acceptance/bettertestspoc/config/model/user_model_gen.go
+++ b/pkg/acceptance/bettertestspoc/config/model/user_model_gen.go
@@ -37,6 +37,7 @@ type UserModel struct {
ErrorOnNondeterministicMerge tfconfig.Variable `json:"error_on_nondeterministic_merge,omitempty"`
ErrorOnNondeterministicUpdate tfconfig.Variable `json:"error_on_nondeterministic_update,omitempty"`
FirstName tfconfig.Variable `json:"first_name,omitempty"`
+ FullyQualifiedName tfconfig.Variable `json:"fully_qualified_name,omitempty"`
GeographyOutputFormat tfconfig.Variable `json:"geography_output_format,omitempty"`
GeometryOutputFormat tfconfig.Variable `json:"geometry_output_format,omitempty"`
HasRsaPublicKey tfconfig.Variable `json:"has_rsa_public_key,omitempty"`
@@ -246,6 +247,11 @@ func (u *UserModel) WithFirstName(firstName string) *UserModel {
return u
}
+func (u *UserModel) WithFullyQualifiedName(fullyQualifiedName string) *UserModel {
+ u.FullyQualifiedName = tfconfig.StringVariable(fullyQualifiedName)
+ return u
+}
+
func (u *UserModel) WithGeographyOutputFormat(geographyOutputFormat string) *UserModel {
u.GeographyOutputFormat = tfconfig.StringVariable(geographyOutputFormat)
return u
@@ -625,6 +631,11 @@ func (u *UserModel) WithFirstNameValue(value tfconfig.Variable) *UserModel {
return u
}
+func (u *UserModel) WithFullyQualifiedNameValue(value tfconfig.Variable) *UserModel {
+ u.FullyQualifiedName = value
+ return u
+}
+
func (u *UserModel) WithGeographyOutputFormatValue(value tfconfig.Variable) *UserModel {
u.GeographyOutputFormat = value
return u
diff --git a/pkg/acceptance/bettertestspoc/config/model/warehouse_model_gen.go b/pkg/acceptance/bettertestspoc/config/model/warehouse_model_gen.go
index 26b25b684d..388b71ce33 100644
--- a/pkg/acceptance/bettertestspoc/config/model/warehouse_model_gen.go
+++ b/pkg/acceptance/bettertestspoc/config/model/warehouse_model_gen.go
@@ -14,6 +14,7 @@ type WarehouseModel struct {
AutoSuspend tfconfig.Variable `json:"auto_suspend,omitempty"`
Comment tfconfig.Variable `json:"comment,omitempty"`
EnableQueryAcceleration tfconfig.Variable `json:"enable_query_acceleration,omitempty"`
+ FullyQualifiedName tfconfig.Variable `json:"fully_qualified_name,omitempty"`
InitiallySuspended tfconfig.Variable `json:"initially_suspended,omitempty"`
MaxClusterCount tfconfig.Variable `json:"max_cluster_count,omitempty"`
MaxConcurrencyLevel tfconfig.Variable `json:"max_concurrency_level,omitempty"`
@@ -75,6 +76,11 @@ func (w *WarehouseModel) WithEnableQueryAcceleration(enableQueryAcceleration str
return w
}
+func (w *WarehouseModel) WithFullyQualifiedName(fullyQualifiedName string) *WarehouseModel {
+ w.FullyQualifiedName = tfconfig.StringVariable(fullyQualifiedName)
+ return w
+}
+
func (w *WarehouseModel) WithInitiallySuspended(initiallySuspended bool) *WarehouseModel {
w.InitiallySuspended = tfconfig.BoolVariable(initiallySuspended)
return w
@@ -159,6 +165,11 @@ func (w *WarehouseModel) WithEnableQueryAccelerationValue(value tfconfig.Variabl
return w
}
+func (w *WarehouseModel) WithFullyQualifiedNameValue(value tfconfig.Variable) *WarehouseModel {
+ w.FullyQualifiedName = value
+ return w
+}
+
func (w *WarehouseModel) WithInitiallySuspendedValue(value tfconfig.Variable) *WarehouseModel {
w.InitiallySuspended = value
return w
diff --git a/pkg/acceptance/helpers/database_role_client.go b/pkg/acceptance/helpers/database_role_client.go
index 96adf35aa0..75893addd5 100644
--- a/pkg/acceptance/helpers/database_role_client.go
+++ b/pkg/acceptance/helpers/database_role_client.go
@@ -70,3 +70,8 @@ func (c *DatabaseRoleClient) CleanupDatabaseRoleFunc(t *testing.T, id sdk.Databa
require.NoError(t, err)
}
}
+
+func (c *DatabaseRoleClient) Show(t *testing.T, id sdk.DatabaseObjectIdentifier) (*sdk.DatabaseRole, error) {
+ t.Helper()
+ return c.client().ShowByID(context.Background(), id)
+}
diff --git a/pkg/datasources/database_roles.go b/pkg/datasources/database_roles.go
index 495d027937..ce45c48257 100644
--- a/pkg/datasources/database_roles.go
+++ b/pkg/datasources/database_roles.go
@@ -2,80 +2,116 @@ package datasources
import (
"context"
- "log"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/resources"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/schemas"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
var databaseRolesSchema = map[string]*schema.Schema{
- "database": {
+ "in_database": {
Type: schema.TypeString,
Required: true,
Description: "The database from which to return the database roles from.",
},
- "database_roles": {
+ "like": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "Filters the output with **case-insensitive** pattern, with support for SQL wildcard characters (`%` and `_`).",
+ },
+ "limit": {
Type: schema.TypeList,
- Computed: true,
- Description: "Lists all the database roles in a specified database.",
+ Optional: true,
+ Description: "Limits the number of rows returned. If the `limit.from` is set, then the limit wll start from the first element matched by the expression. The expression is only used to match with the first element, later on the elements are not matched by the prefix, but you can enforce a certain pattern with `starts_with` or `like`.",
+ MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
- "name": {
- Type: schema.TypeString,
- Computed: true,
- Description: "Identifier for the role.",
+ "rows": {
+ Type: schema.TypeInt,
+ Required: true,
+ Description: "The maximum number of rows to return.",
},
- "comment": {
+ "from": {
Type: schema.TypeString,
- Computed: true,
- Description: "The comment on the role",
+ Optional: true,
+ Description: "Specifies a **case-sensitive** pattern that is used to match object name. After the first match, the limit on the number of rows will be applied.",
},
- "owner": {
- Type: schema.TypeString,
+ },
+ },
+ },
+ "database_roles": {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "Holds the aggregated output of all database role details queries.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ resources.ShowOutputAttributeName: {
+ Type: schema.TypeList,
Computed: true,
- Description: "The owner of the role",
+ Description: "Holds the output of SHOW DATABASE ROLES.",
+ Elem: &schema.Resource{
+ Schema: schemas.ShowDatabaseRoleSchema,
+ },
},
},
},
},
}
-// DatabaseRoles Snowflake Database Roles resource.
func DatabaseRoles() *schema.Resource {
return &schema.Resource{
- Read: ReadDatabaseRoles,
- Schema: databaseRolesSchema,
+ ReadContext: ReadDatabaseRoles,
+ Schema: databaseRolesSchema,
}
}
-// ReadDatabaseRoles Reads the database metadata information.
-func ReadDatabaseRoles(d *schema.ResourceData, meta interface{}) error {
+func ReadDatabaseRoles(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
client := meta.(*provider.Context).Client
- d.SetId("database_roles_read")
+ req := sdk.NewShowDatabaseRoleRequest(sdk.NewAccountObjectIdentifier(d.Get("in_database").(string)))
- databaseName := d.Get("database").(string)
+ if likePattern, ok := d.GetOk("like"); ok {
+ req.WithLike(sdk.Like{
+ Pattern: sdk.String(likePattern.(string)),
+ })
+ }
- ctx := context.Background()
- showRequest := sdk.NewShowDatabaseRoleRequest(sdk.NewAccountObjectIdentifier(databaseName))
- extractedDatabaseRoles, err := client.DatabaseRoles.Show(ctx, showRequest)
- if err != nil {
- log.Printf("[DEBUG] unable to show database roles in db (%s)", databaseName)
- d.SetId("")
- return err
+ if limit, ok := d.GetOk("limit"); ok && len(limit.([]any)) == 1 {
+ limitMap := limit.([]any)[0].(map[string]any)
+
+ rows := limitMap["rows"].(int)
+ limitFrom := sdk.LimitFrom{
+ Rows: &rows,
+ }
+
+ if from, ok := limitMap["from"].(string); ok {
+ limitFrom.From = &from
+ }
+
+ req.WithLimit(limitFrom)
}
- databaseRoles := make([]map[string]any, 0, len(extractedDatabaseRoles))
- for _, databaseRole := range extractedDatabaseRoles {
- databaseRoleMap := map[string]any{}
+ databaseRoles, err := client.DatabaseRoles.Show(ctx, req)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ d.SetId("database_roles_read")
- databaseRoleMap["name"] = databaseRole.Name
- databaseRoleMap["comment"] = databaseRole.Comment
- databaseRoleMap["owner"] = databaseRole.Owner
+ flattenedDatabaseRoles := make([]map[string]any, len(databaseRoles))
+ for i, databaseRole := range databaseRoles {
+ databaseRole := databaseRole
+ flattenedDatabaseRoles[i] = map[string]any{
+ resources.ShowOutputAttributeName: []map[string]any{schemas.DatabaseRoleToSchema(&databaseRole)},
+ }
+ }
- databaseRoles = append(databaseRoles, databaseRoleMap)
+ err = d.Set("database_roles", flattenedDatabaseRoles)
+ if err != nil {
+ return diag.FromErr(err)
}
- return d.Set("database_roles", databaseRoles)
+ return nil
}
diff --git a/pkg/datasources/database_roles_acceptance_test.go b/pkg/datasources/database_roles_acceptance_test.go
index 479ae7dcd9..1fe041363d 100644
--- a/pkg/datasources/database_roles_acceptance_test.go
+++ b/pkg/datasources/database_roles_acceptance_test.go
@@ -11,8 +11,10 @@ import (
)
func TestAcc_DatabaseRoles(t *testing.T) {
- dbName := acc.TestClient().Ids.Alpha()
- dbRoleName := acc.TestClient().Ids.Alpha()
+ databaseName := acc.TestClient().Ids.Alpha()
+ databaseRoleNamePrefix := acc.TestClient().Ids.Alpha()
+ databaseRoleName := databaseRoleNamePrefix + "1" + acc.TestClient().Ids.Alpha()
+ databaseRoleName2 := databaseRoleNamePrefix + "2" + acc.TestClient().Ids.Alpha()
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
@@ -22,59 +24,53 @@ func TestAcc_DatabaseRoles(t *testing.T) {
CheckDestroy: nil,
Steps: []resource.TestStep{
{
- Config: databaseRoles(dbName, dbRoleName),
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttrSet("data.snowflake_database_roles.db_roles", "database_roles.#"),
- resource.TestCheckResourceAttrSet("data.snowflake_database_roles.db_roles", "database_roles.0.name"),
- resource.TestCheckResourceAttrSet("data.snowflake_database_roles.db_roles", "database_roles.0.comment"),
- resource.TestCheckResourceAttrSet("data.snowflake_database_roles.db_roles", "database_roles.0.owner"),
- ),
- },
- {
- Config: databaseRolesEmpty(dbName),
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttrSet("data.snowflake_database_roles.db_roles", "database_roles.#"),
- resource.TestCheckResourceAttrSet("data.snowflake_database_roles.db_roles", "database_roles.0.name"),
- resource.TestCheckResourceAttrSet("data.snowflake_database_roles.db_roles", "database_roles.0.comment"),
- resource.TestCheckResourceAttrSet("data.snowflake_database_roles.db_roles", "database_roles.0.owner"),
+ Config: databaseRoles(databaseName, databaseRoleName, databaseRoleName2, databaseRoleNamePrefix+"%"),
+ Check: resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttr("data.snowflake_database_roles.db_roles", "database_roles.#", "1"),
+ resource.TestCheckResourceAttrSet("data.snowflake_database_roles.db_roles", "database_roles.0.show_output.0.created_on"),
+ resource.TestCheckResourceAttr("data.snowflake_database_roles.db_roles", "database_roles.0.show_output.0.name", databaseRoleName2),
+ resource.TestCheckResourceAttr("data.snowflake_database_roles.db_roles", "database_roles.0.show_output.0.is_default", "false"),
+ resource.TestCheckResourceAttrSet("data.snowflake_database_roles.db_roles", "database_roles.0.show_output.0.is_current"),
+ resource.TestCheckResourceAttr("data.snowflake_database_roles.db_roles", "database_roles.0.show_output.0.is_inherited", "false"),
+ resource.TestCheckResourceAttr("data.snowflake_database_roles.db_roles", "database_roles.0.show_output.0.granted_to_roles", "0"),
+ resource.TestCheckResourceAttr("data.snowflake_database_roles.db_roles", "database_roles.0.show_output.0.granted_to_database_roles", "0"),
+ resource.TestCheckResourceAttr("data.snowflake_database_roles.db_roles", "database_roles.0.show_output.0.granted_database_roles", "0"),
+ resource.TestCheckResourceAttrSet("data.snowflake_database_roles.db_roles", "database_roles.0.show_output.0.owner"),
+ resource.TestCheckResourceAttr("data.snowflake_database_roles.db_roles", "database_roles.0.show_output.0.comment", "test"),
+ resource.TestCheckResourceAttrSet("data.snowflake_database_roles.db_roles", "database_roles.0.show_output.0.owner_role_type"),
),
},
},
})
}
-func databaseRoles(dbName, dbRoleName string) string {
+func databaseRoles(databaseName, databaseRoleName, databaseRoleName2, databaseNamePrefix string) string {
return fmt.Sprintf(`
- resource snowflake_database "test_db" {
- name = "%v"
- }
+resource snowflake_database "test_db" {
+ name = "%v"
+}
- resource snowflake_database_role "test_role" {
- name = "%v"
- comment = "test"
- database = snowflake_database.test_db.name
- }
+resource snowflake_database_role "test_role" {
+ name = "%v"
+ comment = "test"
+ database = snowflake_database.test_db.name
+}
- data snowflake_database_roles "db_roles" {
- database = snowflake_database.test_db.name
- depends_on = [
- snowflake_database_role.test_role,
- ]
- }
- `, dbName, dbRoleName)
+resource snowflake_database_role "test_role2" {
+ name = "%v"
+ comment = "test"
+ database = snowflake_database.test_db.name
}
-func databaseRolesEmpty(dbName string) string {
- return fmt.Sprintf(`
- resource snowflake_database "test_db" {
- name = "%v"
- }
+data snowflake_database_roles "db_roles" {
+ depends_on = [ snowflake_database_role.test_role, snowflake_database_role.test_role2 ]
- data snowflake_database_roles "db_roles" {
- database = snowflake_database.test_db.name
- depends_on = [
- snowflake_database.test_db,
- ]
- }
- `, dbName)
+ in_database = snowflake_database.test_db.name
+ like = "%v"
+ limit {
+ rows = 1
+ from = snowflake_database_role.test_role.name
+ }
+}
+ `, databaseName, databaseRoleName, databaseRoleName2, databaseNamePrefix)
}
diff --git a/pkg/resources/alert_acceptance_test.go b/pkg/resources/alert_acceptance_test.go
index 7725ddec5f..e0356b6ec2 100644
--- a/pkg/resources/alert_acceptance_test.go
+++ b/pkg/resources/alert_acceptance_test.go
@@ -32,10 +32,10 @@ type (
}
)
-var (
- id = acc.TestClient().Ids.RandomSchemaObjectIdentifier()
+func TestAcc_Alert(t *testing.T) {
+ id := acc.TestClient().Ids.RandomSchemaObjectIdentifier()
- alertInitialState = &AccAlertTestSettings{ //nolint
+ alertInitialState := &AccAlertTestSettings{ //nolint
WarehouseName: acc.TestWarehouseName,
DatabaseName: acc.TestDatabaseName,
Alert: &AlertSettings{
@@ -50,7 +50,7 @@ var (
}
// Changes: condition, action, comment, schedule.
- alertStepOne = &AccAlertTestSettings{ //nolint
+ alertStepOne := &AccAlertTestSettings{ //nolint
WarehouseName: acc.TestWarehouseName,
DatabaseName: acc.TestDatabaseName,
Alert: &AlertSettings{
@@ -65,7 +65,7 @@ var (
}
// Changes: condition, action, comment, schedule.
- alertStepTwo = &AccAlertTestSettings{ //nolint
+ alertStepTwo := &AccAlertTestSettings{ //nolint
WarehouseName: acc.TestWarehouseName,
DatabaseName: acc.TestDatabaseName,
Alert: &AlertSettings{
@@ -80,7 +80,7 @@ var (
}
// Changes: condition, action, comment, schedule.
- alertStepThree = &AccAlertTestSettings{ //nolint
+ alertStepThree := &AccAlertTestSettings{ //nolint
WarehouseName: acc.TestWarehouseName,
DatabaseName: acc.TestDatabaseName,
Alert: &AlertSettings{
@@ -92,9 +92,7 @@ var (
Schedule: 5,
},
}
-)
-func TestAcc_Alert(t *testing.T) {
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
PreCheck: func() { acc.TestAccPreCheck(t) },
diff --git a/pkg/resources/database_role.go b/pkg/resources/database_role.go
index 2745514e8c..ee98900a7b 100644
--- a/pkg/resources/database_role.go
+++ b/pkg/resources/database_role.go
@@ -2,14 +2,16 @@ package resources
import (
"context"
+ "errors"
"fmt"
"log"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
- "github.com/hashicorp/go-cty/cty"
-
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/schemas"
+ "github.com/hashicorp/go-cty/cty"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -19,15 +21,14 @@ var databaseRoleSchema = map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
- Description: "Specifies the identifier for the database role.",
- ForceNew: true,
+ Description: blocklistedCharactersFieldDescription("Specifies the identifier for the database role."),
DiffSuppressFunc: suppressIdentifierQuoting,
},
"database": {
Type: schema.TypeString,
Required: true,
- Description: "The database in which to create the database role.",
ForceNew: true,
+ Description: blocklistedCharactersFieldDescription("The database in which to create the database role."),
DiffSuppressFunc: suppressIdentifierQuoting,
},
"comment": {
@@ -35,22 +36,34 @@ var databaseRoleSchema = map[string]*schema.Schema{
Optional: true,
Description: "Specifies a comment for the database role.",
},
+ ShowOutputAttributeName: {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "Outputs the result of `SHOW DATABASE ROLES` for the given database role. Note that this value will be only recomputed whenever comment field changes.",
+ Elem: &schema.Resource{
+ Schema: schemas.ShowDatabaseRoleSchema,
+ },
+ },
FullyQualifiedNameAttributeName: schemas.FullyQualifiedNameSchema,
}
-// DatabaseRole returns a pointer to the resource representing a database role.
func DatabaseRole() *schema.Resource {
return &schema.Resource{
- Create: CreateDatabaseRole,
- Read: ReadDatabaseRole,
- Update: UpdateDatabaseRole,
- Delete: DeleteDatabaseRole,
+ CreateContext: CreateDatabaseRole,
+ ReadContext: ReadDatabaseRole,
+ UpdateContext: UpdateDatabaseRole,
+ DeleteContext: DeleteDatabaseRole,
Schema: databaseRoleSchema,
Importer: &schema.ResourceImporter{
StateContext: ImportName[sdk.DatabaseObjectIdentifier],
},
+ CustomizeDiff: customdiff.All(
+ ComputedIfAnyAttributeChanged(ShowOutputAttributeName, "comment"),
+ ComputedIfAnyAttributeChangedWithSuppressDiff(ShowOutputAttributeName, suppressIdentifierQuoting, "name"),
+ ),
+
SchemaVersion: 1,
StateUpgraders: []schema.StateUpgrader{
{
@@ -63,96 +76,121 @@ func DatabaseRole() *schema.Resource {
}
}
-// ReadDatabaseRole implements schema.ReadFunc.
-func ReadDatabaseRole(d *schema.ResourceData, meta interface{}) error {
+func ReadDatabaseRole(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
client := meta.(*provider.Context).Client
id, err := sdk.ParseDatabaseObjectIdentifier(d.Id())
if err != nil {
- return err
+ return diag.FromErr(err)
}
- ctx := context.Background()
- databaseRole, err := client.DatabaseRoles.ShowByID(ctx, id)
+ _, err = client.Databases.ShowByID(ctx, id.DatabaseId())
if err != nil {
- // If not found, mark resource to be removed from state file during apply or refresh
- log.Printf("[DEBUG] database role (%s) not found", d.Id())
+ log.Printf("[DEBUG] database %s for database role %s not found", id.DatabaseId().Name(), id.Name())
d.SetId("")
- return nil
+ return diag.Diagnostics{
+ diag.Diagnostic{
+ Severity: diag.Warning,
+ Summary: "Failed to query database. Marking the resource as removed.",
+ Detail: fmt.Sprintf("database role name: %s, Err: %s", id.FullyQualifiedName(), err),
+ },
+ }
}
- if err := d.Set(FullyQualifiedNameAttributeName, id.FullyQualifiedName()); err != nil {
- return err
+ databaseRole, err := client.DatabaseRoles.ShowByID(ctx, id)
+ if err != nil {
+ if errors.Is(err, sdk.ErrObjectNotFound) {
+ d.SetId("")
+ return diag.Diagnostics{
+ diag.Diagnostic{
+ Severity: diag.Warning,
+ Summary: "Database role not found; marking it as removed",
+ Detail: fmt.Sprintf("Database role name: %s, err: %s", id.FullyQualifiedName(), err),
+ },
+ }
+ }
+ return diag.FromErr(err)
}
if err := d.Set("comment", databaseRole.Comment); err != nil {
- return err
+ return diag.FromErr(err)
+ }
+
+ if err := d.Set(FullyQualifiedNameAttributeName, id.FullyQualifiedName()); err != nil {
+ return diag.FromErr(err)
+ }
+
+ if err = d.Set(ShowOutputAttributeName, []map[string]any{schemas.DatabaseRoleToSchema(databaseRole)}); err != nil {
+ return diag.FromErr(err)
}
+
return nil
}
-// CreateDatabaseRole implements schema.CreateFunc.
-func CreateDatabaseRole(d *schema.ResourceData, meta interface{}) error {
+func CreateDatabaseRole(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
client := meta.(*provider.Context).Client
databaseName := d.Get("database").(string)
roleName := d.Get("name").(string)
-
- objectIdentifier := sdk.NewDatabaseObjectIdentifier(databaseName, roleName)
- createRequest := sdk.NewCreateDatabaseRoleRequest(objectIdentifier)
+ id := sdk.NewDatabaseObjectIdentifier(databaseName, roleName)
+ createRequest := sdk.NewCreateDatabaseRoleRequest(id)
if v, ok := d.GetOk("comment"); ok {
- createRequest.WithComment(sdk.String(v.(string)))
+ createRequest.WithComment(v.(string))
}
- ctx := context.Background()
err := client.DatabaseRoles.Create(ctx, createRequest)
if err != nil {
- return err
+ return diag.FromErr(err)
}
- d.SetId(helpers.EncodeResourceIdentifier(objectIdentifier))
+ d.SetId(helpers.EncodeResourceIdentifier(id))
- return ReadDatabaseRole(d, meta)
+ return ReadDatabaseRole(ctx, d, meta)
}
-// UpdateDatabaseRole implements schema.UpdateFunc.
-func UpdateDatabaseRole(d *schema.ResourceData, meta interface{}) error {
+func UpdateDatabaseRole(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
client := meta.(*provider.Context).Client
- objectIdentifier, err := sdk.ParseDatabaseObjectIdentifier(d.Id())
+ id, err := sdk.ParseDatabaseObjectIdentifier(d.Id())
if err != nil {
- return err
+ return diag.FromErr(err)
}
- if d.HasChange("comment") {
- _, newVal := d.GetChange("comment")
+ if d.HasChange("name") {
+ newId := sdk.NewDatabaseObjectIdentifier(id.DatabaseName(), d.Get("name").(string))
- ctx := context.Background()
- alterRequest := sdk.NewAlterDatabaseRoleRequest(objectIdentifier).WithSetComment(newVal.(string))
- err := client.DatabaseRoles.Alter(ctx, alterRequest)
+ err = client.DatabaseRoles.Alter(ctx, sdk.NewAlterDatabaseRoleRequest(id).WithRename(newId))
if err != nil {
- return fmt.Errorf("error updating database role %v: %w", objectIdentifier.Name(), err)
+ return diag.FromErr(err)
}
+
+ d.SetId(helpers.EncodeResourceIdentifier(newId))
+ id = newId
}
- return ReadDatabaseRole(d, meta)
+ if d.HasChange("comment") {
+ newComment := d.Get("comment").(string)
+ err := client.DatabaseRoles.Alter(ctx, sdk.NewAlterDatabaseRoleRequest(id).WithSet(*sdk.NewDatabaseRoleSetRequest(newComment)))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ }
+
+ return ReadDatabaseRole(ctx, d, meta)
}
-// DeleteDatabaseRole implements schema.DeleteFunc.
-func DeleteDatabaseRole(d *schema.ResourceData, meta interface{}) error {
+func DeleteDatabaseRole(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
client := meta.(*provider.Context).Client
- objectIdentifier, err := sdk.ParseDatabaseObjectIdentifier(d.Id())
+ id, err := sdk.ParseDatabaseObjectIdentifier(d.Id())
if err != nil {
- return err
+ return diag.FromErr(err)
}
- ctx := context.Background()
- dropRequest := sdk.NewDropDatabaseRoleRequest(objectIdentifier)
- err = client.DatabaseRoles.Drop(ctx, dropRequest)
+ err = client.DatabaseRoles.Drop(ctx, sdk.NewDropDatabaseRoleRequest(id).WithIfExists(true))
if err != nil {
- return err
+ return diag.FromErr(err)
}
d.SetId("")
diff --git a/pkg/resources/database_role_acceptance_test.go b/pkg/resources/database_role_acceptance_test.go
index b7d2fda990..1d3552a86c 100644
--- a/pkg/resources/database_role_acceptance_test.go
+++ b/pkg/resources/database_role_acceptance_test.go
@@ -4,6 +4,14 @@ import (
"fmt"
"testing"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert/objectassert"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert/resourceassert"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert/resourceshowoutputassert"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/config"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/config/model"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
+
"github.com/hashicorp/terraform-plugin-testing/plancheck"
acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance"
@@ -15,10 +23,11 @@ import (
)
func TestAcc_DatabaseRole(t *testing.T) {
- resourceName := "snowflake_database_role.test_db_role"
id := acc.TestClient().Ids.RandomDatabaseObjectIdentifier()
+ newId := acc.TestClient().Ids.RandomDatabaseObjectIdentifier()
comment := random.Comment()
- comment2 := random.Comment()
+ databaseRoleModel := model.DatabaseRole("test", id.DatabaseName(), id.Name())
+ databaseRoleModelWithComment := model.DatabaseRole("test", id.DatabaseName(), id.Name()).WithComment(comment)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
@@ -29,41 +38,121 @@ func TestAcc_DatabaseRole(t *testing.T) {
CheckDestroy: acc.CheckDestroy(t, resources.DatabaseRole),
Steps: []resource.TestStep{
{
- Config: databaseRoleConfig(id.Name(), acc.TestDatabaseName, comment),
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr(resourceName, "name", id.Name()),
- resource.TestCheckResourceAttr(resourceName, "fully_qualified_name", id.FullyQualifiedName()),
- resource.TestCheckResourceAttr(resourceName, "database", acc.TestDatabaseName),
- resource.TestCheckResourceAttr(resourceName, "comment", comment),
+ Config: config.FromModel(t, databaseRoleModel),
+ Check: assert.AssertThat(t,
+ resourceassert.DatabaseRoleResource(t, "snowflake_database_role.test").
+ HasNameString(id.Name()).
+ HasDatabaseString(id.DatabaseName()).
+ HasCommentString("").
+ HasFullyQualifiedNameString(id.FullyQualifiedName()),
+ resourceshowoutputassert.DatabaseRoleShowOutput(t, "snowflake_database_role.test").
+ HasName(id.Name()).
+ HasComment(""),
+ objectassert.DatabaseRole(t, id).
+ HasName(id.Name()).
+ HasComment(""),
+ ),
+ },
+ {
+ ResourceName: "snowflake_database_role.test",
+ ImportState: true,
+ ImportStateCheck: assert.AssertThatImport(t,
+ resourceassert.ImportedDatabaseRoleResource(t, helpers.EncodeResourceIdentifier(id)).
+ HasNameString(id.Name()).
+ HasCommentString(""),
+ resourceshowoutputassert.ImportedWarehouseShowOutput(t, helpers.EncodeResourceIdentifier(id)).
+ HasName(id.Name()).
+ HasComment(""),
+ ),
+ },
+ // set comment
+ {
+ Config: config.FromModel(t, databaseRoleModelWithComment),
+ Check: assert.AssertThat(t,
+ resourceassert.DatabaseRoleResource(t, "snowflake_database_role.test").
+ HasNameString(id.Name()).
+ HasDatabaseString(id.DatabaseName()).
+ HasCommentString(comment).
+ HasFullyQualifiedNameString(id.FullyQualifiedName()),
+ resourceshowoutputassert.DatabaseRoleShowOutput(t, "snowflake_database_role.test").
+ HasName(id.Name()).
+ HasComment(comment),
+ objectassert.DatabaseRole(t, id).
+ HasName(id.Name()).
+ HasComment(comment),
+ ),
+ },
+ {
+ ResourceName: "snowflake_database_role.test",
+ ImportState: true,
+ ImportStateCheck: assert.AssertThatImport(t,
+ resourceassert.ImportedDatabaseRoleResource(t, helpers.EncodeResourceIdentifier(id)).
+ HasNameString(id.Name()).
+ HasCommentString(comment),
+ resourceshowoutputassert.ImportedWarehouseShowOutput(t, helpers.EncodeResourceIdentifier(id)).
+ HasName(id.Name()).
+ HasComment(comment),
),
},
+ // unset comment
{
- Config: databaseRoleConfig(id.Name(), acc.TestDatabaseName, comment2),
- Check: resource.ComposeTestCheckFunc(
- resource.TestCheckResourceAttr(resourceName, "name", id.Name()),
- resource.TestCheckResourceAttr(resourceName, "fully_qualified_name", id.FullyQualifiedName()),
- resource.TestCheckResourceAttr(resourceName, "database", acc.TestDatabaseName),
- resource.TestCheckResourceAttr(resourceName, "comment", comment2),
+ Config: config.FromModel(t, databaseRoleModel),
+ Check: assert.AssertThat(t,
+ resourceassert.DatabaseRoleResource(t, "snowflake_database_role.test").
+ HasNameString(id.Name()).
+ HasDatabaseString(id.DatabaseName()).
+ HasCommentString("").
+ HasFullyQualifiedNameString(id.FullyQualifiedName()),
+ resourceshowoutputassert.DatabaseRoleShowOutput(t, "snowflake_database_role.test").
+ HasName(id.Name()).
+ HasComment(""),
+ objectassert.DatabaseRole(t, id).
+ HasName(id.Name()).
+ HasComment(""),
+ ),
+ },
+ {
+ ResourceName: "snowflake_database_role.test",
+ ImportState: true,
+ ImportStateCheck: assert.AssertThatImport(t,
+ resourceassert.ImportedDatabaseRoleResource(t, helpers.EncodeResourceIdentifier(id)).
+ HasNameString(id.Name()).
+ HasCommentString(""),
+ resourceshowoutputassert.ImportedWarehouseShowOutput(t, helpers.EncodeResourceIdentifier(id)).
+ HasName(id.Name()).
+ HasComment(""),
+ ),
+ },
+ // rename
+ {
+ ConfigPlanChecks: resource.ConfigPlanChecks{
+ PreApply: []plancheck.PlanCheck{
+ plancheck.ExpectResourceAction("snowflake_database_role.test", plancheck.ResourceActionUpdate),
+ },
+ },
+ Config: config.FromModel(t, databaseRoleModel.WithName(newId.Name())),
+ Check: assert.AssertThat(t,
+ resourceassert.DatabaseRoleResource(t, "snowflake_database_role.test").
+ HasNameString(newId.Name()).
+ HasDatabaseString(newId.DatabaseName()).
+ HasCommentString("").
+ HasFullyQualifiedNameString(newId.FullyQualifiedName()),
+ resourceshowoutputassert.DatabaseRoleShowOutput(t, "snowflake_database_role.test").
+ HasName(newId.Name()).
+ HasComment(""),
+ objectassert.DatabaseRole(t, newId).
+ HasName(newId.Name()).
+ HasComment(""),
),
},
},
})
}
-func databaseRoleConfig(dbRoleName string, databaseName string, comment string) string {
- s := `
-resource "snowflake_database_role" "test_db_role" {
- name = "%s"
- database = "%s"
- comment = "%s"
-}
- `
- return fmt.Sprintf(s, dbRoleName, databaseName, comment)
-}
-
func TestAcc_DatabaseRole_migrateFromV0941_ensureSmoothUpgradeWithNewResourceId(t *testing.T) {
id := acc.TestClient().Ids.RandomDatabaseObjectIdentifier()
comment := random.Comment()
+ databaseRoleModelWithComment := model.DatabaseRole("test", id.DatabaseName(), id.Name()).WithComment(comment)
resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
@@ -78,24 +167,24 @@ func TestAcc_DatabaseRole_migrateFromV0941_ensureSmoothUpgradeWithNewResourceId(
Source: "Snowflake-Labs/snowflake",
},
},
- Config: databaseRoleConfig(id.Name(), id.DatabaseName(), comment),
+ Config: config.FromModel(t, databaseRoleModelWithComment),
Check: resource.ComposeAggregateTestCheckFunc(
- resource.TestCheckResourceAttr("snowflake_database_role.test_db_role", "id", fmt.Sprintf(`%s|%s`, id.DatabaseName(), id.Name())),
+ resource.TestCheckResourceAttr("snowflake_database_role.test", "id", fmt.Sprintf(`%s|%s`, id.DatabaseName(), id.Name())),
),
},
{
ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
- Config: databaseRoleConfig(id.Name(), id.DatabaseName(), comment),
+ Config: config.FromModel(t, databaseRoleModelWithComment),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
- plancheck.ExpectResourceAction("snowflake_database_role.test_db_role", plancheck.ResourceActionNoop),
+ plancheck.ExpectResourceAction("snowflake_database_role.test", plancheck.ResourceActionNoop),
},
PostApplyPostRefresh: []plancheck.PlanCheck{
- plancheck.ExpectResourceAction("snowflake_database_role.test_db_role", plancheck.ResourceActionNoop),
+ plancheck.ExpectResourceAction("snowflake_database_role.test", plancheck.ResourceActionNoop),
},
},
Check: resource.ComposeAggregateTestCheckFunc(
- resource.TestCheckResourceAttr("snowflake_database_role.test_db_role", "id", id.FullyQualifiedName()),
+ resource.TestCheckResourceAttr("snowflake_database_role.test", "id", id.FullyQualifiedName()),
),
},
},
@@ -104,8 +193,9 @@ func TestAcc_DatabaseRole_migrateFromV0941_ensureSmoothUpgradeWithNewResourceId(
func TestAcc_DatabaseRole_IdentifierQuotingDiffSuppression(t *testing.T) {
id := acc.TestClient().Ids.RandomDatabaseObjectIdentifier()
- quotedDatabaseRoleId := fmt.Sprintf(`\"%s\"`, id.Name())
+ quotedDatabaseRoleId := fmt.Sprintf(`"%s"`, id.Name())
comment := random.Comment()
+ databaseRoleModelWithComment := model.DatabaseRole("test", id.DatabaseName(), quotedDatabaseRoleId).WithComment(comment)
resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
@@ -121,28 +211,28 @@ func TestAcc_DatabaseRole_IdentifierQuotingDiffSuppression(t *testing.T) {
},
},
ExpectNonEmptyPlan: true,
- Config: databaseRoleConfig(quotedDatabaseRoleId, id.DatabaseName(), comment),
+ Config: config.FromModel(t, databaseRoleModelWithComment),
Check: resource.ComposeAggregateTestCheckFunc(
- resource.TestCheckResourceAttr("snowflake_database_role.test_db_role", "database", id.DatabaseName()),
- resource.TestCheckResourceAttr("snowflake_database_role.test_db_role", "name", id.Name()),
- resource.TestCheckResourceAttr("snowflake_database_role.test_db_role", "id", fmt.Sprintf(`%s|%s`, id.DatabaseName(), id.Name())),
+ resource.TestCheckResourceAttr("snowflake_database_role.test", "database", id.DatabaseName()),
+ resource.TestCheckResourceAttr("snowflake_database_role.test", "name", id.Name()),
+ resource.TestCheckResourceAttr("snowflake_database_role.test", "id", fmt.Sprintf(`%s|%s`, id.DatabaseName(), id.Name())),
),
},
{
ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
- Config: databaseRoleConfig(quotedDatabaseRoleId, id.DatabaseName(), comment),
+ Config: config.FromModel(t, databaseRoleModelWithComment),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
- plancheck.ExpectResourceAction("snowflake_database_role.test_db_role", plancheck.ResourceActionNoop),
+ plancheck.ExpectResourceAction("snowflake_database_role.test", plancheck.ResourceActionNoop),
},
PostApplyPostRefresh: []plancheck.PlanCheck{
- plancheck.ExpectResourceAction("snowflake_database_role.test_db_role", plancheck.ResourceActionNoop),
+ plancheck.ExpectResourceAction("snowflake_database_role.test", plancheck.ResourceActionNoop),
},
},
Check: resource.ComposeAggregateTestCheckFunc(
- resource.TestCheckResourceAttr("snowflake_database_role.test_db_role", "database", id.DatabaseName()),
- resource.TestCheckResourceAttr("snowflake_database_role.test_db_role", "name", id.Name()),
- resource.TestCheckResourceAttr("snowflake_database_role.test_db_role", "id", id.FullyQualifiedName()),
+ resource.TestCheckResourceAttr("snowflake_database_role.test", "database", id.DatabaseName()),
+ resource.TestCheckResourceAttr("snowflake_database_role.test", "name", id.Name()),
+ resource.TestCheckResourceAttr("snowflake_database_role.test", "id", id.FullyQualifiedName()),
),
},
},
diff --git a/pkg/resources/grant_ownership_test.go b/pkg/resources/grant_ownership_test.go
index b1b091a82a..208346de46 100644
--- a/pkg/resources/grant_ownership_test.go
+++ b/pkg/resources/grant_ownership_test.go
@@ -62,7 +62,7 @@ func TestGetOnObjectIdentifier(t *testing.T) {
},
{
Name: "validation - valid identifier",
- ObjectType: sdk.ObjectTypeSchema,
+ ObjectType: sdk.ObjectTypeDatabase,
ObjectName: "to.many.parts.in.this.identifier",
Expected: sdk.NewAccountObjectIdentifier("to.many.parts.in.this.identifier"),
},
diff --git a/pkg/sdk/database_role.go b/pkg/sdk/database_role.go
index dbe2378cce..d9a8d2ab73 100644
--- a/pkg/sdk/database_role.go
+++ b/pkg/sdk/database_role.go
@@ -40,9 +40,11 @@ type alterDatabaseRoleOptions struct {
name DatabaseObjectIdentifier `ddl:"identifier"`
// One of
- Rename *DatabaseRoleRename `ddl:"list,no_parentheses" sql:"RENAME TO"`
- Set *DatabaseRoleSet `ddl:"list,no_parentheses" sql:"SET"`
- Unset *DatabaseRoleUnset `ddl:"list,no_parentheses" sql:"UNSET"`
+ Rename *DatabaseObjectIdentifier `ddl:"identifier" sql:"RENAME TO"`
+ Set *DatabaseRoleSet `ddl:"list,no_parentheses" sql:"SET"`
+ Unset *DatabaseRoleUnset `ddl:"list,no_parentheses" sql:"UNSET"`
+ SetTags []TagAssociation `ddl:"keyword" sql:"SET TAG"`
+ UnsetTags []ObjectIdentifier `ddl:"keyword" sql:"UNSET TAG"`
}
type DatabaseRoleRename struct {
@@ -73,6 +75,7 @@ type showDatabaseRoleOptions struct {
Like *Like `ddl:"keyword" sql:"LIKE"`
in bool `ddl:"static" sql:"IN DATABASE"`
Database AccountObjectIdentifier `ddl:"identifier"`
+ Limit *LimitFrom `ddl:"keyword" sql:"LIMIT"`
}
// databaseRoleDBRow is used to decode the result of a SHOW DATABASE ROLES query.
@@ -95,6 +98,7 @@ type databaseRoleDBRow struct {
type DatabaseRole struct {
CreatedOn string
Name string
+ DatabaseName string // value not returned by SHOW, filled in the convert function
IsDefault bool
IsCurrent bool
IsInherited bool
@@ -106,6 +110,10 @@ type DatabaseRole struct {
OwnerRoleType string
}
+func (v DatabaseRole) ID() DatabaseObjectIdentifier {
+ return NewDatabaseObjectIdentifier(v.DatabaseName, v.Name)
+}
+
func (row databaseRoleDBRow) convert() *DatabaseRole {
databaseRole := DatabaseRole{
CreatedOn: row.CreatedOn,
diff --git a/pkg/sdk/database_role_dto.go b/pkg/sdk/database_role_dto.go
index 8be5f38a5f..8d06e69413 100644
--- a/pkg/sdk/database_role_dto.go
+++ b/pkg/sdk/database_role_dto.go
@@ -21,13 +21,11 @@ type AlterDatabaseRoleRequest struct {
name DatabaseObjectIdentifier // required
// One of
- rename *DatabaseRoleRenameRequest
- set *DatabaseRoleSetRequest
- unset *DatabaseRoleUnsetRequest
-}
-
-type DatabaseRoleRenameRequest struct {
- name DatabaseObjectIdentifier // required
+ rename *DatabaseObjectIdentifier
+ set *DatabaseRoleSetRequest
+ unset *DatabaseRoleUnsetRequest
+ setTags []TagAssociation
+ unsetTags []ObjectIdentifier
}
type DatabaseRoleSetRequest struct {
@@ -44,6 +42,7 @@ type DropDatabaseRoleRequest struct {
type ShowDatabaseRoleRequest struct {
like *Like
database AccountObjectIdentifier // required
+ limit *LimitFrom
}
type GrantDatabaseRoleRequest struct {
diff --git a/pkg/sdk/database_role_dto_builders.go b/pkg/sdk/database_role_dto_builders_gen.go
similarity index 73%
rename from pkg/sdk/database_role_dto_builders.go
rename to pkg/sdk/database_role_dto_builders_gen.go
index 3d215a8d42..85e04d9271 100644
--- a/pkg/sdk/database_role_dto_builders.go
+++ b/pkg/sdk/database_role_dto_builders_gen.go
@@ -1,5 +1,9 @@
+// Code generated by dto builder generator; DO NOT EDIT.
+
package sdk
+import ()
+
func NewCreateDatabaseRoleRequest(
name DatabaseObjectIdentifier,
) *CreateDatabaseRoleRequest {
@@ -18,8 +22,8 @@ func (s *CreateDatabaseRoleRequest) WithIfNotExists(ifNotExists bool) *CreateDat
return s
}
-func (s *CreateDatabaseRoleRequest) WithComment(comment *string) *CreateDatabaseRoleRequest {
- s.comment = comment
+func (s *CreateDatabaseRoleRequest) WithComment(comment string) *CreateDatabaseRoleRequest {
+ s.comment = &comment
return s
}
@@ -36,27 +40,29 @@ func (s *AlterDatabaseRoleRequest) WithIfExists(ifExists bool) *AlterDatabaseRol
return s
}
-func (s *AlterDatabaseRoleRequest) WithRename(name DatabaseObjectIdentifier) *AlterDatabaseRoleRequest {
- s.rename = NewDatabaseRoleRenameRequest(name)
+func (s *AlterDatabaseRoleRequest) WithRename(rename DatabaseObjectIdentifier) *AlterDatabaseRoleRequest {
+ s.rename = &rename
return s
}
-func (s *AlterDatabaseRoleRequest) WithSetComment(comment string) *AlterDatabaseRoleRequest {
- s.set = NewDatabaseRoleSetRequest(comment)
+func (s *AlterDatabaseRoleRequest) WithSet(set DatabaseRoleSetRequest) *AlterDatabaseRoleRequest {
+ s.set = &set
return s
}
-func (s *AlterDatabaseRoleRequest) WithUnsetComment() *AlterDatabaseRoleRequest {
- s.unset = NewDatabaseRoleUnsetRequest()
+func (s *AlterDatabaseRoleRequest) WithUnset(unset DatabaseRoleUnsetRequest) *AlterDatabaseRoleRequest {
+ s.unset = &unset
return s
}
-func NewDatabaseRoleRenameRequest(
- name DatabaseObjectIdentifier,
-) *DatabaseRoleRenameRequest {
- s := DatabaseRoleRenameRequest{}
- s.name = name
- return &s
+func (s *AlterDatabaseRoleRequest) WithSetTags(setTags []TagAssociation) *AlterDatabaseRoleRequest {
+ s.setTags = setTags
+ return s
+}
+
+func (s *AlterDatabaseRoleRequest) WithUnsetTags(unsetTags []ObjectIdentifier) *AlterDatabaseRoleRequest {
+ s.unsetTags = unsetTags
+ return s
}
func NewDatabaseRoleSetRequest(
@@ -92,10 +98,13 @@ func NewShowDatabaseRoleRequest(
return &s
}
-func (s *ShowDatabaseRoleRequest) WithLike(pattern string) *ShowDatabaseRoleRequest {
- s.like = &Like{
- Pattern: String(pattern),
- }
+func (s *ShowDatabaseRoleRequest) WithLike(like Like) *ShowDatabaseRoleRequest {
+ s.like = &like
+ return s
+}
+
+func (s *ShowDatabaseRoleRequest) WithLimit(limit LimitFrom) *ShowDatabaseRoleRequest {
+ s.limit = &limit
return s
}
@@ -108,13 +117,11 @@ func NewGrantDatabaseRoleRequest(
}
func (s *GrantDatabaseRoleRequest) WithDatabaseRole(databaseRole DatabaseObjectIdentifier) *GrantDatabaseRoleRequest {
- s.accountRole = nil
s.databaseRole = &databaseRole
return s
}
func (s *GrantDatabaseRoleRequest) WithAccountRole(accountRole AccountObjectIdentifier) *GrantDatabaseRoleRequest {
- s.databaseRole = nil
s.accountRole = &accountRole
return s
}
@@ -128,13 +135,11 @@ func NewRevokeDatabaseRoleRequest(
}
func (s *RevokeDatabaseRoleRequest) WithDatabaseRole(databaseRole DatabaseObjectIdentifier) *RevokeDatabaseRoleRequest {
- s.accountRole = nil
s.databaseRole = &databaseRole
return s
}
func (s *RevokeDatabaseRoleRequest) WithAccountRole(accountRole AccountObjectIdentifier) *RevokeDatabaseRoleRequest {
- s.databaseRole = nil
s.accountRole = &accountRole
return s
}
diff --git a/pkg/sdk/database_role_impl.go b/pkg/sdk/database_role_impl.go
index 72f8320965..21d0bc7210 100644
--- a/pkg/sdk/database_role_impl.go
+++ b/pkg/sdk/database_role_impl.go
@@ -36,11 +36,15 @@ func (v *databaseRoles) Show(ctx context.Context, request *ShowDatabaseRoleReque
resultList := convertRows[databaseRoleDBRow, DatabaseRole](dbRows)
+ for i := range resultList {
+ resultList[i].DatabaseName = request.database.name
+ }
+
return resultList, nil
}
func (v *databaseRoles) ShowByID(ctx context.Context, id DatabaseObjectIdentifier) (*DatabaseRole, error) {
- request := NewShowDatabaseRoleRequest(id.DatabaseId()).WithLike(id.Name())
+ request := NewShowDatabaseRoleRequest(id.DatabaseId()).WithLike(Like{Pointer(id.Name())})
databaseRoles, err := v.Show(ctx, request)
if err != nil {
return nil, err
@@ -80,11 +84,11 @@ func (s *CreateDatabaseRoleRequest) toOpts() *createDatabaseRoleOptions {
func (s *AlterDatabaseRoleRequest) toOpts() *alterDatabaseRoleOptions {
opts := alterDatabaseRoleOptions{
- IfExists: Bool(s.ifExists),
- name: s.name,
- }
- if s.rename != nil {
- opts.Rename = &DatabaseRoleRename{s.rename.name}
+ IfExists: Bool(s.ifExists),
+ name: s.name,
+ Rename: s.rename,
+ SetTags: s.setTags,
+ UnsetTags: s.unsetTags,
}
if s.set != nil {
opts.Set = &DatabaseRoleSet{s.set.comment}
@@ -106,6 +110,7 @@ func (s *ShowDatabaseRoleRequest) toOpts() *showDatabaseRoleOptions {
return &showDatabaseRoleOptions{
Like: s.like,
Database: s.database,
+ Limit: s.limit,
}
}
diff --git a/pkg/sdk/database_role_test.go b/pkg/sdk/database_role_test.go
index 423ff0599e..670ce22f6a 100644
--- a/pkg/sdk/database_role_test.go
+++ b/pkg/sdk/database_role_test.go
@@ -75,7 +75,7 @@ func TestDatabaseRoleAlter(t *testing.T) {
t.Run("validation: no alter action", func(t *testing.T) {
opts := defaultOpts()
- assertOptsInvalidJoinedErrors(t, opts, errExactlyOneOf("alterDatabaseRoleOptions", "Rename", "Set", "Unset"))
+ assertOptsInvalidJoinedErrors(t, opts, errExactlyOneOf("alterDatabaseRoleOptions", "Rename", "Set", "Unset", "SetTags", "UnsetTags"))
})
t.Run("validation: multiple alter actions", func(t *testing.T) {
@@ -86,24 +86,22 @@ func TestDatabaseRoleAlter(t *testing.T) {
opts.Unset = &DatabaseRoleUnset{
Comment: true,
}
- assertOptsInvalidJoinedErrors(t, opts, errExactlyOneOf("alterDatabaseRoleOptions", "Rename", "Set", "Unset"))
+ opts.SetTags = []TagAssociation{}
+ opts.UnsetTags = []ObjectIdentifier{}
+ assertOptsInvalidJoinedErrors(t, opts, errExactlyOneOf("alterDatabaseRoleOptions", "Rename", "Set", "Unset", "SetTags", "UnsetTags"))
})
t.Run("validation: invalid new name", func(t *testing.T) {
opts := defaultOpts()
- opts.Rename = &DatabaseRoleRename{
- Name: emptyDatabaseObjectIdentifier,
- }
- assertOptsInvalidJoinedErrors(t, opts, ErrInvalidObjectIdentifier)
+ opts.Rename = &emptyDatabaseObjectIdentifier
+ assertOptsInvalidJoinedErrors(t, opts, errInvalidIdentifier("alterDatabaseRoleOptions", "Rename"))
})
t.Run("validation: new name from different db", func(t *testing.T) {
newId := randomDatabaseObjectIdentifier()
opts := defaultOpts()
- opts.Rename = &DatabaseRoleRename{
- Name: newId,
- }
+ opts.Rename = &newId
assertOptsInvalidJoinedErrors(t, opts, ErrDifferentDatabase)
})
@@ -119,9 +117,7 @@ func TestDatabaseRoleAlter(t *testing.T) {
newId := randomDatabaseObjectIdentifierInDatabase(id.DatabaseId())
opts := defaultOpts()
- opts.Rename = &DatabaseRoleRename{
- Name: newId,
- }
+ opts.Rename = &newId
assertOptsValidAndSQLEquals(t, opts, `ALTER DATABASE ROLE %s RENAME TO %s`, id.FullyQualifiedName(), newId.FullyQualifiedName())
})
@@ -134,6 +130,22 @@ func TestDatabaseRoleAlter(t *testing.T) {
assertOptsValidAndSQLEquals(t, opts, `ALTER DATABASE ROLE IF EXISTS %s SET COMMENT = 'new comment'`, id.FullyQualifiedName())
})
+ t.Run("set tags", func(t *testing.T) {
+ opts := defaultOpts()
+ opts.IfExists = Bool(true)
+ opts.SetTags = []TagAssociation{
+ {
+ Name: NewAccountObjectIdentifier("123"),
+ Value: "value-123",
+ },
+ {
+ Name: NewAccountObjectIdentifier("456"),
+ Value: "value-123",
+ },
+ }
+ assertOptsValidAndSQLEquals(t, opts, `ALTER DATABASE ROLE IF EXISTS %s SET TAG "123" = 'value-123', "456" = 'value-123'`, id.FullyQualifiedName())
+ })
+
t.Run("set comment to empty", func(t *testing.T) {
opts := defaultOpts()
opts.IfExists = Bool(true)
@@ -151,6 +163,16 @@ func TestDatabaseRoleAlter(t *testing.T) {
}
assertOptsValidAndSQLEquals(t, opts, `ALTER DATABASE ROLE IF EXISTS %s UNSET COMMENT`, id.FullyQualifiedName())
})
+
+ t.Run("unset tags", func(t *testing.T) {
+ opts := defaultOpts()
+ opts.IfExists = Bool(true)
+ opts.UnsetTags = []ObjectIdentifier{
+ NewAccountObjectIdentifier("123"),
+ NewAccountObjectIdentifier("456"),
+ }
+ assertOptsValidAndSQLEquals(t, opts, `ALTER DATABASE ROLE IF EXISTS %s UNSET TAG "123", "456"`, id.FullyQualifiedName())
+ })
}
func TestDatabaseRoleDrop(t *testing.T) {
@@ -223,6 +245,18 @@ func TestDatabaseRolesShow(t *testing.T) {
}
assertOptsValidAndSQLEquals(t, opts, `SHOW DATABASE ROLES LIKE '%s' IN DATABASE %s`, id.Name(), id.FullyQualifiedName())
})
+
+ t.Run("show with like and limit from", func(t *testing.T) {
+ opts := defaultOpts()
+ opts.Like = &Like{
+ Pattern: String(id.Name()),
+ }
+ opts.Limit = &LimitFrom{
+ Rows: Int(10),
+ From: String("name"),
+ }
+ assertOptsValidAndSQLEquals(t, opts, `SHOW DATABASE ROLES LIKE '%s' IN DATABASE %s LIMIT 10 FROM 'name'`, id.Name(), id.FullyQualifiedName())
+ })
}
func TestDatabaseRoles_Grant(t *testing.T) {
diff --git a/pkg/sdk/database_role_validations.go b/pkg/sdk/database_role_validations.go
index e09bc81c98..dfd1b909f8 100644
--- a/pkg/sdk/database_role_validations.go
+++ b/pkg/sdk/database_role_validations.go
@@ -35,14 +35,14 @@ func (opts *alterDatabaseRoleOptions) validate() error {
if !ValidObjectIdentifier(opts.name) {
errs = append(errs, ErrInvalidObjectIdentifier)
}
- if !exactlyOneValueSet(opts.Rename, opts.Set, opts.Unset) {
- errs = append(errs, errExactlyOneOf("alterDatabaseRoleOptions", "Rename", "Set", "Unset"))
+ if !exactlyOneValueSet(opts.Rename, opts.Set, opts.Unset, opts.SetTags, opts.UnsetTags) {
+ errs = append(errs, errExactlyOneOf("alterDatabaseRoleOptions", "Rename", "Set", "Unset", "SetTags", "UnsetTags"))
}
- if rename := opts.Rename; valueSet(rename) {
- if !ValidObjectIdentifier(rename.Name) {
- errs = append(errs, ErrInvalidObjectIdentifier)
+ if opts.Rename != nil {
+ if !ValidObjectIdentifier(opts.Rename) {
+ errs = append(errs, errInvalidIdentifier("alterDatabaseRoleOptions", "Rename"))
}
- if opts.name.DatabaseName() != rename.Name.DatabaseName() {
+ if opts.name.DatabaseName() != opts.Rename.DatabaseName() {
errs = append(errs, ErrDifferentDatabase)
}
}
diff --git a/pkg/sdk/testint/database_role_integration_test.go b/pkg/sdk/testint/database_role_integration_test.go
index 519ab7674f..affca49e1f 100644
--- a/pkg/sdk/testint/database_role_integration_test.go
+++ b/pkg/sdk/testint/database_role_integration_test.go
@@ -50,7 +50,7 @@ func TestInt_DatabaseRoles(t *testing.T) {
id := testClientHelper().Ids.RandomDatabaseObjectIdentifier()
comment := random.Comment()
- request := sdk.NewCreateDatabaseRoleRequest(id).WithComment(&comment).WithIfNotExists(true)
+ request := sdk.NewCreateDatabaseRoleRequest(id).WithComment(comment).WithIfNotExists(true)
err := client.DatabaseRoles.Create(ctx, request)
require.NoError(t, err)
t.Cleanup(cleanupDatabaseRoleProvider(id))
@@ -101,7 +101,7 @@ func TestInt_DatabaseRoles(t *testing.T) {
require.NoError(t, err)
t.Cleanup(cleanupDatabaseRoleProvider(id))
- alterRequest := sdk.NewAlterDatabaseRoleRequest(id).WithSetComment("new comment")
+ alterRequest := sdk.NewAlterDatabaseRoleRequest(id).WithSet(*sdk.NewDatabaseRoleSetRequest("new comment"))
err = client.DatabaseRoles.Alter(ctx, alterRequest)
require.NoError(t, err)
@@ -110,7 +110,7 @@ func TestInt_DatabaseRoles(t *testing.T) {
assert.Equal(t, "new comment", alteredDatabaseRole.Comment)
- alterRequest = sdk.NewAlterDatabaseRoleRequest(id).WithUnsetComment()
+ alterRequest = sdk.NewAlterDatabaseRoleRequest(id).WithUnset(*sdk.NewDatabaseRoleUnsetRequest())
err = client.DatabaseRoles.Alter(ctx, alterRequest)
require.NoError(t, err)
@@ -163,6 +163,39 @@ func TestInt_DatabaseRoles(t *testing.T) {
assert.ErrorIs(t, err, sdk.ErrDifferentDatabase)
})
+ t.Run("alter database_role: set and unset tag", func(t *testing.T) {
+ tag, tagCleanup := testClientHelper().Tag.CreateTag(t)
+ t.Cleanup(tagCleanup)
+
+ databaseRole, cleanupDatabaseRole := testClientHelper().DatabaseRole.CreateDatabaseRole(t)
+ t.Cleanup(cleanupDatabaseRole)
+
+ tagValue := "abc"
+ tags := []sdk.TagAssociation{
+ {
+ Name: tag.ID(),
+ Value: tagValue,
+ },
+ }
+
+ err := client.DatabaseRoles.Alter(ctx, sdk.NewAlterDatabaseRoleRequest(databaseRole.ID()).WithSetTags(tags))
+ require.NoError(t, err)
+
+ returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), databaseRole.ID(), sdk.ObjectTypeDatabaseRole)
+ require.NoError(t, err)
+
+ assert.Equal(t, tagValue, returnedTagValue)
+
+ unsetTags := []sdk.ObjectIdentifier{
+ tag.ID(),
+ }
+ err = client.DatabaseRoles.Alter(ctx, sdk.NewAlterDatabaseRoleRequest(databaseRole.ID()).WithUnsetTags(unsetTags))
+ require.NoError(t, err)
+
+ _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), databaseRole.ID(), sdk.ObjectTypeDatabaseRole)
+ require.Error(t, err)
+ })
+
t.Run("show database_role: without like", func(t *testing.T) {
role1 := createDatabaseRole(t)
role2 := createDatabaseRole(t)
@@ -180,7 +213,7 @@ func TestInt_DatabaseRoles(t *testing.T) {
role1 := createDatabaseRole(t)
role2 := createDatabaseRole(t)
- showRequest := sdk.NewShowDatabaseRoleRequest(testDb(t).ID()).WithLike(role1.Name)
+ showRequest := sdk.NewShowDatabaseRoleRequest(testDb(t).ID()).WithLike(sdk.Like{Pattern: &role1.Name})
returnedDatabaseRoles, err := client.DatabaseRoles.Show(ctx, showRequest)
require.NoError(t, err)
@@ -189,8 +222,35 @@ func TestInt_DatabaseRoles(t *testing.T) {
assert.NotContains(t, returnedDatabaseRoles, *role2)
})
+ t.Run("show database_role: with like and limit", func(t *testing.T) {
+ prefix := "SHOW_TEST_ROLE_"
+ roleId1 := testClientHelper().Ids.AlphaWithPrefix(prefix + "1")
+ roleId2 := testClientHelper().Ids.AlphaWithPrefix(prefix + "2")
+
+ role1, cleanupRole1 := testClientHelper().DatabaseRole.CreateDatabaseRoleWithName(t, roleId1)
+ t.Cleanup(cleanupRole1)
+
+ role2, cleanupRole2 := testClientHelper().DatabaseRole.CreateDatabaseRoleWithName(t, roleId2)
+ t.Cleanup(cleanupRole2)
+
+ showRequest := sdk.NewShowDatabaseRoleRequest(testDb(t).ID()).
+ WithLike(sdk.Like{
+ Pattern: sdk.Pointer(prefix + "%"),
+ }).
+ WithLimit(sdk.LimitFrom{
+ Rows: sdk.Pointer(1),
+ From: sdk.Pointer(roleId1),
+ })
+ returnedDatabaseRoles, err := client.DatabaseRoles.Show(ctx, showRequest)
+
+ require.NoError(t, err)
+ assert.Equal(t, 1, len(returnedDatabaseRoles))
+ assert.NotContains(t, returnedDatabaseRoles, *role1)
+ assert.Contains(t, returnedDatabaseRoles, *role2)
+ })
+
t.Run("show database_role: no matches", func(t *testing.T) {
- showRequest := sdk.NewShowDatabaseRoleRequest(testDb(t).ID()).WithLike("non-existent")
+ showRequest := sdk.NewShowDatabaseRoleRequest(testDb(t).ID()).WithLike(sdk.Like{Pattern: sdk.Pointer("non-existent")})
returnedDatabaseRoles, err := client.DatabaseRoles.Show(ctx, showRequest)
require.NoError(t, err)
diff --git a/templates/data-sources/database_roles.md.tmpl b/templates/data-sources/database_roles.md.tmpl
new file mode 100644
index 0000000000..d3ff8d9c6c
--- /dev/null
+++ b/templates/data-sources/database_roles.md.tmpl
@@ -0,0 +1,24 @@
+---
+page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}"
+subcategory: ""
+description: |-
+{{ if gt (len (split .Description "")) 1 -}}
+{{ index (split .Description "") 1 | plainmarkdown | trimspace | prefixlines " " }}
+{{- else -}}
+{{ .Description | plainmarkdown | trimspace | prefixlines " " }}
+{{- end }}
+---
+
+!> **V1 release candidate** This data source was reworked and is a release candidate for the V1. We do not expect significant changes in it before the V1. We will welcome any feedback and adjust the data source if needed. Any errors reported will be resolved with a higher priority. We encourage checking this data source out before the V1 release. Please follow the [migration guide](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/MIGRATION_GUIDE.md#v0920--v0930) to use it.
+
+# {{.Name}} ({{.Type}})
+
+{{ .Description | trimspace }}
+
+{{ if .HasExample -}}
+## Example Usage
+
+{{ tffile (printf "examples/data-sources/%s/data-source.tf" .Name)}}
+{{- end }}
+
+{{ .SchemaMarkdown | trimspace }}
diff --git a/templates/resources/database_role.md.tmpl b/templates/resources/database_role.md.tmpl
new file mode 100644
index 0000000000..fb6aff121b
--- /dev/null
+++ b/templates/resources/database_role.md.tmpl
@@ -0,0 +1,35 @@
+---
+page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}"
+subcategory: ""
+description: |-
+{{ if gt (len (split .Description "")) 1 -}}
+{{ index (split .Description "") 1 | plainmarkdown | trimspace | prefixlines " " }}
+{{- else -}}
+{{ .Description | plainmarkdown | trimspace | prefixlines " " }}
+{{- end }}
+---
+
+!> **V1 release candidate** This resource was reworked and is a release candidate for the V1. We do not expect significant changes in it before the V1. We will welcome any feedback and adjust the resource if needed. Any errors reported will be resolved with a higher priority. We encourage checking this resource out before the V1 release.
+
+# {{.Name}} ({{.Type}})
+
+{{ .Description | trimspace }}
+
+{{ if .HasExample -}}
+## Example Usage
+
+{{ tffile (printf "examples/resources/%s/resource.tf" .Name)}}
+-> **Note** Instead of using fully_qualified_name, you can reference objects managed outside Terraform by constructing a correct ID, consult [identifiers guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/identifiers#new-computed-fully-qualified-name-field-in-resources).
+
+
+{{- end }}
+
+{{ .SchemaMarkdown | trimspace }}
+{{- if .HasImport }}
+
+## Import
+
+Import is supported using the following syntax:
+
+{{ codefile "shell" (printf "examples/resources/%s/import.sh" .Name)}}
+{{- end }}
diff --git a/v1-preparations/ESSENTIAL_GA_OBJECTS.MD b/v1-preparations/ESSENTIAL_GA_OBJECTS.MD
index ac0cb168e4..93b10d0726 100644
--- a/v1-preparations/ESSENTIAL_GA_OBJECTS.MD
+++ b/v1-preparations/ESSENTIAL_GA_OBJECTS.MD
@@ -12,28 +12,28 @@ Status is one of:
Known issues lists open issues touching the given object. Note that some of these issues may be already fixed in the
newer provider versions. We will address these while working on the given object.
-| Object Type | Status | Known issues |
-|--------------------------|:------:|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| ACCOUNT | ❌ | [#2030](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2030), [#2015](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2015), [#1891](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1891), [#1679](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1679), [#1671](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1671), [#1501](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1501), [#1062](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1062) |
-| DATABASE | 🚀 | [#2590](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2590), [#2321](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2321), [#2277](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2277), [#1833](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1833), [#1770](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1770), [#1453](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1453), [#1371](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1371), [#1367](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1367), [#1045](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1045), [#506](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/506) |
-| DATABASE ROLE | ❌ | - |
-| NETWORK POLICY | 🚀 | - |
-| RESOURCE MONITOR | ❌ | [#1990](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1990), [#1832](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1832), [#1821](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1821), [#1754](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1754), [#1716](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1716), [#1714](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1714), [#1624](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1624), [#1500](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1500), [#1175](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1175) |
-| ROLE | 🚀 | - |
-| SECURITY INTEGRATION | 🚀 | [#2855](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2855), [#2719](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2719), [#2568](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2568), [#2177](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2177), [#1851](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1851), [#1773](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1773), [#1741](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1741), [#1637](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1637), [#1503](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1503), [#1498](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1498), [#1421](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1421), [#1224](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1224) |
-| USER | 👨💻 | [#2970](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2970), [#2951](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2951), [#2942](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2942), [#2938](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2938), [#2902](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2902), [#2817](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2817), [#2662](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2662), [#1572](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1572), [#1535](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1535), [#1155](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1155) |
-| WAREHOUSE | 🚀 | issues in the older versions: [resources](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues?q=label%3Aresource%3Awarehouse+) and [datasources](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues?q=label%3Adata_source%3Awarehouses+) |
-| FUNCTION | ❌ | [2859](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2859), [#2735](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2735), [#2426](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2426), [#1479](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1479), [#1393](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1393), [#1208](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1208), [#1079](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1079) |
-| MASKING POLICY | ❌ | [#2236](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2236), [#2035](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2035), [#1799](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1799), [#1764](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1764), [#1656](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1656), [#1444](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1444), [#1422](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1422), [#1097](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1097) |
-| PROCEDURE | ❌ | [#2735](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2735), [#2623](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2623), [#2257](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2257), [#2146](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2146), [#1855](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1855), [#1695](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1695), [#1640](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1640), [#1195](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1195), [#1189](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1189), [#1178](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1178), [#1050](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1050) |
-| ROW ACCESS POLICY | ❌ | [#2053](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2053), [#1600](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1600), [#1151](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1151) |
-| SCHEMA | 🚀 | [#2826](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2826), [#2211](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2211), [#1243](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1243), [#506](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/506) |
+| Object Type | Status | Known issues |
+|--------------------------|:------:|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| ACCOUNT | ❌ | [#2030](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2030), [#2015](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2015), [#1891](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1891), [#1679](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1679), [#1671](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1671), [#1501](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1501), [#1062](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1062) |
+| DATABASE | 🚀 | [#2590](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2590), [#2321](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2321), [#2277](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2277), [#1833](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1833), [#1770](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1770), [#1453](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1453), [#1371](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1371), [#1367](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1367), [#1045](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1045), [#506](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/506) |
+| DATABASE ROLE | 🚀 | - |
+| NETWORK POLICY | 🚀 | - |
+| RESOURCE MONITOR | ❌ | [#1990](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1990), [#1832](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1832), [#1821](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1821), [#1754](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1754), [#1716](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1716), [#1714](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1714), [#1624](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1624), [#1500](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1500), [#1175](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1175) |
+| ROLE | 🚀 | - |
+| SECURITY INTEGRATION | 🚀 | [#2855](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2855), [#2719](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2719), [#2568](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2568), [#2177](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2177), [#1851](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1851), [#1773](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1773), [#1741](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1741), [#1637](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1637), [#1503](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1503), [#1498](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1498), [#1421](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1421), [#1224](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1224) |
+| USER | 👨💻 | [#2970](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2970), [#2951](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2951), [#2942](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2942), [#2938](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2938), [#2902](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2902), [#2817](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2817), [#2662](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2662), [#1572](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1572), [#1535](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1535), [#1155](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1155) |
+| WAREHOUSE | 🚀 | issues in the older versions: [resources](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues?q=label%3Aresource%3Awarehouse+) and [datasources](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues?q=label%3Adata_source%3Awarehouses+) |
+| FUNCTION | ❌ | [2859](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2859), [#2735](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2735), [#2426](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2426), [#1479](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1479), [#1393](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1393), [#1208](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1208), [#1079](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1079) |
+| MASKING POLICY | ❌ | [#2236](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2236), [#2035](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2035), [#1799](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1799), [#1764](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1764), [#1656](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1656), [#1444](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1444), [#1422](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1422), [#1097](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1097) |
+| PROCEDURE | ❌ | [#2735](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2735), [#2623](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2623), [#2257](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2257), [#2146](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2146), [#1855](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1855), [#1695](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1695), [#1640](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1640), [#1195](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1195), [#1189](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1189), [#1178](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1178), [#1050](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1050) |
+| ROW ACCESS POLICY | ❌ | [#2053](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2053), [#1600](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1600), [#1151](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1151) |
+| SCHEMA | 🚀 | [#2826](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2826), [#2211](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2211), [#1243](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1243), [#506](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/506) |
| STAGE | ❌ | [#2995](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2995), [#2818](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2818), [#2505](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2505), [#1911](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1911), [#1903](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1903), [#1795](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1795), [#1705](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1705), [#1544](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1544), [#1491](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1491), [#1087](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1087), [#265](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/265) |
-| STREAM | ❌ | [#2975](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2975), [#2413](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2413), [#2201](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2201), [#1150](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1150) |
-| STREAMLIT | 🚀 | [#1933](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1933) |
+| STREAM | ❌ | [#2975](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2975), [#2413](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2413), [#2201](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2201), [#1150](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1150) |
+| STREAMLIT | 🚀 | [#1933](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1933) |
| TABLE | ❌ | [#2997](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2997), [#2844](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2844), [#2839](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2839), [#2735](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2735), [#2733](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2733), [#2683](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2683), [#2676](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2676), [#2674](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2674), [#2629](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2629), [#2418](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2418), [#2415](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2415), [#2406](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2406), [#2236](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2236), [#2035](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2035), [#1823](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1823), [#1799](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1799), [#1764](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1764), [#1600](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1600), [#1387](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1387), [#1272](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1272), [#1271](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1271), [#1248](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1248), [#1241](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1241), [#1146](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1146), [#1032](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1032), [#420](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/420) |
-| TAG | ❌ | [#2943](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2902), [#2598](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2598), [#1910](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1910), [#1909](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1909), [#1862](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1862), [#1806](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1806), [#1657](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1657), [#1496](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1496), [#1443](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1443), [#1394](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1394), [#1372](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1372), [#1074](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1074) |
-| TASK | ❌ | [#1419](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1419), [#1250](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1250), [#1194](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1194), [#1088](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1088) |
-| VIEW | 👨💻 | [#3000](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/3000), [#2430](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2430), [#2085](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2085), [#2055](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2055), [#2031](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2031), [#1526](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1526), [#1253](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1253), [#1049](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1049) |
-| snowflake_unsafe_execute | ❌ | [#2934](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2934) |
+| TAG | ❌ | [#2943](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2902), [#2598](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2598), [#1910](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1910), [#1909](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1909), [#1862](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1862), [#1806](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1806), [#1657](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1657), [#1496](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1496), [#1443](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1443), [#1394](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1394), [#1372](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1372), [#1074](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1074) |
+| TASK | ❌ | [#1419](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1419), [#1250](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1250), [#1194](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1194), [#1088](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1088) |
+| VIEW | 👨💻 | [#3000](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/3000), [#2430](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2430), [#2085](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2085), [#2055](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2055), [#2031](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2031), [#1526](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1526), [#1253](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1253), [#1049](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/1049) |
+| snowflake_unsafe_execute | ❌ | [#2934](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2934) |