Skip to content

Commit e0c6c66

Browse files
authored
Merge pull request #61 from sudoapt-getclean/master
Add Group Membership, Group Variable, fix Project Variable, refactor Project Membership
2 parents 596e2da + 97bd4f7 commit e0c6c66

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2502
-277
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
11
## 1.0.1 (Unreleased)
2+
3+
FEATURES:
4+
5+
* **New Resource:** `gitlab_project_membership`
6+
* **New Resource:** `gitlab_group_membership` ([#8](https://github.com/terraform-providers/terraform-provider-gitlab/issues/8))
7+
* **New Resource:** `gitlab_project_variable` ([#47](https://github.com/terraform-providers/terraform-provider-gitlab/issues/47))
8+
* **New Resource:** `gitlab_group_variable` ([#47](https://github.com/terraform-providers/terraform-provider-gitlab/issues/47))
9+
10+
BACKWARDS INCOMPATIBILITIES:
11+
12+
`gitlab_project_membership` is not compatible with a previous *unrealeased* version due to an id change resource will need to be reimported manually
13+
e.g
14+
```bash
15+
terraform state rm gitlab_project_membership.foo
16+
terraform import gitlab_project_membership.foo 12345:1337
17+
```
18+
219
## 1.0.0 (October 06, 2017)
320

421
BACKWARDS INCOMPATIBILITIES:

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,16 @@ $ $GOPATH/bin/terraform-provider-gitlab
4848
...
4949
```
5050

51-
In order to test the provider, you can simply run `make test`.
51+
### Running tests
52+
The Terraform Provider only has acceptance tests, these can run against a gitlab instance where you have a token with administrator permissions (likely not gitlab.com).
53+
There is excellent documentation on [how to run gitlab from docker at gitlab.com](https://docs.gitlab.com/omnibus/docker/)
5254

53-
```sh
54-
$ make test
55-
```
55+
In order to run the full suite of acceptance tests, export the environment variables:
5656

57-
In order to run the full suite of Acceptance tests, run `make testacc`.
57+
- `GITLAB_TOKEN` //token for account with admin priviliges
58+
- `GITLAB_BASE_URL` //URL with api part e.g. `http://localhost:8929/api/v4/`
5859

59-
*Note:* Acceptance tests create real resources, and often cost money to run.
60+
and run `make testacc`.
6061

6162
```sh
6263
$ make testacc

gitlab/data_source_gitlab_user.go

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ func dataSourceGitlabUser() *schema.Resource {
1515
Schema: map[string]*schema.Schema{
1616
"email": {
1717
Type: schema.TypeString,
18-
Required: true,
18+
Optional: true,
19+
},
20+
"username": {
21+
Type: schema.TypeString,
22+
Optional: true,
1923
},
2024
},
2125
}
@@ -27,8 +31,15 @@ func dataSourceGitlabUserRead(d *schema.ResourceData, meta interface{}) error {
2731
log.Printf("[INFO] Reading Gitlab user")
2832

2933
searchEmail := strings.ToLower(d.Get("email").(string))
34+
userName := strings.ToLower(d.Get("username").(string))
35+
var q *string
36+
if searchEmail != "" {
37+
q = &searchEmail
38+
} else {
39+
q = &userName
40+
}
3041
query := &gitlab.ListUsersOptions{
31-
Search: &searchEmail,
42+
Search: q,
3243
}
3344
users, _, err := client.Users.ListUsers(query)
3445
if err != nil {
@@ -37,18 +48,28 @@ func dataSourceGitlabUserRead(d *schema.ResourceData, meta interface{}) error {
3748

3849
var found *gitlab.User
3950

40-
for _, user := range users {
41-
if strings.ToLower(user.Email) == searchEmail {
42-
found = user
43-
break
51+
if searchEmail != "" {
52+
for _, user := range users {
53+
if strings.ToLower(user.Email) == searchEmail {
54+
found = user
55+
break
56+
}
57+
}
58+
} else {
59+
for _, user := range users {
60+
if strings.ToLower(user.Username) == userName {
61+
found = user
62+
break
63+
}
4464
}
4565
}
66+
4667
if found == nil {
4768
return fmt.Errorf("The email '%s' does not match any user email", searchEmail)
4869
}
4970
d.SetId(fmt.Sprintf("%d", found.ID))
5071
d.Set("name", found.Name)
51-
d.Set("username", found.Username)
72+
d.Set("userName", found.Username)
5273
d.Set("email", found.Email)
5374
return nil
5475
}

gitlab/provider.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ func Provider() terraform.ResourceProvider {
5454
"gitlab_deploy_key": resourceGitlabDeployKey(),
5555
"gitlab_user": resourceGitlabUser(),
5656
"gitlab_project_membership": resourceGitlabProjectMembership(),
57+
"gitlab_group_membership": resourceGitlabGroupMembership(),
58+
"gitlab_project_variable": resourceGitlabProjectVariable(),
59+
"gitlab_group_variable": resourceGitlabGroupVariable(),
5760
},
5861

5962
ConfigureFunc: providerConfigure,
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package gitlab
2+
3+
import (
4+
"log"
5+
"strconv"
6+
"strings"
7+
8+
"github.com/hashicorp/terraform/helper/schema"
9+
"github.com/xanzy/go-gitlab"
10+
)
11+
12+
func resourceGitlabGroupMembership() *schema.Resource {
13+
acceptedAccessLevels := make([]string, 0, len(accessLevelID))
14+
for k := range accessLevelID {
15+
acceptedAccessLevels = append(acceptedAccessLevels, k)
16+
}
17+
return &schema.Resource{
18+
Create: resourceGitlabGroupMembershipCreate,
19+
Read: resourceGitlabGroupMembershipRead,
20+
Update: resourceGitlabGroupMembershipUpdate,
21+
Delete: resourceGitlabGroupMembershipDelete,
22+
Importer: &schema.ResourceImporter{
23+
State: schema.ImportStatePassthrough,
24+
},
25+
26+
Schema: map[string]*schema.Schema{
27+
"group_id": {
28+
Type: schema.TypeString,
29+
ForceNew: true,
30+
Required: true,
31+
},
32+
"user_id": {
33+
Type: schema.TypeInt,
34+
ForceNew: true,
35+
Required: true,
36+
},
37+
"access_level": {
38+
Type: schema.TypeString,
39+
ValidateFunc: validateValueFunc(acceptedAccessLevels),
40+
Required: true,
41+
},
42+
"expires_at": {
43+
Type: schema.TypeString, // Format YYYY-MM-DD
44+
ValidateFunc: validateDateFunc(),
45+
Optional: true,
46+
},
47+
},
48+
}
49+
}
50+
51+
func resourceGitlabGroupMembershipCreate(d *schema.ResourceData, meta interface{}) error {
52+
client := meta.(*gitlab.Client)
53+
54+
userId := d.Get("user_id").(int)
55+
groupId := d.Get("group_id").(string)
56+
expiresAt := d.Get("expires_at").(string)
57+
accessLevelId := accessLevelID[d.Get("access_level").(string)]
58+
59+
options := &gitlab.AddGroupMemberOptions{
60+
UserID: &userId,
61+
AccessLevel: &accessLevelId,
62+
ExpiresAt: &expiresAt,
63+
}
64+
log.Printf("[DEBUG] create gitlab group groupMember for %d in %s", options.UserID, groupId)
65+
66+
groupMember, _, err := client.GroupMembers.AddGroupMember(groupId, options)
67+
if err != nil {
68+
return err
69+
}
70+
userIdString := strconv.Itoa(groupMember.ID)
71+
d.SetId(buildTwoPartID(&groupId, &userIdString))
72+
return resourceGitlabGroupMembershipRead(d, meta)
73+
}
74+
75+
func resourceGitlabGroupMembershipRead(d *schema.ResourceData, meta interface{}) error {
76+
client := meta.(*gitlab.Client)
77+
id := d.Id()
78+
log.Printf("[DEBUG] read gitlab group groupMember %s", id)
79+
80+
groupId, userId, e := groupIdAndUserIdFromId(id)
81+
if e != nil {
82+
return e
83+
}
84+
85+
groupMember, resp, err := client.GroupMembers.GetGroupMember(groupId, userId)
86+
if err != nil {
87+
if resp.StatusCode == 404 {
88+
log.Printf("[WARN] Group member %v not found in group %s", userId, groupId)
89+
d.SetId("")
90+
return nil
91+
}
92+
return err
93+
}
94+
95+
resourceGitlabGroupMembershipSetToState(d, groupMember, &groupId)
96+
return nil
97+
}
98+
99+
func groupIdAndUserIdFromId(id string) (string, int, error) {
100+
groupId, userIdString, err := parseTwoPartID(id)
101+
userId, e := strconv.Atoi(userIdString)
102+
if err != nil {
103+
e = err
104+
}
105+
if e != nil {
106+
log.Printf("[WARN] cannot get group member id from input: %v", id)
107+
}
108+
return groupId, userId, e
109+
}
110+
111+
func resourceGitlabGroupMembershipUpdate(d *schema.ResourceData, meta interface{}) error {
112+
client := meta.(*gitlab.Client)
113+
114+
userId := d.Get("user_id").(int)
115+
groupId := d.Get("group_id").(string)
116+
expiresAt := d.Get("expires_at").(string)
117+
accessLevelId := accessLevelID[strings.ToLower(d.Get("access_level").(string))]
118+
119+
options := gitlab.EditGroupMemberOptions{
120+
AccessLevel: &accessLevelId,
121+
ExpiresAt: &expiresAt,
122+
}
123+
log.Printf("[DEBUG] update gitlab group membership %v for %s", userId, groupId)
124+
125+
_, resp, err := client.GroupMembers.EditGroupMember(groupId, userId, &options)
126+
if err != nil {
127+
if resp.StatusCode == 404 {
128+
log.Printf("[WARN] Group member %v not found in group %s, removing from state", userId, groupId)
129+
d.SetId("")
130+
return nil
131+
}
132+
return err
133+
}
134+
135+
return resourceGitlabGroupMembershipRead(d, meta)
136+
}
137+
138+
func resourceGitlabGroupMembershipDelete(d *schema.ResourceData, meta interface{}) error {
139+
client := meta.(*gitlab.Client)
140+
141+
id := d.Id()
142+
groupId, userId, e := groupIdAndUserIdFromId(id)
143+
if e != nil {
144+
return e
145+
}
146+
147+
log.Printf("[DEBUG] Delete gitlab group membership %v for %s", userId, groupId)
148+
149+
_, err := client.GroupMembers.RemoveGroupMember(groupId, userId)
150+
return err
151+
}
152+
153+
func resourceGitlabGroupMembershipSetToState(d *schema.ResourceData, groupMember *gitlab.GroupMember, groupId *string) {
154+
155+
d.Set("group_id", groupId)
156+
d.Set("user_id", groupMember.ID)
157+
d.Set("access_level", accessLevel[groupMember.AccessLevel])
158+
d.Set("expires_at", groupMember.ExpiresAt)
159+
160+
userId := strconv.Itoa(groupMember.ID)
161+
d.SetId(buildTwoPartID(groupId, &userId))
162+
}

0 commit comments

Comments
 (0)