Skip to content

Commit f5a9824

Browse files
authored
Merge pull request #196 from DrFaust92/project_perm
project user and group permission resources
2 parents 8f8b5ba + c7dd69e commit f5a9824

7 files changed

+674
-0
lines changed

Diff for: bitbucket/provider.go

+2
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ func Provider() *schema.Provider {
8585
"bitbucket_project": resourceProject(),
8686
"bitbucket_project_branching_model": resourceProjectBranchingModel(),
8787
"bitbucket_project_default_reviewers": resourceProjectDefaultReviewers(),
88+
"bitbucket_project_group_permission": resourceProjectGroupPermission(),
89+
"bitbucket_project_user_permission": resourceProjectUserPermission(),
8890
"bitbucket_repository": resourceRepository(),
8991
"bitbucket_repository_group_permission": resourceRepositoryGroupPermission(),
9092
"bitbucket_repository_user_permission": resourceRepositoryUserPermission(),

Diff for: bitbucket/resource_project_group_permission.go

+187
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
package bitbucket
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"encoding/json"
7+
"fmt"
8+
"io"
9+
"log"
10+
"net/http"
11+
"strings"
12+
13+
"github.com/DrFaust92/bitbucket-go-client"
14+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
15+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
16+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
17+
)
18+
19+
type ProjectGroupPermission struct {
20+
Permission string `json:"permission"`
21+
Group *ProjectGroup `json:"group,omitempty"`
22+
}
23+
24+
type ProjectGroup struct {
25+
Name string `json:"name,omitempty"`
26+
Slug string `json:"slug,omitempty"`
27+
Workspace bitbucket.Workspace `json:"workspace,omitempty"`
28+
}
29+
30+
func resourceProjectGroupPermission() *schema.Resource {
31+
return &schema.Resource{
32+
CreateWithoutTimeout: resourceProjectGroupPermissionPut,
33+
ReadWithoutTimeout: resourceProjectGroupPermissionRead,
34+
UpdateWithoutTimeout: resourceProjectGroupPermissionPut,
35+
DeleteWithoutTimeout: resourceProjectGroupPermissionDelete,
36+
Importer: &schema.ResourceImporter{
37+
StateContext: schema.ImportStatePassthroughContext,
38+
},
39+
40+
Schema: map[string]*schema.Schema{
41+
"workspace": {
42+
Type: schema.TypeString,
43+
Required: true,
44+
ForceNew: true,
45+
},
46+
"project_key": {
47+
Type: schema.TypeString,
48+
Required: true,
49+
ForceNew: true,
50+
},
51+
"group_slug": {
52+
Type: schema.TypeString,
53+
Required: true,
54+
ForceNew: true,
55+
},
56+
"permission": {
57+
Type: schema.TypeString,
58+
Required: true,
59+
ValidateFunc: validation.StringInSlice([]string{"admin", "write", "read", "create-repo"}, false),
60+
},
61+
},
62+
}
63+
}
64+
65+
func createProjectGroupPermission(d *schema.ResourceData) *ProjectGroupPermission {
66+
67+
permission := &ProjectGroupPermission{
68+
Permission: d.Get("permission").(string),
69+
}
70+
71+
return permission
72+
}
73+
74+
func resourceProjectGroupPermissionPut(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
75+
client := m.(Clients).httpClient
76+
permission := createProjectGroupPermission(d)
77+
78+
payload, err := json.Marshal(permission)
79+
if err != nil {
80+
return diag.FromErr(err)
81+
}
82+
83+
workspace := d.Get("workspace").(string)
84+
projectKey := d.Get("project_key").(string)
85+
groupSlug := d.Get("group_slug").(string)
86+
87+
permissionReq, err := client.Put(fmt.Sprintf("2.0/workspaces/%s/projects/%s/permissions-config/groups/%s",
88+
workspace,
89+
projectKey,
90+
groupSlug,
91+
), bytes.NewBuffer(payload))
92+
93+
if err != nil {
94+
return diag.FromErr(err)
95+
}
96+
97+
body, readerr := io.ReadAll(permissionReq.Body)
98+
if readerr != nil {
99+
return diag.FromErr(readerr)
100+
}
101+
102+
decodeerr := json.Unmarshal(body, &permission)
103+
if decodeerr != nil {
104+
return diag.FromErr(decodeerr)
105+
}
106+
107+
if d.IsNewResource() {
108+
d.SetId(fmt.Sprintf("%s:%s:%s", workspace, projectKey, groupSlug))
109+
}
110+
111+
return resourceProjectGroupPermissionRead(ctx, d, m)
112+
}
113+
114+
func resourceProjectGroupPermissionRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
115+
client := m.(Clients).httpClient
116+
117+
workspace, projectKey, groupSlug, err := projectGroupPermissionId(d.Id())
118+
if err != nil {
119+
return diag.FromErr(err)
120+
}
121+
122+
permissionReq, err := client.Get(fmt.Sprintf("2.0/workspaces/%s/projects/%s/permissions-config/groups/%s",
123+
workspace,
124+
projectKey,
125+
groupSlug,
126+
))
127+
128+
if permissionReq.StatusCode == http.StatusNotFound {
129+
log.Printf("[WARN] Project Group Permission (%s) not found, removing from state", d.Id())
130+
d.SetId("")
131+
return nil
132+
}
133+
134+
if err != nil {
135+
return diag.FromErr(err)
136+
}
137+
138+
var permission ProjectGroupPermission
139+
140+
body, readerr := io.ReadAll(permissionReq.Body)
141+
if readerr != nil {
142+
return diag.FromErr(readerr)
143+
}
144+
145+
log.Printf("Project Group Permission raw is: %#v", string(body))
146+
147+
decodeerr := json.Unmarshal(body, &permission)
148+
if decodeerr != nil {
149+
return diag.FromErr(decodeerr)
150+
}
151+
152+
log.Printf("Project Group Permission decoded is: %#v", permission)
153+
154+
d.Set("permission", permission.Permission)
155+
d.Set("group_slug", permission.Group.Slug)
156+
d.Set("workspace", permission.Group.Workspace.Slug)
157+
d.Set("project_key", projectKey)
158+
159+
return nil
160+
}
161+
162+
func resourceProjectGroupPermissionDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
163+
client := m.(Clients).httpClient
164+
165+
workspace, projectKey, groupSlug, err := projectGroupPermissionId(d.Id())
166+
if err != nil {
167+
return diag.FromErr(err)
168+
}
169+
170+
_, err = client.Delete(fmt.Sprintf("2.0/workspaces/%s/projects/%s/permissions-config/groups/%s",
171+
workspace,
172+
projectKey,
173+
groupSlug,
174+
))
175+
176+
return diag.FromErr(err)
177+
}
178+
179+
func projectGroupPermissionId(id string) (string, string, string, error) {
180+
parts := strings.Split(id, ":")
181+
182+
if len(parts) != 3 {
183+
return "", "", "", fmt.Errorf("unexpected format of ID (%q), expected WORKSPACE:PROJECT-KEY:GROUP-SLUG", id)
184+
}
185+
186+
return parts[0], parts[1], parts[2], nil
187+
}

