Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add resource identity_user_membership_v3 #1149

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions openstack/import_openstack_identity_user_membership_v3_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package openstack

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)

func TestAccIdentityV3UserMembership_importBasic(t *testing.T) {
resourceName := "openstack_identity_user_membership_v3.user_membership_1"

groupName := fmt.Sprintf("ACCPTTEST-%s", acctest.RandString(5))
userName := fmt.Sprintf("ACCPTTEST-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccPreCheckAdminOnly(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckIdentityV3UserMembershipDestroy,
Steps: []resource.TestStep{
{
Config: testAccIdentityV3UserMembershipBasic(groupName, userName),
},

{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
1 change: 1 addition & 0 deletions openstack/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ func Provider() terraform.ResourceProvider {
"openstack_identity_role_assignment_v3": resourceIdentityRoleAssignmentV3(),
"openstack_identity_service_v3": resourceIdentityServiceV3(),
"openstack_identity_user_v3": resourceIdentityUserV3(),
"openstack_identity_user_membership_v3": resourceIdentityUserMembershipV3(),
"openstack_identity_group_v3": resourceIdentityGroupV3(),
"openstack_identity_application_credential_v3": resourceIdentityApplicationCredentialV3(),
"openstack_identity_ec2_credential_v3": resourceIdentityEc2CredentialV3(),
Expand Down
114 changes: 114 additions & 0 deletions openstack/resource_openstack_identity_user_membership_v3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package openstack

import (
"fmt"
"strings"

"github.com/gophercloud/gophercloud/openstack/identity/v3/users"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func resourceIdentityUserMembershipV3() *schema.Resource {
return &schema.Resource{
Create: resourceIdentityUserMembershipV3Create,
Read: resourceIdentityUserMembershipV3Read,
Delete: resourceIdentityUserMembershipV3Delete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"region": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"user_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"group_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
}
}

func resourceIdentityUserMembershipV3Create(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
identityClient, err := config.IdentityV3Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating OpenStack identity client: %s", err)
}

userID := d.Get("user_id").(string)
groupID := d.Get("group_id").(string)

if err := users.AddToGroup(identityClient, groupID, userID).ExtractErr(); err != nil {
return fmt.Errorf("Error creating openstack_identity_user_membership_v3: %s", err)
}

id := fmt.Sprintf("%s/%s", userID, groupID)
d.SetId(id)

return resourceIdentityUserMembershipV3Read(d, meta)
}

func resourceIdentityUserMembershipV3Read(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
identityClient, err := config.IdentityV3Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating OpenStack identity client: %s", err)
}

userID, groupID, err := parseUserMembershipID(d.Id())
if err != nil {
return CheckDeleted(d, err, "Error parsing ID of openstack_identity_user_membership_v3")
}

userMembership, err := users.IsMemberOfGroup(identityClient, groupID, userID).Extract()
if err != nil || !userMembership {
return CheckDeleted(d, err, "Error retrieving openstack_identity_user_membership_v3")
}

d.Set("region", GetRegion(d, config))
d.Set("user_id", userID)
d.Set("group_id", groupID)

return nil
}

func resourceIdentityUserMembershipV3Delete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
identityClient, err := config.IdentityV3Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating OpenStack identity client: %s", err)
}

userID, groupID, err := parseUserMembershipID(d.Id())
if err != nil {
return CheckDeleted(d, err, "Error parsing ID of openstack_identity_user_membership_v3")
}

if err := users.RemoveFromGroup(identityClient, groupID, userID).ExtractErr(); err != nil {
return CheckDeleted(d, err, "Error removing openstack_identity_user_membership_v3")
}

return nil
}

func parseUserMembershipID(id string) (string, string, error) {
idParts := strings.Split(id, "/")
if len(idParts) < 2 {
return "", "", fmt.Errorf("Unable to determine user membership ID %s", id)
}

userID := idParts[0]
groupID := idParts[1]

return userID, groupID, nil
}
118 changes: 118 additions & 0 deletions openstack/resource_openstack_identity_user_membership_v3_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package openstack

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"

"github.com/gophercloud/gophercloud/openstack/identity/v3/groups"
"github.com/gophercloud/gophercloud/openstack/identity/v3/users"
)

func TestAccIdentityV3UserMembership_basic(t *testing.T) {
var group groups.Group
var groupName = fmt.Sprintf("ACCPTTEST-%s", acctest.RandString(5))

var user users.User
var userName = fmt.Sprintf("ACCPTTEST-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccPreCheckAdminOnly(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckIdentityV3UserMembershipDestroy,
Steps: []resource.TestStep{
{
Config: testAccIdentityV3UserMembershipBasic(groupName, userName),
Check: resource.ComposeTestCheckFunc(
testAccCheckIdentityV3UserExists("openstack_identity_user_v3.user_1", &user),
testAccCheckIdentityV3GroupExists("openstack_identity_group_v3.group_1", &group),
testAccCheckIdentityV3UserMembershipExists("openstack_identity_user_membership_v3.user_membership_1"),
resource.TestCheckResourceAttrPtr(
"openstack_identity_user_membership_v3.user_membership_1", "user_id", &user.ID),
resource.TestCheckResourceAttrPtr(
"openstack_identity_user_membership_v3.user_membership_1", "group_id", &group.ID),
),
},
},
})
}

