diff --git a/docs/resources/codearts_deploy_application.md b/docs/resources/codearts_deploy_application.md
index 10dc00cde0..f63d9f7536 100644
--- a/docs/resources/codearts_deploy_application.md
+++ b/docs/resources/codearts_deploy_application.md
@@ -2,7 +2,8 @@
subcategory: "CodeArts Deploy"
layout: "huaweicloud"
page_title: "HuaweiCloud: huaweicloud_codearts_deploy_application"
-description: ""
+description: |-
+ Manages a CodeArts deploy application resource within HuaweiCloud.
---
# huaweicloud_codearts_deploy_application
@@ -100,6 +101,9 @@ The following arguments are supported:
-> When value is **true**, it's unable to update other parameters.
+* `permission_level` - (Optional, String) Specifies the permission level.
+ Valid values are **instance** and **project**. Defaults to **project**.
+
The `operation_list` block supports:
@@ -139,7 +143,7 @@ In addition to all arguments above, the following attributes are exported:
* `can_copy` - Indicates whether the user has the copy permission.
-* `can_manage` - Check whether the user has the management permission, including adding, deleting, modifying,
+* `can_manage` - Indicates whether the user has the management permission, including adding, deleting, modifying,
querying deployment and permission modification.
* `can_create_env` - Indicates whether the user has the permission to create an environment.
@@ -154,6 +158,35 @@ In addition to all arguments above, the following attributes are exported:
* `steps` - The deployment steps. The example value is `{"step1":"XXX", "step2":"XXX"}`.
+* `permission_matrix` - Indicates the permission matrix.
+ The [permission_matrix](#attrblock--permission_matrix) structure is documented below.
+
+
+The `permission_matrix` block supports:
+
+* `role_id` - Indicates the role ID.
+
+* `role_name` - Indicates the role name.
+
+* `role_type` - Indicates the role type.
+
+* `can_modify` - Indicates whether the role has the editing permission.
+
+* `can_delete` - Indicates whether the role has the deletion permission.
+
+* `can_view` - Indicates whether the role has the view permission.
+
+* `can_execute` - Indicates whether the role has the deployment permission.
+
+* `can_copy` - Indicates whether the role has the copy permission.
+
+* `can_manage` - Check whether the role has the management permission, including adding, deleting, modifying,
+ querying deployment and permission modification.
+
+* `can_create_env` - Indicates whether the role has the permission to create an environment.
+
+* `can_disable` - Indicates whether the role has the permission to disable the application.
+
## Import
The CodeArts deploy application resource can be imported using the `id`, e.g.
diff --git a/docs/resources/codearts_deploy_application_permission.md b/docs/resources/codearts_deploy_application_permission.md
new file mode 100644
index 0000000000..ce052bc27e
--- /dev/null
+++ b/docs/resources/codearts_deploy_application_permission.md
@@ -0,0 +1,82 @@
+---
+subcategory: "CodeArts Deploy"
+layout: "huaweicloud"
+page_title: "HuaweiCloud: huaweicloud_codearts_deploy_application_permission"
+description: |-
+ Manages a CodeArts deploy application permission resource within HuaweiCloud.
+---
+
+# huaweicloud_codearts_deploy_application_permission
+
+Manages a CodeArts deploy application permission resource within HuaweiCloud.
+
+-> Only when the applications using instance level permission, this resource is available.
+
+## Example Usage
+
+```hcl
+variable "project_id" {}
+variable "application_ids" {}
+variable "role_id" {}
+
+resource "huaweicloud_codearts_deploy_group_permission" "test" {
+ project_id = var.project_id
+ application_ids = var.application_ids
+
+ roles {
+ role_id = var.role_id
+ can_modify = true
+ can_disable = true
+ can_delete = true
+ can_view = true
+ can_execute = true
+ can_copy = true
+ can_manage = true
+ can_create_env = true
+ }
+}
+```
+
+## Argument Reference
+
+The following arguments are supported:
+
+* `region` - (Optional, String, ForceNew) Specifies the region in which to create the resource.
+ If omitted, the provider-level region will be used.
+ Changing this creates a new resource.
+
+* `project_id` - (Required, String, ForceNew) Specifies the project ID for CodeArts service.
+ Changing this creates a new resource.
+
+* `application_ids` - (Required, List) Specifies the application IDs.
+
+* `roles` - (Required, List) Specifies the role permissions list.
+ The [roles](#block--roles) structure is documented below.
+
+
+The `roles` block supports:
+
+* `role_id` - (Required, String) Specifies the role ID.
+
+* `can_copy` - (Required, Bool) Specifies whether the role has the copy permission.
+
+* `can_create_env` - (Required, Bool) Specifies whether the role has the permission to create an environment.
+
+* `can_delete` - (Required, Bool) Specifies whether the role has the deletion permission.
+
+* `can_disable` - (Required, Bool) Specifies whether the role has the permission to disable application.
+
+* `can_execute` - (Required, Bool) Specifies whether the role has the deployment permission.
+
+* `can_manage` - (Required, Bool) Specifies whether the role has the management permission, including adding, deleting,
+ modifying, querying deployment and permission modification.
+
+* `can_modify` - (Required, Bool) Specifies whether the role has the editing permission.
+
+* `can_view` - (Required, Bool) Specifies whether the role has the view permission.
+
+## Attribute Reference
+
+In addition to all arguments above, the following attributes are exported:
+
+* `id` - The resource ID.
diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go
index 1c481e093c..7f5e22e342 100644
--- a/huaweicloud/provider.go
+++ b/huaweicloud/provider.go
@@ -2253,6 +2253,7 @@ func Provider() *schema.Provider {
"huaweicloud_codearts_repository": codearts.ResourceRepository(),
"huaweicloud_codearts_deploy_application": codeartsdeploy.ResourceDeployApplication(),
+ "huaweicloud_codearts_deploy_application_permission": codeartsdeploy.ResourceDeployApplicationPermission(),
"huaweicloud_codearts_deploy_application_group": codeartsdeploy.ResourceDeployApplicationGroup(),
"huaweicloud_codearts_deploy_application_group_move": codeartsdeploy.ResourceDeployApplicationGroupMove(),
"huaweicloud_codearts_deploy_environment": codeartsdeploy.ResourceDeployEnvironment(),
diff --git a/huaweicloud/services/acceptance/codeartsdeploy/resource_huaweicloud_codearts_deploy_application_permission_test.go b/huaweicloud/services/acceptance/codeartsdeploy/resource_huaweicloud_codearts_deploy_application_permission_test.go
new file mode 100644
index 0000000000..864bdb833c
--- /dev/null
+++ b/huaweicloud/services/acceptance/codeartsdeploy/resource_huaweicloud_codearts_deploy_application_permission_test.go
@@ -0,0 +1,49 @@
+package codeartsdeploy
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+
+ "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance"
+)
+
+func TestAccDeployApplicationPermissionModify_basic(t *testing.T) {
+ rName := acceptance.RandomAccResourceName()
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { acceptance.TestAccPreCheck(t) },
+ ProviderFactories: acceptance.TestAccProviderFactories,
+ CheckDestroy: nil,
+ Steps: []resource.TestStep{
+ {
+ Config: testAccDeployApplicationPermissionModify_basic(rName, false),
+ },
+ {
+ Config: testAccDeployApplicationPermissionModify_basic(rName, true),
+ },
+ },
+ })
+}
+
+func testAccDeployApplicationPermissionModify_basic(rName string, value bool) string {
+ return fmt.Sprintf(`
+%s
+
+resource "huaweicloud_codearts_deploy_application_permission" "test" {
+ project_id = huaweicloud_codearts_deploy_application.test.project_id
+ application_ids = [huaweicloud_codearts_deploy_application.test.id]
+
+ roles {
+ role_id = try(huaweicloud_codearts_deploy_application.test.permission_matrix[2].role_id, "")
+ can_modify = %t
+ can_disable = true
+ can_delete = true
+ can_view = true
+ can_execute = true
+ can_copy = true
+ can_manage = true
+ can_create_env = true
+ }
+}`, testDeployApplication_basic(rName), value)
+}
diff --git a/huaweicloud/services/acceptance/codeartsdeploy/resource_huaweicloud_codearts_deploy_application_test.go b/huaweicloud/services/acceptance/codeartsdeploy/resource_huaweicloud_codearts_deploy_application_test.go
index 335f43e204..ae3f9d6c2d 100644
--- a/huaweicloud/services/acceptance/codeartsdeploy/resource_huaweicloud_codearts_deploy_application_test.go
+++ b/huaweicloud/services/acceptance/codeartsdeploy/resource_huaweicloud_codearts_deploy_application_test.go
@@ -76,6 +76,7 @@ func TestAccDeployApplication_basic(t *testing.T) {
resource.TestCheckResourceAttr(rName, "trigger_source", "0"),
resource.TestCheckResourceAttr(rName, "steps.step1", "Download Package"),
resource.TestCheckResourceAttr(rName, "is_disable", "false"),
+ resource.TestCheckResourceAttr(rName, "permission_level", "instance"),
resource.TestCheckResourceAttrSet(rName, "created_at"),
resource.TestCheckResourceAttrSet(rName, "updated_at"),
resource.TestCheckResourceAttrSet(rName, "project_name"),
@@ -105,6 +106,7 @@ func TestAccDeployApplication_basic(t *testing.T) {
resource.TestCheckResourceAttr(rName, "trigger_source", "0"),
resource.TestCheckResourceAttr(rName, "steps.step1", "Download Package"),
resource.TestCheckResourceAttr(rName, "is_disable", "true"),
+ resource.TestCheckResourceAttr(rName, "permission_level", "project"),
resource.TestCheckResourceAttrSet(rName, "created_at"),
resource.TestCheckResourceAttrSet(rName, "updated_at"),
resource.TestCheckResourceAttrSet(rName, "project_name"),
@@ -231,12 +233,13 @@ func testDeployApplication_basic(name string) string {
%[1]s
resource "huaweicloud_codearts_deploy_application" "test" {
- project_id = huaweicloud_codearts_project.test.id
- name = "%[2]s"
- description = "test description"
- is_draft = true
- create_type = "template"
- trigger_source = "0"
+ project_id = huaweicloud_codearts_project.test.id
+ name = "%[2]s"
+ description = "test description"
+ is_draft = true
+ create_type = "template"
+ trigger_source = "0"
+ permission_level = "instance"
operation_list {
name = "Download Package"
@@ -279,13 +282,14 @@ func testDeployApplication_update(name string) string {
%[1]s
resource "huaweicloud_codearts_deploy_application" "test" {
- project_id = huaweicloud_codearts_project.test.id
- name = "%[2]s-update"
- is_draft = false
- create_type = "template"
- trigger_source = "0"
- is_disable = true
- group_id = huaweicloud_codearts_deploy_application_group.test.id
+ project_id = huaweicloud_codearts_project.test.id
+ name = "%[2]s-update"
+ is_draft = false
+ create_type = "template"
+ trigger_source = "0"
+ is_disable = true
+ group_id = huaweicloud_codearts_deploy_application_group.test.id
+ permission_level = "project"
operation_list {
name = "Download Package"
diff --git a/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_application.go b/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_application.go
index 11ed6148cc..a58c825c3b 100644
--- a/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_application.go
+++ b/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_application.go
@@ -2,12 +2,17 @@ package codeartsdeploy
import (
"context"
+ "encoding/json"
"fmt"
+ "log"
"strings"
+ "time"
"github.com/hashicorp/go-multierror"
"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/jmespath/go-jmespath"
"github.com/chnsz/golangsdk"
@@ -21,6 +26,8 @@ import (
// @API CodeArtsDeploy PUT /v1/applications
// @API CodeArtsDeploy DELETE /v1/applications/{app_id}
// @API CodeArtsDeploy PUT /v1/applications/{app_id}/disable
+// @API CodeArtsDeploy PUT /v3/applications/permission-level
+// @API CodeArtsDeploy GET /v3/applications/permissions
// @API CodeArtsDeploy PUT /v1/projects/{project_id}/applications/groups/move
func ResourceDeployApplication() *schema.Resource {
return &schema.Resource{
@@ -32,6 +39,11 @@ func ResourceDeployApplication() *schema.Resource {
StateContext: schema.ImportStatePassthroughContext,
},
+ Timeouts: &schema.ResourceTimeout{
+ Create: schema.DefaultTimeout(10 * time.Minute),
+ Update: schema.DefaultTimeout(10 * time.Minute),
+ },
+
// precheck values for `is_draft` and `operation_list`,
// when `operation_list` is empty and `is_draft` is true, the application is actually created,
// and it's only shown in list API, which means 404 will return when get single application.
@@ -126,6 +138,12 @@ func ResourceDeployApplication() *schema.Resource {
Optional: true,
Description: `Specifies whether to disable the application.`,
},
+ "permission_level": {
+ Type: schema.TypeString,
+ Optional: true,
+ Computed: true,
+ Description: `Specifies the permission level.`,
+ },
"is_care": {
Type: schema.TypeBool,
Computed: true,
@@ -179,7 +197,7 @@ func ResourceDeployApplication() *schema.Resource {
"can_manage": {
Type: schema.TypeBool,
Computed: true,
- Description: `Check whether the user has the management permission, including adding, deleting,
+ Description: `Indicates whether the user has the management permission, including adding, deleting,
modifying, querying deployment and permission modification.`,
},
"can_create_env": {
@@ -203,6 +221,12 @@ modifying, querying deployment and permission modification.`,
Computed: true,
Description: `The deployment steps.`,
},
+ "permission_matrix": {
+ Type: schema.TypeList,
+ Elem: deployApplicationPermissionMatrixSchema(),
+ Computed: true,
+ Description: `Indicates the permission matrix.`,
+ },
},
}
}
@@ -250,6 +274,70 @@ func deployApplicationOperationSchema() *schema.Resource {
return &sc
}
+func deployApplicationPermissionMatrixSchema() *schema.Resource {
+ sc := schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "role_id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: `Indicates the role ID.`,
+ },
+ "role_name": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: `Indicates the role name.`,
+ },
+ "role_type": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: `Indicates the role type.`,
+ },
+ "can_modify": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the editing permission.`,
+ },
+ "can_disable": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the permission to disable application.`,
+ },
+ "can_delete": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the deletion permission.`,
+ },
+ "can_view": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the view permission.`,
+ },
+ "can_execute": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the deployment permission.`,
+ },
+ "can_copy": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the copy permission.`,
+ },
+ "can_manage": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the management permission, including adding, deleting,
+modifying, querying deployment and permission modification.`,
+ },
+ "can_create_env": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the permission to create an environment.`,
+ },
+ },
+ }
+ return &sc
+}
+
func resourceDeployApplicationCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var (
cfg = meta.(*config.Config)
@@ -294,6 +382,13 @@ func resourceDeployApplicationCreate(ctx context.Context, d *schema.ResourceData
}
}
+ // `permission_level` defaults to project level when the application is created
+ if v := d.Get("permission_level").(string); v == "instance" {
+ if err := updateDeployApplicationPermissionLevel(ctx, client, d, d.Timeout(schema.TimeoutCreate)); err != nil {
+ return diag.FromErr(err)
+ }
+ }
+
return resourceDeployApplicationRead(ctx, d, meta)
}
@@ -319,6 +414,39 @@ func updateDeployApplicationDisable(client *golangsdk.ServiceClient, d *schema.R
return nil
}
+func updateDeployApplicationPermissionLevel(ctx context.Context, client *golangsdk.ServiceClient, d *schema.ResourceData,
+ timeout time.Duration) error {
+ httpUrl := "v3/applications/permission-level"
+ updatePath := client.Endpoint + httpUrl
+ updateOpt := golangsdk.RequestOpts{
+ KeepResponseBody: true,
+ JSONBody: map[string]interface{}{
+ "project_id": d.Get("project_id"),
+ "permission_level": d.Get("permission_level"),
+ "application_ids": []string{d.Id()},
+ },
+ }
+
+ err := resource.RetryContext(ctx, timeout, func() *resource.RetryError {
+ _, err := client.Request("PUT", updatePath, &updateOpt)
+ isRetry, err := handleDeployApplicationPermissionLevelOperationError(err)
+ if isRetry {
+ // lintignore:R018
+ time.Sleep(10 * time.Second)
+ return resource.RetryableError(err)
+ }
+ if err != nil {
+ return resource.NonRetryableError(err)
+ }
+ return nil
+ })
+ if err != nil {
+ return fmt.Errorf("error updating CodeArts deploy application permission level: %s", err)
+ }
+
+ return nil
+}
+
func buildCreateDeployApplicationBodyParams(d *schema.ResourceData) map[string]interface{} {
bodyParams := map[string]interface{}{
"project_id": d.Get("project_id"),
@@ -438,11 +566,57 @@ func resourceDeployApplicationRead(_ context.Context, d *schema.ResourceData, me
d.Set("steps", flattenDeployApplicationSteps(resultRespBody)),
d.Set("is_disable", utils.PathSearch("is_disable", resultRespBody, nil)),
d.Set("is_care", utils.PathSearch("is_care", resultRespBody, nil)),
+ d.Set("permission_level", utils.PathSearch("permission_level", resultRespBody, nil)),
+ )
+
+ permissionMatrix, err := getDeployApplicationPermissionMatrix(client, d)
+ if err != nil {
+ log.Printf("[WARN] failed to retrieve application permission matrix: %s", err)
+ }
+
+ mErr = multierror.Append(
+ mErr,
+ d.Set("permission_matrix", flattenDeployApplicationPermissionMatrix(permissionMatrix)),
)
return diag.FromErr(mErr.ErrorOrNil())
}
+func getDeployApplicationPermissionMatrix(client *golangsdk.ServiceClient, d *schema.ResourceData) (interface{}, error) {
+ permissionLevel := d.Get("permission_level").(string)
+
+ httpUrl := "v3/applications/permissions"
+ getPath := client.Endpoint + httpUrl
+ if permissionLevel == "instance" {
+ getPath += fmt.Sprintf("?app_id=%s", d.Id())
+ } else {
+ getPath += fmt.Sprintf("?project_id=%s", d.Get("project_id").(string))
+ }
+ getOpt := golangsdk.RequestOpts{
+ KeepResponseBody: true,
+ }
+
+ getResp, err := client.Request("GET", getPath, &getOpt)
+ if err != nil {
+ return nil, err
+ }
+ getRespBody, err := utils.FlattenResponse(getResp)
+ if err != nil {
+ return nil, err
+ }
+
+ permissionMatrix := utils.PathSearch("result", getRespBody, make([]interface{}, 0)).([]interface{})
+ if len(permissionMatrix) == 0 {
+ return nil, golangsdk.ErrDefault404{
+ ErrUnexpectedResponseCode: golangsdk.ErrUnexpectedResponseCode{
+ Body: []byte("error retrieving CodeArts deploy application permission matrix, empty list"),
+ },
+ }
+ }
+
+ return permissionMatrix, nil
+}
+
// flattenDeployApplicationSteps use to flatten deployment steps.
// An example of the return value of this function is as follows: '{"step1":"XXX", "step2":"XXX"}'
func flattenDeployApplicationSteps(resp interface{}) interface{} {
@@ -459,6 +633,30 @@ func flattenDeployApplicationSteps(resp interface{}) interface{} {
return rst
}
+func flattenDeployApplicationPermissionMatrix(respBody interface{}) []interface{} {
+ if resp, isList := respBody.([]interface{}); isList {
+ rst := make([]interface{}, 0, len(resp))
+ for _, v := range resp {
+ rst = append(rst, map[string]interface{}{
+ "role_id": utils.PathSearch("role_id", v, nil),
+ "role_name": utils.PathSearch("name", v, nil),
+ "role_type": utils.PathSearch("role_type", v, nil),
+ "can_modify": utils.PathSearch("can_modify", v, nil),
+ "can_disable": utils.PathSearch("can_disable", v, nil),
+ "can_delete": utils.PathSearch("can_delete", v, nil),
+ "can_view": utils.PathSearch("can_view", v, nil),
+ "can_execute": utils.PathSearch("can_execute", v, nil),
+ "can_copy": utils.PathSearch("can_copy", v, nil),
+ "can_manage": utils.PathSearch("can_manage", v, nil),
+ "can_create_env": utils.PathSearch("can_create_env", v, nil),
+ })
+ }
+ return rst
+ }
+
+ return nil
+}
+
func resourceDeployApplicationUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
cfg := meta.(*config.Config)
region := cfg.GetRegion(d)
@@ -502,6 +700,12 @@ func resourceDeployApplicationUpdate(ctx context.Context, d *schema.ResourceData
}
}
+ if d.HasChange("permission_level") {
+ if err := updateDeployApplicationPermissionLevel(ctx, client, d, d.Timeout(schema.TimeoutUpdate)); err != nil {
+ return diag.FromErr(err)
+ }
+ }
+
if d.HasChange("is_disable") {
if err := updateDeployApplicationDisable(client, d); err != nil {
return diag.FromErr(err)
@@ -583,3 +787,27 @@ func resourceDeployApplicationDelete(_ context.Context, d *schema.ResourceData,
return nil
}
+
+// Deploy.00060222: Some application permissions in this project are being updated. Try again later.
+// Error will occur when two or more applications using instance level permission are creating.
+func handleDeployApplicationPermissionLevelOperationError(err error) (bool, error) {
+ if err == nil {
+ return false, nil
+ }
+
+ if errCode, ok := err.(golangsdk.ErrDefault400); ok {
+ var apiError interface{}
+ if jsonErr := json.Unmarshal(errCode.Body, &apiError); jsonErr != nil {
+ return false, jsonErr
+ }
+
+ errorCode, errorCodeErr := jmespath.Search("error_code", apiError)
+ if errorCodeErr != nil {
+ return false, fmt.Errorf("error parse error code from response body: %s", errorCodeErr)
+ }
+ if errorCode == "Deploy.00060222" {
+ return true, err
+ }
+ }
+ return false, err
+}
diff --git a/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_application_permission.go b/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_application_permission.go
new file mode 100644
index 0000000000..031945f0ad
--- /dev/null
+++ b/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_application_permission.go
@@ -0,0 +1,188 @@
+package codeartsdeploy
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/hashicorp/go-uuid"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+
+ "github.com/chnsz/golangsdk"
+
+ "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config"
+)
+
+// @API CodeArtsDeploy PUT /v3/applications/permissions
+func ResourceDeployApplicationPermission() *schema.Resource {
+ return &schema.Resource{
+ CreateContext: resourceDeployApplicationPermissionCreateOrUpdate,
+ ReadContext: resourceDeployApplicationPermissionRead,
+ UpdateContext: resourceDeployApplicationPermissionCreateOrUpdate,
+ DeleteContext: resourceDeployApplicationPermissionDelete,
+
+ Schema: map[string]*schema.Schema{
+ "region": {
+ Type: schema.TypeString,
+ Optional: true,
+ Computed: true,
+ ForceNew: true,
+ },
+ "project_id": {
+ Type: schema.TypeString,
+ Required: true,
+ ForceNew: true,
+ Description: `Specifies the project ID for CodeArts service.`,
+ },
+ "application_ids": {
+ Type: schema.TypeSet,
+ Required: true,
+ Elem: &schema.Schema{Type: schema.TypeString},
+ Description: `Specifies the application IDs.`,
+ },
+ "roles": {
+ Type: schema.TypeSet,
+ Required: true,
+ Description: `Specifies the role permissions list.`,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "role_id": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: `Specifies the role ID.`,
+ },
+ "can_modify": {
+ Type: schema.TypeBool,
+ Required: true,
+ Description: `Specifies whether the role has the editing permission.`,
+ },
+ "can_disable": {
+ Type: schema.TypeBool,
+ Required: true,
+ Description: `Specifies whether the role has the permission to disable application.`,
+ },
+ "can_delete": {
+ Type: schema.TypeBool,
+ Required: true,
+ Description: `Specifies whether the role has the deletion permission.`,
+ },
+ "can_view": {
+ Type: schema.TypeBool,
+ Required: true,
+ Description: `Specifies whether the role has the view permission.`,
+ },
+ "can_execute": {
+ Type: schema.TypeBool,
+ Required: true,
+ Description: `Specifies whether the role has the deployment permission.`,
+ },
+ "can_copy": {
+ Type: schema.TypeBool,
+ Required: true,
+ Description: `Specifies whether the role has the copy permission.`,
+ },
+ "can_manage": {
+ Type: schema.TypeBool,
+ Required: true,
+ Description: `Specifies whether the role has the management permission, including adding, deleting,
+ modifying, querying deployment and permission modification.`,
+ },
+ "can_create_env": {
+ Type: schema.TypeBool,
+ Required: true,
+ Description: `Specifies whether the role has the permission to create an environment.`,
+ },
+ },
+ },
+ },
+ },
+ }
+}
+
+func resourceDeployApplicationPermissionCreateOrUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+ cfg := meta.(*config.Config)
+ client, err := cfg.NewServiceClient("codearts_deploy", cfg.GetRegion(d))
+ if err != nil {
+ return diag.Errorf("error creating CodeArts deploy client: %s", err)
+ }
+
+ err = modifyDeployApplicationPermission(client, d)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ if d.IsNewResource() {
+ id, err := uuid.GenerateUUID()
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ d.SetId(id)
+ }
+
+ return resourceDeployApplicationPermissionRead(ctx, d, meta)
+}
+
+func modifyDeployApplicationPermission(client *golangsdk.ServiceClient, d *schema.ResourceData) error {
+ httpUrl := "v3/applications/permissions"
+ modifyPath := client.Endpoint + httpUrl
+ modifyOpt := golangsdk.RequestOpts{
+ KeepResponseBody: true,
+ JSONBody: buildDeployApplicationPermissionBodyParams(d),
+ }
+
+ _, err := client.Request("PUT", modifyPath, &modifyOpt)
+ if err != nil {
+ return fmt.Errorf("error updating CodeArts deploy application permission")
+ }
+
+ return nil
+}
+
+func buildDeployApplicationPermissionBodyParams(d *schema.ResourceData) map[string]interface{} {
+ return map[string]interface{}{
+ "project_id": d.Get("project_id"),
+ "application_ids": d.Get("application_ids").(*schema.Set).List(),
+ "roles": buildDeployApplicationPermissionBodyParamsRoles(d),
+ }
+}
+
+func buildDeployApplicationPermissionBodyParamsRoles(d *schema.ResourceData) []map[string]interface{} {
+ rawArray := d.Get("roles").(*schema.Set).List()
+ if len(rawArray) == 0 {
+ return nil
+ }
+
+ rst := make([]map[string]interface{}, 0, len(rawArray))
+ for _, v := range rawArray {
+ if raw, isMap := v.(map[string]interface{}); isMap {
+ rst = append(rst, map[string]interface{}{
+ "dev_role_id": raw["role_id"],
+ "can_modify": raw["can_modify"],
+ "can_disable": raw["can_disable"],
+ "can_delete": raw["can_delete"],
+ "can_view": raw["can_view"],
+ "can_execute": raw["can_execute"],
+ "can_copy": raw["can_copy"],
+ "can_manage": raw["can_manage"],
+ "can_create_env": raw["can_create_env"],
+ })
+ }
+ }
+
+ return rst
+}
+
+func resourceDeployApplicationPermissionRead(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
+ return nil
+}
+
+func resourceDeployApplicationPermissionDelete(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
+ errorMsg := "Deleting permission resource is not supported. The resource is only removed from the state," +
+ " the application permission matrix remains in the cloud."
+ return diag.Diagnostics{
+ diag.Diagnostic{
+ Severity: diag.Warning,
+ Summary: errorMsg,
+ },
+ }
+}