Skip to content

Commit de7f54a

Browse files
authored
fix: Changes actions attribute to TypeSet in mongodbatlas_custom_db_role to not be sensitive to order (#3508)
* rename files * avoids order sensitivity * Use TypeSet checks instead of index-based checks for actions * changelog change * inline calls in config
1 parent e212c81 commit de7f54a

File tree

6 files changed

+120
-15
lines changed

6 files changed

+120
-15
lines changed

.changelog/3508.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:breaking-change
2+
resource/mongodbatlas_custom_db_role: Changes actions attribute to not be sensitive to order
3+
```

internal/service/customdbrole/resource_custom_db_role.go renamed to internal/service/customdbrole/resource.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func Resource() *schema.Resource {
5151
),
5252
},
5353
"actions": {
54-
Type: schema.TypeList,
54+
Type: schema.TypeSet,
5555
Optional: true,
5656
Elem: &schema.Resource{
5757
Schema: map[string]*schema.Schema{
@@ -269,8 +269,8 @@ func resourceImport(ctx context.Context, d *schema.ResourceData, meta any) ([]*s
269269
}
270270

271271
func expandActions(d *schema.ResourceData) *[]admin.DatabasePrivilegeAction {
272-
actions := make([]admin.DatabasePrivilegeAction, len(d.Get("actions").([]any)))
273-
for k, v := range d.Get("actions").([]any) {
272+
actions := make([]admin.DatabasePrivilegeAction, len(d.Get("actions").(*schema.Set).List()))
273+
for k, v := range d.Get("actions").(*schema.Set).List() {
274274
a := v.(map[string]any)
275275
actions[k] = admin.DatabasePrivilegeAction{
276276
Action: a["action"].(string),

internal/service/customdbrole/resource_custom_db_role_test.go renamed to internal/service/customdbrole/resource_test.go

Lines changed: 114 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
1010
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
11+
"github.com/hashicorp/terraform-plugin-testing/plancheck"
1112
"github.com/hashicorp/terraform-plugin-testing/statecheck"
1213
"github.com/hashicorp/terraform-plugin-testing/terraform"
1314
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
@@ -38,6 +39,10 @@ func TestAccCustomDBRoles_Basic(t *testing.T) {
3839
resource.ParallelTest(t, *basicTestCase(t))
3940
}
4041

42+
func TestAccCustomDBRoles_BasicWithTwoActions(t *testing.T) {
43+
resource.ParallelTest(t, *basicTestCaseWithTwoActions(t))
44+
}
45+
4146
func basicTestCase(t *testing.T) *resource.TestCase {
4247
t.Helper()
4348
var (
@@ -84,6 +89,39 @@ func basicTestCase(t *testing.T) *resource.TestCase {
8489
}
8590
}
8691

92+
func basicTestCaseWithTwoActions(t *testing.T) *resource.TestCase {
93+
t.Helper()
94+
var (
95+
projectID = acc.ProjectIDExecution(t)
96+
roleName = acc.RandomName()
97+
action1 = "INSERT"
98+
action2 = "UPDATE"
99+
databaseName1 = acc.RandomClusterName()
100+
databaseName2 = acc.RandomClusterName()
101+
)
102+
103+
return &resource.TestCase{
104+
PreCheck: func() { acc.PreCheckBasic(t) },
105+
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
106+
CheckDestroy: checkDestroy,
107+
Steps: []resource.TestStep{
108+
{
109+
Config: configBasicWithTwoActions(projectID, roleName, action1, databaseName1, action2, databaseName2),
110+
Check: checkExists(resourceName),
111+
},
112+
{
113+
Config: configBasicWithTwoActions(projectID, roleName, action2, databaseName2, action1, databaseName1), // reverse the actions order
114+
Check: checkExists(resourceName),
115+
ConfigPlanChecks: resource.ConfigPlanChecks{
116+
PreApply: []plancheck.PlanCheck{
117+
plancheck.ExpectEmptyPlan(),
118+
},
119+
},
120+
},
121+
},
122+
}
123+
}
124+
87125
func checkAttrs(projectID, roleName, action, databaseName string) resource.TestCheckFunc {
88126
return acc.CheckRSAndDS(
89127
resourceName,
@@ -378,16 +416,28 @@ func TestAccConfigRSCustomDBRoles_MultipleCustomRoles(t *testing.T) {
378416
resource.TestCheckResourceAttrSet(InheritedRoleResourceName, "project_id"),
379417
resource.TestCheckResourceAttr(InheritedRoleResourceName, "role_name", inheritRole.RoleName),
380418
resource.TestCheckResourceAttr(InheritedRoleResourceName, "actions.#", cast.ToString(len(inheritRole.GetActions()))),
381-
resource.TestCheckResourceAttr(InheritedRoleResourceName, "actions.0.action", inheritRole.GetActions()[0].Action),
382-
resource.TestCheckResourceAttr(InheritedRoleResourceName, "actions.0.resources.#", cast.ToString(len(inheritRole.GetActions()[0].GetResources()))),
419+
resource.TestCheckTypeSetElemNestedAttrs(InheritedRoleResourceName, "actions.*", map[string]string{
420+
"action": inheritRole.GetActions()[0].Action,
421+
"resources.#": cast.ToString(len(inheritRole.GetActions()[0].GetResources())),
422+
}),
423+
resource.TestCheckTypeSetElemNestedAttrs(InheritedRoleResourceName, "actions.*", map[string]string{
424+
"action": inheritRole.GetActions()[1].Action,
425+
"resources.#": cast.ToString(len(inheritRole.GetActions()[1].GetResources())),
426+
}),
383427

384428
// For Test Role
385429
checkExists(testRoleResourceName),
386430
resource.TestCheckResourceAttrSet(testRoleResourceName, "project_id"),
387431
resource.TestCheckResourceAttr(testRoleResourceName, "role_name", testRole.RoleName),
388432
resource.TestCheckResourceAttr(testRoleResourceName, "actions.#", cast.ToString(len(testRole.GetActions()))),
389-
resource.TestCheckResourceAttr(testRoleResourceName, "actions.0.action", testRole.GetActions()[0].Action),
390-
resource.TestCheckResourceAttr(testRoleResourceName, "actions.0.resources.#", cast.ToString(len(testRole.GetActions()[0].GetResources()))),
433+
resource.TestCheckTypeSetElemNestedAttrs(testRoleResourceName, "actions.*", map[string]string{
434+
"action": testRole.GetActions()[0].Action,
435+
"resources.#": cast.ToString(len(testRole.GetActions()[0].GetResources())),
436+
}),
437+
resource.TestCheckTypeSetElemNestedAttrs(testRoleResourceName, "actions.*", map[string]string{
438+
"action": testRole.GetActions()[1].Action,
439+
"resources.#": cast.ToString(len(testRole.GetActions()[1].GetResources())),
440+
}),
391441
),
392442
},
393443
{
@@ -399,16 +449,28 @@ func TestAccConfigRSCustomDBRoles_MultipleCustomRoles(t *testing.T) {
399449
resource.TestCheckResourceAttrSet(InheritedRoleResourceName, "project_id"),
400450
resource.TestCheckResourceAttr(InheritedRoleResourceName, "role_name", inheritRoleUpdated.RoleName),
401451
resource.TestCheckResourceAttr(InheritedRoleResourceName, "actions.#", cast.ToString(len(inheritRoleUpdated.GetActions()))),
402-
resource.TestCheckResourceAttr(InheritedRoleResourceName, "actions.0.action", inheritRoleUpdated.GetActions()[0].Action),
403-
resource.TestCheckResourceAttr(InheritedRoleResourceName, "actions.0.resources.#", cast.ToString(len(inheritRoleUpdated.GetActions()[0].GetResources()))),
452+
resource.TestCheckTypeSetElemNestedAttrs(InheritedRoleResourceName, "actions.*", map[string]string{
453+
"action": inheritRoleUpdated.GetActions()[0].Action,
454+
"resources.#": cast.ToString(len(inheritRoleUpdated.GetActions()[0].GetResources())),
455+
}),
456+
resource.TestCheckTypeSetElemNestedAttrs(InheritedRoleResourceName, "actions.*", map[string]string{
457+
"action": inheritRoleUpdated.GetActions()[1].Action,
458+
"resources.#": cast.ToString(len(inheritRoleUpdated.GetActions()[1].GetResources())),
459+
}),
460+
resource.TestCheckTypeSetElemNestedAttrs(InheritedRoleResourceName, "actions.*", map[string]string{
461+
"action": inheritRoleUpdated.GetActions()[2].Action,
462+
"resources.#": cast.ToString(len(inheritRoleUpdated.GetActions()[2].GetResources())),
463+
}),
404464

405465
// For Test Role
406466
checkExists(testRoleResourceName),
407467
resource.TestCheckResourceAttrSet(testRoleResourceName, "project_id"),
408468
resource.TestCheckResourceAttr(testRoleResourceName, "role_name", testRoleUpdated.RoleName),
409469
resource.TestCheckResourceAttr(testRoleResourceName, "actions.#", cast.ToString(len(testRoleUpdated.GetActions()))),
410-
resource.TestCheckResourceAttr(testRoleResourceName, "actions.0.action", testRoleUpdated.GetActions()[0].Action),
411-
resource.TestCheckResourceAttr(testRoleResourceName, "actions.0.resources.#", cast.ToString(len(testRoleUpdated.GetActions()[0].GetResources()))),
470+
resource.TestCheckTypeSetElemNestedAttrs(testRoleResourceName, "actions.*", map[string]string{
471+
"action": testRoleUpdated.GetActions()[0].Action,
472+
"resources.#": cast.ToString(len(testRoleUpdated.GetActions()[0].GetResources())),
473+
}),
412474
resource.TestCheckResourceAttr(testRoleResourceName, "inherited_roles.#", "1"),
413475
),
414476
},
@@ -509,8 +571,14 @@ func TestAccConfigRSCustomDBRoles_UpdatedInheritRoles(t *testing.T) {
509571
resource.TestCheckResourceAttrSet(InheritedRoleResourceName, "project_id"),
510572
resource.TestCheckResourceAttr(InheritedRoleResourceName, "role_name", inheritRole.RoleName),
511573
resource.TestCheckResourceAttr(InheritedRoleResourceName, "actions.#", cast.ToString(len(inheritRole.GetActions()))),
512-
resource.TestCheckResourceAttr(InheritedRoleResourceName, "actions.0.action", inheritRole.GetActions()[0].Action),
513-
resource.TestCheckResourceAttr(InheritedRoleResourceName, "actions.0.resources.#", cast.ToString(len(inheritRole.GetActions()[0].GetResources()))),
574+
resource.TestCheckTypeSetElemNestedAttrs(InheritedRoleResourceName, "actions.*", map[string]string{
575+
"action": inheritRole.GetActions()[0].Action,
576+
"resources.#": cast.ToString(len(inheritRole.GetActions()[0].GetResources())),
577+
}),
578+
resource.TestCheckTypeSetElemNestedAttrs(InheritedRoleResourceName, "actions.*", map[string]string{
579+
"action": inheritRole.GetActions()[1].Action,
580+
"resources.#": cast.ToString(len(inheritRole.GetActions()[1].GetResources())),
581+
}),
514582

515583
// For Test Role
516584
checkExists(testRoleResourceName),
@@ -529,8 +597,18 @@ func TestAccConfigRSCustomDBRoles_UpdatedInheritRoles(t *testing.T) {
529597
resource.TestCheckResourceAttrSet(InheritedRoleResourceName, "project_id"),
530598
resource.TestCheckResourceAttr(InheritedRoleResourceName, "role_name", inheritRoleUpdated.RoleName),
531599
resource.TestCheckResourceAttr(InheritedRoleResourceName, "actions.#", cast.ToString(len(inheritRoleUpdated.GetActions()))),
532-
resource.TestCheckResourceAttr(InheritedRoleResourceName, "actions.0.action", inheritRoleUpdated.GetActions()[0].Action),
533-
resource.TestCheckResourceAttr(InheritedRoleResourceName, "actions.0.resources.#", cast.ToString(len(inheritRoleUpdated.GetActions()[0].GetResources()))),
600+
resource.TestCheckTypeSetElemNestedAttrs(InheritedRoleResourceName, "actions.*", map[string]string{
601+
"action": inheritRoleUpdated.GetActions()[0].Action,
602+
"resources.#": cast.ToString(len(inheritRoleUpdated.GetActions()[0].GetResources())),
603+
}),
604+
resource.TestCheckTypeSetElemNestedAttrs(InheritedRoleResourceName, "actions.*", map[string]string{
605+
"action": inheritRoleUpdated.GetActions()[1].Action,
606+
"resources.#": cast.ToString(len(inheritRoleUpdated.GetActions()[1].GetResources())),
607+
}),
608+
resource.TestCheckTypeSetElemNestedAttrs(InheritedRoleResourceName, "actions.*", map[string]string{
609+
"action": inheritRoleUpdated.GetActions()[2].Action,
610+
"resources.#": cast.ToString(len(inheritRoleUpdated.GetActions()[2].GetResources())),
611+
}),
534612

535613
// For Test Role
536614
checkExists(testRoleResourceName),
@@ -603,6 +681,30 @@ func configBasic(projectID, roleName, action, databaseName string) string {
603681
`, projectID, roleName, action, databaseName)
604682
}
605683

684+
func generateActionConfig(action, databaseName string) string {
685+
return fmt.Sprintf(`
686+
actions {
687+
action = %q
688+
resources {
689+
collection_name = ""
690+
database_name = %q
691+
}
692+
}
693+
`, action, databaseName)
694+
}
695+
696+
func configBasicWithTwoActions(projectID, roleName, action1, databaseName1, action2, databaseName2 string) string {
697+
return fmt.Sprintf(`
698+
resource "mongodbatlas_custom_db_role" "test" {
699+
project_id = %[1]q
700+
role_name = %[2]q
701+
702+
%[3]s
703+
%[4]s
704+
}
705+
`, projectID, roleName, generateActionConfig(action1, databaseName1), generateActionConfig(action2, databaseName2))
706+
}
707+
606708
func configWithInheritedRoles(orgID, projectName string, inheritedRole []admin.UserCustomDBRole, testRole *admin.UserCustomDBRole) string {
607709
return fmt.Sprintf(`
608710

0 commit comments

Comments
 (0)