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

IAM: all_project management for opentelekomcloud_identity_role_assignment_v3 #2234

Merged
merged 2 commits into from Jul 21, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 27 additions & 0 deletions docs/resources/identity_role_assignment_v3.md
Expand Up @@ -58,6 +58,30 @@ resource "opentelekomcloud_identity_role_assignment_v3" "role_assignment_1" {
}
```

### Assign Role for All Projects (existing and future)

```hcl
variable "domain_id" {
default = "01aafcf63744d988ebef2b1e04c5c34"
description = "this is the domain id"
}

resource "opentelekomcloud_identity_group_v3" "group_1" {
name = "group_1"
}

data "opentelekomcloud_identity_role_v3" "role_1" {
name = "secu_admin" #security admin
}

resource "opentelekomcloud_identity_role_assignment_v3" "role_assignment_1" {
group_id = opentelekomcloud_identity_group_v3.group_1.id
domain_id = var.domain_id
role_id = data.opentelekomcloud_identity_role_v3.role_1.id
all_projects = true
}
```

## Argument Reference

The following arguments are supported:
Expand All @@ -70,6 +94,9 @@ The following arguments are supported:

* `role_id` - (Required) The role to assign.

* `all_projects` - (Optional) Whether to assign role for all existing and future projects.
`domain_id` has to be specified if `all_projects` is set to `true`.

## Attributes Reference

The following attributes are exported:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -14,7 +14,7 @@ require (
github.com/jinzhu/copier v0.3.5
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
github.com/mitchellh/go-homedir v1.1.0
github.com/opentelekomcloud/gophertelekomcloud v0.7.1-0.20230719101009-5686c7aa2c10
github.com/opentelekomcloud/gophertelekomcloud v0.7.1-0.20230721123824-97f24b448bd4
github.com/unknwon/com v1.0.1
golang.org/x/crypto v0.1.0
golang.org/x/sync v0.1.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -154,8 +154,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758=
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/opentelekomcloud/gophertelekomcloud v0.7.1-0.20230719101009-5686c7aa2c10 h1:Q4XwyCCAhVSM+ezh2JH+ekUylFjXTOISpHnhym4HukE=
github.com/opentelekomcloud/gophertelekomcloud v0.7.1-0.20230719101009-5686c7aa2c10/go.mod h1:9Deb3q2gJvq5dExV+aX+iO+G+mD9Zr9uFt+YY9ONmq0=
github.com/opentelekomcloud/gophertelekomcloud v0.7.1-0.20230721123824-97f24b448bd4 h1:tXaosDbtNFjLogtnqkVIPKLVNFJ+gOPjbzEJwjcRbeM=
github.com/opentelekomcloud/gophertelekomcloud v0.7.1-0.20230721123824-97f24b448bd4/go.mod h1:9Deb3q2gJvq5dExV+aX+iO+G+mD9Zr9uFt+YY9ONmq0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down
Expand Up @@ -62,6 +62,14 @@ func TestAccIdentityV3RoleAssignment_basic(t *testing.T) {
"opentelekomcloud_identity_role_assignment_v3.role_assignment_1", "role_id", &role.ID),
),
},
{
Config: testAccIdentityRoleAssignAllProjectsV3_basic(domainId, groupName, roleName),
Check: resource.ComposeTestCheckFunc(resource.TestCheckResourceAttrPtr(
"opentelekomcloud_identity_role_assignment_v3.role_assignment_1", "group_id", &group.ID),
resource.TestCheckResourceAttrPtr(
"opentelekomcloud_identity_role_assignment_v3.role_assignment_1", "role_id", &role.ID),
),
},
},
})
}
Expand Down Expand Up @@ -249,3 +257,22 @@ resource "opentelekomcloud_identity_role_assignment_v3" "role_assignment_1" {
}
`, group_name, role_name, domain_id)
}

func testAccIdentityRoleAssignAllProjectsV3_basic(domain_id string, group_name string, role_name string) string {
return fmt.Sprintf(`
resource "opentelekomcloud_identity_group_v3" "group_1" {
name = "%s"
}

data "opentelekomcloud_identity_role_v3" "role_1" {
name = "%s"
}

resource "opentelekomcloud_identity_role_assignment_v3" "role_assignment_1" {
group_id = opentelekomcloud_identity_group_v3.group_1.id
domain_id = "%s"
role_id = data.opentelekomcloud_identity_role_v3.role_1.id
all_projects = true
}
`, group_name, role_name, domain_id)
}
Expand Up @@ -53,6 +53,13 @@ func ResourceIdentityRoleAssignmentV3() *schema.Resource {
Required: true,
ForceNew: true,
},

