Skip to content

Commit 1ae9f34

Browse files
authored
Merge pull request #1209 from timofurrer/feature/resource/gitlab_group_membership
resource/gitlab_group_membership: Support removal options
2 parents f292fdf + 82ef7ff commit 1ae9f34

File tree

4 files changed

+86
-2
lines changed

4 files changed

+86
-2
lines changed

docs/resources/group_membership.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ resource "gitlab_group_membership" "test" {
3939
### Optional
4040

4141
- `expires_at` (String) Expiration date for the group membership. Format: `YYYY-MM-DD`
42+
- `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.
43+
- `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.
4244

4345
### Read-Only
4446

internal/provider/helper_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,30 @@ func testAccCreateGroups(t *testing.T, n int) []*gitlab.Group {
225225
return groups
226226
}
227227

228+
// testAccCreateSubGroups is a test helper for creating a specified number of subgroups.
229+
func testAccCreateSubGroups(t *testing.T, parentGroup *gitlab.Group, n int) []*gitlab.Group {
230+
t.Helper()
231+
232+
groups := make([]*gitlab.Group, n)
233+
234+
for i := range groups {
235+
var err error
236+
name := acctest.RandomWithPrefix("acctest-group")
237+
groups[i], _, err = testGitlabClient.Groups.CreateGroup(&gitlab.CreateGroupOptions{
238+
Name: gitlab.String(name),
239+
Path: gitlab.String(name),
240+
// So that acceptance tests can be run in a gitlab organization with no billing.
241+
Visibility: gitlab.Visibility(gitlab.PublicVisibility),
242+
ParentID: gitlab.Int(parentGroup.ID),
243+
})
244+
if err != nil {
245+
t.Fatalf("could not create test subgroup: %v", err)
246+
}
247+
}
248+
249+
return groups
250+
}
251+
228252
// testAccCreateBranches is a test helper for creating a specified number of branches.
229253
// It assumes the project will be destroyed at the end of the test and will not cleanup created branches.
230254
func testAccCreateBranches(t *testing.T, project *gitlab.Project, n int) []*gitlab.Branch {

internal/provider/resource_gitlab_group_membership.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ var _ = registerResource("gitlab_group_membership", func() *schema.Resource {
5454
ValidateFunc: validateDateFunc,
5555
Optional: true,
5656
},
57+
"skip_subresources_on_destroy": {
58+
Description: "Whether the deletion of direct memberships of the removed member in subgroups and projects should be skipped. Only used during a destroy.",
59+
Type: schema.TypeBool,
60+
Optional: true,
61+
Default: false,
62+
},
63+
"unassign_issuables_on_destroy": {
64+
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.",
65+
Type: schema.TypeBool,
66+
Optional: true,
67+
Default: false,
68+
},
5769
},
5870
}
5971
})
@@ -149,9 +161,14 @@ func resourceGitlabGroupMembershipDelete(ctx context.Context, d *schema.Resource
149161
return diag.FromErr(err)
150162
}
151163

152-
log.Printf("[DEBUG] Delete gitlab group membership %v for %s", userId, groupId)
164+
options := gitlab.RemoveGroupMemberOptions{
165+
SkipSubresources: gitlab.Bool(d.Get("skip_subresources_on_destroy").(bool)),
166+
UnassignIssuables: gitlab.Bool(d.Get("unassign_issuables_on_destroy").(bool)),
167+
}
168+
169+
log.Printf("[DEBUG] Delete gitlab group membership %v for %s with options: %+v", userId, groupId, options)
153170

154-
_, err = client.GroupMembers.RemoveGroupMember(groupId, userId, &gitlab.RemoveGroupMemberOptions{}, gitlab.WithContext(ctx))
171+
_, err = client.GroupMembers.RemoveGroupMember(groupId, userId, &options, gitlab.WithContext(ctx))
155172
if err != nil {
156173
return diag.FromErr(err)
157174
}

internal/provider/resource_gitlab_group_membership_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,47 @@ func TestAccGitlabGroupMembership_basic(t *testing.T) {
5151
})
5252
}
5353

54+
func TestAccGitlabGroupMembership_skipRemoveFromSubgroup(t *testing.T) {
55+
testUser := testAccCreateUsers(t, 1)[0]
56+
testGroup := testAccCreateGroups(t, 1)[0]
57+
testSubgroup := testAccCreateSubGroups(t, testGroup, 1)[0]
58+
59+
resource.ParallelTest(t, resource.TestCase{
60+
ProviderFactories: providerFactories,
61+
CheckDestroy: testAccCheckGitlabGroupMembershipDestroy,
62+
Steps: []resource.TestStep{
63+
// Add user to main and subgroup individually
64+
{
65+
Config: fmt.Sprintf(`
66+
resource "gitlab_group_membership" "main_group" {
67+
group_id = "%d"
68+
user_id = %d
69+
access_level = "developer"
70+
skip_subresources_on_destroy = true
71+
}
72+
73+
resource "gitlab_group_membership" "sub_group" {
74+
group_id = "%d"
75+
user_id = %d
76+
access_level = "maintainer"
77+
}
78+
`, testGroup.ID, testUser.ID, testSubgroup.ID, testUser.ID),
79+
},
80+
// Remove user from main group without removing from subgroup
81+
{
82+
Config: fmt.Sprintf(`
83+
resource "gitlab_group_membership" "sub_group" {
84+
group_id = "%d"
85+
user_id = %d
86+
access_level = "maintainer"
87+
}
88+
`, testSubgroup.ID, testUser.ID),
89+
Check: testAccCheckGitlabGroupMembershipExists("gitlab_group_membership.sub_group", &gitlab.GroupMember{}),
90+
},
91+
},
92+
})
93+
}
94+
5495
func testAccCheckGitlabGroupMembershipExists(n string, membership *gitlab.GroupMember) resource.TestCheckFunc {
5596
return func(s *terraform.State) error {
5697
rs, ok := s.RootModule().Resources[n]

0 commit comments

Comments
 (0)