Skip to content

Commit 58e939d

Browse files
fix: avoid error when removing project api key assignment for deleted project (#1641)
1 parent bc33bf4 commit 58e939d

File tree

2 files changed

+92
-22
lines changed

2 files changed

+92
-22
lines changed

mongodbatlas/resource_mongodbatlas_project_api_key.go

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,12 @@ func resourceMongoDBAtlasProjectAPIKeyUpdate(ctx context.Context, d *schema.Reso
192192
apiKeyID := ids["api_key_id"]
193193

194194
if d.HasChange("project_assignment") {
195-
// Getting the current api_keys and the new api_keys with changes
196-
newAPIKeys, changedAPIKeys, removedAPIKeys := getStateProjectAssignmentAPIKeys(d)
195+
// Getting the changes to api key project assignments
196+
newAssignments, changedAssignments, removedAssignments := getStateProjectAssignmentAPIKeys(d)
197197

198-
// Adding new api_keys into the project
199-
if len(newAPIKeys) > 0 {
200-
for _, apiKey := range newAPIKeys {
198+
// Adding new projects assignments
199+
if len(newAssignments) > 0 {
200+
for _, apiKey := range newAssignments {
201201
projectID := apiKey.(map[string]any)["project_id"].(string)
202202
roles := expandStringList(apiKey.(map[string]any)["role_names"].(*schema.Set).List())
203203
_, err := conn.ProjectAPIKeys.Assign(ctx, projectID, apiKeyID, &matlas.AssignAPIKey{
@@ -209,17 +209,20 @@ func resourceMongoDBAtlasProjectAPIKeyUpdate(ctx context.Context, d *schema.Reso
209209
}
210210
}
211211

212-
// Removing api_keys from the project
213-
for _, apiKey := range removedAPIKeys {
212+
// Removing projects assignments
213+
for _, apiKey := range removedAssignments {
214214
projectID := apiKey.(map[string]any)["project_id"].(string)
215215
_, err := conn.ProjectAPIKeys.Unassign(ctx, projectID, apiKeyID)
216+
if err != nil && strings.Contains(err.Error(), "GROUP_NOT_FOUND") {
217+
continue // allows removing assignment for a project that has been deleted
218+
}
216219
if err != nil {
217220
return diag.Errorf("error removing api_key(%s) from the project(%s): %s", apiKeyID, projectID, err)
218221
}
219222
}
220223

221-
// Updating the role names for the api_key
222-
for _, apiKey := range changedAPIKeys {
224+
// Updating the role names for the project assignments
225+
for _, apiKey := range changedAssignments {
223226
projectID := apiKey.(map[string]any)["project_id"].(string)
224227
roles := expandStringList(apiKey.(map[string]any)["role_names"].(*schema.Set).List())
225228
_, err := conn.ProjectAPIKeys.Assign(ctx, projectID, apiKeyID, &matlas.AssignAPIKey{
@@ -396,30 +399,30 @@ func newProjectAssignment(ctx context.Context, conn *matlas.Client, apiKeyID str
396399
return results, nil
397400
}
398401

399-
func getStateProjectAssignmentAPIKeys(d *schema.ResourceData) (newAPIKeys, changedAPIKeys, removedAPIKeys []any) {
400-
currentAPIKeys, changes := d.GetChange("project_assignment")
402+
func getStateProjectAssignmentAPIKeys(d *schema.ResourceData) (newAssignments, changedAssignments, removedAssignments []any) {
403+
prevAssignments, currAssignments := d.GetChange("project_assignment")
401404

402-
rAPIKeys := currentAPIKeys.(*schema.Set).Difference(changes.(*schema.Set))
403-
nAPIKeys := changes.(*schema.Set).Difference(currentAPIKeys.(*schema.Set))
404-
changedAPIKeys = make([]any, 0)
405+
rAssignments := prevAssignments.(*schema.Set).Difference(currAssignments.(*schema.Set))
406+
nAssignments := currAssignments.(*schema.Set).Difference(prevAssignments.(*schema.Set))
407+
changedAssignments = make([]any, 0)
405408

406-
for _, changed := range nAPIKeys.List() {
407-
for _, removed := range rAPIKeys.List() {
409+
for _, changed := range nAssignments.List() {
410+
for _, removed := range rAssignments.List() {
408411
if changed.(map[string]any)["project_id"] == removed.(map[string]any)["project_id"] {
409-
rAPIKeys.Remove(removed)
412+
rAssignments.Remove(removed)
410413
}
411414
}
412415

413-
for _, current := range currentAPIKeys.(*schema.Set).List() {
416+
for _, current := range prevAssignments.(*schema.Set).List() {
414417
if changed.(map[string]any)["project_id"] == current.(map[string]any)["project_id"] {
415-
changedAPIKeys = append(changedAPIKeys, changed.(map[string]any))
416-
nAPIKeys.Remove(changed)
418+
changedAssignments = append(changedAssignments, changed.(map[string]any))
419+
nAssignments.Remove(changed)
417420
}
418421
}
419422
}
420423

421-
newAPIKeys = nAPIKeys.List()
422-
removedAPIKeys = rAPIKeys.List()
424+
newAssignments = nAssignments.List()
425+
removedAssignments = rAssignments.List()
423426

424427
return
425428
}

mongodbatlas/resource_mongodbatlas_project_api_key_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,37 @@ func TestAccConfigRSProjectAPIKey_RecreateWhenDeletedExternally(t *testing.T) {
175175
})
176176
}
177177

178+
func TestAccConfigRSProjectAPIKey_DeleteProjectAndAssignment(t *testing.T) {
179+
var (
180+
resourceName = "mongodbatlas_project_api_key.test"
181+
orgID = os.Getenv("MONGODB_ATLAS_ORG_ID")
182+
projectName = acctest.RandomWithPrefix("test-acc")
183+
secondProjectName = acctest.RandomWithPrefix("test-acc")
184+
description = fmt.Sprintf("%s-%s", "test-acc-project", acctest.RandString(5))
185+
)
186+
187+
resource.ParallelTest(t, resource.TestCase{
188+
PreCheck: func() { testAccPreCheckBasic(t) },
189+
ProtoV6ProviderFactories: testAccProviderV6Factories,
190+
CheckDestroy: testAccCheckMongoDBAtlasProjectAPIKeyDestroy,
191+
Steps: []resource.TestStep{
192+
{
193+
Config: testAccMongoDBAtlasProjectAPIKeyConfigDeletedProjectAndAssignment(orgID, projectName, secondProjectName, description, true),
194+
Check: resource.ComposeTestCheckFunc(
195+
resource.TestCheckResourceAttrSet(resourceName, "project_assignment.0.project_id"),
196+
resource.TestCheckResourceAttrSet(resourceName, "project_assignment.1.project_id"),
197+
),
198+
},
199+
{
200+
Config: testAccMongoDBAtlasProjectAPIKeyConfigDeletedProjectAndAssignment(orgID, projectName, secondProjectName, description, false),
201+
Check: resource.ComposeTestCheckFunc(
202+
resource.TestCheckResourceAttrSet(resourceName, "project_assignment.0.project_id"),
203+
),
204+
},
205+
},
206+
})
207+
}
208+
178209
func deleteAPIKeyManually(orgID, descriptionPrefix string) error {
179210
conn := testAccProviderSdkV2.Meta().(*MongoDBClient).Atlas
180211
list, _, err := conn.APIKeys.List(context.Background(), orgID, &matlas.ListOptions{})
@@ -268,3 +299,39 @@ func testAccMongoDBAtlasProjectAPIKeyConfigMultiple(orgID, projectName, descript
268299
}
269300
`, orgID, projectName, description, roleNames)
270301
}
302+
303+
func testAccMongoDBAtlasProjectAPIKeyConfigDeletedProjectAndAssignment(orgID, projectName, secondProjectName, description string, includeSecondProject bool) string {
304+
var secondProject string
305+
if includeSecondProject {
306+
secondProject = fmt.Sprintf(`
307+
resource "mongodbatlas_project" "project2" {
308+
org_id = %[1]q
309+
name = %[2]q
310+
}`, orgID, secondProjectName)
311+
}
312+
var secondProjectAssignment string
313+
if includeSecondProject {
314+
secondProjectAssignment = `
315+
project_assignment {
316+
project_id = mongodbatlas_project.project2.id
317+
role_names = ["GROUP_OWNER"]
318+
}
319+
`
320+
}
321+
return fmt.Sprintf(`
322+
resource "mongodbatlas_project" "project1" {
323+
org_id = %[1]q
324+
name = %[2]q
325+
}
326+
%[3]s
327+
resource "mongodbatlas_project_api_key" "test" {
328+
project_id = mongodbatlas_project.project1.id
329+
description = %[4]q
330+
project_assignment {
331+
project_id = mongodbatlas_project.project1.id
332+
role_names = ["GROUP_OWNER"]
333+
}
334+
%[5]s
335+
}
336+
`, orgID, projectName, secondProject, description, secondProjectAssignment)
337+
}

0 commit comments

Comments
 (0)