func testAccCheckIdentityV3UserMembershipDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)
identityClient, err := config.IdentityV3Client(osRegionName)
if err != nil {
return fmt.Errorf("Error creating OpenStack identity client: %s", err)
}

for _, rs := range s.RootModule().Resources {
if rs.Type != "openstack_identity_user_membership_v3" {
continue
}

uid, gid, err := parseUserMembershipID(rs.Primary.ID)
if err != nil {
return err
}

um, err := users.IsMemberOfGroup(identityClient, gid, uid).Extract()
if err == nil && um {
return fmt.Errorf("User membership still exists")
}
}

return nil
}

func testAccCheckIdentityV3UserMembershipExists(n string) 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 ID is set")
}

config := testAccProvider.Meta().(*Config)
identityClient, err := config.IdentityV3Client(osRegionName)
if err != nil {
return fmt.Errorf("Error creating OpenStack identity client: %s", err)
}

uid, gid, err := parseUserMembershipID(rs.Primary.ID)
if err != nil {
return err
}

um, err := users.IsMemberOfGroup(identityClient, gid, uid).Extract()
if err != nil || !um {
return fmt.Errorf("User membership not found")
}

return nil
}
}

func testAccIdentityV3UserMembershipBasic(groupName, userName string) string {
return fmt.Sprintf(`
resource "openstack_identity_group_v3" "group_1" {
name = "%s"
}

resource "openstack_identity_user_v3" "user_1" {
name = "%s"
}

resource "openstack_identity_user_membership_v3" "user_membership_1" {
user_id = "${openstack_identity_user_v3.user_1.id}"
group_id = "${openstack_identity_group_v3.group_1.id}"
}
`, groupName, userName)
}
79 changes: 79 additions & 0 deletions website/docs/r/identity_user_membership_v3.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
layout: "openstack"
page_title: "OpenStack: openstack_identity_user_membership_v3"
sidebar_current: "docs-openstack-resource-identity-user-membership-v3"
description: |-
Manages a user membership to group V3 resource within OpenStack.
---

# openstack\_identity\_user\_membership_v3

Manages a user membership to group V3 resource within OpenStack.

Note: You _must_ have admin privileges in your OpenStack cloud to use
this resource.

---

## Example Usage

```hcl
resource "openstack_identity_project_v3" "project_1" {
name = "project_1"
}

resource "openstack_identity_user_v3" "user_1" {
name = "user_1"
default_project_id = "${openstack_identity_project_v3.project_1.id}"
}

resource "openstack_identity_group_v3" "group_1" {
name = "group_1"
description = "group 1"
}

resource "openstack_identity_role_v3" "role_1" {
name = "role_1"
}

resource "openstack_identity_user_membership_v3" "user_membership_1" {
user_id = "${openstack_identity_user_v3.user_1.id}"
group_id = "${openstack_identity_group_v3.group_1.id}"
}

resource "openstack_identity_role_assignment_v3" "role_assignment_1" {
group_id = "${openstack_identity_group_v3.group_1.id}"
project_id = "${openstack_identity_project_v3.project_1.id}"
role_id = "${openstack_identity_role_v3.role_1.id}"
}
```

## Argument Reference

The following arguments are supported:

* `region` - (Optional) The region in which to obtain the V3 Identity client.
If omitted, the `region` argument of the provider is used.
Changing this creates a new user membership.

* `user_id` - (Required) The UUID of user to use. Changing this creates a new user membership.

* `group_id` - (Required) The UUID of group to which the user will be added.
Changing this creates a new user membership.

## Attributes Reference

The following attributes are exported:

* `region` - See Argument Reference above.
* `user_id` - See Argument Reference above.
* `group_id` - See Argument Reference above.

## Import

This resource can be imported by specifying all two arguments, separated
by a forward slash:

```
$ terraform import openstack_identity_user_membership_v3.user_membership_1 <user_id>/<group_id>
```
3 changes: 3 additions & 0 deletions website/openstack.erb
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,9 @@
<li<%= sidebar_current("docs-openstack-resource-identity-user-v3") %>>
<a href="/docs/providers/openstack/r/identity_user_v3.html">openstack_identity_user_v3</a>
</li>
<li<%= sidebar_current("docs-openstack-resource-identity-user-membership-v3") %>>
<a href="/docs/providers/openstack/r/identity_user_membership_v3.html">openstack_identity_user_membership_v3</a>
</li>
<li<%= sidebar_current("docs-openstack-resource-identity-service-v3") %>>
<a href="/docs/providers/openstack/r/identity_service_v3.html">openstack_identity_service_v3</a>
</li>
Expand Down