diff --git a/docs/resources/codearts_deploy_group.md b/docs/resources/codearts_deploy_group.md
index b7ff69238e0..1efa1d8b22a 100644
--- a/docs/resources/codearts_deploy_group.md
+++ b/docs/resources/codearts_deploy_group.md
@@ -93,6 +93,9 @@ In addition to all arguments above, the following attributes are exported:
* `permission` - The group permission detail.
The [permission](#DeployGroup_permission) structure is documented below.
+* `permission_matrix` - The group permission matrix detail.
+ The [permission_matrix](#DeployGroup_permission_matrix) structure is documented below.
+
The `object` block supports:
@@ -115,6 +118,31 @@ The `permission` block supports:
* `can_copy` - Indicates whether the user has the permission to copy.
+
+The `permission_matrix` block supports:
+
+* `role_id` - Indicates the role ID.
+
+* `role_name` - Indicates the role name.
+
+* `role_type` - Indicates the role type.
+
+* `can_view` - Indicates whether the role has the view permission.
+
+* `can_edit` - Indicates whether the role has the edit permission.
+
+* `can_delete` - Indicates whether the role has the deletion permission.
+
+* `can_add_host` - Indicates whether the role has the permission to add hosts.
+
+* `can_manage` - Indicates whether the role has the management permission.
+
+* `can_copy` - Indicates whether the role has the permission to copy.
+
+* `created_at` - The permission create time.
+
+* `updated_at` - The permission update time.
+
## Import
The CodeArts deploy group resource can be imported using the `project_id` and `id`, separated by a slash, e.g.
diff --git a/docs/resources/codearts_deploy_group_permission.md b/docs/resources/codearts_deploy_group_permission.md
new file mode 100644
index 00000000000..a2b0c57a8a5
--- /dev/null
+++ b/docs/resources/codearts_deploy_group_permission.md
@@ -0,0 +1,58 @@
+---
+subcategory: "CodeArts Deploy"
+layout: "huaweicloud"
+page_title: "HuaweiCloud: huaweicloud_codearts_deploy_group_permission"
+description: |-
+ Manages a CodeArts deploy group permission resource within HuaweiCloud.
+---
+
+# huaweicloud_codearts_deploy_group_permission
+
+Manages a CodeArts deploy group permission resource within HuaweiCloud.
+
+## Example Usage
+
+```hcl
+variable "project_id" {}
+variable "group_id" {}
+variable "role_id" {}
+
+resource "huaweicloud_codearts_deploy_group_permission" "test" {
+ project_id = var.project_id
+ group_id = var.group_id
+ role_id = var.role_id
+ permission_name = "can_add_host"
+ permission_value = false
+}
+```
+
+## 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.
+ Changing this creates a new resource.
+
+* `group_id` - (Required, String, ForceNew) Specifies the group ID.
+ Changing this creates a new resource.
+
+* `role_id` - (Required, String, ForceNew) Specifies the role ID.
+ Changing this creates a new resource.
+
+* `permission_name` - (Required, String, ForceNew) Specifies the permission name.
+ Valid values are **can_view**, **can_edit**, **can_delete**, **can_add_host**, **can_manage**, and **can_copy**.
+
+ Changing this creates a new resource.
+
+* `permission_value` - (Optional, Bool, ForceNew) Specifies whether to enable the permission.
+ Changing this creates a new resource.
+
+## 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 31d9a824859..2f9785dbd8b 100644
--- a/huaweicloud/provider.go
+++ b/huaweicloud/provider.go
@@ -2191,9 +2191,10 @@ func Provider() *schema.Provider {
"huaweicloud_codearts_project": codearts.ResourceProject(),
"huaweicloud_codearts_repository": codearts.ResourceRepository(),
- "huaweicloud_codearts_deploy_application": codeartsdeploy.ResourceDeployApplication(),
- "huaweicloud_codearts_deploy_group": codeartsdeploy.ResourceDeployGroup(),
- "huaweicloud_codearts_deploy_host": codeartsdeploy.ResourceDeployHost(),
+ "huaweicloud_codearts_deploy_application": codeartsdeploy.ResourceDeployApplication(),
+ "huaweicloud_codearts_deploy_group": codeartsdeploy.ResourceDeployGroup(),
+ "huaweicloud_codearts_deploy_group_permission": codeartsdeploy.ResourceDeployGroupPermission(),
+ "huaweicloud_codearts_deploy_host": codeartsdeploy.ResourceDeployHost(),
"huaweicloud_codearts_inspector_website": codeartsinspector.ResourceInspectorWebsite(),
"huaweicloud_codearts_inspector_website_scan": codeartsinspector.ResourceInspectorWebsiteScan(),
diff --git a/huaweicloud/services/acceptance/codeartsdeploy/resource_huaweicloud_codearts_deploy_group_permission_test.go b/huaweicloud/services/acceptance/codeartsdeploy/resource_huaweicloud_codearts_deploy_group_permission_test.go
new file mode 100644
index 00000000000..9fa5167dcec
--- /dev/null
+++ b/huaweicloud/services/acceptance/codeartsdeploy/resource_huaweicloud_codearts_deploy_group_permission_test.go
@@ -0,0 +1,37 @@
+package codeartsdeploy
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+
+ "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance"
+)
+
+func TestAccDeployGroupPermissionModify_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: testAccDeployGroupPermissionModify_basic(rName),
+ },
+ },
+ })
+}
+
+func testAccDeployGroupPermissionModify_basic(rName string) string {
+ return fmt.Sprintf(`
+%s
+
+resource "huaweicloud_codearts_deploy_group_permission" "test" {
+ project_id = huaweicloud_codearts_deploy_group.test.project_id
+ group_id = huaweicloud_codearts_deploy_group.test.id
+ role_id = try(huaweicloud_codearts_deploy_group.test.permission_matrix[2].role_id, "")
+ permission_name = "can_add_host"
+ permission_value = false
+}`, testDeployGroup_basic(rName))
+}
diff --git a/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_group.go b/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_group.go
index 7e2ce340df4..83c52a4b433 100644
--- a/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_group.go
+++ b/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_group.go
@@ -21,6 +21,7 @@ import (
// @API CodeArtsDeploy PUT /v1/resources/host-groups/{group_id}
// @API CodeArtsDeploy GET /v1/resources/host-groups/{group_id}
// @API CodeArtsDeploy DELETE /v1/resources/host-groups/{group_id}
+// @API CodeArtsDeploy GET /v2/host-groups/{group_id}/permissions
func ResourceDeployGroup() *schema.Resource {
return &schema.Resource{
CreateContext: resourceDeployGroupCreate,
@@ -92,6 +93,11 @@ func ResourceDeployGroup() *schema.Resource {
Elem: deployGroupPermissionSchema(),
Computed: true,
},
+ "permission_matrix": {
+ Type: schema.TypeList,
+ Elem: deployGroupPermissionMatrixSchema(),
+ Computed: true,
+ },
},
}
}
@@ -152,6 +158,69 @@ func deployGroupPermissionSchema() *schema.Resource {
return &sc
}
+func deployGroupPermissionMatrixSchema() *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_view": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the view permission.`,
+ },
+ "can_edit": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the edit permission.`,
+ },
+ "can_delete": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the deletion permission.`,
+ },
+ "can_add_host": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the permission to add hosts.`,
+ },
+ "can_manage": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the management permission.`,
+ },
+ "can_copy": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: `Indicates whether the role has the permission to copy.`,
+ },
+ "created_at": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: `The create time.`,
+ },
+ "updated_at": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: `The update time.`,
+ },
+ },
+ }
+ return &sc
+}
+
func resourceDeployGroupCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var (
cfg = meta.(*config.Config)
@@ -236,6 +305,11 @@ func resourceDeployGroupRead(_ context.Context, d *schema.ResourceData, meta int
return diag.Errorf("error retrieving CodeArts deploy group: result is not found in API response")
}
+ permissionMatrix, err := getDeployGroupPermissionMatrix(client, d.Id())
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
mErr = multierror.Append(
mErr,
d.Set("region", region),
@@ -248,11 +322,40 @@ func resourceDeployGroupRead(_ context.Context, d *schema.ResourceData, meta int
d.Set("updated_at", utils.PathSearch("updated_time", resultRespBody, nil)),
d.Set("created_by", flattenDeployGroupCreatedBy(resultRespBody)),
d.Set("permission", flattenDeployGroupPermission(resultRespBody)),
+ d.Set("permission_matrix", flattenDeployGroupPermissionMatrix(permissionMatrix.([]interface{}))),
)
return diag.FromErr(mErr.ErrorOrNil())
}
+func getDeployGroupPermissionMatrix(client *golangsdk.ServiceClient, id string) (interface{}, error) {
+ httpUrl := "v2/host-groups/{group_id}/permissions"
+ getPath := client.Endpoint + httpUrl
+ getPath = strings.ReplaceAll(getPath, "{group_id}", id)
+ 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 := getRespBody.([]interface{})
+ if len(permissionMatrix) == 0 {
+ return nil, golangsdk.ErrDefault404{
+ ErrUnexpectedResponseCode: golangsdk.ErrUnexpectedResponseCode{
+ Body: []byte("error retrieving CodeArts deploy group permission matrix, empty list"),
+ },
+ }
+ }
+ return permissionMatrix, nil
+}
+
func flattenDeployGroupCreatedBy(resp interface{}) []interface{} {
curJson := utils.PathSearch("created_by", resp, nil)
if curJson == nil {
@@ -287,6 +390,27 @@ func flattenDeployGroupPermission(resp interface{}) []interface{} {
}
}
+func flattenDeployGroupPermissionMatrix(resp []interface{}) []interface{} {
+ 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_view": utils.PathSearch("can_view", v, nil),
+ "can_edit": utils.PathSearch("can_edit", v, nil),
+ "can_delete": utils.PathSearch("can_delete", v, nil),
+ "can_add_host": utils.PathSearch("can_add_host", v, nil),
+ "can_manage": utils.PathSearch("can_manage", v, nil),
+ "can_copy": utils.PathSearch("can_copy", v, nil),
+ "created_at": utils.PathSearch("create_time", v, nil),
+ "updated_at": utils.PathSearch("update_time", v, nil),
+ })
+ }
+
+ return rst
+}
+
func resourceDeployGroupUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var (
cfg = meta.(*config.Config)
diff --git a/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_group_permission.go b/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_group_permission.go
new file mode 100644
index 00000000000..64e5b36a0d3
--- /dev/null
+++ b/huaweicloud/services/codeartsdeploy/resource_huaweicloud_codearts_deploy_group_permission.go
@@ -0,0 +1,153 @@
+package codeartsdeploy
+
+import (
+ "context"
+ "fmt"
+ "strings"
+
+ "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/schema"
+
+ "github.com/chnsz/golangsdk"
+
+ "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/common"
+ "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config"
+ "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils"
+)
+
+// @API CodeArtsDeploy PUT /v2/host-groups/{group_id}/permissions
+// @API CodeArtsDeploy GET /v2/host-groups/{group_id}/permissions
+func ResourceDeployGroupPermission() *schema.Resource {
+ return &schema.Resource{
+ CreateContext: resourceDeployGroupPermissionCreate,
+ ReadContext: resourceDeployGroupPermissionRead,
+ DeleteContext: resourceDeployGroupPermissionDelete,
+
+ Schema: map[string]*schema.Schema{
+ "region": {
+ Type: schema.TypeString,
+ Optional: true,
+ Computed: true,
+ ForceNew: true,
+ },
+ "project_id": {
+ Type: schema.TypeString,
+ Required: true,
+ ForceNew: true,
+ },
+ "group_id": {
+ Type: schema.TypeString,
+ Required: true,
+ ForceNew: true,
+ },
+ "role_id": {
+ Type: schema.TypeString,
+ Required: true,
+ ForceNew: true,
+ },
+ "permission_name": {
+ Type: schema.TypeString,
+ Required: true,
+ ForceNew: true,
+ },
+ "permission_value": {
+ Type: schema.TypeBool,
+ Optional: true,
+ ForceNew: true,
+ },
+ },
+ }
+}
+
+func resourceDeployGroupPermissionCreate(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 = modifyDeployGroupPermission(client, d)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ id, err := uuid.GenerateUUID()
+ if err != nil {
+ return diag.Errorf("unable to generate ID: %s", err)
+ }
+ d.SetId(id)
+
+ return resourceDeployGroupPermissionRead(ctx, d, meta)
+}
+
+func modifyDeployGroupPermission(client *golangsdk.ServiceClient, d *schema.ResourceData) error {
+ httpUrl := "v2/host-groups/{group_id}/permissions"
+ modifyPath := client.Endpoint + httpUrl
+ modifyPath = strings.ReplaceAll(modifyPath, "{group_id}", d.Get("group_id").(string))
+
+ modifyOpt := golangsdk.RequestOpts{
+ KeepResponseBody: true,
+ MoreHeaders: map[string]string{
+ "Content-Type": "application/json;charset=utf-8",
+ },
+ JSONBody: buildDeployGroupPermissionBodyParams(d),
+ }
+
+ _, err := client.Request("PUT", modifyPath, &modifyOpt)
+ if err != nil {
+ return fmt.Errorf("error modifying CodeArts deploy group permission")
+ }
+
+ return nil
+}
+
+func buildDeployGroupPermissionBodyParams(d *schema.ResourceData) map[string]interface{} {
+ return map[string]interface{}{
+ "project_id": d.Get("project_id"),
+ "role_id": d.Get("role_id"),
+ "permission_name": d.Get("permission_name"),
+ "permission_value": d.Get("permission_value"),
+ }
+}
+
+func resourceDeployGroupPermissionRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+ cfg := meta.(*config.Config)
+ region := cfg.GetRegion(d)
+ client, err := cfg.NewServiceClient("codearts_deploy", region)
+ if err != nil {
+ return diag.Errorf("error creating CodeArts deploy client: %s", err)
+ }
+
+ permissionMatrix, err := getDeployGroupPermissionMatrix(client, d.Get("group_id").(string))
+ if err != nil {
+ return common.CheckDeletedDiag(d, err, "error retrieving CodeArts deploy group permission")
+ }
+
+ roleId := d.Get("role_id").(string)
+ permissionName := d.Get("permission_name").(string)
+ expression := fmt.Sprintf("[?role_id=='%s']|[0]", roleId)
+ role := utils.PathSearch(expression, permissionMatrix, nil)
+ if role == nil {
+ return diag.Errorf("unable to find role (%s) from API response", roleId)
+ }
+
+ mErr := multierror.Append(nil,
+ d.Set("region", region),
+ d.Set("permission_value", utils.PathSearch(permissionName, role, nil)),
+ )
+
+ return diag.FromErr(mErr.ErrorOrNil())
+}
+
+func resourceDeployGroupPermissionDelete(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
+ errorMsg := "Deleting permission resource is not supported. The resource is only removed from the state," +
+ " the group permission matrix remains in the cloud."
+ return diag.Diagnostics{
+ diag.Diagnostic{
+ Severity: diag.Warning,
+ Summary: errorMsg,
+ },
+ }
+}