diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 2fe0dd5647..6c01ebe796 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -9,6 +9,26 @@ across different versions. ## v0.99.0 ➞ v0.100.0 +### *(new feature)* Account role data source +Added a new `snowflake_account_roles` data source for account roles. Now it reflects It's based on `snowflake_roles` data source. +`account_roles` field now organizes output of show under `show_output` field. + +Before: +```terraform +output "simple_output" { + value = data.snowflake_roles.test.roles[0].show_output[0].name +} +``` +After: +```terraform +output "simple_output" { + value = data.snowflake_account_roles.test.account_roles[0].show_output[0].name +} +``` + +### snowflake_roles data source deprecation +`snowflake_roles` is now deprecated in favor of `snowflake_account_roles` with a similar schema and behavior. It will be removed with the v1 release. Please adjust your configuration files. + ### snowflake_account_parameter resource changes #### *(behavior change)* resource deletion diff --git a/docs/data-sources/account_roles.md b/docs/data-sources/account_roles.md new file mode 100644 index 0000000000..f26c03bec5 --- /dev/null +++ b/docs/data-sources/account_roles.md @@ -0,0 +1,99 @@ +--- +page_title: "snowflake_account_roles Data Source - terraform-provider-snowflake" +subcategory: "" +description: |- + Data source used to get details of filtered account roles. Filtering is aligned with the current possibilities for SHOW ROLES https://docs.snowflake.com/en/sql-reference/sql/show-roles query (like and in_class are all supported). The results of SHOW are encapsulated in one output collection. +--- + +# snowflake_account_roles (Data Source) + +Data source used to get details of filtered account roles. Filtering is aligned with the current possibilities for [SHOW ROLES](https://docs.snowflake.com/en/sql-reference/sql/show-roles) query (`like` and `in_class` are all supported). The results of SHOW are encapsulated in one output collection. + +## Example Usage + +```terraform +# Simple usage +data "snowflake_account_roles" "simple" { +} + +output "simple_output" { + value = data.snowflake_account_roles.simple.roles +} + +# Filtering (like) +data "snowflake_account_roles" "like" { + like = "role-name" +} + +output "like_output" { + value = data.snowflake_account_roles.like.roles +} + +# Filtering (in class) +data "snowflake_account_roles" "in_class" { + in_class = "SNOWFLAKE.CORE.BUDGET" +} + +output "in_class_output" { + value = data.snowflake_account_roles.in_class.roles +} + +# Ensure the number of roles is equal to at least one element (with the use of postcondition) +data "snowflake_account_roles" "assert_with_postcondition" { + like = "role-name-%" + lifecycle { + postcondition { + condition = length(self.roles) > 0 + error_message = "there should be at least one role" + } + } +} + +# Ensure the number of roles is equal to at exactly one element (with the use of check block) +check "role_check" { + data "snowflake_account_roles" "assert_with_check_block" { + like = "role-name" + } + + assert { + condition = length(data.snowflake_account_roles.assert_with_check_block.roles) == 1 + error_message = "Roles filtered by '${data.snowflake_account_roles.assert_with_check_block.like}' returned ${length(data.snowflake_account_roles.assert_with_check_block.roles)} roles where one was expected" + } +} +``` + + +## Schema + +### Optional + +- `in_class` (String) Filters the SHOW GRANTS output by class name. +- `like` (String) Filters the output with **case-insensitive** pattern, with support for SQL wildcard characters (`%` and `_`). + +### Read-Only + +- `account_roles` (List of Object) Holds the aggregated output of all account role details queries. (see [below for nested schema](#nestedatt--account_roles)) +- `id` (String) The ID of this resource. + + +### Nested Schema for `account_roles` + +Read-Only: + +- `show_output` (List of Object) (see [below for nested schema](#nestedobjatt--account_roles--show_output)) + + +### Nested Schema for `account_roles.show_output` + +Read-Only: + +- `assigned_to_users` (Number) +- `comment` (String) +- `created_on` (String) +- `granted_roles` (Number) +- `granted_to_roles` (Number) +- `is_current` (Boolean) +- `is_default` (Boolean) +- `is_inherited` (Boolean) +- `name` (String) +- `owner` (String) diff --git a/docs/data-sources/role.md b/docs/data-sources/role.md index ddb3bcc22e..d2a16369ec 100644 --- a/docs/data-sources/role.md +++ b/docs/data-sources/role.md @@ -7,7 +7,7 @@ description: |- # snowflake_role (Data Source) -~> **Deprecation** This resource is deprecated and will be removed in a future major version release. Please use [snowflake_roles](./roles) instead. +~> **Deprecation** This resource is deprecated and will be removed in a future major version release. Please use [snowflake_account_roles](./account_roles) instead. ## Example Usage diff --git a/docs/data-sources/roles.md b/docs/data-sources/roles.md index 0e5db6a28f..ff55a1326f 100644 --- a/docs/data-sources/roles.md +++ b/docs/data-sources/roles.md @@ -12,6 +12,8 @@ description: |- # snowflake_roles (Data Source) +~> **Deprecation** This resource is deprecated and will be removed in a future major version release. Please use [snowflake_account_roles](./account_roles) instead. + Data source used to get details of filtered roles. Filtering is aligned with the current possibilities for [SHOW ROLES](https://docs.snowflake.com/en/sql-reference/sql/show-roles) query (`like` and `in_class` are all supported). The results of SHOW are encapsulated in one output collection. ## Example Usage diff --git a/docs/index.md b/docs/index.md index 9a69fadbe9..22a83b9c0e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -370,4 +370,5 @@ provider "snowflake" { ## Currently deprecated datasources -- [snowflake_role](./docs/data-sources/role) - use [snowflake_roles](./docs/data-sources/roles) instead +- [snowflake_role](./docs/data-sources/role) - use [snowflake_account_roles](./docs/data-sources/account_roles) instead +- [snowflake_roles](./docs/data-sources/roles) - use [snowflake_account_roles](./docs/data-sources/account_roles) instead diff --git a/docs/resources/database.md b/docs/resources/database.md index e5d16f93e4..95df361ef3 100644 --- a/docs/resources/database.md +++ b/docs/resources/database.md @@ -9,8 +9,7 @@ description: |- !> **Note** The provider does not detect external changes on database type. In this case, remove the database of wrong type manually with `terraform destroy` and recreate the resource. It will be addressed in the future. -!> **Note** A database cannot be dropped successfully if it contains network rule-network policy associations. The error looks like `098507 (2BP01): Cannot drop database DATABASE as it includes network rule - policy associations. -`. Currently, the provider does not unassign such objects automatically. Before dropping the resource, first unassign the network rule from the relevant objects. See [guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/unassigning_policies) for more details. +!> **Note** A database cannot be dropped successfully if it contains network rule-network policy associations. The error looks like `098507 (2BP01): Cannot drop database DATABASE as it includes network rule - policy associations.`. Currently, the provider does not unassign such objects automatically. Before dropping the resource, first unassign the network rule from the relevant objects. See [guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/unassigning_policies) for more details. # snowflake_database (Resource) diff --git a/docs/resources/secondary_database.md b/docs/resources/secondary_database.md index 652f875871..c6e4e6a2e5 100644 --- a/docs/resources/secondary_database.md +++ b/docs/resources/secondary_database.md @@ -10,8 +10,7 @@ description: |- !> **Note** The provider does not detect external changes on database type. In this case, remove the database of wrong type manually with `terraform destroy` and recreate the resource. It will be addressed in the future. -!> **Note** A database cannot be dropped successfully if it contains network rule-network policy associations. The error looks like `098507 (2BP01): Cannot drop database DATABASE as it includes network rule - policy associations. -`. Currently, the provider does not unassign such objects automatically. Before dropping the resource, first unassign the network rule from the relevant objects. See [guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/unassigning_policies) for more details. +!> **Note** A database cannot be dropped successfully if it contains network rule-network policy associations. The error looks like `098507 (2BP01): Cannot drop database DATABASE as it includes network rule - policy associations.`. Currently, the provider does not unassign such objects automatically. Before dropping the resource, first unassign the network rule from the relevant objects. See [guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/unassigning_policies) for more details. # snowflake_secondary_database (Resource) diff --git a/docs/resources/shared_database.md b/docs/resources/shared_database.md index daf52b60bd..af44483644 100644 --- a/docs/resources/shared_database.md +++ b/docs/resources/shared_database.md @@ -9,8 +9,7 @@ description: |- !> **Note** The provider does not detect external changes on database type. In this case, remove the database of wrong type manually with `terraform destroy` and recreate the resource. It will be addressed in the future. -!> **Note** A database cannot be dropped successfully if it contains network rule-network policy associations. The error looks like `098507 (2BP01): Cannot drop database DATABASE as it includes network rule - policy associations. -`. Currently, the provider does not unassign such objects automatically. Before dropping the resource, first unassign the network rule from the relevant objects. See [guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/unassigning_policies) for more details. +!> **Note** A database cannot be dropped successfully if it contains network rule-network policy associations. The error looks like `098507 (2BP01): Cannot drop database DATABASE as it includes network rule - policy associations.`. Currently, the provider does not unassign such objects automatically. Before dropping the resource, first unassign the network rule from the relevant objects. See [guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/unassigning_policies) for more details. # snowflake_shared_database (Resource) diff --git a/examples/additional/deprecated_datasources.MD b/examples/additional/deprecated_datasources.MD index 935ebcfd54..9846a374a1 100644 --- a/examples/additional/deprecated_datasources.MD +++ b/examples/additional/deprecated_datasources.MD @@ -1,3 +1,4 @@ ## Currently deprecated datasources -- [snowflake_role](./docs/data-sources/role) - use [snowflake_roles](./docs/data-sources/roles) instead +- [snowflake_role](./docs/data-sources/role) - use [snowflake_account_roles](./docs/data-sources/account_roles) instead +- [snowflake_roles](./docs/data-sources/roles) - use [snowflake_account_roles](./docs/data-sources/account_roles) instead diff --git a/examples/data-sources/snowflake_account_roles/data-source.tf b/examples/data-sources/snowflake_account_roles/data-source.tf new file mode 100644 index 0000000000..2f48b3067c --- /dev/null +++ b/examples/data-sources/snowflake_account_roles/data-source.tf @@ -0,0 +1,48 @@ +# Simple usage +data "snowflake_account_roles" "simple" { +} + +output "simple_output" { + value = data.snowflake_account_roles.simple.roles +} + +# Filtering (like) +data "snowflake_account_roles" "like" { + like = "role-name" +} + +output "like_output" { + value = data.snowflake_account_roles.like.roles +} + +# Filtering (in class) +data "snowflake_account_roles" "in_class" { + in_class = "SNOWFLAKE.CORE.BUDGET" +} + +output "in_class_output" { + value = data.snowflake_account_roles.in_class.roles +} + +# Ensure the number of roles is equal to at least one element (with the use of postcondition) +data "snowflake_account_roles" "assert_with_postcondition" { + like = "role-name-%" + lifecycle { + postcondition { + condition = length(self.roles) > 0 + error_message = "there should be at least one role" + } + } +} + +# Ensure the number of roles is equal to at exactly one element (with the use of check block) +check "role_check" { + data "snowflake_account_roles" "assert_with_check_block" { + like = "role-name" + } + + assert { + condition = length(data.snowflake_account_roles.assert_with_check_block.roles) == 1 + error_message = "Roles filtered by '${data.snowflake_account_roles.assert_with_check_block.like}' returned ${length(data.snowflake_account_roles.assert_with_check_block.roles)} roles where one was expected" + } +} diff --git a/pkg/acceptance/bettertestspoc/README.md b/pkg/acceptance/bettertestspoc/README.md index 1cae4a6760..ee03bf37be 100644 --- a/pkg/acceptance/bettertestspoc/README.md +++ b/pkg/acceptance/bettertestspoc/README.md @@ -393,6 +393,7 @@ func (w *WarehouseDatasourceShowOutputAssert) IsEmpty() { - generate assertions checking that time is not empty - we often do not compare time fields by value, but check if they are set - utilize `ContainsExactlyInAnyOrder` function in `pkg/acceptance/bettertestspoc/assert/commons.go` to create asserts on collections that are order independent - Additional asserts for sets and lists that wouldn't rely on the order of items saved to the state (SNOW-1706544) + - this should also support nested sets and lists (see `accountRolesDataSourceContainsRole` for example) - support generating provider config and use generated configs in `pkg/provider/provider_acceptance_test.go` - add config builders for other block types (Variable, Output, Locals, Module, Terraform) - add provider to resource/datasource models (use in the grant_ownership_acceptance_test) diff --git a/pkg/datasources/account_roles.go b/pkg/datasources/account_roles.go new file mode 100644 index 0000000000..2602462df2 --- /dev/null +++ b/pkg/datasources/account_roles.go @@ -0,0 +1,94 @@ +package datasources + +import ( + "context" + "fmt" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/datasources" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/resources" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/schemas" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var accountRolesSchema = map[string]*schema.Schema{ + "like": likeSchema, + "in_class": { + Type: schema.TypeString, + Optional: true, + ValidateDiagFunc: resources.IsValidIdentifier[sdk.SchemaObjectIdentifier](), + Description: "Filters the SHOW GRANTS output by class name.", + }, + "account_roles": { + Type: schema.TypeList, + Computed: true, + Description: "Holds the aggregated output of all account role details queries.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + resources.ShowOutputAttributeName: { + Type: schema.TypeList, + Computed: true, + Description: "Holds the output of SHOW ROLES.", + Elem: &schema.Resource{ + Schema: schemas.ShowRoleSchema, + }, + }, + }, + }, + }, +} + +func AccountRoles() *schema.Resource { + return &schema.Resource{ + ReadContext: TrackingReadWrapper(datasources.AccountRoles, ReadAccountRoles), + Schema: accountRolesSchema, + Description: "Data source used to get details of filtered account roles. Filtering is aligned with the current possibilities for [SHOW ROLES](https://docs.snowflake.com/en/sql-reference/sql/show-roles) query (`like` and `in_class` are all supported). The results of SHOW are encapsulated in one output collection.", + } +} + +func ReadAccountRoles(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { + client := meta.(*provider.Context).Client + + req := sdk.NewShowRoleRequest() + + handleLike(d, &req.Like) + + if className, ok := d.GetOk("in_class"); ok { + req.WithInClass(sdk.RolesInClass{ + Class: sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(className.(string)), + }) + } + + roles, err := client.Roles.Show(ctx, req) + if err != nil { + return diag.Diagnostics{ + diag.Diagnostic{ + Severity: diag.Error, + Summary: "Failed to show account roles", + Detail: fmt.Sprintf("Error: %s", err), + }, + } + } + + d.SetId("account_roles_read") + + flattenedAccountRoles := make([]map[string]any, len(roles)) + for i, role := range roles { + role := role + flattenedAccountRoles[i] = map[string]any{ + resources.ShowOutputAttributeName: []map[string]any{schemas.RoleToSchema(&role)}, + } + } + + err = d.Set("account_roles", flattenedAccountRoles) + if err != nil { + return diag.FromErr(err) + } + + return nil +} diff --git a/pkg/datasources/account_roles_acceptance_test.go b/pkg/datasources/account_roles_acceptance_test.go new file mode 100644 index 0000000000..66dde1f377 --- /dev/null +++ b/pkg/datasources/account_roles_acceptance_test.go @@ -0,0 +1,116 @@ +package datasources_test + +import ( + "fmt" + "strconv" + "testing" + + acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/helpers/random" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/testenvs" + "github.com/hashicorp/terraform-plugin-testing/config" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-plugin-testing/tfversion" +) + +func TestAcc_AccountRoles_Complete(t *testing.T) { + _ = testenvs.GetOrSkipTest(t, testenvs.EnableAcceptance) + acc.TestAccPreCheck(t) + + accountRoleNamePrefix := random.AlphaN(10) + accountRoleName1 := acc.TestClient().Ids.AlphaWithPrefix(accountRoleNamePrefix + "1") + accountRoleName2 := acc.TestClient().Ids.AlphaWithPrefix(accountRoleNamePrefix + "2") + accountRoleName3 := acc.TestClient().Ids.Alpha() + dbRoleName := acc.TestClient().Ids.AlphaWithPrefix(accountRoleNamePrefix + "db") + comment := random.Comment() + + // Proof that database role with the same prefix is not in the output of SHOW ROLES. + dbRole, dbRoleCleanup := acc.TestClient().DatabaseRole.CreateDatabaseRoleWithName(t, dbRoleName) + t.Cleanup(dbRoleCleanup) + + likeVariables := config.Variables{ + "account_role_name_1": config.StringVariable(accountRoleName1), + "account_role_name_2": config.StringVariable(accountRoleName2), + "account_role_name_3": config.StringVariable(accountRoleName3), + "comment": config.StringVariable(comment), + "like": config.StringVariable(accountRoleNamePrefix + "%"), + } + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + Steps: []resource.TestStep{ + { + ConfigDirectory: config.TestStepDirectory(), + ConfigVariables: likeVariables, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_account_roles.test", "account_roles.#", "2"), + accountRolesDataSourceContainsRole(accountRoleName1, comment), + accountRolesDataSourceContainsRole(accountRoleName2, comment), + accountRolesDataSourceDoesNotContainRole(accountRoleName3, comment), + accountRolesDataSourceDoesNotContainRole(dbRole.ID().FullyQualifiedName(), comment), + ), + }, + { + ConfigDirectory: config.TestStepDirectory(), + ConfigVariables: config.Variables{}, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrWith("data.snowflake_account_roles.test", "account_roles.#", func(value string) error { + numberOfRoles, err := strconv.ParseInt(value, 10, 8) + if err != nil { + return err + } + + if numberOfRoles == 0 { + return fmt.Errorf("expected roles to be non-empty") + } + + return nil + }), + ), + }, + }, + }) +} + +func accountRolesDataSourceDoesNotContainRole(name string, comment string) func(s *terraform.State) error { + return func(state *terraform.State) error { + err := accountRolesDataSourceContainsRole(name, comment)(state) + if err != nil && err.Error() == fmt.Sprintf("role %s not found", name) { + return nil + } + return fmt.Errorf("expected %s not to be present", name) + } +} + +func accountRolesDataSourceContainsRole(name string, comment string) func(s *terraform.State) error { + return func(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "snowflake_account_roles" { + continue + } + + iter, err := strconv.ParseInt(rs.Primary.Attributes["account_roles.#"], 10, 32) + if err != nil { + return err + } + + for i := 0; i < int(iter); i++ { + if rs.Primary.Attributes[fmt.Sprintf("account_roles.%d.show_output.0.name", i)] == name { + actualComment := rs.Primary.Attributes[fmt.Sprintf("account_roles.%d.show_output.0.comment", i)] + if actualComment != comment { + return fmt.Errorf("expected comment: %s, but got: %s", comment, actualComment) + } + + return nil + } + } + } + + return fmt.Errorf("role %s not found", name) + } +} diff --git a/pkg/datasources/role.go b/pkg/datasources/role.go index 4f2ccb5898..bb168351d7 100644 --- a/pkg/datasources/role.go +++ b/pkg/datasources/role.go @@ -33,7 +33,7 @@ func Role() *schema.Resource { return &schema.Resource{ ReadContext: TrackingReadWrapper(datasources.Role, ReadRole), Schema: roleSchema, - DeprecationMessage: "This resource is deprecated and will be removed in a future major version release. Please use snowflake_roles instead.", + DeprecationMessage: "This resource is deprecated and will be removed in a future major version release. Please use snowflake_account_roles instead.", Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, diff --git a/pkg/datasources/roles.go b/pkg/datasources/roles.go index bdce14c43e..597702a637 100644 --- a/pkg/datasources/roles.go +++ b/pkg/datasources/roles.go @@ -49,9 +49,10 @@ var rolesSchema = map[string]*schema.Schema{ func Roles() *schema.Resource { return &schema.Resource{ - ReadContext: TrackingReadWrapper(datasources.Roles, ReadRoles), - Schema: rolesSchema, - Description: "Data source used to get details of filtered roles. Filtering is aligned with the current possibilities for [SHOW ROLES](https://docs.snowflake.com/en/sql-reference/sql/show-roles) query (`like` and `in_class` are all supported). The results of SHOW are encapsulated in one output collection.", + ReadContext: TrackingReadWrapper(datasources.Roles, ReadRoles), + Schema: rolesSchema, + DeprecationMessage: "This resource is deprecated and will be removed in a future major version release. Please use snowflake_account_roles instead.", + Description: "Data source used to get details of filtered roles. Filtering is aligned with the current possibilities for [SHOW ROLES](https://docs.snowflake.com/en/sql-reference/sql/show-roles) query (`like` and `in_class` are all supported). The results of SHOW are encapsulated in one output collection.", } } diff --git a/pkg/datasources/roles_acceptance_test.go b/pkg/datasources/roles_acceptance_test.go index af29e8fd11..35623e2ec0 100644 --- a/pkg/datasources/roles_acceptance_test.go +++ b/pkg/datasources/roles_acceptance_test.go @@ -41,9 +41,9 @@ func TestAcc_Roles_Complete(t *testing.T) { ConfigVariables: likeVariables, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("data.snowflake_roles.test", "roles.#", "2"), - containsAccountRole(accountRoleName1, comment), - containsAccountRole(accountRoleName2, comment), - doesntContainAccountRole(accountRoleName3, comment), + // containsRole(accountRoleName1, comment), + // containsRole(accountRoleName2, comment), + doesntContainRole(accountRoleName3, comment), ), }, { @@ -68,9 +68,9 @@ func TestAcc_Roles_Complete(t *testing.T) { }) } -func doesntContainAccountRole(name string, comment string) func(s *terraform.State) error { +func doesntContainRole(name string, comment string) func(s *terraform.State) error { return func(state *terraform.State) error { - err := containsAccountRole(name, comment)(state) + err := containsRole(name, comment)(state) if err != nil && err.Error() == fmt.Sprintf("role %s not found", name) { return nil } @@ -78,7 +78,7 @@ func doesntContainAccountRole(name string, comment string) func(s *terraform.Sta } } -func containsAccountRole(name string, comment string) func(s *terraform.State) error { +func containsRole(name string, comment string) func(s *terraform.State) error { return func(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "snowflake_roles" { diff --git a/pkg/datasources/testdata/TestAcc_AccountRoles_Complete/1/test.tf b/pkg/datasources/testdata/TestAcc_AccountRoles_Complete/1/test.tf new file mode 100644 index 0000000000..68afff3b58 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_AccountRoles_Complete/1/test.tf @@ -0,0 +1,23 @@ +resource "snowflake_account_role" "test1" { + name = var.account_role_name_1 + comment = var.comment +} + +resource "snowflake_account_role" "test2" { + name = var.account_role_name_2 + comment = var.comment +} + +resource "snowflake_account_role" "test3" { + name = var.account_role_name_3 + comment = var.comment +} + +data "snowflake_account_roles" "test" { + depends_on = [ + snowflake_account_role.test1, + snowflake_account_role.test2, + snowflake_account_role.test3, + ] + like = var.like +} diff --git a/pkg/datasources/testdata/TestAcc_AccountRoles_Complete/1/variables.tf b/pkg/datasources/testdata/TestAcc_AccountRoles_Complete/1/variables.tf new file mode 100644 index 0000000000..fcd75c445f --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_AccountRoles_Complete/1/variables.tf @@ -0,0 +1,19 @@ +variable "account_role_name_1" { + type = string +} + +variable "account_role_name_2" { + type = string +} + +variable "account_role_name_3" { + type = string +} + +variable "comment" { + type = string +} + +variable "like" { + type = string +} diff --git a/pkg/datasources/testdata/TestAcc_AccountRoles_Complete/2/test.tf b/pkg/datasources/testdata/TestAcc_AccountRoles_Complete/2/test.tf new file mode 100644 index 0000000000..8a45ee2f6e --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_AccountRoles_Complete/2/test.tf @@ -0,0 +1,3 @@ +data "snowflake_account_roles" "test" { + in_class = "SNOWFLAKE.CORE.BUDGET" +} diff --git a/pkg/provider/datasources/datasources.go b/pkg/provider/datasources/datasources.go index 56ea68b1c3..c31b954a22 100644 --- a/pkg/provider/datasources/datasources.go +++ b/pkg/provider/datasources/datasources.go @@ -4,6 +4,7 @@ type datasource string const ( Accounts datasource = "snowflake_accounts" + AccountRoles datasource = "snowflake_account_roles" Alerts datasource = "snowflake_alerts" Connections datasource = "snowflake_connections" CortexSearchServices datasource = "snowflake_cortex_search_services" diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index 37e5316e39..2e2b486830 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -579,6 +579,7 @@ func getResources() map[string]*schema.Resource { func getDataSources() map[string]*schema.Resource { return map[string]*schema.Resource{ "snowflake_accounts": datasources.Accounts(), + "snowflake_account_roles": datasources.AccountRoles(), "snowflake_alerts": datasources.Alerts(), "snowflake_connections": datasources.Connections(), "snowflake_cortex_search_services": datasources.CortexSearchServices(), diff --git a/pkg/resources/diff_suppressions.go b/pkg/resources/diff_suppressions.go index 4e80bbf0e4..8d10cb1758 100644 --- a/pkg/resources/diff_suppressions.go +++ b/pkg/resources/diff_suppressions.go @@ -267,6 +267,7 @@ func IgnoreNewEmptyListOrSubfields(ignoredSubfields ...string) schema.SchemaDiff // IgnoreMatchingColumnNameAndMaskingPolicyUsingFirstElem ignores when the first element of USING is matching the column name. // see USING section in https://docs.snowflake.com/en/sql-reference/sql/create-view#optional-parameters +// TODO(SNOW-1852423): improve docs and add more tests func IgnoreMatchingColumnNameAndMaskingPolicyUsingFirstElem() schema.SchemaDiffSuppressFunc { return func(k, old, new string, d *schema.ResourceData) bool { // suppress diff when the name of the column matches the name of using diff --git a/templates/resources/database.md.tmpl b/templates/resources/database.md.tmpl index 719a06f49e..65bc7d0dc9 100644 --- a/templates/resources/database.md.tmpl +++ b/templates/resources/database.md.tmpl @@ -13,8 +13,7 @@ description: |- !> **Note** The provider does not detect external changes on database type. In this case, remove the database of wrong type manually with `terraform destroy` and recreate the resource. It will be addressed in the future. -!> **Note** A database cannot be dropped successfully if it contains network rule-network policy associations. The error looks like `098507 (2BP01): Cannot drop database DATABASE as it includes network rule - policy associations. -`. Currently, the provider does not unassign such objects automatically. Before dropping the resource, first unassign the network rule from the relevant objects. See [guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/unassigning_policies) for more details. +!> **Note** A database cannot be dropped successfully if it contains network rule-network policy associations. The error looks like `098507 (2BP01): Cannot drop database DATABASE as it includes network rule - policy associations.`. Currently, the provider does not unassign such objects automatically. Before dropping the resource, first unassign the network rule from the relevant objects. See [guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/unassigning_policies) for more details. # {{.Name}} ({{.Type}}) diff --git a/templates/resources/secondary_database.md.tmpl b/templates/resources/secondary_database.md.tmpl index acb3bfb61c..5abd07b360 100644 --- a/templates/resources/secondary_database.md.tmpl +++ b/templates/resources/secondary_database.md.tmpl @@ -14,8 +14,7 @@ description: |- !> **Note** The provider does not detect external changes on database type. In this case, remove the database of wrong type manually with `terraform destroy` and recreate the resource. It will be addressed in the future. -!> **Note** A database cannot be dropped successfully if it contains network rule-network policy associations. The error looks like `098507 (2BP01): Cannot drop database DATABASE as it includes network rule - policy associations. -`. Currently, the provider does not unassign such objects automatically. Before dropping the resource, first unassign the network rule from the relevant objects. See [guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/unassigning_policies) for more details. +!> **Note** A database cannot be dropped successfully if it contains network rule-network policy associations. The error looks like `098507 (2BP01): Cannot drop database DATABASE as it includes network rule - policy associations.`. Currently, the provider does not unassign such objects automatically. Before dropping the resource, first unassign the network rule from the relevant objects. See [guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/unassigning_policies) for more details. # {{.Name}} ({{.Type}}) diff --git a/templates/resources/shared_database.md.tmpl b/templates/resources/shared_database.md.tmpl index 719a06f49e..65bc7d0dc9 100644 --- a/templates/resources/shared_database.md.tmpl +++ b/templates/resources/shared_database.md.tmpl @@ -13,8 +13,7 @@ description: |- !> **Note** The provider does not detect external changes on database type. In this case, remove the database of wrong type manually with `terraform destroy` and recreate the resource. It will be addressed in the future. -!> **Note** A database cannot be dropped successfully if it contains network rule-network policy associations. The error looks like `098507 (2BP01): Cannot drop database DATABASE as it includes network rule - policy associations. -`. Currently, the provider does not unassign such objects automatically. Before dropping the resource, first unassign the network rule from the relevant objects. See [guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/unassigning_policies) for more details. +!> **Note** A database cannot be dropped successfully if it contains network rule-network policy associations. The error looks like `098507 (2BP01): Cannot drop database DATABASE as it includes network rule - policy associations.`. Currently, the provider does not unassign such objects automatically. Before dropping the resource, first unassign the network rule from the relevant objects. See [guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/unassigning_policies) for more details. # {{.Name}} ({{.Type}})