Skip to content

Commit

Permalink
feat(identitycenter): support permission set tags (#6099)
Browse files Browse the repository at this point in the history
  • Loading branch information
luoping-12345 authored Dec 27, 2024
1 parent 1012b69 commit 1542c67
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 12 deletions.
2 changes: 2 additions & 0 deletions docs/resources/identitycenter_permission_set.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ In addition to all arguments above, the following attributes are exported:

* `account_ids` - The array of one or more account IDs bound to the permission set.

* `tags` - (Optional, Map) Specifies the key/value pairs to associate with the permission set.

## Import

The Identity Center permission set can be imported using the `instance_id` and `id` separated by a slash, e.g.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ func TestAccPermissionSet_basic(t *testing.T) {
resource.TestCheckResourceAttr(rName, "description", "created by terraform"),
resource.TestCheckResourceAttrSet(rName, "urn"),
resource.TestCheckResourceAttrSet(rName, "created_at"),
resource.TestCheckResourceAttrPair(rName, "instance_id",
"data.huaweicloud_identitycenter_instance.system", "id"),
resource.TestCheckResourceAttrPair(rName, "instance_id", "data.huaweicloud_identitycenter_instance.system", "id"),
resource.TestCheckResourceAttr(rName, "tags.foo", "bar"),
),
},
{
Expand All @@ -78,6 +78,7 @@ func TestAccPermissionSet_basic(t *testing.T) {
resource.TestCheckResourceAttr(rName, "name", name),
resource.TestCheckResourceAttr(rName, "session_duration", "PT4H"),
resource.TestCheckResourceAttr(rName, "description", "updated by terraform"),
resource.TestCheckResourceAttr(rName, "tags.foo", "bar_update"),
),
},
{
Expand Down Expand Up @@ -123,6 +124,10 @@ resource "huaweicloud_identitycenter_permission_set" "test" {
name = "%s"
session_duration = "PT8H"
description = "created by terraform"
tags = {
foo = "bar"
}
}
`, name)
}
Expand All @@ -148,6 +153,10 @@ resource "huaweicloud_identitycenter_permission_set" "test" {
instance_id = data.huaweicloud_identitycenter_instance.system.id
name = "%s"
session_duration = "PT4H"
tags = {
foo = "bar_update"
}
}
`, name)
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import (
// @API IdentityCenter DELETE /v1/instances/{instance_id}/permission-sets/{id}
// @API IdentityCenter GET /v1/instances/{instance_id}/permission-sets/{id}
// @API IdentityCenter PUT /v1/instances/{instance_id}/permission-sets/{id}
// @API IdentityCenter POST /v1/instances/{resource_type}/{resource_id}/tags/create
// @API IdentityCenter POST /v1/instances/{resource_type}/{resource_id}/tags/delete
// @API IdentityCenter GET /v1/instances/{resource_type}/{resource_id}/tags
func ResourcePermissionSet() *schema.Resource {
return &schema.Resource{
CreateContext: resourcePermissionSetCreate,
Expand Down Expand Up @@ -62,6 +65,7 @@ func ResourcePermissionSet() *schema.Resource {
Optional: true,
Computed: true,
},
"tags": common.TagsSchema(),
"urn": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -115,6 +119,13 @@ func resourcePermissionSetCreate(ctx context.Context, d *schema.ResourceData, me
}

d.SetId(permissionSetId)

if _, ok := d.GetOk("tags"); ok {
if err := updateTags(createPermissionSetClient, d, "identitycenter:permissionset", d.Id()); err != nil {
return diag.Errorf("error creating tags of Identity Center permission set %s: %s", d.Id(), err)
}
}

return resourcePermissionSetRead(ctx, d, meta)
}

Expand Down Expand Up @@ -176,6 +187,16 @@ func resourcePermissionSetRead(_ context.Context, d *schema.ResourceData, meta i
d.Set("account_ids", accountIDs),
)

tags, err := getPermissionSetTags(getPermissionSetClient, d.Id())
if err != nil {
log.Printf("[WARN] error fetching tags of permission set: %s", err)
}

mErr = multierror.Append(
mErr,
d.Set("tags", tags),
)

return diag.FromErr(mErr.ErrorOrNil())
}

Expand Down Expand Up @@ -205,6 +226,10 @@ func getAssignededAccounts(client *golangsdk.ServiceClient, instanceID, psID str
func resourcePermissionSetUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
cfg := meta.(*config.Config)
region := cfg.GetRegion(d)
client, err := cfg.NewServiceClient("identitycenter", region)
if err != nil {
return diag.Errorf("error creating Identity Center client: %s", err)
}

updatePermissionSetChanges := []string{
"session_duration",
Expand All @@ -213,29 +238,28 @@ func resourcePermissionSetUpdate(ctx context.Context, d *schema.ResourceData, me
}

if d.HasChanges(updatePermissionSetChanges...) {
var (
updatePermissionSetHttpUrl = "v1/instances/{instance_id}/permission-sets/{id}"
updatePermissionSetProduct = "identitycenter"
)
updatePermissionSetClient, err := cfg.NewServiceClient(updatePermissionSetProduct, region)
if err != nil {
return diag.Errorf("error creating Identity Center client: %s", err)
}
updatePermissionSetHttpUrl := "v1/instances/{instance_id}/permission-sets/{id}"

updatePermissionSetPath := updatePermissionSetClient.Endpoint + updatePermissionSetHttpUrl
updatePermissionSetPath := client.Endpoint + updatePermissionSetHttpUrl
updatePermissionSetPath = strings.ReplaceAll(updatePermissionSetPath, "{instance_id}", d.Get("instance_id").(string))
updatePermissionSetPath = strings.ReplaceAll(updatePermissionSetPath, "{id}", d.Id())

updatePermissionSetOpt := golangsdk.RequestOpts{
KeepResponseBody: true,
}
updatePermissionSetOpt.JSONBody = utils.RemoveNil(buildUpdatePermissionSetBodyParams(d))
_, err = updatePermissionSetClient.Request("PUT", updatePermissionSetPath, &updatePermissionSetOpt)
_, err = client.Request("PUT", updatePermissionSetPath, &updatePermissionSetOpt)
if err != nil {
return diag.Errorf("error updating permission set: %s", err)
}
}

if d.HasChange("tags") {
if err := updateTags(client, d, "identitycenter:permissionset", d.Id()); err != nil {
return diag.Errorf("error updating tags of Identitycenter permission set %s: %s", d.Id(), err)
}
}

return resourcePermissionSetRead(ctx, d, meta)
}

Expand Down Expand Up @@ -295,3 +319,83 @@ func resourcePermissionSetImport(_ context.Context, d *schema.ResourceData, _ in

return []*schema.ResourceData{d}, nil
}

func updateTags(client *golangsdk.ServiceClient, d *schema.ResourceData, tagsType string, id string) error {
oRaw, nRaw := d.GetChange("tags")
oMap := oRaw.(map[string]interface{})
nMap := nRaw.(map[string]interface{})

manageTagsHttpUrl := "v1/instances/{resource_type}/{resource_id}/tags/{action}"
manageTagsPath := client.Endpoint + manageTagsHttpUrl
manageTagsPath = strings.ReplaceAll(manageTagsPath, "{resource_type}", tagsType)
manageTagsPath = strings.ReplaceAll(manageTagsPath, "{resource_id}", id)
manageTagsOpt := golangsdk.RequestOpts{
KeepResponseBody: true,
}

// remove old tags
if len(oMap) > 0 {
manageDeleteTagsPath := strings.ReplaceAll(manageTagsPath, "{action}", "delete")
manageTagsOpt.JSONBody = map[string]interface{}{
"tags": utils.ExpandResourceTags(oMap),
}
_, err := client.Request("POST", manageDeleteTagsPath, &manageTagsOpt)
if err != nil {
return err
}
}

// set new tags
if len(nMap) > 0 {
manageCreateTagsPath := strings.ReplaceAll(manageTagsPath, "{action}", "create")
manageTagsOpt.JSONBody = map[string]interface{}{
"tags": utils.ExpandResourceTags(nMap),
}
_, err := client.Request("POST", manageCreateTagsPath, &manageTagsOpt)
if err != nil {
return err
}
}

return nil
}

func getPermissionSetTags(client *golangsdk.ServiceClient, id string) (interface{}, error) {
getPermissionSetTagsHttpUrl := "v1/instances/{resource_type}/{resource_id}/tags?limit=10"
getPermissionSetTagsPath := client.Endpoint + getPermissionSetTagsHttpUrl
getPermissionSetTagsPath = strings.ReplaceAll(getPermissionSetTagsPath, "{resource_type}", "identitycenter:permissionset")
getPermissionSetTagsPath = strings.ReplaceAll(getPermissionSetTagsPath, "{resource_id}", id)

getPermissionSetTagsOpt := golangsdk.RequestOpts{
KeepResponseBody: true,
}

path := getPermissionSetTagsPath
var permissionSetTags []interface{}
for {
getPermissionSetTagsResp, err := client.Request("GET", path, &getPermissionSetTagsOpt)
if err != nil {
return nil, err
}
getPermissionSetTagsRespBody, err := utils.FlattenResponse(getPermissionSetTagsResp)
if err != nil {
return nil, err
}
tags := utils.PathSearch("tags", getPermissionSetTagsRespBody, make([]interface{}, 0)).([]interface{})
permissionSetTags = append(permissionSetTags, tags...)

marker := utils.PathSearch("page_info.next_marker", getPermissionSetTagsRespBody, nil)
if marker == nil {
break
}
path = fmt.Sprintf("%s&marker=%s", getPermissionSetTagsPath, marker)
}

result := make(map[string]interface{})
for _, val := range permissionSetTags {
valMap := val.(map[string]interface{})
result[valMap["key"].(string)] = valMap["value"]
}

return result, nil
}

0 comments on commit 1542c67

Please sign in to comment.