"all_projects": {
Type: schema.TypeBool,
ConflictsWith: []string{"project_id"},
Optional: true,
ForceNew: true,
},
},
}
}
Expand All @@ -70,15 +77,23 @@ func resourceIdentityRoleAssignmentV3Create(ctx context.Context, d *schema.Resou
groupID := d.Get("group_id").(string)
projectID := d.Get("project_id").(string)
roleID := d.Get("role_id").(string)
opts := roles.AssignOpts{
DomainID: domainID,
GroupID: groupID,
ProjectID: projectID,
}

err = roles.Assign(identityClient, roleID, opts).ExtractErr()
if err != nil {
return fmterr.Errorf("error assigning role: %s", err)
if !d.Get("all_projects").(bool) {
opts := roles.AssignOpts{
DomainID: domainID,
GroupID: groupID,
ProjectID: projectID,
}

err = roles.Assign(identityClient, roleID, opts).ExtractErr()
if err != nil {
return fmterr.Errorf("error assigning role: %s", err)
}
} else {
err = roles.UpdateGroupAllProjects(identityClient, domainID, groupID, roleID)
if err != nil {
return fmterr.Errorf("error assigning role to all projects: %s", err)
}
}

d.SetId(buildRoleAssignmentID(domainID, projectID, groupID, roleID))
Expand All @@ -95,19 +110,30 @@ func resourceIdentityRoleAssignmentV3Read(ctx context.Context, d *schema.Resourc
if err != nil {
return fmterr.Errorf(clientCreationFail, err)
}
var mErr *multierror.Error
var roleAssignmentId string

domainID, projectID, groupID, _ := ExtractRoleAssignmentID(d.Id())

roleAssignment, err := getRoleAssignment(identityClient, d)
if !d.Get("all_projects").(bool) {
roleAssignmentId, err = getRoleAssignment(identityClient, d)
} else {
err = getAllProjectsRoleAssignment(identityClient, d)
if err != nil {
diag.FromErr(err)
}
_, _, _, roleAssignmentId = ExtractRoleAssignmentID(d.Id())
}
if err != nil {
return fmterr.Errorf("error getting role assignment: %s", err)
}
domainID, projectID, groupID, _ := ExtractRoleAssignmentID(d.Id())

log.Printf("[DEBUG] Retrieved OpenStack role assignment: %#v", roleAssignment)
mErr := multierror.Append(
log.Printf("[DEBUG] Retrieved OpenStack role assignment ID: %s", roleAssignmentId)
mErr = multierror.Append(
d.Set("domain_id", domainID),
d.Set("project_id", projectID),
d.Set("group_id", groupID),
d.Set("role_id", roleAssignment.ID),
d.Set("role_id", roleAssignmentId),
)
if err := mErr.ErrorOrNil(); err != nil {
return diag.FromErr(err)
Expand All @@ -124,22 +150,28 @@ func resourceIdentityRoleAssignmentV3Delete(ctx context.Context, d *schema.Resou
if err != nil {
return fmterr.Errorf(clientCreationFail, err)
}

domainID, projectID, groupID, roleID := ExtractRoleAssignmentID(d.Id())
opts := roles.UnassignOpts{
DomainID: domainID,
GroupID: groupID,
ProjectID: projectID,
}
err = roles.Unassign(identityClient, roleID, opts).ExtractErr()
if err != nil {
return fmterr.Errorf("error unassigning role: %s", err)
if !d.Get("all_projects").(bool) {
opts := roles.UnassignOpts{
DomainID: domainID,
GroupID: groupID,
ProjectID: projectID,
}
err = roles.Unassign(identityClient, roleID, opts).ExtractErr()
if err != nil {
return fmterr.Errorf("error unassigning role: %s", err)
}
} else {
err = roles.RemoveGroupAllProjects(identityClient, domainID, groupID, roleID)
if err != nil {
return fmterr.Errorf("error assigning role to all projects: %s", err)
}
}

return nil
}

func getRoleAssignment(identityClient *golangsdk.ServiceClient, d *schema.ResourceData) (roles.RoleAssignment, error) {
func getRoleAssignment(identityClient *golangsdk.ServiceClient, d *schema.ResourceData) (string, error) {
domainID, projectID, groupID, roleID := ExtractRoleAssignmentID(d.Id())

opts := roles.ListAssignmentsOpts{
Expand Down Expand Up @@ -167,7 +199,15 @@ func getRoleAssignment(identityClient *golangsdk.ServiceClient, d *schema.Resour
return true, nil
})

return assignment, err
return assignment.ID, err
}

func getAllProjectsRoleAssignment(identityClient *golangsdk.ServiceClient, d *schema.ResourceData) error {
domainID, _, groupID, roleID := ExtractRoleAssignmentID(d.Id())

err := roles.CheckGroupAllProjects(identityClient, domainID, groupID, roleID)

return err
}

// Role assignments have no ID in OpenStack. Build an ID out of the IDs that make up the role assignment
Expand Down
4 changes: 4 additions & 0 deletions releasenotes/notes/iam_all_projects-f983e1d6f6fdb1d1.yaml
@@ -0,0 +1,4 @@
---
enhancements:
- |
**[IAM]** Added `all_projects` setting for ``resource/opentelekomcloud_identity_role_assignment_v3`` (`#2234 <https://github.com/opentelekomcloud/terraform-provider-opentelekomcloud/pull/2234>`_)