Skip to content

Commit b125af0

Browse files
authored
Fix gitlab_project and gitlab_project_share relationship (#421)
- gitlab_project: remove shared_with_groups attribute - gitlab_project_share: fix update failing to change access_level
1 parent 7c3ee26 commit b125af0

7 files changed

+90
-472
lines changed

docs/resources/project.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,6 @@ The following arguments are supported:
7474

7575
* `shared_runners_enabled` - (Optional) Enable shared runners for this project.
7676

77-
* `shared_with_groups` - (Optional) Enable sharing the project with a list of groups (maps).
78-
* `group_id` - (Required) Group id of the group you want to share the project with.
79-
* `group_access_level` - (Required) Group's sharing permissions. See [group members permission][group_members_permissions] for more info.
80-
Valid values are `guest`, `reporter`, `developer`, `maintainer`.
81-
8277
* `archived` - (Optional) Whether the project is in read-only mode (archived). Repositories can be archived/unarchived by toggling this parameter.
8378

8479
* `initialize_with_readme` - (Optional) Create master branch with first commit containing a README.md file.
@@ -101,9 +96,6 @@ The following additional attributes are exported:
10196

10297
* `runners_token` - Registration token to use during runner setup.
10398

104-
* `shared_with_groups` - List of the groups the project is shared with.
105-
* `group_name` - Group's name.
106-
10799
* `remove_source_branch_after_merge` - Enable `Delete source branch` option by default for all new merge requests.
108100

109101

gitlab/data_source_gitlab_projects.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,3 +850,19 @@ func dataSourceGitlabProjectsRead(d *schema.ResourceData, meta interface{}) (err
850850
}
851851
return err
852852
}
853+
854+
func flattenSharedWithGroupsOptions(project *gitlab.Project) []interface{} {
855+
var sharedWithGroupsList []interface{}
856+
857+
for _, option := range project.SharedWithGroups {
858+
values := map[string]interface{}{
859+
"group_id": option.GroupID,
860+
"group_access_level": accessLevelValueToName[gitlab.AccessLevelValue(option.GroupAccessLevel)],
861+
"group_name": option.GroupName,
862+
}
863+
864+
sharedWithGroupsList = append(sharedWithGroupsList, values)
865+
}
866+
867+
return sharedWithGroupsList
868+
}

gitlab/helper_test.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,6 @@ func testAccCompareGitLabAttribute(attr string, expected, received *schema.Resou
2828
return nil
2929
}
3030

