-
Notifications
You must be signed in to change notification settings - Fork 163
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(identitycenter): add resource identitycenter provision permissio…
…n set
- Loading branch information
1 parent
905a902
commit 589ee14
Showing
4 changed files
with
323 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
--- | ||
subcategory: "IAM Identity Center" | ||
layout: "huaweicloud" | ||
page_title: "HuaweiCloud: huaweicloud_identitycenter_provision_permission_set" | ||
description: |- | ||
Manages an Identity Center provision permission set resource within HuaweiCloud. | ||
--- | ||
|
||
# huaweicloud_identitycenter_provision_permission_set | ||
|
||
Manages an Identity Center provision permission set resource within HuaweiCloud. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
variable "instance_id" {} | ||
variable "permission_set_id" {} | ||
variable "target_type" {} | ||
variable "target_id" {} | ||
resource "huaweicloud_identitycenter_provision_permission_set" "test" { | ||
instance_id = var.instance_id | ||
permission_set_id = var.permission_set_id | ||
target_type = var.target_type | ||
target_id = var.target_id | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `region` - (Optional, String) Specifies the region in which to query the resource. | ||
If omitted, the provider-level region will be used. | ||
|
||
* `instance_id` - (Required, String, NonUpdatable) Specifies the ID of an IAM Identity Center instance. | ||
|
||
* `permission_set_id` - (Required, String, NonUpdatable) Specifies the ID of a permission set. | ||
|
||
* `target_id` - (Required, String, NonUpdatable) Specifies the account ID. | ||
|
||
* `target_type` - (Required, String, NonUpdatable) Specifies the type of the principal to be attached. | ||
|
||
## Attribute Reference | ||
|
||
In addition to all arguments above, the following attributes are exported: | ||
|
||
* `id` - The resource ID. | ||
|
||
* `status` - The authorization status of a permission set. | ||
|
||
## Timeouts | ||
|
||
This resource provides the following timeouts configuration options: | ||
|
||
* `create` - Default is 10 minutes. |
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
55 changes: 55 additions & 0 deletions
55
...tance/identitycenter/resource_huaweicloud_identitycenter_provision_permission_set_test.go
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,55 @@ | ||
package identitycenter | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
|
||
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" | ||
) | ||
|
||
func TestAccProvisionPermissionSet_basic(t *testing.T) { | ||
name := acceptance.RandomAccResourceName() | ||
rName := "huaweicloud_identitycenter_provision_permission_set.test" | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { | ||
acceptance.TestAccPreCheck(t) | ||
acceptance.TestAccPreCheckMultiAccount(t) | ||
}, | ||
ProviderFactories: acceptance.TestAccProviderFactories, | ||
CheckDestroy: nil, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testProvisionPermissionSet_basic(name), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr(rName, "status", "SUCCEEDED"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testProvisionPermissionSet_basic(name string) string { | ||
return fmt.Sprintf(` | ||
%[1]s | ||
resource "huaweicloud_identitycenter_user" "test" { | ||
identity_store_id = data.huaweicloud_identitycenter_instance.test.identity_store_id | ||
user_name = "%[2]s" | ||
password_mode = "OTP" | ||
family_name = "test_family_name" | ||
given_name = "test_given_name" | ||
display_name = "test_display_name" | ||
email = "[email protected]" | ||
} | ||
resource "huaweicloud_identitycenter_provision_permission_set" "test" { | ||
instance_id = data.huaweicloud_identitycenter_instance.system.id | ||
permission_set_id = huaweicloud_identitycenter_permission_set.test.id | ||
target_id = huaweicloud_identitycenter_user.test.id | ||
target_type = "ACCOUNT" | ||
} | ||
`, testPermissionSet_basic(name), name) | ||
} |
211 changes: 211 additions & 0 deletions
211
...d/services/identitycenter/resource_huaweicloud_identitycenter_provision_permission_set.go
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,211 @@ | ||
package identitycenter | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"strings" | ||
"time" | ||
|
||
"github.com/hashicorp/go-multierror" | ||
"github.com/hashicorp/go-uuid" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" | ||
|
||
"github.com/chnsz/golangsdk" | ||
|
||
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" | ||
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" | ||
) | ||
|
||
var provisionPermissionSetNonUpdatableParams = []string{"instance_id", "permission_set_id", "target_type", "target_id"} | ||
|
||
// @API IdentityCenter POST /v1/instances/{instance_id}/permission-sets/{permission_set_id}/provision | ||
// @API IdentityCenter GET /v1/instances/{instance_id}/permission-sets/provisioning-statuses | ||
func ResourceProvisionPermissionSet() *schema.Resource { | ||
return &schema.Resource{ | ||
CreateContext: resourceProvisionPermissionSetCreate, | ||
UpdateContext: resourceProvisionPermissionSetUpdate, | ||
ReadContext: resourceProvisionPermissionSetRead, | ||
DeleteContext: resourceProvisionPermissionSetDelete, | ||
|
||
Timeouts: &schema.ResourceTimeout{ | ||
Create: schema.DefaultTimeout(10 * time.Minute), | ||
}, | ||
|
||
CustomizeDiff: config.FlexibleForceNew(provisionPermissionSetNonUpdatableParams), | ||
|
||
Description: "schema: Internal", | ||
Schema: map[string]*schema.Schema{ | ||
"region": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Computed: true, | ||
ForceNew: true, | ||
}, | ||
"instance_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: `Specifies the ID of the IAM Identity Center instance.`, | ||
}, | ||
"permission_set_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: `Specifies the ID of the IAM Identity Center instance.`, | ||
}, | ||
"target_type": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: `Specifies the type of the principal to be attached.`, | ||
}, | ||
"target_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: `Specifies the account ID.`, | ||
}, | ||
"status": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: `The authorization status of a permission set.`, | ||
}, | ||
"enable_force_new": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ValidateFunc: validation.StringInSlice([]string{"true", "false"}, false), | ||
Description: utils.SchemaDesc("", utils.SchemaDescInput{Internal: true}), | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceProvisionPermissionSetCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
cfg := meta.(*config.Config) | ||
region := cfg.GetRegion(d) | ||
instanceId := d.Get("instance_id").(string) | ||
permissionSetId := d.Get("permission_set_id").(string) | ||
// createIdentityCenterProvisionPermissionSet: create IdentityCenter provision permission set | ||
var ( | ||
createProvisionPermissionSetHttpUrl = "v1/instances/{instance_id}/permission-sets/{permission_set_id}/provision" | ||
createProduct = "identitycenter" | ||
) | ||
client, err := cfg.NewServiceClient(createProduct, region) | ||
if err != nil { | ||
return diag.Errorf("error creating IdentityCenter client: %s", err) | ||
} | ||
|
||
createProvisionPermissionSetPath := client.Endpoint + createProvisionPermissionSetHttpUrl | ||
createProvisionPermissionSetPath = strings.ReplaceAll(createProvisionPermissionSetPath, "{instance_id}", instanceId) | ||
createProvisionPermissionSetPath = strings.ReplaceAll(createProvisionPermissionSetPath, "{permission_set_id}", permissionSetId) | ||
|
||
createProvisionPermissionSetPathOpt := golangsdk.RequestOpts{ | ||
KeepResponseBody: true, | ||
} | ||
|
||
createProvisionPermissionSetPathOpt.JSONBody = map[string]interface{}{ | ||
"target_type": d.Get("target_type").(string), | ||
"target_id": d.Get("target_id").(string), | ||
} | ||
|
||
_, err = client.Request("POST", createProvisionPermissionSetPath, &createProvisionPermissionSetPathOpt) | ||
if err != nil { | ||
return diag.Errorf("error creating IdentityCenter provision permission set: %s", err) | ||
} | ||
|
||
err = checkProvisionPermissionSetStatus(ctx, client, instanceId, d.Timeout(schema.TimeoutCreate)) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
uuId, err := uuid.GenerateUUID() | ||
if err != nil { | ||
return diag.Errorf("unable to generate ID: %s", err) | ||
} | ||
d.SetId(uuId) | ||
|
||
return resourceProvisionPermissionSetRead(ctx, d, meta) | ||
} | ||
|
||
func resourceProvisionPermissionSetRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
cfg := meta.(*config.Config) | ||
region := cfg.GetRegion(d) | ||
instanceId := d.Get("instance_id").(string) | ||
|
||
client, err := cfg.NewServiceClient("identitycenter", region) | ||
if err != nil { | ||
return diag.Errorf("error creating IdentityCenter client: %s", err) | ||
} | ||
|
||
resp, err := getProvisionPermissionSetStatus(client, instanceId) | ||
if err != nil { | ||
return diag.Errorf("error querying IdentityCenter provision permission set: %s", err) | ||
} | ||
|
||
mErr := multierror.Append( | ||
d.Set("region", region), | ||
d.Set("status", utils.PathSearch("permission_sets_provisioning_status[0].status", resp, nil)), | ||
) | ||
|
||
return diag.FromErr(mErr.ErrorOrNil()) | ||
} | ||
|
||
func resourceProvisionPermissionSetUpdate(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics { | ||
return nil | ||
} | ||
|
||
func resourceProvisionPermissionSetDelete(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics { | ||
return nil | ||
} | ||
|
||
func checkProvisionPermissionSetStatus(ctx context.Context, client *golangsdk.ServiceClient, instanceId string, timeout time.Duration) error { | ||
stateConf := &resource.StateChangeConf{ | ||
Pending: []string{"PENDING"}, | ||
Target: []string{"COMPLETED"}, | ||
Refresh: provisionPermissionSetStateRefreshFunc(client, instanceId), | ||
Timeout: timeout, | ||
PollInterval: 10 * timeout, | ||
Delay: 10 * time.Second, | ||
} | ||
_, err := stateConf.WaitForStateContext(ctx) | ||
if err != nil { | ||
return fmt.Errorf("error waiting for IdentityCenter provision permission set to be completed: %s", err) | ||
} | ||
return nil | ||
} | ||
|
||
func provisionPermissionSetStateRefreshFunc(client *golangsdk.ServiceClient, instanceId string) resource.StateRefreshFunc { | ||
return func() (interface{}, string, error) { | ||
respBody, err := getProvisionPermissionSetStatus(client, instanceId) | ||
if err != nil { | ||
return nil, "ERROR", err | ||
} | ||
|
||
status := utils.PathSearch("permission_sets_provisioning_status[0].status", respBody, nil).(string) | ||
if status == "SUCCEEDED" { | ||
return respBody, "COMPLETED", nil | ||
} | ||
|
||
if status == "FAILED" { | ||
return respBody, "ERROR", fmt.Errorf("failed to provision IdentityCenter permission set") | ||
} | ||
|
||
return respBody, "PENDING", nil | ||
} | ||
} | ||
|
||
func getProvisionPermissionSetStatus(client *golangsdk.ServiceClient, instanceId string) (interface{}, error) { | ||
getProvisionPermissionSetHttpUrl := "v1/instances/{instance_id}/permission-sets/provisioning-statuses" | ||
getProvisionPermissionSetPath := client.Endpoint + getProvisionPermissionSetHttpUrl | ||
getProvisionPermissionSetPath = strings.ReplaceAll(getProvisionPermissionSetPath, "{instance_id}", instanceId) | ||
|
||
getProvisionPermissionSetPathOpt := golangsdk.RequestOpts{ | ||
KeepResponseBody: true, | ||
} | ||
|
||
getProvisionPermissionSetResp, err := client.Request("GET", getProvisionPermissionSetPath, &getProvisionPermissionSetPathOpt) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return utils.FlattenResponse(getProvisionPermissionSetResp) | ||
} |