forked from aeirola/terraform-provider-bitbucket
-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #44 from DrFaust92/group-member
Group member resource
- Loading branch information
Showing
5 changed files
with
339 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
package bitbucket | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"log" | ||
"strings" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
type UserGroupMembership struct { | ||
UUID string `json:"uuid,omitempty"` | ||
} | ||
|
||
func resourceGroupMembership() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceGroupMembershipsPut, | ||
Read: resourceGroupMembershipsRead, | ||
Delete: resourceGroupMembershipsDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"workspace": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"group_slug": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"uuid": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"slug": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceGroupMembershipsPut(d *schema.ResourceData, m interface{}) error { | ||
client := m.(*Client) | ||
|
||
workspace := d.Get("workspace").(string) | ||
groupSlug := d.Get("group_slug").(string) | ||
uuid := d.Get("uuid").(string) | ||
|
||
_, err := client.PutOnly(fmt.Sprintf("1.0/groups/%s/%s/members/%s", | ||
workspace, groupSlug, uuid)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
d.SetId(string(fmt.Sprintf("%s/%s/%s", workspace, groupSlug, uuid))) | ||
|
||
return resourceGroupMembershipsRead(d, m) | ||
} | ||
|
||
func resourceGroupMembershipsRead(d *schema.ResourceData, m interface{}) error { | ||
client := m.(*Client) | ||
|
||
workspace, slug, uuid, err := groupMemberId(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
groupsReq, _ := client.Get(fmt.Sprintf("1.0/groups/%s/%s/members", workspace, slug)) | ||
|
||
if groupsReq.StatusCode == 404 { | ||
log.Printf("[WARN] Group Membership (%s) not found, removing from state", d.Id()) | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
if groupsReq.Body == nil { | ||
return fmt.Errorf("error reading Group Membership (%s): empty response", d.Id()) | ||
} | ||
|
||
var members []*UserGroupMembership | ||
|
||
body, readerr := ioutil.ReadAll(groupsReq.Body) | ||
if readerr != nil { | ||
return readerr | ||
} | ||
|
||
log.Printf("[DEBUG] Group Membership Response JSON: %v", string(body)) | ||
|
||
decodeerr := json.Unmarshal(body, &members) | ||
if decodeerr != nil { | ||
return decodeerr | ||
} | ||
|
||
log.Printf("[DEBUG] Group Membership Response Decoded: %#v", members) | ||
|
||
if len(members) == 0 { | ||
return fmt.Errorf("error getting Group Members (%s): empty response", d.Id()) | ||
} | ||
|
||
var member *UserGroupMembership | ||
for _, mbr := range members { | ||
if mbr.UUID == uuid { | ||
member = mbr | ||
break | ||
} | ||
} | ||
|
||
if member == nil { | ||
return fmt.Errorf("error getting Group Member (%s): not found", d.Id()) | ||
} | ||
|
||
log.Printf("[DEBUG] Group Member Response Decoded: %#v", member) | ||
|
||
d.Set("workspace", workspace) | ||
d.Set("group_slug", slug) | ||
d.Set("uuid", member.UUID) | ||
|
||
return nil | ||
} | ||
|
||
func resourceGroupMembershipsDelete(d *schema.ResourceData, m interface{}) error { | ||
client := m.(*Client) | ||
|
||
workspace, slug, uuid, err := groupMemberId(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
_, err = client.Delete(fmt.Sprintf("1.0/groups/%s/%s/members/%s", | ||
workspace, slug, uuid)) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
return err | ||
} | ||
|
||
func groupMemberId(id string) (string, string, string, error) { | ||
parts := strings.Split(id, "/") | ||
|
||
if len(parts) != 3 { | ||
return "", "", "", fmt.Errorf("unexpected format of ID (%q), expected WORKSPACE-ID/GROUP-SLUG-ID/MEMBER-UUID", id) | ||
} | ||
|
||
return parts[0], parts[1], parts[2], nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package bitbucket | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"log" | ||
"os" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform" | ||
) | ||
|
||
func TestAccBitbucketGroupMembership_basic(t *testing.T) { | ||
var group UserGroup | ||
resourceName := "bitbucket_group_membership.test" | ||
grpResourceName := "bitbucket_group.test" | ||
|
||
workspace := os.Getenv("BITBUCKET_TEAM") | ||
rName := acctest.RandomWithPrefix("tf-test") | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckBitbucketGroupMembershipDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccBitbucketGroupMembershipConfig(workspace, rName), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckBitbucketGroupMembershipExists(resourceName, &group), | ||
resource.TestCheckResourceAttrPair(resourceName, "workspace", grpResourceName, "workspace"), | ||
resource.TestCheckResourceAttrPair(resourceName, "group_slug", grpResourceName, "slug"), | ||
resource.TestCheckResourceAttrPair(resourceName, "uuid", "data.bitbucket_current_user.test", "id"), | ||
), | ||
}, | ||
{ | ||
ResourceName: resourceName, | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckBitbucketGroupMembershipDestroy(s *terraform.State) error { | ||
client := testAccProvider.Meta().(*Client) | ||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "bitbucket_group_membership" { | ||
continue | ||
} | ||
|
||
workspace, slug, uuid, err := groupMemberId(rs.Primary.ID) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
response, _ := client.Get(fmt.Sprintf("1.0/groups/%s/%s/members", | ||
workspace, slug)) | ||
|
||
if response.StatusCode == 404 { | ||
continue | ||
} | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
var members []*UserGroupMembership | ||
body, readerr := ioutil.ReadAll(response.Body) | ||
if readerr != nil { | ||
return readerr | ||
} | ||
|
||
log.Printf("[DEBUG] Group Membership Response Test JSON: %v", string(body)) | ||
|
||
decodeerr := json.Unmarshal(body, &members) | ||
if decodeerr != nil { | ||
return decodeerr | ||
} | ||
|
||
log.Printf("[DEBUG] Group Membership Response Test Decoded: %#v", members) | ||
|
||
var member *UserGroupMembership | ||
for _, mbr := range members { | ||
if mbr.UUID == uuid { | ||
member = mbr | ||
continue | ||
} | ||
} | ||
|
||
if member != nil { | ||
return fmt.Errorf("Group Member still exists") | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func testAccCheckBitbucketGroupMembershipExists(n string, group *UserGroup) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
rs, ok := s.RootModule().Resources[n] | ||
if !ok { | ||
return fmt.Errorf("Not found %s", n) | ||
} | ||
if rs.Primary.ID == "" { | ||
return fmt.Errorf("No Group Membership ID is set") | ||
} | ||
return nil | ||
} | ||
} | ||
|
||
func testAccBitbucketGroupMembershipConfig(workspace, rName string) string { | ||
return fmt.Sprintf(` | ||
data "bitbucket_workspace" "test" { | ||
workspace = %[1]q | ||
} | ||
resource "bitbucket_group" "test" { | ||
workspace = data.bitbucket_workspace.test.id | ||
name = %[2]q | ||
} | ||
data "bitbucket_current_user" "test" {} | ||
resource "bitbucket_group_membership" "test" { | ||
workspace = bitbucket_group.test.workspace | ||
group_slug = bitbucket_group.test.slug | ||
uuid = data.bitbucket_current_user.test.id | ||
} | ||
`, workspace, rName) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
--- | ||
layout: "bitbucket" | ||
page_title: "Bitbucket: bitbucket_group_membership" | ||
sidebar_current: "docs-bitbucket-resource-group-membership" | ||
description: |- | ||
Provides a Bitbucket Group | ||
--- | ||
|
||
# bitbucket\_group | ||
|
||
Provides a Bitbucket group membership resource. | ||
|
||
This allows you to manage your group membership. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
data "bitbucket_workspace" "test" { | ||
workspace = "example" | ||
} | ||
resource "bitbucket_group" "test" { | ||
workspace = data.bitbucket_workspace.test.id | ||
name = "example" | ||
} | ||
data "bitbucket_current_user" "test" {} | ||
resource "bitbucket_group_membership" "test" { | ||
workspace = bitbucket_group.test.workspace | ||
group_slug = bitbucket_group.test.slug | ||
uuid = data.bitbucket_current_user.test.id | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `workspace` - (Required) The workspace of this repository. | ||
* `group_slug` - (Required) The slug of the group. | ||
* `uuid` - (Required) The member UUID to add to the group. | ||
|
||
## Import | ||
|
||
Group Memberss can be imported using their `workspace/group-slug/member-uuid` ID, e.g. | ||
|
||
```sh | ||
terraform import bitbucket_group_membership.group my-workspace/group-slug/member-uuid | ||
``` |