From 53b2c6fed47dc946805ecb4b3fbac2aea3c37da5 Mon Sep 17 00:00:00 2001 From: Zippo-Wang <852420284@qq.com> Date: Mon, 8 Jan 2024 10:07:50 +0800 Subject: [PATCH] WIP(ELB): Synchronized ELB resources and data sources. --- docs/data-sources/lb_loadbalancer_v2.md | 25 +- docs/resources/lb_member_v2.md | 49 ++-- docs/resources/lb_monitor_v2.md | 98 +++++-- docs/resources/lb_whitelist_v2.md | 36 ++- ..._flexibleengine_lb_loadbalancer_v2_test.go | 95 +++++++ ...source_flexibleengine_lb_member_v2_test.go | 230 ++++++++++++++++ ...ource_flexibleengine_lb_monitor_v2_test.go | 250 ++++++++++++++++++ ...rce_flexibleengine_lb_whitelist_v2_test.go | 130 +++++++++ flexibleengine/provider.go | 13 +- 9 files changed, 849 insertions(+), 77 deletions(-) create mode 100644 flexibleengine/acceptance/data_source_flexibleengine_lb_loadbalancer_v2_test.go create mode 100644 flexibleengine/acceptance/resource_flexibleengine_lb_member_v2_test.go create mode 100644 flexibleengine/acceptance/resource_flexibleengine_lb_monitor_v2_test.go create mode 100644 flexibleengine/acceptance/resource_flexibleengine_lb_whitelist_v2_test.go diff --git a/docs/data-sources/lb_loadbalancer_v2.md b/docs/data-sources/lb_loadbalancer_v2.md index e08382caa..56d3907f2 100644 --- a/docs/data-sources/lb_loadbalancer_v2.md +++ b/docs/data-sources/lb_loadbalancer_v2.md @@ -2,41 +2,46 @@ subcategory: "Elastic Load Balance (ELB)" --- -# flexibleengine_lb_loadbalancer_v2 +# flexibleengine_lb_loadbalancer -Use this data source to get a specific elb loadbalancer within FlexibleEngine. +Use this data source to get available FlexibleEngine elb load balancer. ## Example Usage ```hcl variable "lb_name" {} -data "flexibleengine_lb_loadbalancer_v2" "test" { +data "flexibleengine_lb_loadbalancer" "test" { name = var.lb_name } ``` ## Argument Reference -* `region` - (Optional, String) The region in which to query the data source. If omitted, the provider-level region - will be used. +* `region` - (Optional, String) Specifies the region in which to obtain the load balancer. If omitted, the + provider-level region will be used. * `name` - (Optional, String) Specifies the name of the load balancer. * `id` - (Optional, String) Specifies the data source ID of the load balancer in UUID format. -* `description` - (Optional, String) Specifies the supplementary information about the load balancer. +* `status` - (Optional, String) Specifies the operating status of the load balancer. Valid values are *ONLINE* and + *FROZEN*. -* `vip_subnet_id` - (Optional, String) Specifies the ID of the subnet where the load balancer works. +* `description` - (Optional, String) Specifies the supplementary information about the load balancer. * `vip_address` - (Optional, String) Specifies the private IP address of the load balancer. +* `vip_subnet_id` - (Optional, String) Specifies the **IPv4 subnet ID** of the subnet where the load balancer works. + +* `enterprise_project_id` - (Optional, String) Specifies the enterprise project id of the load balancer. + ## Attribute Reference In addition to all arguments above, the following attributes are exported: -* `vip_port_id` - The ID of the port bound to the private IP address of the load balancer. +* `tags` - The tags associated with the load balancer. -* `status` - The operating status of the load balancer. +* `vip_port_id` - The ID of the port bound to the private IP address of the load balancer. -* `tags` - The tags associated with the load balancer. +* `public_ip` - The EIP address that is associated to the Load Balancer instance. diff --git a/docs/resources/lb_member_v2.md b/docs/resources/lb_member_v2.md index 1cc77f807..9bd0d38c5 100644 --- a/docs/resources/lb_member_v2.md +++ b/docs/resources/lb_member_v2.md @@ -1,21 +1,22 @@ --- subcategory: "Elastic Load Balance (ELB)" -description: "" -page_title: "flexibleengine_lb_member_v2" --- -# flexibleengine_lb_member_v2 +# flexibleengine_lb_member -Manages an **enhanced** load balancer member resource within FlexibleEngine. +Manages an ELB member resource within FlexibleEngine. ## Example Usage ```hcl -resource "flexibleengine_lb_member_v2" "example_member" { +variable "lb_pool_id" {} +variable "ipv4_subnet_id" {} + +resource "flexibleengine_lb_member" "member_1" { address = "192.168.199.23" protocol_port = 8080 - pool_id = flexibleengine_lb_pool_v2.example_pool.id - subnet_id = flexibleengine_vpc_subnet_v1.example_subnet.ipv4_subnet_id + pool_id = var.lb_pool_id + subnet_id = var.ipv4_subnet_id } ``` @@ -23,28 +24,24 @@ resource "flexibleengine_lb_member_v2" "example_member" { The following arguments are supported: -* `region` - (Optional, String, ForceNew) The region in which to obtain the V2 Networking client. - A Networking client is needed to be created. If omitted, the `region` argument of the provider is used. - Changing this creates a new member. +* `region` - (Optional, String, ForceNew) The region in which to create the ELB member resource. If omitted, the the + provider-level region will be used. Changing this creates a new member. -* `pool_id` - (Required, String, ForceNew) The id of the pool that this member will be - assigned to. Changing this creates a new member. +* `pool_id` - (Required, String, ForceNew) The id of the pool that this member will be assigned to. -* `subnet_id` - (Required, String, ForceNew) The `ipv4_subnet_id` or `ipv6_subnet_id` of the - VPC Subnet in which to access the member. Changing this creates a new member. +* `subnet_id` - (Required, String, ForceNew) The **IPv4 subnet ID** of the subnet in which to access the member. -* `address` - (Required, String, ForceNew) The IP address of the member to receive traffic from - the load balancer. Changing this creates a new member. +* `name` - (Optional, String) Human-readable name for the member. -* `protocol_port` - (Required, Int, ForceNew) The port on which to listen for client traffic. +* `address` - (Required, String, ForceNew) The IP address of the member to receive traffic from the load balancer. Changing this creates a new member. -* `name` - (Optional, String) Human-readable name for the member. +* `protocol_port` - (Required, Int, ForceNew) The port on which to listen for client traffic. Changing this creates a + new member. -* `weight` - (Optional, Int) A positive integer value that indicates the relative - portion of traffic that this member should receive from the pool. For - example, a member with a weight of 10 receives five times as much traffic - as a member with a weight of 2. +* `weight` - (Optional, Int) A positive integer value that indicates the relative portion of traffic that this member + should receive from the pool. For example, a member with a weight of 10 receives five times as much traffic as a + member with a weight of 2. ## Attribute Reference @@ -59,3 +56,11 @@ This resource provides the following timeouts configuration options: * `create` - Default is 10 minutes. * `update` - Default is 10 minutes. * `delete` - Default is 10 minutes. + +## Import + +ELB member can be imported using the pool ID and member ID separated by a slash, e.g. + +```shell +terraform import flexibleengine_lb_member.member_1 e0bd694a-abbe-450e-b329-0931fd1cc5eb/4086b0c9-b18c-4d1c-b6b8-4c56c3ad2a9e +``` diff --git a/docs/resources/lb_monitor_v2.md b/docs/resources/lb_monitor_v2.md index fbf122496..534438708 100644 --- a/docs/resources/lb_monitor_v2.md +++ b/docs/resources/lb_monitor_v2.md @@ -1,22 +1,48 @@ --- subcategory: "Elastic Load Balance (ELB)" -description: "" -page_title: "flexibleengine_lb_monitor_v2" --- -# flexibleengine_lb_monitor_v2 +# flexibleengine_lb_monitor -Manages an **enhanced** load balancer monitor resource within FlexibleEngine. +Manages an ELB monitor resource within FlexibleEngine. ## Example Usage +### TCP Health Check + +```hcl +resource "flexibleengine_lb_monitor" "monitor_tcp" { + pool_id = var.pool_id + type = "TCP" + delay = 5 + timeout = 3 + max_retries = 3 +} +``` + +### UDP Health Check + +```hcl +resource "flexibleengine_lb_monitor" "monitor_udp" { + pool_id = var.pool_id + type = "UDP_CONNECT" + delay = 5 + timeout = 3 + max_retries = 3 +} +``` + +### HTTP Health Check + ```hcl -resource "flexibleengine_lb_monitor_v2" "monitor_1" { - pool_id = flexibleengine_lb_pool_v2.pool_1.id - type = "PING" - delay = 20 - timeout = 10 - max_retries = 5 +resource "flexibleengine_lb_monitor" "monitor_http" { + pool_id = var.pool_id + type = "HTTP" + delay = 5 + timeout = 3 + max_retries = 3 + url_path = "/test" + expected_codes = "200-202" } ``` @@ -24,35 +50,41 @@ resource "flexibleengine_lb_monitor_v2" "monitor_1" { The following arguments are supported: -* `region` - (Optional, String, ForceNew) The region in which to create the resources. - If omitted, the `region` argument of the provider is used. Changing this creates a new resource. +* `region` - (Optional, String, ForceNew) The region in which to create the ELB monitor resource. If omitted, the + provider-level region will be used. Changing this creates a new monitor. + +* `pool_id` - (Required, String, ForceNew) Specifies the id of the pool that this monitor will be assigned to. Changing + this creates a new monitor. -* `pool_id` - (Required, String, ForceNew) The id of the pool that this monitor will be assigned to. - Changing this creates a new monitor. +* `type` - (Required, String, ForceNew) Specifies the monitor protocol. + The value can be *TCP*, *UDP_CONNECT*, or *HTTP*. + If the listener protocol is UDP, the monitor protocol must be *UDP_CONNECT*. Changing this creates a new monitor. -* `type` - (Required, String, ForceNew) The type of probe, which is PING, TCP, HTTP, or HTTPS, - that is sent by the load balancer to verify the member state. Changing this creates a new monitor. +* `delay` - (Required, Int) Specifies the maximum time between health checks in the unit of second. The value ranges + from 1 to 50. -* `delay` - (Required, Int) The time, in seconds, between sending probes to members. +* `timeout` - (Required, Int) Specifies the health check timeout duration in the unit of second. + The value ranges from 1 to 50 and must be less than the `delay` value. -* `timeout` - (Required, Int) Maximum number of seconds for a monitor to wait for a - ping reply before it times out. The value must be less than the delay value. +* `max_retries` - (Required, Int) Specifies the maximum number of consecutive health checks after which the backend + servers are declared *healthy*. The value ranges from 1 to 10. -* `max_retries` - (Required, Int) Number of permissible ping failures before - changing the member's status to INACTIVE. Must be a number between 1 and 10. + -> Backend servers can be declared *unhealthy* after **three** consecutive health checks that detect these backend + servers are unhealthy, regardless of the value set for `max_retries`. -* `name` - (Optional, String) The Name of the Monitor. +* `name` - (Optional, String) Specifies the health check name. The value contains a maximum of 255 characters. -* `url_path` - (Optional, String) Required for HTTP(S) types. URI path that will be - accessed if monitor type is HTTP or HTTPS. +* `port` - (Optional, Int) Specifies the health check port. The port number ranges from 1 to 65535. If not specified, + the port of the backend server will be used as the health check port. -* `http_method` - (Optional, String) Required for HTTP(S) types. The HTTP method used - for requests by the monitor. If this attribute is not specified, it defaults to "GET". +* `url_path` - (Optional, String) Specifies the HTTP request path for the health check. Required for HTTP type. + The value starts with a slash (/) and contains a maximum of 255 characters. -* `expected_codes` - (Optional, String) Required for HTTP(S) types. Expected HTTP codes - for a passing HTTP(S) monitor. You can either specify a single status like "200", or a range like "200-202". +* `http_method` - (Optional, String) Specifies the HTTP request method. Required for HTTP type. + The default value is *GET*. -* `port` - (Optional, Int) Specifies the health check port. The value ranges from 1 to 65536. +* `expected_codes` - (Optional, String) Specifies the expected HTTP status code. Required for HTTP type. + You can either specify a single status like "200", or a range like "200-202". ## Attribute Reference @@ -67,3 +99,11 @@ This resource provides the following timeouts configuration options: * `create` - Default is 10 minutes. * `update` - Default is 10 minutes. * `delete` - Default is 10 minutes. + +## Import + +ELB monitor can be imported using the monitor ID, e.g. + +```shell +terraform import flexibleengine_lb_monitor.monitor_1 5c20fdad-7288-11eb-b817-0255ac10158b +``` diff --git a/docs/resources/lb_whitelist_v2.md b/docs/resources/lb_whitelist_v2.md index b54749573..8ec47040f 100644 --- a/docs/resources/lb_whitelist_v2.md +++ b/docs/resources/lb_whitelist_v2.md @@ -1,20 +1,25 @@ --- subcategory: "Elastic Load Balance (ELB)" -description: "" -page_title: "flexibleengine_lb_whitelist_v2" --- -# flexibleengine_lb_whitelist_v2 +# flexibleengine_lb_whitelist -Manages an **enhanced** load balancer whitelist resource within FlexibleEngine. +Manages an ELB whitelist resource within FlexibleEngine. ## Example Usage ```hcl -resource "flexibleengine_lb_whitelist_v2" "whitelist_1" { +resource "flexibleengine_lb_listener" "listener_1" { + name = "listener_1" + protocol = "HTTP" + protocol_port = 8080 + loadbalancer_id = var.loadbalancer_id +} + +resource "flexibleengine_lb_whitelist" "whitelist_1" { enable_whitelist = true whitelist = "192.168.11.1,192.168.0.1/24,192.168.201.18/8" - listener_id = "d9415786-5f1a-428b-b35f-2f1523e146d2" + listener_id = flexibleengine_lb_listener.listener_1.id } ``` @@ -22,13 +27,16 @@ resource "flexibleengine_lb_whitelist_v2" "whitelist_1" { The following arguments are supported: -* `listener_id` - (Required, String, ForceNew) The Listener ID that the whitelist will be associated with. - Changing this creates a new whitelist. +* `region` - (Optional, String, ForceNew) The region in which to create the ELB whitelist resource. If omitted, the + provider-level region will be used. Changing this creates a new whitelist. + +* `listener_id` - (Required, String, ForceNew) The Listener ID that the whitelist will be associated with. Changing this + creates a new whitelist. * `enable_whitelist` - (Optional, Bool) Specify whether to enable access control. -* `whitelist` - (Optional, String) Specifies the IP addresses in the whitelist. Use commas(,) to separate - the multiple IP addresses. +* `whitelist` - (Optional, String) Specifies the IP addresses in the whitelist. Use commas(,) to separate the multiple + IP addresses. ## Attribute Reference @@ -43,3 +51,11 @@ This resource provides the following timeouts configuration options: * `create` - Default is 10 minutes. * `update` - Default is 10 minutes. * `delete` - Default is 10 minutes. + +## Import + +ELB whitelist can be imported using the whitelist ID, e.g. + +```shell +terraform import flexibleengine_lb_whitelist.whitelist_1 5c20fdad-7288-11eb-b817-0255ac10158b +``` diff --git a/flexibleengine/acceptance/data_source_flexibleengine_lb_loadbalancer_v2_test.go b/flexibleengine/acceptance/data_source_flexibleengine_lb_loadbalancer_v2_test.go new file mode 100644 index 000000000..4d250b25d --- /dev/null +++ b/flexibleengine/acceptance/data_source_flexibleengine_lb_loadbalancer_v2_test.go @@ -0,0 +1,95 @@ +package acceptance + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" + + "github.com/chnsz/golangsdk/openstack/elb/v2/loadbalancers" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" +) + +func getLoadBalancerResourceFunc(conf *config.Config, state *terraform.ResourceState) (interface{}, error) { + c, err := conf.LoadBalancerClient(OS_REGION_NAME) + if err != nil { + return nil, fmt.Errorf("error creating ELB v2 Client: %s", err) + } + resp, err := loadbalancers.Get(c, state.Primary.ID).Extract() + if resp == nil && err == nil { + return resp, fmt.Errorf("unable to find the LoadBalancer (%s)", state.Primary.ID) + } + return resp, err +} + +func TestAccELBV2LoadbalancerDataSource_basic(t *testing.T) { + rName := acceptance.RandomAccResourceNameWithDash() + dataSourceName1 := "data.flexibleengine_lb_loadbalancer_v2.test_by_name" + dc1 := acceptance.InitDataSourceCheck(dataSourceName1) + dataSourceName2 := "data.flexibleengine_lb_loadbalancer_v2.test_by_description" + dc2 := acceptance.InitDataSourceCheck(dataSourceName2) + + var lb loadbalancers.LoadBalancer + resourceName := "flexibleengine_lb_loadbalancer_v2.test" + + rc := acceptance.InitResourceCheck( + resourceName, + &lb, + getLoadBalancerResourceFunc, + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: TestAccProviderFactories, + CheckDestroy: rc.CheckResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccELBV2LoadbalancerDataSource_basic(rName), + Check: resource.ComposeTestCheckFunc( + dc1.CheckResourceExists(), + dc2.CheckResourceExists(), + resource.TestCheckResourceAttr(dataSourceName1, "name", rName), + resource.TestCheckResourceAttr(dataSourceName2, "name", rName), + ), + }, + }, + }) +} + +func testAccELBV2LoadbalancerDataSource_basic(rName string) string { + return fmt.Sprintf(` + +resource "flexibleengine_vpc_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/16" +} + +resource "flexibleengine_vpc_subnet_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/24" + vpc_id = flexibleengine_vpc_v1.test.id + gateway_ip = "192.168.0.1" +} + +resource "flexibleengine_lb_loadbalancer_v2" "test" { + name = "%[1]s" + vip_subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id + description = "test for load balancer data source" +} + +data "flexibleengine_lb_loadbalancer_v2" "test_by_name" { + name = flexibleengine_lb_loadbalancer_v2.test.name + + depends_on = [flexibleengine_lb_loadbalancer_v2.test] +} + +data "flexibleengine_lb_loadbalancer_v2" "test_by_description" { + description = flexibleengine_lb_loadbalancer_v2.test.description + + depends_on = [flexibleengine_lb_loadbalancer_v2.test] +} +`, rName) +} diff --git a/flexibleengine/acceptance/resource_flexibleengine_lb_member_v2_test.go b/flexibleengine/acceptance/resource_flexibleengine_lb_member_v2_test.go new file mode 100644 index 000000000..77fecf368 --- /dev/null +++ b/flexibleengine/acceptance/resource_flexibleengine_lb_member_v2_test.go @@ -0,0 +1,230 @@ +package acceptance + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + + "github.com/chnsz/golangsdk/openstack/elb/v2/pools" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils/fmtp" +) + +func TestAccLBV2Member_basic(t *testing.T) { + var member_1 pools.Member + var member_2 pools.Member + resourceName1 := "flexibleengine_lb_member_v2.member_1" + resourceName2 := "flexibleengine_lb_member_v2.member_2" + rName := acceptance.RandomAccResourceNameWithDash() + + rc1 := acceptance.InitResourceCheck( + resourceName1, + &member_1, + getMemberResourceFunc, + ) + rc2 := acceptance.InitResourceCheck( + resourceName2, + &member_2, + getMemberResourceFunc, + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: TestAccProviderFactories, + CheckDestroy: testAccCheckLBV2MemberDestroy, + Steps: []resource.TestStep{ + { + Config: testAccLBV2MemberConfig_basic(rName), + ExpectNonEmptyPlan: true, // Because admin_state_up remains false. + Check: resource.ComposeTestCheckFunc( + rc1.CheckResourceExists(), + rc2.CheckResourceExists(), + ), + }, + { + Config: testAccLBV2MemberConfig_update(rName), + ExpectNonEmptyPlan: true, // Because admin_state_up remains false. + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("flexibleengine_lb_member_v2.member_1", "weight", "10"), + resource.TestCheckResourceAttr("flexibleengine_lb_member_v2.member_2", "weight", "15"), + ), + }, + { + ResourceName: "flexibleengine_lb_member_v2.member_1", + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: testAccLBMemberImportStateIdFunc(), + }, + }, + }) +} + +func testAccCheckLBV2MemberDestroy(s *terraform.State) error { + config := acceptance.TestAccProvider.Meta().(*config.Config) + elbClient, err := config.LoadBalancerClient(OS_REGION_NAME) + if err != nil { + return fmtp.Errorf("Error creating HuaweiCloud elb client: %s", err) + } + + for _, rs := range s.RootModule().Resources { + if rs.Type != "flexibleengine_lb_member" { + continue + } + + poolId := rs.Primary.Attributes["pool_id"] + _, err := pools.GetMember(elbClient, poolId, rs.Primary.ID).Extract() + if err == nil { + return fmtp.Errorf("Member still exists: %s", rs.Primary.ID) + } + } + + return nil +} + +func testAccLBMemberImportStateIdFunc() resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + pool, ok := s.RootModule().Resources["flexibleengine_lb_pool_v2.pool_1"] + if !ok { + return "", fmt.Errorf("pool not found: %s", pool) + } + member, ok := s.RootModule().Resources["flexibleengine_lb_member_v2.member_1"] + if !ok { + return "", fmt.Errorf("member not found: %s", member) + } + if pool.Primary.ID == "" || member.Primary.ID == "" { + return "", fmt.Errorf("resource not found: %s/%s", pool.Primary.ID, member.Primary.ID) + } + return fmt.Sprintf("%s/%s", pool.Primary.ID, member.Primary.ID), nil + } +} + +func testAccLBV2MemberConfig_basic(rName string) string { + return fmt.Sprintf(` +resource "flexibleengine_vpc_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/16" +} + +resource "flexibleengine_vpc_subnet_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/24" + vpc_id = flexibleengine_vpc_v1.test.id + gateway_ip = "192.168.0.1" +} + +resource "flexibleengine_lb_loadbalancer_v2" "loadbalancer_1" { + name = "%[1]s" + vip_subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id + +} + +resource "flexibleengine_lb_listener_v2" "listener_1" { + name = "%[1]s" + protocol = "HTTP" + protocol_port = 8080 + loadbalancer_id = flexibleengine_lb_loadbalancer_v2.loadbalancer_1.id +} + +resource "flexibleengine_lb_pool_v2" "pool_1" { + name = "%[1]s" + protocol = "HTTP" + lb_method = "ROUND_ROBIN" + listener_id = flexibleengine_lb_listener_v2.listener_1.id +} + +resource "flexibleengine_lb_member_v2" "member_1" { + address = "192.168.0.10" + protocol_port = 8080 + pool_id = flexibleengine_lb_pool_v2.pool_1.id + subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } +} + +resource "flexibleengine_lb_member_v2" "member_2" { + address = "192.168.0.11" + protocol_port = 8080 + pool_id = flexibleengine_lb_pool_v2.pool_1.id + subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } +} +`, rName) +} + +func testAccLBV2MemberConfig_update(rName string) string { + return fmt.Sprintf(` +resource "flexibleengine_vpc_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/16" +} + +resource "flexibleengine_vpc_subnet_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/24" + vpc_id = flexibleengine_vpc_v1.test.id + gateway_ip = "192.168.0.1" +} + +resource "flexibleengine_lb_loadbalancer_v2" "loadbalancer_1" { + name = "%[1]s" + vip_subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id +} + +resource "flexibleengine_lb_listener_v2" "listener_1" { + name = "%[1]s" + protocol = "HTTP" + protocol_port = 8080 + loadbalancer_id = flexibleengine_lb_loadbalancer_v2.loadbalancer_1.id +} + +resource "flexibleengine_lb_pool_v2" "pool_1" { + name = "%[1]s" + protocol = "HTTP" + lb_method = "ROUND_ROBIN" + listener_id = flexibleengine_lb_listener_v2.listener_1.id +} + +resource "flexibleengine_lb_member_v2" "member_1" { + address = "192.168.0.10" + protocol_port = 8080 + weight = 10 + admin_state_up = "true" + pool_id = flexibleengine_lb_pool_v2.pool_1.id + subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } +} + +resource "flexibleengine_lb_member_v2" "member_2" { + address = "192.168.0.11" + protocol_port = 8080 + weight = 15 + admin_state_up = "true" + pool_id = flexibleengine_lb_pool_v2.pool_1.id + subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } +} +`, rName) +} diff --git a/flexibleengine/acceptance/resource_flexibleengine_lb_monitor_v2_test.go b/flexibleengine/acceptance/resource_flexibleengine_lb_monitor_v2_test.go new file mode 100644 index 000000000..417f466a1 --- /dev/null +++ b/flexibleengine/acceptance/resource_flexibleengine_lb_monitor_v2_test.go @@ -0,0 +1,250 @@ +package acceptance + +import ( + "fmt" + "testing" + + "github.com/chnsz/golangsdk/openstack/elb/v2/monitors" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" +) + +func TestAccLBV2Monitor_basic(t *testing.T) { + var monitor monitors.Monitor + rName := acceptance.RandomAccResourceNameWithDash() + rNameUpdate := rName + "-update" + resourceName := "flexibleengine_lb_monitor_v2.monitor_1" + + rc := acceptance.InitResourceCheck( + resourceName, + &monitor, + getMonitorResourceFunc, + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: TestAccProviderFactories, + CheckDestroy: rc.CheckResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccLBV2MonitorConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "type", "TCP"), + resource.TestCheckResourceAttr(resourceName, "delay", "20"), + resource.TestCheckResourceAttr(resourceName, "timeout", "10"), + resource.TestCheckResourceAttr(resourceName, "max_retries", "5"), + ), + }, + { + Config: testAccLBV2MonitorConfig_update(rName, rNameUpdate), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", rNameUpdate), + resource.TestCheckResourceAttr(resourceName, "delay", "30"), + resource.TestCheckResourceAttr(resourceName, "timeout", "15"), + resource.TestCheckResourceAttr(resourceName, "max_retries", "3"), + resource.TestCheckResourceAttr(resourceName, "port", "8888"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccLBV2Monitor_udp(t *testing.T) { + var monitor monitors.Monitor + rName := acceptance.RandomAccResourceNameWithDash() + resourceName := "flexibleengine_lb_monitor_v2.monitor_udp" + + rc := acceptance.InitResourceCheck( + resourceName, + &monitor, + getMonitorResourceFunc, + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: TestAccProviderFactories, + CheckDestroy: rc.CheckResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccLBV2MonitorConfig_udp(rName), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "type", "UDP_CONNECT"), + resource.TestCheckResourceAttr(resourceName, "delay", "20"), + resource.TestCheckResourceAttr(resourceName, "timeout", "10"), + resource.TestCheckResourceAttr(resourceName, "max_retries", "5"), + ), + }, + }, + }) +} + +func TestAccLBV2Monitor_http(t *testing.T) { + var monitor monitors.Monitor + rName := acceptance.RandomAccResourceNameWithDash() + resourceName := "flexibleengine_lb_monitor_v2.monitor_http" + + rc := acceptance.InitResourceCheck( + resourceName, + &monitor, + getMonitorResourceFunc, + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: TestAccProviderFactories, + CheckDestroy: rc.CheckResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccLBV2MonitorConfig_http(rName), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "type", "HTTP"), + resource.TestCheckResourceAttr(resourceName, "delay", "20"), + resource.TestCheckResourceAttr(resourceName, "timeout", "10"), + resource.TestCheckResourceAttr(resourceName, "max_retries", "5"), + resource.TestCheckResourceAttr(resourceName, "url_path", "/api"), + resource.TestCheckResourceAttr(resourceName, "http_method", "GET"), + resource.TestCheckResourceAttr(resourceName, "expected_codes", "200-202"), + ), + }, + }, + }) +} + +func testAccLBV2MonitorConfig_base(rName string) string { + return fmt.Sprintf(` +resource "flexibleengine_vpc_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/16" +} + +resource "flexibleengine_vpc_subnet_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/24" + vpc_id = flexibleengine_vpc_v1.test.id + gateway_ip = "192.168.0.1" +} + +resource "flexibleengine_lb_loadbalancer_v2" "loadbalancer_1" { + name = "%[1]s" + vip_subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id +} + +resource "flexibleengine_lb_listener_v2" "listener_1" { + name = "%[1]s" + protocol = "HTTP" + protocol_port = 8080 + loadbalancer_id = flexibleengine_lb_loadbalancer_v2.loadbalancer_1.id +} + +resource "flexibleengine_lb_pool_v2" "pool_1" { + name = "%[1]s" + protocol = "HTTP" + lb_method = "ROUND_ROBIN" + listener_id = flexibleengine_lb_listener_v2.listener_1.id +} +`, rName) +} + +func testAccLBV2MonitorConfig_basic(rName string) string { + return fmt.Sprintf(` +%s + +resource "flexibleengine_lb_monitor_v2" "monitor_1" { + pool_id = flexibleengine_lb_pool_v2.pool_1.id + name = "%s" + type = "TCP" + delay = 20 + timeout = 10 + max_retries = 5 +} +`, testAccLBV2MonitorConfig_base(rName), rName) +} + +func testAccLBV2MonitorConfig_update(rName, rNameUpdate string) string { + return fmt.Sprintf(` +%s + +resource "flexibleengine_lb_monitor_v2" "monitor_1" { + pool_id = flexibleengine_lb_pool_v2.pool_1.id + name = "%s" + type = "TCP" + delay = 30 + timeout = 15 + max_retries = 3 + port = 8888 +} +`, testAccLBV2MonitorConfig_base(rName), rNameUpdate) +} + +func testAccLBV2MonitorConfig_http(rName string) string { + return fmt.Sprintf(` +%s + +resource "flexibleengine_lb_monitor_v2" "monitor_http" { + pool_id = flexibleengine_lb_pool_v2.pool_1.id + name = "%s" + type = "HTTP" + delay = 20 + timeout = 10 + max_retries = 5 + url_path = "/api" + expected_codes = "200-202" +} +`, testAccLBV2MonitorConfig_base(rName), rName) +} + +func testAccLBV2MonitorConfig_udp(rName string) string { + return fmt.Sprintf(` +resource "flexibleengine_vpc_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/16" +} + +resource "flexibleengine_vpc_subnet_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/24" + vpc_id = flexibleengine_vpc_v1.test.id + gateway_ip = "192.168.0.1" +} + +resource "flexibleengine_lb_loadbalancer_v2" "loadbalancer_1" { + name = "%[1]s" + vip_subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id +} + +resource "flexibleengine_lb_listener_v2" "listener_1" { + name = "%[1]s" + protocol = "UDP" + protocol_port = 8080 + loadbalancer_id = flexibleengine_lb_loadbalancer_v2.loadbalancer_1.id +} + +resource "flexibleengine_lb_pool_v2" "pool_1" { + name = "%[1]s" + protocol = "UDP" + lb_method = "ROUND_ROBIN" + listener_id = flexibleengine_lb_listener_v2.listener_1.id +} + +resource "flexibleengine_lb_monitor_v2" "monitor_udp" { + pool_id = flexibleengine_lb_pool_v2.pool_1.id + name = "%[1]s" + type = "UDP_CONNECT" + delay = 20 + timeout = 10 + max_retries = 5 +} +`, rName) +} diff --git a/flexibleengine/acceptance/resource_flexibleengine_lb_whitelist_v2_test.go b/flexibleengine/acceptance/resource_flexibleengine_lb_whitelist_v2_test.go new file mode 100644 index 000000000..30d7c6d1f --- /dev/null +++ b/flexibleengine/acceptance/resource_flexibleengine_lb_whitelist_v2_test.go @@ -0,0 +1,130 @@ +package acceptance + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + + "github.com/chnsz/golangsdk/openstack/elb/v2/whitelists" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" +) + +func getWhitelistResourceFunc(conf *config.Config, state *terraform.ResourceState) (interface{}, error) { + c, err := conf.LoadBalancerClient(OS_REGION_NAME) + if err != nil { + return nil, fmt.Errorf("error creating FlexibleEngine LB v2 client: %s", err) + } + resp, err := whitelists.Get(c, state.Primary.ID).Extract() + if resp == nil && err == nil { + return resp, fmt.Errorf("Unable to find the whitelist (%s)", state.Primary.ID) + } + return resp, err +} + +func TestAccLBV2Whitelist_basic(t *testing.T) { + var whitelist whitelists.Whitelist + rName := acceptance.RandomAccResourceNameWithDash() + resourceName := "flexibleengine_lb_whitelist_v2.whitelist_1" + + rc := acceptance.InitResourceCheck( + resourceName, + &whitelist, + getWhitelistResourceFunc, + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: TestAccProviderFactories, + CheckDestroy: rc.CheckResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccLBV2WhitelistConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + ), + }, + { + Config: testAccLBV2WhitelistConfig_update(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "enable_whitelist", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccLBV2WhitelistConfig_basic(rName string) string { + return fmt.Sprintf(` +resource "flexibleengine_vpc_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/16" +} + +resource "flexibleengine_vpc_subnet_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/24" + vpc_id = flexibleengine_vpc_v1.test.id + gateway_ip = "192.168.0.1" +} +resource "flexibleengine_lb_loadbalancer_v2" "loadbalancer_1" { + name = "%[1]s" + vip_subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id +} + +resource "flexibleengine_lb_listener_v2" "listener_1" { + name = "%[1]s" + protocol = "HTTP" + protocol_port = 8080 + loadbalancer_id = flexibleengine_lb_loadbalancer_v2.loadbalancer_1.id +} + +resource "flexibleengine_lb_whitelist_v2" "whitelist_1" { + enable_whitelist = true + whitelist = "192.168.11.1,192.168.0.1/24" + listener_id = flexibleengine_lb_listener_v2.listener_1.id +} +`, rName) +} + +func testAccLBV2WhitelistConfig_update(rName string) string { + return fmt.Sprintf(` +resource "flexibleengine_vpc_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/16" +} + +resource "flexibleengine_vpc_subnet_v1" "test" { + name = "%[1]s" + cidr = "192.168.0.0/24" + vpc_id = flexibleengine_vpc_v1.test.id + gateway_ip = "192.168.0.1" +} + +resource "flexibleengine_lb_loadbalancer_v2" "loadbalancer_1" { + name = "%[1]s" + vip_subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id +} + +resource "flexibleengine_lb_listener_v2" "listener_1" { + name = "%[1]s" + protocol = "HTTP" + protocol_port = 8080 + loadbalancer_id = flexibleengine_lb_loadbalancer_v2.loadbalancer_1.id +} + +resource "flexibleengine_lb_whitelist_v2" "whitelist_1" { + enable_whitelist = true + whitelist = "192.168.11.1,192.168.0.1/24,192.168.201.18/8" + listener_id = flexibleengine_lb_listener_v2.listener_1.id +} +`, rName) +} diff --git a/flexibleengine/provider.go b/flexibleengine/provider.go index 5a861c878..ece768abe 100644 --- a/flexibleengine/provider.go +++ b/flexibleengine/provider.go @@ -289,8 +289,7 @@ func Provider() *schema.Provider { "flexibleengine_dds_flavors_v3": dataSourceDDSFlavorsV3(), - "flexibleengine_lb_certificate_v2": dataSourceCertificateV2(), - "flexibleengine_lb_loadbalancer_v2": dataSourceELBV2Loadbalancer(), + "flexibleengine_lb_certificate_v2": dataSourceCertificateV2(), "flexibleengine_sdrs_domain_v1": dataSourceSdrsDomainV1(), @@ -347,7 +346,8 @@ func Provider() *schema.Provider { "flexibleengine_fgs_dependencies": fgs.DataSourceFunctionGraphDependencies(), - "flexibleengine_lb_listeners_v2": lb.DataSourceListeners(), + "flexibleengine_lb_listeners_v2": lb.DataSourceListeners(), + "flexibleengine_lb_loadbalancer_v2": lb.DataSourceELBV2Loadbalancer(), "flexibleengine_gaussdb_cassandra_flavors": gaussdb.DataSourceCassandraFlavors(), "flexibleengine_gaussdb_cassandra_instances": gaussdb.DataSourceGeminiDBInstances(), @@ -435,9 +435,6 @@ func Provider() *schema.Provider { "flexibleengine_lb_loadbalancer_v2": resourceLoadBalancerV2(), "flexibleengine_lb_listener_v2": resourceListenerV2(), - "flexibleengine_lb_member_v2": resourceMemberV2(), - "flexibleengine_lb_monitor_v2": resourceMonitorV2(), - "flexibleengine_lb_whitelist_v2": resourceWhitelistV2(), "flexibleengine_lb_l7policy_v2": resourceL7PolicyV2(), "flexibleengine_lb_l7rule_v2": resourceL7RuleV2(), @@ -674,6 +671,10 @@ func Provider() *schema.Provider { "flexibleengine_elb_security_policy": elb.ResourceSecurityPolicy(), "flexibleengine_elb_logtank": elb.ResourceLogTank(), + "flexibleengine_lb_member_v2": lb.ResourceMemberV2(), + "flexibleengine_lb_monitor_v2": lb.ResourceMonitorV2(), + "flexibleengine_lb_whitelist_v2": lb.ResourceWhitelistV2(), + "flexibleengine_modelarts_dataset": modelarts.ResourceDataset(), "flexibleengine_modelarts_dataset_version": modelarts.ResourceDatasetVersion(), "flexibleengine_smn_message_template": smn.ResourceSmnMessageTemplate(),