Diff for: bitbucket/resource_project_group_permission_test.go

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package bitbucket
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"os"
7+
"testing"
8+
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
12+
)
13+
14+
func TestAccBitbucketProjectGroupPermission_basic(t *testing.T) {
15+
var projectGroupPermission ProjectGroupPermission
16+
resourceName := "bitbucket_project_group_permission.test"
17+
workspace := os.Getenv("BITBUCKET_TEAM")
18+
rName := acctest.RandomWithPrefix("tf-test")
19+
20+
resource.Test(t, resource.TestCase{
21+
PreCheck: func() { testAccPreCheck(t) },
22+
Providers: testAccProviders,
23+
CheckDestroy: testAccCheckBitbucketProjectGroupPermissionDestroy,
24+
Steps: []resource.TestStep{
25+
{
26+
Config: testAccBitbucketProjectGroupPermissionConfig(workspace, rName, "read"),
27+
Check: resource.ComposeTestCheckFunc(
28+
testAccCheckBitbucketProjectGroupPermissionExists(resourceName, &projectGroupPermission),
29+
resource.TestCheckResourceAttrPair(resourceName, "project_key", "bitbucket_project.test", "key"),
30+
resource.TestCheckResourceAttrPair(resourceName, "group_slug", "bitbucket_group.test", "slug"),
31+
resource.TestCheckResourceAttr(resourceName, "workspace", workspace),
32+
resource.TestCheckResourceAttr(resourceName, "permission", "read"),
33+
),
34+
},
35+
{
36+
ResourceName: resourceName,
37+
ImportState: true,
38+
ImportStateVerify: true,
39+
},
40+
{
41+
Config: testAccBitbucketProjectGroupPermissionConfig(workspace, rName, "write"),
42+
Check: resource.ComposeTestCheckFunc(
43+
testAccCheckBitbucketProjectGroupPermissionExists(resourceName, &projectGroupPermission),
44+
resource.TestCheckResourceAttrPair(resourceName, "project_key", "bitbucket_project.test", "key"),
45+
resource.TestCheckResourceAttrPair(resourceName, "group_slug", "bitbucket_group.test", "slug"),
46+
resource.TestCheckResourceAttr(resourceName, "workspace", workspace),
47+
resource.TestCheckResourceAttr(resourceName, "permission", "write"),
48+
),
49+
},
50+
},
51+
})
52+
}
53+
54+
func testAccCheckBitbucketProjectGroupPermissionDestroy(s *terraform.State) error {
55+
client := testAccProvider.Meta().(Clients).httpClient
56+
for _, rs := range s.RootModule().Resources {
57+
if rs.Type != "bitbucket_project_group_permission" {
58+
continue
59+
}
60+
61+
response, err := client.Get(fmt.Sprintf("2.0/repositories/%s/%s/permissions-config/groups/%s", rs.Primary.Attributes["workspace"], rs.Primary.Attributes["project_key"], rs.Primary.Attributes["group_slug"]))
62+
63+
if err == nil {
64+
return fmt.Errorf("The resource was found should have errored")
65+
}
66+
67+
if response.StatusCode != http.StatusNotFound {
68+
return fmt.Errorf("Project Group Permission still exists")
69+
}
70+
71+
}
72+
return nil
73+
}
74+
75+
func testAccCheckBitbucketProjectGroupPermissionExists(n string, projectGroupPermission *ProjectGroupPermission) resource.TestCheckFunc {
76+
return func(s *terraform.State) error {
77+
rs, ok := s.RootModule().Resources[n]
78+
if !ok {
79+
return fmt.Errorf("Not found %s", n)
80+
}
81+
if rs.Primary.ID == "" {
82+
return fmt.Errorf("No Project Group Permission ID is set")
83+
}
84+
return nil
85+
}
86+
}
87+
88+
func testAccBitbucketProjectGroupPermissionConfig(workspace, rName, permission string) string {
89+
return fmt.Sprintf(`
90+
resource "bitbucket_project" "test" {
91+
owner = %[1]q
92+
name = %[2]q
93+
key = "GRPPERM"
94+
}
95+
96+
resource "bitbucket_group" "test" {
97+
workspace = %[1]q
98+
name = %[2]q
99+
}
100+
101+
resource "bitbucket_project_group_permission" "test" {
102+
workspace = %[1]q
103+
project_key = bitbucket_project.test.key
104+
group_slug = bitbucket_group.test.slug
105+
permission = %[3]q
106+
}
107+
`, workspace, rName, permission)
108+
}

0 commit comments

Comments
 (0)