Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resource/gitlab_group_membership: Support removal options #1209

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/resources/group_membership.md
Expand Up @@ -39,6 +39,8 @@ resource "gitlab_group_membership" "test" {
### Optional

- `expires_at` (String) Expiration date for the group membership. Format: `YYYY-MM-DD`
- `skip_subresources_on_destroy` (Boolean) Whether the deletion of direct memberships of the removed member in subgroups and projects should be skipped. Only used during a destroy.
- `unassign_issuables_on_destroy` (Boolean) Whether the removed member should be unassigned from any issues or merge requests inside a given group or project. Only used during a destroy.

### Read-Only

Expand Down
24 changes: 24 additions & 0 deletions internal/provider/helper_test.go
Expand Up @@ -225,6 +225,30 @@ func testAccCreateGroups(t *testing.T, n int) []*gitlab.Group {
return groups
}

// testAccCreateSubGroups is a test helper for creating a specified number of subgroups.
func testAccCreateSubGroups(t *testing.T, parentGroup *gitlab.Group, n int) []*gitlab.Group {
t.Helper()

groups := make([]*gitlab.Group, n)

for i := range groups {
var err error
name := acctest.RandomWithPrefix("acctest-group")
groups[i], _, err = testGitlabClient.Groups.CreateGroup(&gitlab.CreateGroupOptions{
Name: gitlab.String(name),
Path: gitlab.String(name),
// So that acceptance tests can be run in a gitlab organization with no billing.
Visibility: gitlab.Visibility(gitlab.PublicVisibility),
ParentID: gitlab.Int(parentGroup.ID),
})
if err != nil {
t.Fatalf("could not create test subgroup: %v", err)
}
}

return groups
}

// testAccCreateBranches is a test helper for creating a specified number of branches.
// It assumes the project will be destroyed at the end of the test and will not cleanup created branches.
func testAccCreateBranches(t *testing.T, project *gitlab.Project, n int) []*gitlab.Branch {
Expand Down
21 changes: 19 additions & 2 deletions internal/provider/resource_gitlab_group_membership.go
Expand Up @@ -54,6 +54,18 @@ var _ = registerResource("gitlab_group_membership", func() *schema.Resource {
ValidateFunc: validateDateFunc,
Optional: true,
},
"skip_subresources_on_destroy": {
Description: "Whether the deletion of direct memberships of the removed member in subgroups and projects should be skipped. Only used during a destroy.",
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"unassign_issuables_on_destroy": {
Description: "Whether the removed member should be unassigned from any issues or merge requests inside a given group or project. Only used during a destroy.",
Type: schema.TypeBool,
Optional: true,
Default: false,
},
},
}
})
Expand Down Expand Up @@ -149,9 +161,14 @@ func resourceGitlabGroupMembershipDelete(ctx context.Context, d *schema.Resource
return diag.FromErr(err)
}

log.Printf("[DEBUG] Delete gitlab group membership %v for %s", userId, groupId)
options := gitlab.RemoveGroupMemberOptions{
SkipSubresources: gitlab.Bool(d.Get("skip_subresources_on_destroy").(bool)),
UnassignIssuables: gitlab.Bool(d.Get("unassign_issuables_on_destroy").(bool)),
}

log.Printf("[DEBUG] Delete gitlab group membership %v for %s with options: %+v", userId, groupId, options)

_, err = client.GroupMembers.RemoveGroupMember(groupId, userId, &gitlab.RemoveGroupMemberOptions{}, gitlab.WithContext(ctx))
_, err = client.GroupMembers.RemoveGroupMember(groupId, userId, &options, gitlab.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}
Expand Down
41 changes: 41 additions & 0 deletions internal/provider/resource_gitlab_group_membership_test.go
Expand Up @@ -51,6 +51,47 @@ func TestAccGitlabGroupMembership_basic(t *testing.T) {
})
}

func TestAccGitlabGroupMembership_skipRemoveFromSubgroup(t *testing.T) {
testUser := testAccCreateUsers(t, 1)[0]
testGroup := testAccCreateGroups(t, 1)[0]
testSubgroup := testAccCreateSubGroups(t, testGroup, 1)[0]

resource.ParallelTest(t, resource.TestCase{
ProviderFactories: providerFactories,
CheckDestroy: testAccCheckGitlabGroupMembershipDestroy,
Steps: []resource.TestStep{
// Add user to main and subgroup individually
{
Config: fmt.Sprintf(`
resource "gitlab_group_membership" "main_group" {
group_id = "%d"
user_id = %d
access_level = "developer"
skip_subresources_on_destroy = true
}

resource "gitlab_group_membership" "sub_group" {
group_id = "%d"
user_id = %d
access_level = "maintainer"
}
`, testGroup.ID, testUser.ID, testSubgroup.ID, testUser.ID),
},
// Remove user from main group without removing from subgroup
{
Config: fmt.Sprintf(`
resource "gitlab_group_membership" "sub_group" {
group_id = "%d"
user_id = %d
access_level = "maintainer"
}
`, testSubgroup.ID, testUser.ID),
Check: testAccCheckGitlabGroupMembershipExists("gitlab_group_membership.sub_group", &gitlab.GroupMember{}),
},
},
})
}

func testAccCheckGitlabGroupMembershipExists(n string, membership *gitlab.GroupMember) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down