31-
func testAccIsSkippedAttribute(needle string, haystack []string) bool {
32-
if needle == "" {
33-
return false
34-
}
35-
for _, hay := range haystack {
36-
if hay == needle {
37-
return true
38-
}
39-
}
40-
return false
41-
}
42-
4331
// Returns true if the acceptance test is running Gitlab EE.
4432
// Meant to be used as SkipFunc to skip tests that work only on Gitlab CE.
4533
func isRunningInEE() (bool, error) {

gitlab/resource_gitlab_project.go

Lines changed: 0 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -172,28 +172,6 @@ var resourceGitLabProjectSchema = map[string]*schema.Schema{
172172
Elem: &schema.Schema{Type: schema.TypeString},
173173
Set: schema.HashString,
174174
},
175-
"shared_with_groups": {
176-
Type: schema.TypeSet,
177-
Optional: true,
178-
Elem: &schema.Resource{
179-
Schema: map[string]*schema.Schema{
180-
"group_id": {
181-
Type: schema.TypeInt,
182-
Required: true,
183-
},
184-
"group_access_level": {
185-
Type: schema.TypeString,
186-
Required: true,
187-
ValidateFunc: validation.StringInSlice([]string{
188-
"no one", "guest", "reporter", "developer", "maintainer"}, false),
189-
},
190-
"group_name": {
191-
Type: schema.TypeString,
192-
Computed: true,
193-
},
194-
},
195-
},
196-
},
197175
"archived": {
198176
Type: schema.TypeBool,
199177
Description: "Whether the project is archived.",
@@ -249,7 +227,6 @@ func resourceGitlabProjectSetToState(d *schema.ResourceData, project *gitlab.Pro
249227
d.Set("web_url", project.WebURL)
250228
d.Set("runners_token", project.RunnersToken)
251229
d.Set("shared_runners_enabled", project.SharedRunnersEnabled)
252-
d.Set("shared_with_groups", flattenSharedWithGroupsOptions(project))
253230
d.Set("tags", project.TagList)
254231
d.Set("archived", project.Archived)
255232
d.Set("remove_source_branch_after_merge", project.RemoveSourceBranchAfterMerge)
@@ -334,14 +311,6 @@ func resourceGitlabProjectCreate(d *schema.ResourceData, meta interface{}) error
334311
}
335312
}
336313

337-
if v, ok := d.GetOk("shared_with_groups"); ok {
338-
for _, option := range expandSharedWithGroupsOptions(v) {
339-
if _, err := client.Projects.ShareProjectWithGroup(project.ID, option); err != nil {
340-
return err
341-
}
342-
}
343-
}
344-
345314
if d.Get("archived").(bool) {
346315
// strange as it may seem, this project is created in archived state...
347316
if _, _, err := client.Projects.ArchiveProject(d.Id()); err != nil {
@@ -476,12 +445,6 @@ func resourceGitlabProjectUpdate(d *schema.ResourceData, meta interface{}) error
476445
}
477446
}
478447

479-
if d.HasChange("shared_with_groups") {
480-
if err := updateSharedWithGroups(d, meta); err != nil {
481-
return err
482-
}
483-
}
484-
485448
if d.HasChange("archived") {
486449
if d.Get("archived").(bool) {
487450
if _, _, err := client.Projects.ArchiveProject(d.Id()); err != nil {
@@ -538,121 +501,3 @@ func resourceGitlabProjectDelete(d *schema.ResourceData, meta interface{}) error
538501
}
539502
return nil
540503
}
541-
542-
func expandSharedWithGroupsOptions(v interface{}) []*gitlab.ShareWithGroupOptions {
543-
shareWithGroupOptionsList := []*gitlab.ShareWithGroupOptions{}
544-
545-
for _, config := range v.(*schema.Set).List() {
546-
data := config.(map[string]interface{})
547-
548-
groupAccess := accessLevelNameToValue[data["group_access_level"].(string)]
549-
550-
shareWithGroupOptions := &gitlab.ShareWithGroupOptions{
551-
GroupID: gitlab.Int(data["group_id"].(int)),
552-
GroupAccess: &groupAccess,
553-
}
554-
555-
shareWithGroupOptionsList = append(shareWithGroupOptionsList,
556-
shareWithGroupOptions)
557-
}
558-
559-
return shareWithGroupOptionsList
560-
}
561-
562-
func flattenSharedWithGroupsOptions(project *gitlab.Project) []interface{} {
563-
sharedWithGroups := project.SharedWithGroups
564-
sharedWithGroupsList := []interface{}{}
565-
566-
for _, option := range sharedWithGroups {
567-
values := map[string]interface{}{
568-
"group_id": option.GroupID,
569-
"group_access_level": accessLevelValueToName[gitlab.AccessLevelValue(
570-
option.GroupAccessLevel)],
571-
"group_name": option.GroupName,
572-
}
573-
574-
sharedWithGroupsList = append(sharedWithGroupsList, values)
575-
}
576-
577-
return sharedWithGroupsList
578-
}
579-
580-
func findGroupProjectSharedWith(target *gitlab.ShareWithGroupOptions,
581-
groups []*gitlab.ShareWithGroupOptions) (*gitlab.ShareWithGroupOptions, int, error) {
582-
for i, group := range groups {
583-
if *group.GroupID == *target.GroupID {
584-
return group, i, nil
585-
}
586-
}
587-
588-
return nil, 0, fmt.Errorf("group not found")
589-
}
590-
591-
func getGroupsProjectSharedWith(project *gitlab.Project) []*gitlab.ShareWithGroupOptions {
592-
sharedGroups := []*gitlab.ShareWithGroupOptions{}
593-
594-
for _, group := range project.SharedWithGroups {
595-
sharedGroups = append(sharedGroups, &gitlab.ShareWithGroupOptions{
596-
GroupID: gitlab.Int(group.GroupID),
597-
GroupAccess: gitlab.AccessLevel(gitlab.AccessLevelValue(
598-
group.GroupAccessLevel)),
599-
})
600-
}
601-
602-
return sharedGroups
603-
}
604-
605-
func updateSharedWithGroups(d *schema.ResourceData, meta interface{}) error {
606-
client := meta.(*gitlab.Client)
607-
608-
var groupsToUnshare []*gitlab.ShareWithGroupOptions
609-
var groupsToShare []*gitlab.ShareWithGroupOptions
610-
611-
// Get target groups from the TF config and current groups from Gitlab server
612-
targetGroups := expandSharedWithGroupsOptions(d.Get("shared_with_groups"))
613-
project, _, err := client.Projects.GetProject(d.Id(), nil)
614-
if err != nil {
615-
return err
616-
}
617-
currentGroups := getGroupsProjectSharedWith(project)
618-
619-
for _, targetGroup := range targetGroups {
620-
currentGroup, index, err := findGroupProjectSharedWith(targetGroup, currentGroups)
621-
622-
// If no corresponding group is found, it must be added
623-
if err != nil {
624-
groupsToShare = append(groupsToShare, targetGroup)
625-
continue
626-
}
627-
628-
// If group is different it must be deleted and added again
629-
if *targetGroup.GroupAccess != *currentGroup.GroupAccess {
630-
groupsToShare = append(groupsToShare, targetGroup)
631-
groupsToUnshare = append(groupsToUnshare, targetGroup)
632-
}
633-
634-
// Remove currentGroup from from list
635-
currentGroups = append(currentGroups[:index], currentGroups[index+1:]...)
636-
}
637-
638-
// All groups still present in currentGroup must be deleted
639-
groupsToUnshare = append(groupsToUnshare, currentGroups...)
640-
641-
// Unshare groups to delete and update
642-
for _, group := range groupsToUnshare {
643-
_, err := client.Projects.DeleteSharedProjectFromGroup(d.Id(), *group.GroupID)
644-
if err != nil {
645-
return err
646-
}
647-
}
648-
649-
// Share groups to add and update
650-
for _, group := range groupsToShare {
651-
_, err := client.Projects.ShareProjectWithGroup(d.Id(), group)
652-
if err != nil {
653-
return err
654-
}
655-
}
656-
657-
return nil
658-
}

gitlab/resource_gitlab_project_share_group.go

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"fmt"
55
"log"
66
"strconv"
7-
"strings"
87

98
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
109
"github.com/xanzy/go-gitlab"
@@ -16,7 +15,6 @@ func resourceGitlabProjectShareGroup() *schema.Resource {
1615
return &schema.Resource{
1716
Create: resourceGitlabProjectShareGroupCreate,
1817
Read: resourceGitlabProjectShareGroupRead,
19-
Update: resourceGitlabProjectShareGroupUpdate,
2018
Delete: resourceGitlabProjectShareGroupDelete,
2119
Importer: &schema.ResourceImporter{
2220
State: schema.ImportStatePassthrough,
@@ -36,6 +34,7 @@ func resourceGitlabProjectShareGroup() *schema.Resource {
3634
"access_level": {
3735
Type: schema.TypeString,
3836
ValidateFunc: validateValueFunc(acceptedAccessLevels),
37+
ForceNew: true,
3938
Required: true,
4039
},
4140
},
@@ -104,26 +103,6 @@ func projectIdAndGroupIdFromId(id string) (string, int, error) {
104103
return projectId, groupId, nil
105104
}
106105

107-
func resourceGitlabProjectShareGroupUpdate(d *schema.ResourceData, meta interface{}) error {
108-
client := meta.(*gitlab.Client)
109-
110-
groupId := d.Get("group_id").(int)
111-
projectId := d.Get("project_id").(string)
112-
accessLevelId := accessLevelID[strings.ToLower(d.Get("access_level").(string))]
113-
114-
options := gitlab.ShareWithGroupOptions{
115-
GroupID: &groupId,
116-
GroupAccess: &accessLevelId,
117-
}
118-
log.Printf("[DEBUG] update gitlab project membership %v for %s", groupId, projectId)
119-
120-
_, err := client.Projects.ShareProjectWithGroup(projectId, &options)
121-
if err != nil {
122-
return err
123-
}
124-
return resourceGitlabProjectShareGroupRead(d, meta)
125-
}
126-
127106
func resourceGitlabProjectShareGroupDelete(d *schema.ResourceData, meta interface{}) error {
128107
client := meta.(*gitlab.Client)
129108

0 commit comments

Comments
 (0)