From 595b734214e12af369e78000878e52f88050331d Mon Sep 17 00:00:00 2001 From: houpeng80 <114376095+houpeng80@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:40:42 +0800 Subject: [PATCH] feat(GaussDB): add gaussdb opengauss recycling instances data source (#6153) --- .../gaussdb_opengauss_recycling_instances.md | 89 ++++++++ huaweicloud/provider.go | 1 + ...ssdb_opengauss_recycling_instances_test.go | 145 ++++++++++++ ...d_gaussdb_opengauss_recycling_instances.go | 215 ++++++++++++++++++ 4 files changed, 450 insertions(+) create mode 100644 docs/data-sources/gaussdb_opengauss_recycling_instances.md create mode 100644 huaweicloud/services/acceptance/gaussdb/data_source_huaweicloud_gaussdb_opengauss_recycling_instances_test.go create mode 100644 huaweicloud/services/gaussdb/data_source_huaweicloud_gaussdb_opengauss_recycling_instances.go diff --git a/docs/data-sources/gaussdb_opengauss_recycling_instances.md b/docs/data-sources/gaussdb_opengauss_recycling_instances.md new file mode 100644 index 0000000000..c8c06ac80a --- /dev/null +++ b/docs/data-sources/gaussdb_opengauss_recycling_instances.md @@ -0,0 +1,89 @@ +--- +subcategory: "GaussDB" +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_gaussdb_opengauss_recycling_instances" +description: |- + Use this data source to get the list of GaussDB OpenGauss instances in the recycle bin. +--- + +# huaweicloud_gaussdb_opengauss_recycling_instances + +Use this data source to get the list of GaussDB OpenGauss instances in the recycle bin. + +## Example Usage + +```hcl +data "huaweicloud_gaussdb_opengauss_recycling_instances" "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. + +* `instance_name` - (Optional, String) Specifies the GaussDB OpenGauss instance name. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The data source ID. + +* `instances` - Indicates the information about all instances in the recycle bin. + + The [instances](#instances_struct) structure is documented below. + + +The `instances` block supports: + +* `id` - Indicates the instance ID. + +* `name` - Indicates the instance name. + +* `mode` - Indicates the product type. + The value can be: + + **basic**: basic edition + + **standard**: standard edition + + **enterprise**: enterprise edition + +* `ha_mode` - Indicates the deployment model. + The value can be: + + **Ha**: primary/standby deployment + + **Independent**: independent deployment + + **Combined**: combined deployment + +* `engine_name` - Indicates the engine name. + +* `engine_version` - Indicates the engine version. + +* `pay_model` - Indicates the billing mode. + The value can be: + + **0**: pay-per-use + + **1**: yearly/monthly + +* `volume_type` - Indicates the disk type. + The value can be: + + **high**: high I/O + + **ultrahigh**: ultra-high I/O + + **essd**: extreme SSD + +* `volume_size` - Indicates the disk size. + +* `enterprise_project_id` - Indicates the enterprise project ID. + +* `enterprise_project_name` - Indicates the enterprise project name. + +* `recycle_backup_id` - Indicates the backup ID. + +* `backup_level` - Indicates the backup level. + +* `data_vip` - Indicates the private IP address. + +* `recycle_status` - Indicates the backup status in the recycle bin. + The value can be: **Running**, **Active**. + +* `created_at` - Indicates the creation time in the **yyyy-mm-ddThh:mm:ssZ** format. + +* `deleted_at` - Indicates the deletion time in the **yyyy-mm-ddThh:mm:ssZ** format. diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index cd358b1653..1c481e093c 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -834,6 +834,7 @@ func Provider() *schema.Provider { "huaweicloud_gaussdb_opengauss_restore_time_ranges": gaussdb.DataSourceGaussdbOpengaussRestoreTimeRanges(), "huaweicloud_gaussdb_opengauss_restorable_instances": gaussdb.DataSourceGaussdbOpengaussRestorableInstances(), "huaweicloud_gaussdb_opengauss_backups": gaussdb.DataSourceGaussdbOpengaussBackups(), + "huaweicloud_gaussdb_opengauss_recycling_instances": gaussdb.DataSourceGaussdbOpengaussRecyclingInstances(), "huaweicloud_gaussdb_mysql_engine_versions": taurusdb.DataSourceGaussdbMysqlEngineVersions(), "huaweicloud_gaussdb_mysql_configuration": taurusdb.DataSourceGaussdbMysqlConfiguration(), diff --git a/huaweicloud/services/acceptance/gaussdb/data_source_huaweicloud_gaussdb_opengauss_recycling_instances_test.go b/huaweicloud/services/acceptance/gaussdb/data_source_huaweicloud_gaussdb_opengauss_recycling_instances_test.go new file mode 100644 index 0000000000..ed1f216ee7 --- /dev/null +++ b/huaweicloud/services/acceptance/gaussdb/data_source_huaweicloud_gaussdb_opengauss_recycling_instances_test.go @@ -0,0 +1,145 @@ +package gaussdb + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance/common" +) + +func TestAccDataSourceGaussdbOpengaussRecyclingInstances_basic(t *testing.T) { + dataSource := "data.huaweicloud_gaussdb_opengauss_recycling_instances.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: testDataSourceGaussdbOpengaussRecyclingInstances_create_instance(rName), + }, + { + Config: testDataSourceGaussdbOpengaussRecyclingInstances_delete_instance(), + }, + { + Config: testDataSourceGaussdbOpengaussRecyclingInstances_basic(rName), + Check: resource.ComposeTestCheckFunc( + dc.CheckResourceExists(), + resource.TestCheckResourceAttrSet(dataSource, "instances.#"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.id"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.name"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.mode"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.ha_mode"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.engine_name"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.engine_version"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.pay_model"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.volume_type"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.enterprise_project_id"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.enterprise_project_name"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.recycle_backup_id"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.data_vip"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.recycle_status"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.created_at"), + resource.TestCheckResourceAttrSet(dataSource, "instances.0.deleted_at"), + resource.TestCheckOutput("instance_name_filter_is_useful", "true"), + ), + }, + }, + }) +} + +func testDataSourceGaussdbOpengaussRecyclingInstances_create_instance(rName string) string { + return fmt.Sprintf(` +%[1]s + +data "huaweicloud_availability_zones" "test" {} + +data "huaweicloud_gaussdb_opengauss_flavors" "test" { + version = "8.201" + ha_mode = "centralization_standard" +} + +resource "huaweicloud_networking_secgroup_rule" "in_v4_tcp_opengauss" { + security_group_id = huaweicloud_networking_secgroup.test.id + ethertype = "IPv4" + direction = "ingress" + protocol = "tcp" + remote_ip_prefix = "0.0.0.0/0" +} + +resource "huaweicloud_networking_secgroup_rule" "in_v4_tcp_opengauss_egress" { + security_group_id = huaweicloud_networking_secgroup.test.id + ethertype = "IPv4" + direction = "egress" + protocol = "tcp" + remote_ip_prefix = "0.0.0.0/0" +} + +resource "huaweicloud_gaussdb_opengauss_instance" "test" { + depends_on = [ + huaweicloud_networking_secgroup_rule.in_v4_tcp_opengauss, + huaweicloud_networking_secgroup_rule.in_v4_tcp_opengauss_egress + ] + + vpc_id = huaweicloud_vpc.test.id + subnet_id = huaweicloud_vpc_subnet.test.id + security_group_id = huaweicloud_networking_secgroup.test.id + + flavor = data.huaweicloud_gaussdb_opengauss_flavors.test.flavors[0].spec_code + name = "%[2]s" + password = "Huangwei!120521" + replica_num = 3 + availability_zone = join(",", [data.huaweicloud_availability_zones.test.names[0], + data.huaweicloud_availability_zones.test.names[1], + data.huaweicloud_availability_zones.test.names[2]]) + + enterprise_project_id = "%[3]s" + + ha { + mode = "centralization_standard" + replication_mode = "sync" + consistency = "eventual" + instance_mode = "basic" + } + + volume { + type = "ULTRAHIGH" + size = 40 + } +} +`, common.TestBaseNetwork(rName), rName, acceptance.HW_ENTERPRISE_PROJECT_ID_TEST) +} + +func testDataSourceGaussdbOpengaussRecyclingInstances_delete_instance() string { + return ` +data "huaweicloud_availability_zones" "test" {} + +data "huaweicloud_gaussdb_opengauss_flavors" "test" { + version = "8.201" + ha_mode = "centralization_standard" +}` +} + +func testDataSourceGaussdbOpengaussRecyclingInstances_basic(rName string) string { + return fmt.Sprintf(` +data "huaweicloud_gaussdb_opengauss_recycling_instances" "test" {} + +locals { + instance_name = "%[1]s" +} +data "huaweicloud_gaussdb_opengauss_recycling_instances" "instance_name_filter" { + instance_name = "%[1]s" +} +output "instance_name_filter_is_useful" { + value = length(data.huaweicloud_gaussdb_opengauss_recycling_instances.instance_name_filter.instances) > 0 && alltrue( + [for v in data.huaweicloud_gaussdb_opengauss_recycling_instances.instance_name_filter.instances[*] : v.name == local.instance_name] + ) +} +`, rName) +} diff --git a/huaweicloud/services/gaussdb/data_source_huaweicloud_gaussdb_opengauss_recycling_instances.go b/huaweicloud/services/gaussdb/data_source_huaweicloud_gaussdb_opengauss_recycling_instances.go new file mode 100644 index 0000000000..d52f609bdd --- /dev/null +++ b/huaweicloud/services/gaussdb/data_source_huaweicloud_gaussdb_opengauss_recycling_instances.go @@ -0,0 +1,215 @@ +// Generated by PMS #513 +package gaussdb + +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 DataSourceGaussdbOpengaussRecyclingInstances() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceGaussdbOpengaussRecyclingInstancesRead, + + 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.`, + }, + "instance_name": { + Type: schema.TypeString, + Optional: true, + Description: `Specifies the GaussDB OpenGauss instance name.`, + }, + "instances": { + Type: schema.TypeList, + Computed: true, + Description: `Indicates the information about all instances in the recycle bin.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the instance ID.`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the instance name.`, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the product type.`, + }, + "ha_mode": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the deployment model.`, + }, + "engine_name": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the engine name.`, + }, + "engine_version": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the engine version.`, + }, + "pay_model": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the billing mode.`, + }, + "volume_type": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the disk type.`, + }, + "volume_size": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the disk size.`, + }, + "enterprise_project_id": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the enterprise project ID.`, + }, + "enterprise_project_name": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the enterprise project name.`, + }, + "recycle_backup_id": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the backup ID.`, + }, + "backup_level": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the backup level.`, + }, + "data_vip": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the private IP address.`, + }, + "recycle_status": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the backup status in the recycle bin.`, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the creation time in the **yyyy-mm-ddThh:mm:ssZ** format.`, + }, + "deleted_at": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the deletion time in the **yyyy-mm-ddThh:mm:ssZ** format.`, + }, + }, + }, + }, + }, + } +} + +type OpengaussRecyclingInstancesDSWrapper struct { + *schemas.ResourceDataWrapper + Config *config.Config +} + +func newOpengaussRecyclingInstancesDSWrapper(d *schema.ResourceData, meta interface{}) *OpengaussRecyclingInstancesDSWrapper { + return &OpengaussRecyclingInstancesDSWrapper{ + ResourceDataWrapper: schemas.NewSchemaWrapper(d), + Config: meta.(*config.Config), + } +} + +func dataSourceGaussdbOpengaussRecyclingInstancesRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + wrapper := newOpengaussRecyclingInstancesDSWrapper(d, meta) + lisRecInsDetRst, err := wrapper.ListRecycleInstancesDetails() + if err != nil { + return diag.FromErr(err) + } + + id, err := uuid.GenerateUUID() + if err != nil { + return diag.FromErr(err) + } + d.SetId(id) + + err = wrapper.listRecycleInstancesDetailsToSchema(lisRecInsDetRst) + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +// @API GaussDB GET /v3.1/{project_id}/recycle-instances +func (w *OpengaussRecyclingInstancesDSWrapper) ListRecycleInstancesDetails() (*gjson.Result, error) { + client, err := w.NewClient(w.Config, "opengauss") + if err != nil { + return nil, err + } + + uri := "/v3.1/{project_id}/recycle-instances" + params := map[string]any{ + "instance_name": w.Get("instance_name"), + } + params = utils.RemoveNil(params) + return httphelper.New(client). + Method("GET"). + URI(uri). + Query(params). + Request(). + Result() +} + +func (w *OpengaussRecyclingInstancesDSWrapper) listRecycleInstancesDetailsToSchema(body *gjson.Result) error { + d := w.ResourceData + mErr := multierror.Append(nil, + d.Set("region", w.Config.GetRegion(w.ResourceData)), + d.Set("instances", schemas.SliceToList(body.Get("instances"), + func(instances gjson.Result) any { + return map[string]any{ + "id": instances.Get("id").Value(), + "name": instances.Get("name").Value(), + "mode": instances.Get("mode").Value(), + "ha_mode": instances.Get("ha_mode").Value(), + "engine_name": instances.Get("engine_name").Value(), + "engine_version": instances.Get("engine_version").Value(), + "pay_model": instances.Get("pay_model").Value(), + "volume_type": instances.Get("volume_type").Value(), + "volume_size": instances.Get("volume_size").Value(), + "enterprise_project_id": instances.Get("enterprise_project_id").Value(), + "enterprise_project_name": instances.Get("enterprise_project_name").Value(), + "recycle_backup_id": instances.Get("recycle_backup_id").Value(), + "backup_level": instances.Get("backup_level").Value(), + "data_vip": instances.Get("data_vip").Value(), + "recycle_status": instances.Get("recycle_status").Value(), + "created_at": instances.Get("created_at").Value(), + "deleted_at": instances.Get("deleted_at").Value(), + } + }, + )), + ) + return mErr.ErrorOrNil() +}