diff --git a/docs/data-sources/dws_schema_space_managements.md b/docs/data-sources/dws_schema_space_managements.md new file mode 100644 index 00000000000..2079e6f8220 --- /dev/null +++ b/docs/data-sources/dws_schema_space_managements.md @@ -0,0 +1,69 @@ +--- +subcategory: "GaussDB(DWS)" +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_dws_schema_space_managements" +description: |- + Use this data source to get the list of schema space management information of the DWS Cluster within HuaweiCloud. +--- + +# huaweicloud_dws_schema_space_managements + +Use this data source to get the list of schema space management information of the DWS Cluster within HuaweiCloud. + +## Example Usage + +```hcl +variable "dws_cluster_id" {} +variable "database_name" {} + +data "huaweicloud_dws_schema_space_managements" "test" { + cluster_id = var.dws_cluster_id + database_name = var.database_name +} +``` + +## 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. + +* `cluster_id` - (Required, String) Specifies the DWS cluster ID. + +* `database_name` - (Required, String) Specifies the database name to which the schema space management belongs + +* `schema_name` - (Optional, String) Specifies the name of the schema. Fuzzy search is supported. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The data source ID. + +* `schemas` - All schema space management that match the filter parameters. + + The [schemas](#schemas_struct) structure is documented below. + + +The `schemas` block supports: + +* `database_name` - The database name corresponding to the schema. + +* `schema_name` - The name of the schema. + +* `used` - The number of schema spaces used, in bytes. + +* `space_limit` - The number of available spaces, in bytes. + +* `skew_percent` - The skew rate of the schema. + +* `min_value` - The number of used spaces by the DN with the minimum usage, in bytes. + +* `max_value` - The number of used spaces by the DN with the maximum usage, in bytes. + +* `dn_num` - The number of DNs. + +* `min_dn` - The DN that uses the least space. + +* `max_dn` - The DN that uses the most space. diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index 51c2df56ab2..5d672337b70 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -1024,20 +1024,21 @@ func Provider() *schema.Provider { "huaweicloud_waf_rules_web_tamper_protection": waf.DataSourceWafRulesWebTamperProtection(), "huaweicloud_waf_source_ips": waf.DataSourceWafSourceIps(), - "huaweicloud_dws_alarm_subscriptions": dws.DataSourceAlarmSubscriptions(), - "huaweicloud_dws_availability_zones": dws.DataSourceDwsAvailabilityZones(), - "huaweicloud_dws_cluster_logs": dws.DataSourceDwsClusterLogs(), - "huaweicloud_dws_clusters": dws.DataSourceDwsClusters(), - "huaweicloud_dws_disaster_recovery_tasks": dws.DataSourceDisasterRecoveryTasks(), - "huaweicloud_dws_event_subscriptions": dws.DataSourceEventSubscriptions(), - "huaweicloud_dws_flavors": dws.DataSourceDwsFlavors(), - "huaweicloud_dws_logical_cluster_rings": dws.DataSourceLogicalClusterRings(), - "huaweicloud_dws_logical_clusters": dws.DataSourceDwsLogicalClusters(), - "huaweicloud_dws_quotas": dws.DataSourceDwsQuotas(), - "huaweicloud_dws_snapshot_policies": dws.DataSourceDwsSnapshotPolicies(), - "huaweicloud_dws_snapshots": dws.DataSourceDwsSnapshots(), - "huaweicloud_dws_workload_plans": dws.DataSourceDwsWorkloadPlans(), - "huaweicloud_dws_workload_queues": dws.DataSourceWorkloadQueues(), + "huaweicloud_dws_alarm_subscriptions": dws.DataSourceAlarmSubscriptions(), + "huaweicloud_dws_availability_zones": dws.DataSourceDwsAvailabilityZones(), + "huaweicloud_dws_cluster_logs": dws.DataSourceDwsClusterLogs(), + "huaweicloud_dws_clusters": dws.DataSourceDwsClusters(), + "huaweicloud_dws_disaster_recovery_tasks": dws.DataSourceDisasterRecoveryTasks(), + "huaweicloud_dws_event_subscriptions": dws.DataSourceEventSubscriptions(), + "huaweicloud_dws_flavors": dws.DataSourceDwsFlavors(), + "huaweicloud_dws_logical_cluster_rings": dws.DataSourceLogicalClusterRings(), + "huaweicloud_dws_logical_clusters": dws.DataSourceDwsLogicalClusters(), + "huaweicloud_dws_quotas": dws.DataSourceDwsQuotas(), + "huaweicloud_dws_schema_space_managements": dws.DataSourceDwsSchemaSpaceManagements(), + "huaweicloud_dws_snapshot_policies": dws.DataSourceDwsSnapshotPolicies(), + "huaweicloud_dws_snapshots": dws.DataSourceDwsSnapshots(), + "huaweicloud_dws_workload_plans": dws.DataSourceDwsWorkloadPlans(), + "huaweicloud_dws_workload_queues": dws.DataSourceWorkloadQueues(), "huaweicloud_workspace_desktops": workspace.DataSourceDesktops(), "huaweicloud_workspace_flavors": workspace.DataSourceWorkspaceFlavors(), diff --git a/huaweicloud/services/acceptance/dws/data_source_huaweicloud_dws_schema_space_managements_test.go b/huaweicloud/services/acceptance/dws/data_source_huaweicloud_dws_schema_space_managements_test.go new file mode 100644 index 00000000000..0e2b4bb007b --- /dev/null +++ b/huaweicloud/services/acceptance/dws/data_source_huaweicloud_dws_schema_space_managements_test.go @@ -0,0 +1,116 @@ +package dws + +import ( + "fmt" + "regexp" + "testing" + + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" +) + +func TestAccDataSourceSchemaSpaceManagements_basic(t *testing.T) { + var ( + notFoundDatabase = "data.huaweicloud_dws_schema_space_managements.test" + dcNotFoundDatabase = acceptance.InitDataSourceCheck(notFoundDatabase) + dataSource = "data.huaweicloud_dws_schema_space_managements.test" + dc = acceptance.InitDataSourceCheck(dataSource) + bySchemaName = "data.huaweicloud_dws_schema_space_managements.filter_by_schema_name" + dcBySchemaName = acceptance.InitDataSourceCheck(bySchemaName) + ) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acceptance.TestAccPreCheck(t) + acceptance.TestAccPreCheckDwsClusterId(t) + }, + ProviderFactories: acceptance.TestAccProviderFactories, + Steps: []resource.TestStep{ + { + Config: testDataSourceSchemaSpaceManagements_clusterIdNotExist(), + ExpectError: regexp.MustCompile("Cluster does not exist or has been deleted"), + }, + { + Config: testDataSourceSchemaSpaceManagements_basic(), + Check: resource.ComposeTestCheckFunc( + dc.CheckResourceExists(), + dcNotFoundDatabase.CheckResourceExists(), + resource.TestCheckOutput("not_found_database", "true"), + resource.TestMatchResourceAttr(dataSource, "schemas.#", regexp.MustCompile(`^[1-9]([0-9]*)?$`)), + resource.TestCheckOutput("assert_space_limit", "true"), + dcBySchemaName.CheckResourceExists(), + resource.TestCheckResourceAttr(bySchemaName, "schemas.0.database_name", "gaussdb"), + resource.TestCheckResourceAttrSet(bySchemaName, "schemas.0.schema_name"), + resource.TestCheckResourceAttrSet(bySchemaName, "schemas.0.used"), + resource.TestCheckResourceAttrSet(bySchemaName, "schemas.0.space_limit"), + resource.TestCheckResourceAttrSet(bySchemaName, "schemas.0.skew_percent"), + resource.TestCheckResourceAttrSet(bySchemaName, "schemas.0.dn_num"), + ), + }, + }, + }) +} + +func testDataSourceSchemaSpaceManagements_clusterIdNotExist() string { + clusterId, _ := uuid.GenerateUUID() + return fmt.Sprintf(` +data "huaweicloud_dws_schema_space_managements" "test" { + cluster_id = "%s" + database_name = "gaussdb" +} +`, clusterId) +} + +func testDataSourceSchemaSpaceManagements_basic() string { + return fmt.Sprintf(` +data "huaweicloud_dws_schema_space_managements" "not_found_database" { + cluster_id = "%[1]s" + database_name = "not_found_database" +} + +output "not_found_database" { + value = length(data.huaweicloud_dws_schema_space_managements.not_found_database.schemas) == 0 +} + +data "huaweicloud_dws_schema_space_managements" "test" { + depends_on = [ + huaweicloud_dws_schema_space_management.test + ] + + cluster_id = "%[1]s" + database_name = huaweicloud_dws_schema_space_management.test.database_name +} + +# Modify space quota for scheduler to 2MB (2048 Byte). +resource "huaweicloud_dws_schema_space_management" "test" { + cluster_id = "%[1]s" + database_name = "gaussdb" + schema_name = "scheduler" + space_limit = "2048" +} + +# Filter by schema name. +data "huaweicloud_dws_schema_space_managements" "filter_by_schema_name" { + depends_on = [ + huaweicloud_dws_schema_space_management.test + ] + + cluster_id = "%[1]s" + database_name = huaweicloud_dws_schema_space_management.test.database_name + schema_name = local.schema_name +} + +locals { + schema_name = huaweicloud_dws_schema_space_management.test.schema_name + + # Convert the obtained value from Byte to MB. + space_limit = try([for v in data.huaweicloud_dws_schema_space_managements.filter_by_schema_name.schemas : ceil(v.space_limit / 1024 / 1024) + if v.schema_name == local.schema_name][0], null) +} + +output "assert_space_limit" { + value = local.space_limit == 2 +} +`, acceptance.HW_DWS_CLUSTER_ID) +} diff --git a/huaweicloud/services/dws/data_source_huaweicloud_dws_schema_space_managements.go b/huaweicloud/services/dws/data_source_huaweicloud_dws_schema_space_managements.go new file mode 100644 index 00000000000..3ccb514c4fe --- /dev/null +++ b/huaweicloud/services/dws/data_source_huaweicloud_dws_schema_space_managements.go @@ -0,0 +1,187 @@ +// Generated by PMS #336 +package dws + +import ( + "context" + "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/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 DataSourceDwsSchemaSpaceManagements() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceDwsSchemaSpaceManagementsRead, + + 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.`, + }, + "cluster_id": { + Type: schema.TypeString, + Required: true, + Description: `Specifies the DWS cluster ID.`, + }, + "database_name": { + Type: schema.TypeString, + Required: true, + Description: `Specifies the database name to which the schema space management belongs`, + }, + "schema_name": { + Type: schema.TypeString, + Optional: true, + Description: `Specifies the name of the schema. Fuzzy search is supported.`, + }, + "schemas": { + Type: schema.TypeList, + Computed: true, + Description: `All schema space management that match the filter parameters.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "database_name": { + Type: schema.TypeString, + Computed: true, + Description: `The database name corresponding to the schema.`, + }, + "schema_name": { + Type: schema.TypeString, + Computed: true, + Description: `The name of the schema.`, + }, + "used": { + Type: schema.TypeInt, + Computed: true, + Description: `The number of schema spaces used, in bytes.`, + }, + "space_limit": { + Type: schema.TypeInt, + Computed: true, + Description: `The number of available spaces, in bytes.`, + }, + "skew_percent": { + Type: schema.TypeFloat, + Computed: true, + Description: `The skew rate of the schema.`, + }, + "min_value": { + Type: schema.TypeInt, + Computed: true, + Description: `The number of used spaces by the DN with the minimum usage, in bytes.`, + }, + "max_value": { + Type: schema.TypeInt, + Computed: true, + Description: `The number of used spaces by the DN with the maximum usage, in bytes.`, + }, + "dn_num": { + Type: schema.TypeInt, + Computed: true, + Description: `The number of DNs.`, + }, + "min_dn": { + Type: schema.TypeString, + Computed: true, + Description: `The DN that uses the least space.`, + }, + "max_dn": { + Type: schema.TypeString, + Computed: true, + Description: `The DN that uses the most space.`, + }, + }, + }, + }, + }, + } +} + +type SchemaSpaceManagementsDSWrapper struct { + *schemas.ResourceDataWrapper + Config *config.Config +} + +func newSchemaSpaceManagementsDSWrapper(d *schema.ResourceData, meta interface{}) *SchemaSpaceManagementsDSWrapper { + return &SchemaSpaceManagementsDSWrapper{ + ResourceDataWrapper: schemas.NewSchemaWrapper(d), + Config: meta.(*config.Config), + } +} + +func dataSourceDwsSchemaSpaceManagementsRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + wrapper := newSchemaSpaceManagementsDSWrapper(d, meta) + listSchemasRst, err := wrapper.ListSchemas() + if err != nil { + return diag.FromErr(err) + } + + id, err := uuid.GenerateUUID() + if err != nil { + return diag.FromErr(err) + } + d.SetId(id) + + err = wrapper.listSchemasToSchema(listSchemasRst) + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +// @API DWS GET /v2/{project_id}/clusters/{cluster_id}/databases/{database_name}/schemas +func (w *SchemaSpaceManagementsDSWrapper) ListSchemas() (*gjson.Result, error) { + client, err := w.NewClient(w.Config, "dws") + if err != nil { + return nil, err + } + + uri := "/v2/{project_id}/clusters/{cluster_id}/databases/{database_name}/schemas" + uri = strings.ReplaceAll(uri, "{cluster_id}", w.Get("cluster_id").(string)) + uri = strings.ReplaceAll(uri, "{database_name}", w.Get("database_name").(string)) + params := map[string]any{ + "keywords": w.Get("schema_name"), + } + params = utils.RemoveNil(params) + return httphelper.New(client). + Method("GET"). + URI(uri). + Query(params). + OffsetPager("schemas", "offset", "limit", 100). + Request(). + Result() +} + +func (w *SchemaSpaceManagementsDSWrapper) listSchemasToSchema(body *gjson.Result) error { + d := w.ResourceData + mErr := multierror.Append(nil, + d.Set("region", w.Config.GetRegion(w.ResourceData)), + d.Set("schemas", schemas.SliceToList(body.Get("schemas"), + func(schemas gjson.Result) any { + return map[string]any{ + "database_name": schemas.Get("database_name").Value(), + "schema_name": schemas.Get("schema_name").Value(), + "used": schemas.Get("total_value").Value(), + "space_limit": schemas.Get("perm_space").Value(), + "skew_percent": schemas.Get("skew_percent").Value(), + "min_value": schemas.Get("min_value").Value(), + "max_value": schemas.Get("max_value").Value(), + "dn_num": schemas.Get("dn_num").Value(), + "min_dn": schemas.Get("min_dn").Value(), + "max_dn": schemas.Get("max_dn").Value(), + } + }, + )), + ) + return mErr.ErrorOrNil() +}