diff --git a/docs/data-sources/cts_operations.md b/docs/data-sources/cts_operations.md new file mode 100644 index 0000000000..5ab3e90875 --- /dev/null +++ b/docs/data-sources/cts_operations.md @@ -0,0 +1,48 @@ +--- +subcategory: "Cloud Trace Service (CTS)" +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_cts_operations" +description: |- + Use this data source to list all operations on a cloud service. +--- + +# huaweicloud_cts_operations + +Use this data source to list all operations on a cloud service. + +## Example Usage + +```hcl +data "huaweicloud_cts_operations" "test" {} +``` + +## 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. + +* `service_type` - (Optional, String) Specifies the type of the cloud service on which operations are performed. + +* `resource_type` - (Optional, String) Specifies the type of the resource on which operations are performed. + If this parameter is used, `service_type` is mandatory. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The data source ID. + +* `operations` - All operations on the cloud service. + + The [operations](#operations_struct) structure is documented below. + + +The `operations` block supports: + +* `service_type` - The type of the cloud service on which operations are performed. + +* `resource_type` - The type of the resource on which operations are performed. + +* `operation_list` - The array of operation names. diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index b16211091a..5a8f879c30 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -578,6 +578,7 @@ func Provider() *schema.Provider { "huaweicloud_cts_notifications": cts.DataSourceNotifications(), "huaweicloud_cts_traces": cts.DataSourceCtsTraces(), "huaweicloud_cts_trackers": cts.DataSourceCtsTrackers(), + "huaweicloud_cts_operations": cts.DataSourceCtsOperations(), "huaweicloud_cts_quotas": cts.DataSourceCtsQuotas(), "huaweicloud_cdm_clusters": cdm.DataSourceCdmClusters(), diff --git a/huaweicloud/services/acceptance/cts/data_source_huaweicloud_cts_operations_test.go b/huaweicloud/services/acceptance/cts/data_source_huaweicloud_cts_operations_test.go new file mode 100644 index 0000000000..c6786051c0 --- /dev/null +++ b/huaweicloud/services/acceptance/cts/data_source_huaweicloud_cts_operations_test.go @@ -0,0 +1,71 @@ +package cts + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" +) + +func TestAccDataSourceCtsOperations_basic(t *testing.T) { + dataSource := "data.huaweicloud_cts_operations.test" + dc := acceptance.InitDataSourceCheck(dataSource) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acceptance.TestAccPreCheck(t) + }, + ProviderFactories: acceptance.TestAccProviderFactories, + Steps: []resource.TestStep{ + { + Config: testDataSourceCtsOperations_basic(), + Check: resource.ComposeTestCheckFunc( + dc.CheckResourceExists(), + resource.TestCheckResourceAttrSet(dataSource, "operations.0.operation_list.#"), + resource.TestCheckResourceAttrSet(dataSource, "operations.0.service_type"), + resource.TestCheckResourceAttrSet(dataSource, "operations.0.resource_type"), + resource.TestCheckOutput("is_default_filter_useful", "true"), + resource.TestCheckOutput("is_service_type_filter_useful", "true"), + resource.TestCheckOutput("is_resource_type_filter_useful", "true"), + ), + }, + }, + }) +} + +func testDataSourceCtsOperations_basic() string { + return ` +locals { + service_type = "CTS" + resource_type = "tracker" +} + +data "huaweicloud_cts_operations" "test" {} + +output "is_default_filter_useful" { + value = length(data.huaweicloud_cts_operations.test.operations) >= 1 +} + +data "huaweicloud_cts_operations" "filter_by_service_type" { + service_type = local.service_type +} + +output "is_service_type_filter_useful" { + value = length(data.huaweicloud_cts_operations.filter_by_service_type.operations) >= 1 && alltrue( + [for op in data.huaweicloud_cts_operations.filter_by_service_type.operations[*] : op.service_type == local.service_type] + ) +} + +data "huaweicloud_cts_operations" "filter_by_resource_type" { + service_type = local.service_type + resource_type = local.resource_type +} + +output "is_resource_type_filter_useful" { + value = length(data.huaweicloud_cts_operations.filter_by_resource_type.operations) >= 1 && alltrue( + [for op in data.huaweicloud_cts_operations.filter_by_resource_type.operations[*] : op.resource_type == local.resource_type] + ) +} +` +} diff --git a/huaweicloud/services/cts/data_source_huaweicloud_cts_operations.go b/huaweicloud/services/cts/data_source_huaweicloud_cts_operations.go new file mode 100644 index 0000000000..7fa449b0f9 --- /dev/null +++ b/huaweicloud/services/cts/data_source_huaweicloud_cts_operations.go @@ -0,0 +1,138 @@ +// Generated by PMS #483 +package cts + +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/tidwall/gjson" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/helper/httphelper" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/helper/schemas" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" +) + +func DataSourceCtsOperations() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceCtsOperationsRead, + + 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.`, + }, + "service_type": { + Type: schema.TypeString, + Optional: true, + Description: `Specifies the type of the cloud service on which operations are performed.`, + }, + "resource_type": { + Type: schema.TypeString, + Optional: true, + Description: `Specifies the type of the resource on which operations are performed.`, + }, + "operations": { + Type: schema.TypeList, + Computed: true, + Description: `All operations on the cloud service.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "service_type": { + Type: schema.TypeString, + Computed: true, + Description: `The type of the cloud service on which operations are performed.`, + }, + "resource_type": { + Type: schema.TypeString, + Computed: true, + Description: `The type of the resource on which operations are performed.`, + }, + "operation_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Description: `The array of operation names.`, + }, + }, + }, + }, + }, + } +} + +type OperationsDSWrapper struct { + *schemas.ResourceDataWrapper + Config *config.Config +} + +func newOperationsDSWrapper(d *schema.ResourceData, meta interface{}) *OperationsDSWrapper { + return &OperationsDSWrapper{ + ResourceDataWrapper: schemas.NewSchemaWrapper(d), + Config: meta.(*config.Config), + } +} + +func dataSourceCtsOperationsRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + wrapper := newOperationsDSWrapper(d, meta) + listOperationsRst, err := wrapper.ListOperations() + if err != nil { + return diag.FromErr(err) + } + + id, err := uuid.GenerateUUID() + if err != nil { + return diag.FromErr(err) + } + d.SetId(id) + + err = wrapper.listOperationsToSchema(listOperationsRst) + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +// @API CTS GET /v3/{project_id}/operations +func (w *OperationsDSWrapper) ListOperations() (*gjson.Result, error) { + client, err := w.NewClient(w.Config, "cts") + if err != nil { + return nil, err + } + + uri := "/v3/{project_id}/operations" + params := map[string]any{ + "service_type": w.Get("service_type"), + "resource_type": w.Get("resource_type"), + } + params = utils.RemoveNil(params) + return httphelper.New(client). + Method("GET"). + URI(uri). + Query(params). + Request(). + Result() +} + +func (w *OperationsDSWrapper) listOperationsToSchema(body *gjson.Result) error { + d := w.ResourceData + mErr := multierror.Append(nil, + d.Set("region", w.Config.GetRegion(w.ResourceData)), + d.Set("operations", schemas.SliceToList(body.Get("operations"), + func(operations gjson.Result) any { + return map[string]any{ + "service_type": operations.Get("service_type").Value(), + "resource_type": operations.Get("resource_type").Value(), + "operation_list": schemas.SliceToStrList(operations.Get("operation_list")), + } + }, + )), + ) + return mErr.ErrorOrNil() +}