diff --git a/docs/data-sources/codearts_deploy_applications.md b/docs/data-sources/codearts_deploy_applications.md new file mode 100644 index 0000000000..70eb07c002 --- /dev/null +++ b/docs/data-sources/codearts_deploy_applications.md @@ -0,0 +1,117 @@ +--- +subcategory: "CodeArts Deploy" +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_codearts_deploy_applications" +description: |- + Use this data source to get the list of CodeArts deploy applications. +--- + +# huaweicloud_codearts_deploy_applications + +Use this data source to get the list of CodeArts deploy applications. + +## Example Usage + +```hcl +variable "project_id" {} + +data "huaweicloud_codearts_deploy_applications" "test" { + project_id = var.project_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. + +* `project_id` - (Required, String) Specifies the project ID + +* `group_id` - (Optional, String) Specifies the application group ID. + Enter **no_grouped** to query ungrouped applications. + +* `states` - (Optional, List) Specifies the application status list. + Values can be as follows: + + **abort**: Deployment suspended. + + **failed**: Deployment failed. + + **not_started**: Execution canceled. + + **pending**: Queuing. + + **running**: Deployment in progress. + + **succeeded**: Deployment succeeded. + + **timeout**: Deployment times out. + + **not_executed**: Deployment not executed. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The data source ID. + +* `applications` - Indicates the application list + The [applications](#attrblock--applications) structure is documented below. + + +The `applications` block supports: + +* `arrange_infos` - Indicates the deployment task information + The [arrange_infos](#attrblock--applications--arrange_infos) structure is documented below. + +* `id` - Indicates the application ID. + +* `name` - Indicates the application name. + +* `can_copy` - Indicates whether user has permission to clone application. + +* `can_create_env` - Indicates whether user has permission to create environment in application. + +* `can_delete` - Indicates whether user has permission to delete application. + +* `can_disable` - Indicates whether the user has permission to disable application. + +* `can_execute` - Indicates whether user has permission to deploy. + +* `can_manage` - Indicates whether user has permission to modify application permission. + +* `can_modify` - Indicates whether user has permission to modify application. + +* `can_view` - Indicates whether user has permission to view application. + +* `create_tenant_id` - Indicates the created tenant ID. + +* `create_user_id` - Indicates the creator user ID. + +* `created_at` - Indicates the created time. + +* `deploy_system` - Indicates the deployment type. + +* `duration` - Indicates the deployment duration. + +* `end_time` - Indicates the deployment end time. + +* `execution_state` - Indicates the execution status. + +* `execution_time` - Indicates the latest execution time. + +* `executor_id` - Indicates the executor user ID. + +* `executor_nick_name` - Indicates the executor user name. + +* `is_care` - Indicates whether application is saved to favorites. + +* `is_disable` - Indicates whether the application is disabled. + +* `project_name` - Indicates the project name. + +* `release_id` - Indicates the release ID. + +* `updated_at` - Indicates the updated time. + + +The `arrange_infos` block supports: + +* `deploy_system` - Indicates the deployment task type. + +* `id` - Indicates the task ID. + +* `state` - Indicates the deployment task status. diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index caadbaa62f..2fae093172 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -578,6 +578,7 @@ func Provider() *schema.Provider { "huaweicloud_codearts_deploy_groups": codeartsdeploy.DataSourceCodeartsDeployGroups(), "huaweicloud_codearts_deploy_hosts": codeartsdeploy.DataSourceCodeartsDeployHosts(), "huaweicloud_codearts_deploy_application_groups": codeartsdeploy.DataSourceCodeartsDeployApplicationGroups(), + "huaweicloud_codearts_deploy_applications": codeartsdeploy.DataSourceCodeartsDeployApplications(), "huaweicloud_cts_notifications": cts.DataSourceNotifications(), "huaweicloud_cts_traces": cts.DataSourceCtsTraces(), diff --git a/huaweicloud/services/acceptance/codeartsdeploy/data_source_huaweicloud_codearts_deploy_applications_test.go b/huaweicloud/services/acceptance/codeartsdeploy/data_source_huaweicloud_codearts_deploy_applications_test.go new file mode 100644 index 0000000000..1cec7c7f43 --- /dev/null +++ b/huaweicloud/services/acceptance/codeartsdeploy/data_source_huaweicloud_codearts_deploy_applications_test.go @@ -0,0 +1,85 @@ +package codeartsdeploy + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" +) + +func TestAccDataSourceCodeartsDeployApplications_basic(t *testing.T) { + dataSource := "data.huaweicloud_codearts_deploy_applications.test" + rName := acceptance.RandomAccResourceName() + dc := acceptance.InitDataSourceCheck(dataSource) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acceptance.TestAccPreCheck(t) + }, + ProviderFactories: acceptance.TestAccProviderFactories, + Steps: []resource.TestStep{ + { + Config: testDataSourceCodeartsDeployApplications_basic(rName), + Check: resource.ComposeTestCheckFunc( + dc.CheckResourceExists(), + resource.TestCheckResourceAttrSet(dataSource, "applications.#"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.project_name"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.id"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.name"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.release_id"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.can_modify"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.can_manage"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.can_create_env"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.can_execute"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.can_copy"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.can_delete"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.can_view"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.can_disable"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.is_care"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.is_disable"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.create_user_id"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.create_tenant_id"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.created_at"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.updated_at"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.arrange_infos.#"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.arrange_infos.0.id"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.arrange_infos.0.state"), + resource.TestCheckResourceAttrSet(dataSource, "applications.0.arrange_infos.0.deploy_system"), + + resource.TestCheckOutput("is_state_filter_useful", "true"), + ), + }, + }, + }) +} + +func testDataSourceCodeartsDeployApplications_basic(name string) string { + return fmt.Sprintf(` +%[1]s + +data "huaweicloud_codearts_deploy_applications" "test" { + depends_on = [huaweicloud_codearts_deploy_application.test] + + project_id = huaweicloud_codearts_project.test.id +} + +// filter by state +data "huaweicloud_codearts_deploy_applications" "filter_by_state" { + depends_on = [huaweicloud_codearts_deploy_application.test] + + project_id = huaweicloud_codearts_project.test.id + states = ["not_executed"] +} + +locals { + filter_result_by_state = [for v in data.huaweicloud_codearts_deploy_applications.filter_by_state.applications[*].arrange_infos[0].state : + v == "Draft"] +} + +output "is_state_filter_useful" { + value = length(local.filter_result_by_state) == 1 && alltrue(local.filter_result_by_state) +} +`, testDeployApplication_basic(name)) +} diff --git a/huaweicloud/services/codeartsdeploy/data_source_huaweicloud_codearts_deploy_applications.go b/huaweicloud/services/codeartsdeploy/data_source_huaweicloud_codearts_deploy_applications.go new file mode 100644 index 0000000000..e5057eb4ca --- /dev/null +++ b/huaweicloud/services/codeartsdeploy/data_source_huaweicloud_codearts_deploy_applications.go @@ -0,0 +1,314 @@ +package codeartsdeploy + +import ( + "context" + + "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/config" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" +) + +// @API CodeArtsDeploy POST /v1/applications/list +func DataSourceCodeartsDeployApplications() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceCodeartsDeployApplicationsRead, + + Schema: map[string]*schema.Schema{ + "region": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: `Specifies the region in which to query the resource. If omitted, the provider-level region will be used.`, + }, + "project_id": { + Type: schema.TypeString, + Required: true, + Description: `Specifies the project ID`, + }, + "states": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Description: `Specifies the application status list.`, + }, + "group_id": { + Type: schema.TypeString, + Optional: true, + Description: `Specifies the application group ID.`, + }, + "applications": { + Type: schema.TypeList, + Computed: true, + Description: `Indicates the application list`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "project_name": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the project name.`, + }, + "id": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the application ID.`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the application name.`, + }, + "deploy_system": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the deployment type.`, + }, + "release_id": { + Type: schema.TypeInt, + Computed: true, + Description: `Indicates the release ID.`, + }, + "can_modify": { + Type: schema.TypeBool, + Computed: true, + Description: `Indicates whether user has permission to modify application.`, + }, + "can_manage": { + Type: schema.TypeBool, + Computed: true, + Description: `Indicates whether user has permission to modify application permission.`, + }, + "can_create_env": { + Type: schema.TypeBool, + Computed: true, + Description: `Indicates whether user has permission to create environment in application.`, + }, + "can_execute": { + Type: schema.TypeBool, + Computed: true, + Description: `Indicates whether user has permission to deploy.`, + }, + "can_copy": { + Type: schema.TypeBool, + Computed: true, + Description: `Indicates whether user has permission to clone application.`, + }, + "can_delete": { + Type: schema.TypeBool, + Computed: true, + Description: `Indicates whether user has permission to delete application.`, + }, + "can_view": { + Type: schema.TypeBool, + Computed: true, + Description: `Indicates whether user has permission to view application.`, + }, + "can_disable": { + Type: schema.TypeBool, + Computed: true, + Description: `Indicates whether the user has permission to disable application.`, + }, + "is_care": { + Type: schema.TypeBool, + Computed: true, + Description: `Indicates whether application is saved to favorites.`, + }, + "is_disable": { + Type: schema.TypeBool, + Computed: true, + Description: `Indicates whether the application is disabled.`, + }, + "create_user_id": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the creator user ID.`, + }, + "create_tenant_id": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the created tenant ID.`, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the created time.`, + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the updated time.`, + }, + "arrange_infos": { + Type: schema.TypeList, + Computed: true, + Description: `Indicates the deployment task information.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the task ID.`, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the deployment task status.`, + }, + "deploy_system": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the deployment task type.`, + }, + }, + }, + }, + "duration": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the deployment duration.`, + }, + "execution_time": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the latest execution time.`, + }, + "end_time": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the deployment end time.`, + }, + "executor_id": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the executor user ID.`, + }, + "executor_nick_name": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the executor user name.`, + }, + "execution_state": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the execution status.`, + }, + }, + }, + }, + }, + } +} + +func dataSourceCodeartsDeployApplicationsRead(_ 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) + } + + getHttpUrl := "v1/applications/list" + getPath := client.Endpoint + getHttpUrl + getOpt := golangsdk.RequestOpts{ + KeepResponseBody: true, + MoreHeaders: map[string]string{ + "Content-Type": "application/json;charset=utf-8", + }, + } + + pageIndex := 1 + + rst := make([]map[string]interface{}, 0) + for { + getOpt.JSONBody = utils.RemoveNil(buildGetDeployApplicationsBodyParams(d, pageIndex)) + getResp, err := client.Request("POST", getPath, &getOpt) + if err != nil { + return diag.Errorf("error retrieving applications: %s", err) + } + getRespBody, err := utils.FlattenResponse(getResp) + if err != nil { + return diag.Errorf("error flatten response: %s", err) + } + + applications := utils.PathSearch("result", getRespBody, make([]interface{}, 0)).([]interface{}) + for _, application := range applications { + rst = append(rst, map[string]interface{}{ + "project_name": utils.PathSearch("project_name", application, nil), + "id": utils.PathSearch("id", application, nil), + "name": utils.PathSearch("name", application, nil), + "deploy_system": utils.PathSearch("deploy_system", application, nil), + "release_id": utils.PathSearch("release_id", application, nil), + "can_modify": utils.PathSearch("can_modify", application, nil), + "can_delete": utils.PathSearch("can_delete", application, nil), + "can_view": utils.PathSearch("can_view", application, nil), + "can_execute": utils.PathSearch("can_execute", application, nil), + "can_copy": utils.PathSearch("can_copy", application, nil), + "can_manage": utils.PathSearch("can_manage", application, nil), + "can_create_env": utils.PathSearch("can_create_env", application, nil), + "can_disable": utils.PathSearch("can_disable", application, nil), + "is_care": utils.PathSearch("is_care", application, nil), + "is_disable": utils.PathSearch("is_disable", application, nil), + "create_user_id": utils.PathSearch("create_user_id", application, nil), + "create_tenant_id": utils.PathSearch("create_tenant_id", application, nil), + "created_at": utils.PathSearch("create_time", application, nil), + "updated_at": utils.PathSearch("update_time", application, nil), + "duration": utils.PathSearch("duration", application, nil), + "execution_time": utils.PathSearch("execution_time", application, nil), + "end_time": utils.PathSearch("end_time", application, nil), + "executor_id": utils.PathSearch("executor_id", application, nil), + "executor_nick_name": utils.PathSearch("executor_nick_name", application, nil), + "execution_state": utils.PathSearch("execution_state", application, nil), + "arrange_infos": flattenDataSourceDeployApplicationArranges( + utils.PathSearch("arrange_infos", application, make([]interface{}, 0)).([]interface{})), + }) + } + + total := utils.PathSearch("total_num", getRespBody, float64(0)).(float64) + if pageSize*(pageIndex-1)+len(applications) >= int(total) { + break + } + pageIndex++ + } + + id, err := uuid.GenerateUUID() + if err != nil { + return diag.FromErr(err) + } + d.SetId(id) + + mErr := multierror.Append(nil, + d.Set("region", region), + d.Set("applications", rst), + ) + + return diag.FromErr(mErr.ErrorOrNil()) +} + +func buildGetDeployApplicationsBodyParams(d *schema.ResourceData, page int) map[string]interface{} { + bodyParams := map[string]interface{}{ + "project_id": d.Get("project_id"), + "page": page, + "size": pageSize, + "states": utils.ValueIgnoreEmpty(d.Get("states")), + "group_id": utils.ValueIgnoreEmpty(d.Get("group_id")), + } + return bodyParams +} + +func flattenDataSourceDeployApplicationArranges(resp []interface{}) []interface{} { + rst := make([]interface{}, 0, len(resp)) + for _, v := range resp { + rst = append(rst, map[string]interface{}{ + "id": utils.PathSearch("id", v, nil), + "state": utils.PathSearch("state", v, nil), + "deploy_system": utils.PathSearch("deploy_system", v, nil), + }) + } + + return rst +}