diff --git a/docs/data-sources/gaussdb_mysql_proxies.md b/docs/data-sources/gaussdb_mysql_proxies.md new file mode 100644 index 0000000000..bd4d81ba56 --- /dev/null +++ b/docs/data-sources/gaussdb_mysql_proxies.md @@ -0,0 +1,132 @@ +--- +subcategory: "GaussDB(for MySQL)" +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_gaussdb_mysql_proxies" +description: |- + Use this data source to get the list of GaussDB MySQL proxies. +--- + +# huaweicloud_gaussdb_mysql_proxies + +Use this data source to get the list of GaussDB MySQL proxies. + +## Example Usage + +```hcl +variable "instance_id" {} + +data "huaweicloud_gaussdb_mysql_proxies" "test" { + instance_id = var.instance_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. + +* `instance_id` - (Required, String) Specifies the ID of the GaussDB MySQL instance. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The data source ID. + +* `proxy_list` - Indicates the list of proxies. + + The [proxy_list](#proxy_list_struct) structure is documented below. + + +The `proxy_list` block supports: + +* `id` - Indicates the proxy ID. + +* `name` - Indicates the proxy name. + +* `flavor` - Indicates the flavor of the proxy. + +* `port` - Indicates the proxy port. + +* `status` - Indicates the status of the proxy instance. + +* `delay_threshold_in_seconds` - Indicates the delay threshold in seconds. + +* `node_num` - Indicates the number of proxy nodes. + +* `ram` - Indicates the memory size of the proxy. + +* `connection_pool_type` - Indicates the connection pool type. + +* `switch_connection_pool_type_enabled` - Indicates whether the proxy version supports session-level connection pool. + +* `mode` - Indicates the proxy mode. + +* `elb_vip` - Indicates the virtual IP address in ELB mode. + +* `vcpus` - Indicates the number of vCPUs of the proxy. + +* `transaction_split` - Indicates whether the proxy transaction splitting is enabled. + +* `balance_route_mode_enabled` - Indicates whether the proxy version supports load balancing. + +* `route_mode` - Indicates the routing policy of the proxy instance. + +* `subnet_id` - Indicates the network ID of a subnet. + +* `consistence_mode` - Indicates the consistency mode of the proxy. + +* `ssl_option` - Indicates whether to enable or disable SSL. + +* `new_node_auto_add_status` - Indicates whether new nodes are automatically associate with proxy. + +* `new_node_weight` - Indicates the read weight of the new node. + +* `address` - Indicates the address of the proxy. + +* `nodes` - Indicates the node information of the proxy. + + The [nodes](#proxy_nodes_struct) structure is documented below. + +* `master_node_weight` - Indicates the read weight of the master node. + + The [master_node_weight](#proxy_list_master_node_weight_struct) structure is documented below. + +* `readonly_nodes_weight` - Indicates the read weight of the read-only node. + + The [readonly_nodes_weight](#proxy_list_readonly_nodes_weight_struct) structure is documented below. + + +The `nodes` block supports: + +* `id` - Indicates the proxy node ID. + +* `name` - Indicates the proxy node name. + +* `role` - Indicates the proxy node role. + +* `az_code` - Indicates the proxy node AZ. + +* `status` - Indicates the proxy node status. + +* `frozen_flag` - Indicates whether the proxy node is frozen. + + +The `master_node_weight` block supports: + +* `id` - Indicates the node ID. + +* `name` - Indicates the node name. + +* `weight` - Indicates the weight assigned to the node. + + +The `readonly_nodes_weight` block supports: + +* `id` - Indicates the node ID. + +* `name` - Indicates the node name. + +* `weight` - Indicates the weight assigned to the node. diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index e08305a18f..581507ac8d 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -691,6 +691,7 @@ func Provider() *schema.Provider { "huaweicloud_gaussdb_mysql_restore_time_ranges": gaussdb.DataSourceGaussdbMysqlRestoreTimeRanges(), "huaweicloud_gaussdb_mysql_databases": gaussdb.DataSourceGaussdbMysqlDatabases(), "huaweicloud_gaussdb_mysql_proxy_flavors": gaussdb.DataSourceGaussdbMysqlProxyFlavors(), + "huaweicloud_gaussdb_mysql_proxies": gaussdb.DataSourceGaussdbMysqlProxies(), "huaweicloud_hss_ransomware_protection_policies": hss.DataSourceRansomwareProtectionPolicies(), "huaweicloud_hss_host_groups": hss.DataSourceHostGroups(), diff --git a/huaweicloud/services/acceptance/gaussdb/data_source_huaweicloud_gaussdb_mysql_proxies_test.go b/huaweicloud/services/acceptance/gaussdb/data_source_huaweicloud_gaussdb_mysql_proxies_test.go new file mode 100644 index 0000000000..1683c7c23c --- /dev/null +++ b/huaweicloud/services/acceptance/gaussdb/data_source_huaweicloud_gaussdb_mysql_proxies_test.go @@ -0,0 +1,137 @@ +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 TestAccDataSourceGaussdbMysqlProxies_basic(t *testing.T) { + dataSource := "data.huaweicloud_gaussdb_mysql_proxies.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: testDataSourceDataSourceGaussdbMysqlProxies_basic(rName), + Check: resource.ComposeTestCheckFunc( + dc.CheckResourceExists(), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.#"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.id"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.name"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.flavor"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.port"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.status"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.delay_threshold_in_seconds"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.node_num"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.ram"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.connection_pool_type"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.switch_connection_pool_type_enabled"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.mode"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.elb_vip"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.vcpus"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.transaction_split"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.balance_route_mode_enabled"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.route_mode"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.subnet_id"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.consistence_mode"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.ssl_option"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.new_node_auto_add_status"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.new_node_weight"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.address"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.master_node_weight.#"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.master_node_weight.0.id"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.master_node_weight.0.name"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.master_node_weight.0.weight"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.readonly_nodes_weight.#"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.readonly_nodes_weight.0.id"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.readonly_nodes_weight.0.name"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.readonly_nodes_weight.0.weight"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.nodes.#"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.nodes.0.id"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.nodes.0.name"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.nodes.0.role"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.nodes.0.az_code"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.nodes.0.status"), + resource.TestCheckResourceAttrSet(dataSource, "proxy_list.0.nodes.0.frozen_flag"), + ), + }, + }, + }) +} + +func testDataSourceDataSourceGaussdbMysqlProxies_base(name string) string { + return fmt.Sprintf(` +%s + +data "huaweicloud_availability_zones" "test" {} + +data "huaweicloud_gaussdb_mysql_flavors" "test" { + engine = "gaussdb-mysql" + version = "8.0" + availability_zone_mode = "multi" +} + +resource "huaweicloud_gaussdb_mysql_instance" "test" { + name = "%s" + password = "Test@12345678" + flavor = data.huaweicloud_gaussdb_mysql_flavors.test.flavors[0].name + vpc_id = huaweicloud_vpc.test.id + subnet_id = huaweicloud_vpc_subnet.test.id + security_group_id = huaweicloud_networking_secgroup.test.id + enterprise_project_id = "0" + master_availability_zone = data.huaweicloud_availability_zones.test.names[0] + availability_zone_mode = "multi" + read_replicas = 4 +} + +data "huaweicloud_gaussdb_mysql_proxy_flavors" "test" { + instance_id = huaweicloud_gaussdb_mysql_instance.test.id +} + +locals{ + sort_nodes = tolist(values({ for node in huaweicloud_gaussdb_mysql_instance.test.nodes : node.name => node })) +} + +resource "huaweicloud_gaussdb_mysql_proxy" "test" { + instance_id = huaweicloud_gaussdb_mysql_instance.test.id + flavor = data.huaweicloud_gaussdb_mysql_proxy_flavors.test.flavor_groups[0].flavors[0].spec_code + node_num = 2 + proxy_name = "%[2]s" + proxy_mode = "readwrite" + route_mode = 1 + subnet_id = huaweicloud_vpc_subnet.test.id + + master_node_weight { + id = local.sort_nodes[0].id + weight = 20 + } + + readonly_nodes_weight { + id = local.sort_nodes[1].id + weight = 30 + } +} +`, common.TestBaseNetwork(name), name) +} + +func testDataSourceDataSourceGaussdbMysqlProxies_basic(name string) string { + return fmt.Sprintf(` +%s + +data "huaweicloud_gaussdb_mysql_proxies" "test" { + depends_on = [huaweicloud_gaussdb_mysql_proxy.test] + + instance_id = huaweicloud_gaussdb_mysql_instance.test.id +} +`, testDataSourceDataSourceGaussdbMysqlProxies_base(name)) +} diff --git a/huaweicloud/services/gaussdb/data_source_huaweicloud_gaussdb_mysql_proxies.go b/huaweicloud/services/gaussdb/data_source_huaweicloud_gaussdb_mysql_proxies.go new file mode 100644 index 0000000000..dca1fc9806 --- /dev/null +++ b/huaweicloud/services/gaussdb/data_source_huaweicloud_gaussdb_mysql_proxies.go @@ -0,0 +1,375 @@ +// Generated by PMS #257 +package gaussdb + +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" +) + +func DataSourceGaussdbMysqlProxies() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceGaussdbMysqlProxiesRead, + + 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_id": { + Type: schema.TypeString, + Required: true, + Description: `Specifies the ID of the GaussDB MySQL instance.`, + }, + "proxy_list": { + Type: schema.TypeList, + Computed: true, + Description: `Indicates the list of proxies.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the proxy ID.`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the proxy name.`, + }, + "flavor": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the flavor of the proxy.`, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + Description: `Indicates the proxy port.`, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the status of the proxy instance.`, + }, + "delay_threshold_in_seconds": { + Type: schema.TypeInt, + Computed: true, + Description: `Indicates the delay threshold in seconds.`, + }, + "node_num": { + Type: schema.TypeInt, + Computed: true, + Description: `Indicates the number of proxy nodes.`, + }, + "ram": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the memory size of the proxy.`, + }, + "connection_pool_type": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the connection pool type.`, + }, + "switch_connection_pool_type_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: `Indicates whether the proxy version supports session-level connection pool.`, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the proxy mode.`, + }, + "elb_vip": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the virtual IP address in ELB mode.`, + }, + "vcpus": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the number of vCPUs of the proxy.`, + }, + "transaction_split": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates whether the proxy transaction splitting is enabled.`, + }, + "balance_route_mode_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: `Indicates whether the proxy version supports load balancing.`, + }, + "route_mode": { + Type: schema.TypeInt, + Computed: true, + Description: `Indicates the routing policy of the proxy instance.`, + }, + "subnet_id": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the network ID of a subnet.`, + }, + "consistence_mode": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the consistency mode of the proxy.`, + }, + "ssl_option": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates whether to enable or disable SSL.`, + }, + "new_node_auto_add_status": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates whether new nodes are automatically associate with proxy.`, + }, + "new_node_weight": { + Type: schema.TypeInt, + Computed: true, + Description: `Indicates the read weight of the new node.`, + }, + "address": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the address of the proxy.`, + }, + "nodes": { + Type: schema.TypeList, + Computed: true, + Description: `Indicates the node information of the proxy.`, + Elem: nodesElem(), + }, + "master_node_weight": { + Type: schema.TypeList, + Computed: true, + Description: `Indicates the read weight of the master node.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the node ID.`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the node name.`, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + Description: `Indicates the weight assigned to the node.`, + }, + }, + }, + }, + "readonly_nodes_weight": { + Type: schema.TypeList, + Computed: true, + Description: `Indicates the read weight of the read-only node.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the node ID.`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the node name.`, + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + Description: `Indicates the weight assigned to the node.`, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +// nodesElem +// The Elem of "nodes" +func nodesElem() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the proxy node ID.`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the proxy node name.`, + }, + "role": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the proxy node role.`, + }, + "az_code": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the proxy node AZ.`, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: `Indicates the proxy node status.`, + }, + "frozen_flag": { + Type: schema.TypeInt, + Computed: true, + Description: `Indicates whether the proxy node is frozen.`, + }, + }, + } +} + +type MysqlProxiesDSWrapper struct { + *schemas.ResourceDataWrapper + Config *config.Config +} + +func newMysqlProxiesDSWrapper(d *schema.ResourceData, meta interface{}) *MysqlProxiesDSWrapper { + return &MysqlProxiesDSWrapper{ + ResourceDataWrapper: schemas.NewSchemaWrapper(d), + Config: meta.(*config.Config), + } +} + +func dataSourceGaussdbMysqlProxiesRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + wrapper := newMysqlProxiesDSWrapper(d, meta) + shoGauMySqlProLisRst, err := wrapper.ShowGaussMySqlProxyList() + if err != nil { + return diag.FromErr(err) + } + + id, err := uuid.GenerateUUID() + if err != nil { + return diag.FromErr(err) + } + d.SetId(id) + + err = wrapper.showGaussMySqlProxyListToSchema(shoGauMySqlProLisRst) + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +// @API GaussDBforMySQL GET /v3/{project_id}/instances/{instance_id}/proxies +func (w *MysqlProxiesDSWrapper) ShowGaussMySqlProxyList() (*gjson.Result, error) { + client, err := w.NewClient(w.Config, "gaussdb") + if err != nil { + return nil, err + } + + uri := "/v3/{project_id}/instances/{instance_id}/proxies" + uri = strings.ReplaceAll(uri, "{instance_id}", w.Get("instance_id").(string)) + return httphelper.New(client). + Method("GET"). + URI(uri). + OffsetPager("proxy_list", "offset", "limit", 0). + Request(). + Result() +} + +func (w *MysqlProxiesDSWrapper) showGaussMySqlProxyListToSchema(body *gjson.Result) error { + d := w.ResourceData + mErr := multierror.Append(nil, + d.Set("region", w.Config.GetRegion(w.ResourceData)), + d.Set("proxy_list", schemas.SliceToList(body.Get("proxy_list"), + func(proxyList gjson.Result) any { + return map[string]any{ + "id": proxyList.Get("proxy.pool_id").Value(), + "name": proxyList.Get("proxy.name").Value(), + "flavor": proxyList.Get("proxy.flavor_ref").Value(), + "port": proxyList.Get("proxy.port").Value(), + "status": proxyList.Get("proxy.status").Value(), + "delay_threshold_in_seconds": proxyList.Get("proxy.delay_threshold_in_seconds").Value(), + "node_num": proxyList.Get("proxy.node_num").Value(), + "ram": proxyList.Get("proxy.ram").Value(), + "connection_pool_type": proxyList.Get("proxy.connection_pool_type").Value(), + "switch_connection_pool_type_enabled": proxyList.Get("proxy.switch_connection_pool_type_enabled").Value(), + "mode": proxyList.Get("proxy.mode").Value(), + "elb_vip": proxyList.Get("proxy.elb_vip").Value(), + "vcpus": proxyList.Get("proxy.vcpus").Value(), + "transaction_split": w.setProLisProTraSplit(proxyList), + "balance_route_mode_enabled": proxyList.Get("proxy.balance_route_mode_enabled").Value(), + "route_mode": proxyList.Get("proxy.route_mode").Value(), + "subnet_id": proxyList.Get("proxy.subnet_id").Value(), + "consistence_mode": proxyList.Get("proxy.consistence_mode").Value(), + "ssl_option": proxyList.Get("proxy.ssl_option").Value(), + "new_node_auto_add_status": proxyList.Get("proxy.new_node_auto_add_status").Value(), + "new_node_weight": proxyList.Get("proxy.new_node_weight").Value(), + "address": proxyList.Get("proxy.address").Value(), + "nodes": w.setProxyListProxyNodes(proxyList), + "master_node_weight": schemas.SliceToList(proxyList.Get("master_node"), + func(masterNodeWeight gjson.Result) any { + return map[string]any{ + "id": masterNodeWeight.Get("id").Value(), + "name": masterNodeWeight.Get("name").Value(), + "weight": masterNodeWeight.Get("weight").Value(), + } + }, + ), + "readonly_nodes_weight": schemas.SliceToList(proxyList.Get("readonly_nodes"), + func(readonlyNodesWeight gjson.Result) any { + return map[string]any{ + "id": readonlyNodesWeight.Get("id").Value(), + "name": readonlyNodesWeight.Get("name").Value(), + "weight": readonlyNodesWeight.Get("weight").Value(), + } + }, + ), + } + }, + )), + ) + return mErr.ErrorOrNil() +} + +func (*MysqlProxiesDSWrapper) setProLisProTraSplit(data gjson.Result) string { + transactionSplit := data.Get("transaction_split").String() + if transactionSplit == "true" { + return "ON" + } + return "OFF" +} + +func (*MysqlProxiesDSWrapper) setProxyListProxyNodes(proxyList gjson.Result) any { + return schemas.SliceToList(proxyList.Get("proxy.nodes"), func(nodes gjson.Result) any { + return map[string]any{ + "id": nodes.Get("id").Value(), + "name": nodes.Get("name").Value(), + "role": nodes.Get("role").Value(), + "az_code": nodes.Get("az_code").Value(), + "status": nodes.Get("status").Value(), + "frozen_flag": nodes.Get("frozen_flag").Value(), + } + }) +}