From 59572fd44e0623087631c3b190da7f6b4827e528 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. --- ..._loadbalancer_v2.md => lb_loadbalancer.md} | 23 +- docs/resources/lb_member.md | 70 +++ docs/resources/lb_member_v2.md | 61 --- docs/resources/lb_monitor.md | 111 ++++ docs/resources/lb_monitor_v2.md | 69 --- docs/resources/lb_whitelist.md | 63 +++ docs/resources/lb_whitelist_v2.md | 45 -- ...rce_flexibleengine_lb_loadbalancer_test.go | 95 ++++ .../resource_flexibleengine_lb_member_test.go | 230 +++++++++ ...resource_flexibleengine_lb_monitor_test.go | 250 +++++++++ ...source_flexibleengine_lb_whitelist_test.go | 130 +++++ ..._flexibleengine_lb_loadbalancer_v2_test.go | 71 --- ...ource_flexibleengine_lb_loadbalancer_v2.go | 9 +- flexibleengine/deprecated/lb_v2_shared.go | 481 ++++++++++++++++++ .../resource_flexibleengine_lb_member_v2.go | 12 +- .../resource_flexibleengine_lb_monitor_v2.go | 14 +- ...resource_flexibleengine_lb_whitelist_v2.go | 27 +- flexibleengine/deprecated/tags.go | 98 ++++ flexibleengine/deprecated/utils.go | 215 ++++++++ flexibleengine/provider.go | 11 +- ...source_flexibleengine_lb_member_v2_test.go | 168 ------ ...ource_flexibleengine_lb_monitor_v2_test.go | 166 ------ ...rce_flexibleengine_lb_whitelist_v2_test.go | 127 ----- 23 files changed, 1806 insertions(+), 740 deletions(-) rename docs/data-sources/{lb_loadbalancer_v2.md => lb_loadbalancer.md} (56%) create mode 100644 docs/resources/lb_member.md delete mode 100644 docs/resources/lb_member_v2.md create mode 100644 docs/resources/lb_monitor.md delete mode 100644 docs/resources/lb_monitor_v2.md create mode 100644 docs/resources/lb_whitelist.md delete mode 100644 docs/resources/lb_whitelist_v2.md create mode 100644 flexibleengine/acceptance/data_source_flexibleengine_lb_loadbalancer_test.go create mode 100644 flexibleengine/acceptance/resource_flexibleengine_lb_member_test.go create mode 100644 flexibleengine/acceptance/resource_flexibleengine_lb_monitor_test.go create mode 100644 flexibleengine/acceptance/resource_flexibleengine_lb_whitelist_test.go delete mode 100644 flexibleengine/data_source_flexibleengine_lb_loadbalancer_v2_test.go rename flexibleengine/{ => deprecated}/data_source_flexibleengine_lb_loadbalancer_v2.go (89%) create mode 100644 flexibleengine/deprecated/lb_v2_shared.go rename flexibleengine/{ => deprecated}/resource_flexibleengine_lb_member_v2.go (95%) rename flexibleengine/{ => deprecated}/resource_flexibleengine_lb_monitor_v2.go (94%) rename flexibleengine/{ => deprecated}/resource_flexibleengine_lb_whitelist_v2.go (85%) create mode 100644 flexibleengine/deprecated/tags.go delete mode 100644 flexibleengine/resource_flexibleengine_lb_member_v2_test.go delete mode 100644 flexibleengine/resource_flexibleengine_lb_monitor_v2_test.go delete mode 100644 flexibleengine/resource_flexibleengine_lb_whitelist_v2_test.go diff --git a/docs/data-sources/lb_loadbalancer_v2.md b/docs/data-sources/lb_loadbalancer.md similarity index 56% rename from docs/data-sources/lb_loadbalancer_v2.md rename to docs/data-sources/lb_loadbalancer.md index e08382caa..a048805e5 100644 --- a/docs/data-sources/lb_loadbalancer_v2.md +++ b/docs/data-sources/lb_loadbalancer.md @@ -2,7 +2,7 @@ subcategory: "Elastic Load Balance (ELB)" --- -# flexibleengine_lb_loadbalancer_v2 +# flexibleengine_lb_loadbalancer Use this data source to get a specific elb loadbalancer within FlexibleEngine. @@ -11,32 +11,37 @@ Use this data source to get a specific elb loadbalancer within FlexibleEngine. ```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.md b/docs/resources/lb_member.md new file mode 100644 index 000000000..dcd1a4a91 --- /dev/null +++ b/docs/resources/lb_member.md @@ -0,0 +1,70 @@ +--- +subcategory: "Elastic Load Balance (ELB)" +description: "" +page_title: "flexibleengine_lb_member" +--- + +# flexibleengine_lb_member + +Manages an **enhanced** load balancer member resource within FlexibleEngine. + +## Example Usage + +```hcl +variable "lb_pool_id" {} +variable "ipv4_subnet_id" {} + +resource "flexibleengine_lb_member" "member_1" { + address = "192.168.199.23" + protocol_port = 8080 + pool_id = var.lb_pool_id + subnet_id = var.ipv4_subnet_id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `region` - (Optional, String, ForceNew) The region in which to create the ELB member resource. If omitted, 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. + +* `subnet_id` - (Required, String, ForceNew) The **IPv4 subnet ID** of the subnet in which to access the member. + Changing this creates a new member. + +* `name` - (Optional, String) Human-readable name for 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. + +* `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. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The unique ID for the member. + +## Timeouts + +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_member_v2.md b/docs/resources/lb_member_v2.md deleted file mode 100644 index 1cc77f807..000000000 --- a/docs/resources/lb_member_v2.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -subcategory: "Elastic Load Balance (ELB)" -description: "" -page_title: "flexibleengine_lb_member_v2" ---- - -# flexibleengine_lb_member_v2 - -Manages an **enhanced** load balancer member resource within FlexibleEngine. - -## Example Usage - -```hcl -resource "flexibleengine_lb_member_v2" "example_member" { - 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 -} -``` - -## Argument Reference - -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. - -* `pool_id` - (Required, String, ForceNew) The id of the pool that this member will be - assigned to. Changing this creates a new member. - -* `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. - -* `address` - (Required, String, ForceNew) The IP address of the member to receive traffic from - the load balancer. Changing this creates a new member. - -* `protocol_port` - (Required, Int, ForceNew) The port on which to listen for client traffic. - Changing this creates a new member. - -* `name` - (Optional, String) Human-readable name for the 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. - -## Attribute Reference - -In addition to all arguments above, the following attributes are exported: - -* `id` - The unique ID for the member. - -## Timeouts - -This resource provides the following timeouts configuration options: - -* `create` - Default is 10 minutes. -* `update` - Default is 10 minutes. -* `delete` - Default is 10 minutes. diff --git a/docs/resources/lb_monitor.md b/docs/resources/lb_monitor.md new file mode 100644 index 000000000..965790351 --- /dev/null +++ b/docs/resources/lb_monitor.md @@ -0,0 +1,111 @@ +--- +subcategory: "Elastic Load Balance (ELB)" +description: "" +page_title: "flexibleengine_lb_monitor" +--- + +# flexibleengine_lb_monitor + +Manages an **enhanced** load balancer 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" "monitor_http" { + pool_id = var.pool_id + type = "HTTP" + delay = 5 + timeout = 3 + max_retries = 3 + url_path = "/test" + expected_codes = "200-202" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `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. + +* `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. + +* `delay` - (Required, Int) Specifies the maximum time between health checks in the unit of second. The value ranges + from 1 to 50. + +* `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. + +* `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. + + -> 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) Specifies the health check name. The value contains a maximum of 255 characters. + +* `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. + +* `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. + +* `http_method` - (Optional, String) Specifies the HTTP request method. Required for HTTP type. + The default value is *GET*. + +* `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 + +In addition to all arguments above, the following attributes are exported: + +* `id` - The unique ID for the monitor. + +## Timeouts + +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_monitor_v2.md b/docs/resources/lb_monitor_v2.md deleted file mode 100644 index fbf122496..000000000 --- a/docs/resources/lb_monitor_v2.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -subcategory: "Elastic Load Balance (ELB)" -description: "" -page_title: "flexibleengine_lb_monitor_v2" ---- - -# flexibleengine_lb_monitor_v2 - -Manages an **enhanced** load balancer monitor resource within FlexibleEngine. - -## Example Usage - -```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 -} -``` - -## Argument Reference - -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. - -* `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) 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) The time, in seconds, between sending probes to members. - -* `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) Number of permissible ping failures before - changing the member's status to INACTIVE. Must be a number between 1 and 10. - -* `name` - (Optional, String) The Name of the Monitor. - -* `url_path` - (Optional, String) Required for HTTP(S) types. URI path that will be - accessed if monitor type is HTTP or HTTPS. - -* `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". - -* `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". - -* `port` - (Optional, Int) Specifies the health check port. The value ranges from 1 to 65536. - -## Attribute Reference - -In addition to all arguments above, the following attributes are exported: - -* `id` - The unique ID for the monitor. - -## Timeouts - -This resource provides the following timeouts configuration options: - -* `create` - Default is 10 minutes. -* `update` - Default is 10 minutes. -* `delete` - Default is 10 minutes. diff --git a/docs/resources/lb_whitelist.md b/docs/resources/lb_whitelist.md new file mode 100644 index 000000000..0ce4622db --- /dev/null +++ b/docs/resources/lb_whitelist.md @@ -0,0 +1,63 @@ +--- +subcategory: "Elastic Load Balance (ELB)" +description: "" +page_title: "flexibleengine_lb_whitelist" +--- + +# flexibleengine_lb_whitelist + +Manages an **enhanced** load balancer whitelist resource within FlexibleEngine. + +## Example Usage + +```hcl +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 = flexibleengine_lb_listener.listener_1.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `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. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The unique ID for the whitelist. + +## Timeouts + +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/docs/resources/lb_whitelist_v2.md b/docs/resources/lb_whitelist_v2.md deleted file mode 100644 index b54749573..000000000 --- a/docs/resources/lb_whitelist_v2.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -subcategory: "Elastic Load Balance (ELB)" -description: "" -page_title: "flexibleengine_lb_whitelist_v2" ---- - -# flexibleengine_lb_whitelist_v2 - -Manages an **enhanced** load balancer whitelist resource within FlexibleEngine. - -## Example Usage - -```hcl -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 = "d9415786-5f1a-428b-b35f-2f1523e146d2" -} -``` - -## Argument Reference - -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. - -* `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. - -## Attribute Reference - -In addition to all arguments above, the following attributes are exported: - -* `id` - The unique ID for the whitelist. - -## Timeouts - -This resource provides the following timeouts configuration options: - -* `create` - Default is 10 minutes. -* `update` - Default is 10 minutes. -* `delete` - Default is 10 minutes. diff --git a/flexibleengine/acceptance/data_source_flexibleengine_lb_loadbalancer_test.go b/flexibleengine/acceptance/data_source_flexibleengine_lb_loadbalancer_test.go new file mode 100644 index 000000000..b96e29e38 --- /dev/null +++ b/flexibleengine/acceptance/data_source_flexibleengine_lb_loadbalancer_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.test_by_name" + dc1 := acceptance.InitDataSourceCheck(dataSourceName1) + dataSourceName2 := "data.flexibleengine_lb_loadbalancer.test_by_description" + dc2 := acceptance.InitDataSourceCheck(dataSourceName2) + + var lb loadbalancers.LoadBalancer + resourceName := "flexibleengine_lb_loadbalancer.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" "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" "test_by_name" { + name = flexibleengine_lb_loadbalancer.test.name + + depends_on = [flexibleengine_lb_loadbalancer.test] +} + +data "flexibleengine_lb_loadbalancer" "test_by_description" { + description = flexibleengine_lb_loadbalancer.test.description + + depends_on = [flexibleengine_lb_loadbalancer.test] +} +`, rName) +} diff --git a/flexibleengine/acceptance/resource_flexibleengine_lb_member_test.go b/flexibleengine/acceptance/resource_flexibleengine_lb_member_test.go new file mode 100644 index 000000000..858c9d8d8 --- /dev/null +++ b/flexibleengine/acceptance/resource_flexibleengine_lb_member_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.member_1" + resourceName2 := "flexibleengine_lb_member.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.member_1", "weight", "10"), + resource.TestCheckResourceAttr("flexibleengine_lb_member.member_2", "weight", "15"), + ), + }, + { + ResourceName: "flexibleengine_lb_member.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.pool_1"] + if !ok { + return "", fmt.Errorf("pool not found: %s", pool) + } + member, ok := s.RootModule().Resources["flexibleengine_lb_member.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" "loadbalancer_1" { + name = "%[1]s" + vip_subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id + +} + +resource "flexibleengine_lb_listener" "listener_1" { + name = "%[1]s" + protocol = "HTTP" + protocol_port = 8080 + loadbalancer_id = flexibleengine_lb_loadbalancer.loadbalancer_1.id +} + +resource "flexibleengine_lb_pool" "pool_1" { + name = "%[1]s" + protocol = "HTTP" + lb_method = "ROUND_ROBIN" + listener_id = flexibleengine_lb_listener.listener_1.id +} + +resource "flexibleengine_lb_member" "member_1" { + address = "192.168.0.10" + protocol_port = 8080 + pool_id = flexibleengine_lb_pool.pool_1.id + subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } +} + +resource "flexibleengine_lb_member" "member_2" { + address = "192.168.0.11" + protocol_port = 8080 + pool_id = flexibleengine_lb_pool.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" "loadbalancer_1" { + name = "%[1]s" + vip_subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id +} + +resource "flexibleengine_lb_listener" "listener_1" { + name = "%[1]s" + protocol = "HTTP" + protocol_port = 8080 + loadbalancer_id = flexibleengine_lb_loadbalancer.loadbalancer_1.id +} + +resource "flexibleengine_lb_pool" "pool_1" { + name = "%[1]s" + protocol = "HTTP" + lb_method = "ROUND_ROBIN" + listener_id = flexibleengine_lb_listener.listener_1.id +} + +resource "flexibleengine_lb_member" "member_1" { + address = "192.168.0.10" + protocol_port = 8080 + weight = 10 + admin_state_up = "true" + pool_id = flexibleengine_lb_pool.pool_1.id + subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id + + timeouts { + create = "5m" + update = "5m" + delete = "5m" + } +} + +resource "flexibleengine_lb_member" "member_2" { + address = "192.168.0.11" + protocol_port = 8080 + weight = 15 + admin_state_up = "true" + pool_id = flexibleengine_lb_pool.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_test.go b/flexibleengine/acceptance/resource_flexibleengine_lb_monitor_test.go new file mode 100644 index 000000000..4fcd860e2 --- /dev/null +++ b/flexibleengine/acceptance/resource_flexibleengine_lb_monitor_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.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.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.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" "loadbalancer_1" { + name = "%[1]s" + vip_subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id +} + +resource "flexibleengine_lb_listener" "listener_1" { + name = "%[1]s" + protocol = "HTTP" + protocol_port = 8080 + loadbalancer_id = flexibleengine_lb_loadbalancer.loadbalancer_1.id +} + +resource "flexibleengine_lb_pool" "pool_1" { + name = "%[1]s" + protocol = "HTTP" + lb_method = "ROUND_ROBIN" + listener_id = flexibleengine_lb_listener.listener_1.id +} +`, rName) +} + +func testAccLBV2MonitorConfig_basic(rName string) string { + return fmt.Sprintf(` +%s + +resource "flexibleengine_lb_monitor" "monitor_1" { + pool_id = flexibleengine_lb_pool.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" "monitor_1" { + pool_id = flexibleengine_lb_pool.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" "monitor_http" { + pool_id = flexibleengine_lb_pool.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" "loadbalancer_1" { + name = "%[1]s" + vip_subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id +} + +resource "flexibleengine_lb_listener" "listener_1" { + name = "%[1]s" + protocol = "UDP" + protocol_port = 8080 + loadbalancer_id = flexibleengine_lb_loadbalancer.loadbalancer_1.id +} + +resource "flexibleengine_lb_pool" "pool_1" { + name = "%[1]s" + protocol = "UDP" + lb_method = "ROUND_ROBIN" + listener_id = flexibleengine_lb_listener.listener_1.id +} + +resource "flexibleengine_lb_monitor" "monitor_udp" { + pool_id = flexibleengine_lb_pool.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_test.go b/flexibleengine/acceptance/resource_flexibleengine_lb_whitelist_test.go new file mode 100644 index 000000000..7b5b5bbe7 --- /dev/null +++ b/flexibleengine/acceptance/resource_flexibleengine_lb_whitelist_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.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" "loadbalancer_1" { + name = "%[1]s" + vip_subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id +} + +resource "flexibleengine_lb_listener" "listener_1" { + name = "%[1]s" + protocol = "HTTP" + protocol_port = 8080 + loadbalancer_id = flexibleengine_lb_loadbalancer.loadbalancer_1.id +} + +resource "flexibleengine_lb_whitelist" "whitelist_1" { + enable_whitelist = true + whitelist = "192.168.11.1,192.168.0.1/24" + listener_id = flexibleengine_lb_listener.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" "loadbalancer_1" { + name = "%[1]s" + vip_subnet_id = flexibleengine_vpc_subnet_v1.test.ipv4_subnet_id +} + +resource "flexibleengine_lb_listener" "listener_1" { + name = "%[1]s" + protocol = "HTTP" + protocol_port = 8080 + loadbalancer_id = flexibleengine_lb_loadbalancer.loadbalancer_1.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 = flexibleengine_lb_listener.listener_1.id +} +`, rName) +} diff --git a/flexibleengine/data_source_flexibleengine_lb_loadbalancer_v2_test.go b/flexibleengine/data_source_flexibleengine_lb_loadbalancer_v2_test.go deleted file mode 100644 index 955554321..000000000 --- a/flexibleengine/data_source_flexibleengine_lb_loadbalancer_v2_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package flexibleengine - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -func TestAccELBV2LoadbalancerDataSource_basic(t *testing.T) { - rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckLBV2LoadBalancerDestroy, - Steps: []resource.TestStep{ - { - Config: testAccELBV2LoadbalancerDataSource_basic(rName), - Check: resource.ComposeTestCheckFunc( - testAccCheckELBV2LoadbalancerDataSourceID("data.flexibleengine_lb_loadbalancer_v2.test_by_name"), - testAccCheckELBV2LoadbalancerDataSourceID("data.flexibleengine_lb_loadbalancer_v2.test_by_id"), - resource.TestCheckResourceAttr( - "data.flexibleengine_lb_loadbalancer_v2.test_by_name", "name", rName), - resource.TestCheckResourceAttr( - "data.flexibleengine_lb_loadbalancer_v2.test_by_id", "name", rName), - ), - }, - }, - }) -} - -func testAccCheckELBV2LoadbalancerDataSourceID(n string) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("Can't find elb load balancer data source: %s", n) - } - - if rs.Primary.ID == "" { - return fmt.Errorf("load balancer data source ID not set") - } - - return nil - } -} - -func testAccELBV2LoadbalancerDataSource_basic(rName string) string { - return fmt.Sprintf(` -resource "flexibleengine_lb_loadbalancer_v2" "test" { - name = "%s" - description = "resource for load balancer data source" - vip_subnet_id = "%s" - - tags = { - key = "value" - owner = "terraform" - } -} - -data "flexibleengine_lb_loadbalancer_v2" "test_by_name" { - name = flexibleengine_lb_loadbalancer_v2.test.name -} - -data "flexibleengine_lb_loadbalancer_v2" "test_by_id" { - id = flexibleengine_lb_loadbalancer_v2.test.id -} -`, rName, OS_SUBNET_ID) -} diff --git a/flexibleengine/data_source_flexibleengine_lb_loadbalancer_v2.go b/flexibleengine/deprecated/data_source_flexibleengine_lb_loadbalancer_v2.go similarity index 89% rename from flexibleengine/data_source_flexibleengine_lb_loadbalancer_v2.go rename to flexibleengine/deprecated/data_source_flexibleengine_lb_loadbalancer_v2.go index 2ec630e7c..c69c2132a 100644 --- a/flexibleengine/data_source_flexibleengine_lb_loadbalancer_v2.go +++ b/flexibleengine/deprecated/data_source_flexibleengine_lb_loadbalancer_v2.go @@ -1,15 +1,18 @@ -package flexibleengine +package deprecated import ( "fmt" "log" + "github.com/FlexibleEngineCloud/terraform-provider-flexibleengine/flexibleengine" "github.com/chnsz/golangsdk/openstack/common/tags" "github.com/chnsz/golangsdk/openstack/networking/v2/extensions/lbaas_v2/loadbalancers" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" ) +// flexibleengine_lb_loadbalancer has deprecated, use flexibleengine_lb_loadbalancer instead. func dataSourceELBV2Loadbalancer() *schema.Resource { return &schema.Resource{ Read: dataSourceELBV2LoadbalancerRead, @@ -57,8 +60,8 @@ func dataSourceELBV2Loadbalancer() *schema.Resource { } func dataSourceELBV2LoadbalancerRead(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) - region := GetRegion(d, config) + config := meta.(*config.Config) + region := flexibleengine.GetRegion(d, config) lbClient, err := config.ElbV2Client(region) if err != nil { return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) diff --git a/flexibleengine/deprecated/lb_v2_shared.go b/flexibleengine/deprecated/lb_v2_shared.go new file mode 100644 index 000000000..459105d2f --- /dev/null +++ b/flexibleengine/deprecated/lb_v2_shared.go @@ -0,0 +1,481 @@ +package deprecated + +import ( + "fmt" + "log" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/chnsz/golangsdk" + "github.com/chnsz/golangsdk/openstack/networking/v2/extensions/lbaas_v2/l7policies" + "github.com/chnsz/golangsdk/openstack/networking/v2/extensions/lbaas_v2/listeners" + "github.com/chnsz/golangsdk/openstack/networking/v2/extensions/lbaas_v2/loadbalancers" + "github.com/chnsz/golangsdk/openstack/networking/v2/extensions/lbaas_v2/monitors" + "github.com/chnsz/golangsdk/openstack/networking/v2/extensions/lbaas_v2/pools" +) + +// lbPendingStatuses are the valid statuses a LoadBalancer will be in while +// it's updating. +var lbPendingStatuses = []string{"PENDING_CREATE", "PENDING_UPDATE"} + +// lbPendingDeleteStatuses are the valid statuses a LoadBalancer will be before delete +var lbPendingDeleteStatuses = []string{"ERROR", "PENDING_UPDATE", "PENDING_DELETE", "ACTIVE"} + +var lbSkipLBStatuses = []string{"ERROR", "ACTIVE"} + +func waitForLBV2Listener(lbClient *golangsdk.ServiceClient, id string, target string, pending []string, timeout time.Duration) error { + log.Printf("[DEBUG] Waiting for listener %s to become %s.", id, target) + + stateConf := &resource.StateChangeConf{ + Target: []string{target}, + Pending: pending, + Refresh: resourceLBV2ListenerRefreshFunc(lbClient, id), + Timeout: timeout, + Delay: 5 * time.Second, + MinTimeout: 1 * time.Second, + } + + _, err := stateConf.WaitForState() + if err != nil { + if _, ok := err.(golangsdk.ErrDefault404); ok { + switch target { + case "DELETED": + return nil + default: + return fmt.Errorf("Error: listener %s not found: %s", id, err) + } + } + return fmt.Errorf("Error waiting for listener %s to become %s: %s", id, target, err) + } + + return nil +} + +func resourceLBV2ListenerRefreshFunc(lbClient *golangsdk.ServiceClient, id string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + listener, err := listeners.Get(lbClient, id).Extract() + if err != nil { + return nil, "", err + } + + // The listener resource has no Status attribute, so a successful Get is the best we can do + return listener, "ACTIVE", nil + } +} + +func waitForLBV2LoadBalancer(lbClient *golangsdk.ServiceClient, id string, target string, pending []string, timeout time.Duration) error { + log.Printf("[DEBUG] Waiting for loadbalancer %s to become %s.", id, target) + + stateConf := &resource.StateChangeConf{ + Target: []string{target}, + Pending: pending, + Refresh: resourceLBV2LoadBalancerRefreshFunc(lbClient, id), + Timeout: timeout, + Delay: 5 * time.Second, + MinTimeout: 1 * time.Second, + } + + _, err := stateConf.WaitForState() + if err != nil { + if _, ok := err.(golangsdk.ErrDefault404); ok { + switch target { + case "DELETED": + return nil + default: + return fmt.Errorf("Error: loadbalancer %s not found: %s", id, err) + } + } + return fmt.Errorf("Error waiting for loadbalancer %s to become %s: %s", id, target, err) + } + + return nil +} + +func resourceLBV2LoadBalancerRefreshFunc(lbClient *golangsdk.ServiceClient, id string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + lb, err := loadbalancers.Get(lbClient, id).Extract() + if err != nil { + return nil, "", err + } + + return lb, lb.ProvisioningStatus, nil + } +} + +func waitForLBV2Member(lbClient *golangsdk.ServiceClient, poolID, memberID string, target string, pending []string, timeout time.Duration) error { + log.Printf("[DEBUG] Waiting for member %s to become %s.", memberID, target) + + stateConf := &resource.StateChangeConf{ + Target: []string{target}, + Pending: pending, + Refresh: resourceLBV2MemberRefreshFunc(lbClient, poolID, memberID), + Timeout: timeout, + Delay: 5 * time.Second, + MinTimeout: 1 * time.Second, + } + + _, err := stateConf.WaitForState() + if err != nil { + if _, ok := err.(golangsdk.ErrDefault404); ok { + switch target { + case "DELETED": + return nil + default: + return fmt.Errorf("Error: member %s not found: %s", memberID, err) + } + } + return fmt.Errorf("Error waiting for member %s to become %s: %s", memberID, target, err) + } + + return nil +} + +func resourceLBV2MemberRefreshFunc(lbClient *golangsdk.ServiceClient, poolID, memberID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + member, err := pools.GetMember(lbClient, poolID, memberID).Extract() + if err != nil { + return nil, "", err + } + + // The member resource has no Status attribute, so a successful Get is the best we can do + return member, "ACTIVE", nil + } +} + +func waitForLBV2Monitor(lbClient *golangsdk.ServiceClient, id string, target string, pending []string, timeout time.Duration) error { + log.Printf("[DEBUG] Waiting for monitor %s to become %s.", id, target) + + stateConf := &resource.StateChangeConf{ + Target: []string{target}, + Pending: pending, + Refresh: resourceLBV2MonitorRefreshFunc(lbClient, id), + Timeout: timeout, + Delay: 5 * time.Second, + MinTimeout: 1 * time.Second, + } + + _, err := stateConf.WaitForState() + if err != nil { + if _, ok := err.(golangsdk.ErrDefault404); ok { + switch target { + case "DELETED": + return nil + default: + return fmt.Errorf("Error: monitor %s not found: %s", id, err) + } + } + return fmt.Errorf("Error waiting for monitor %s to become %s: %s", id, target, err) + } + + return nil +} + +func resourceLBV2MonitorRefreshFunc(lbClient *golangsdk.ServiceClient, id string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + monitor, err := monitors.Get(lbClient, id).Extract() + if err != nil { + return nil, "", err + } + + // The monitor resource has no Status attribute, so a successful Get is the best we can do + return monitor, "ACTIVE", nil + } +} + +func waitForLBV2Pool(lbClient *golangsdk.ServiceClient, id string, target string, pending []string, timeout time.Duration) error { + log.Printf("[DEBUG] Waiting for pool %s to become %s.", id, target) + + stateConf := &resource.StateChangeConf{ + Target: []string{target}, + Pending: pending, + Refresh: resourceLBV2PoolRefreshFunc(lbClient, id), + Timeout: timeout, + Delay: 5 * time.Second, + MinTimeout: 1 * time.Second, + } + + _, err := stateConf.WaitForState() + if err != nil { + if _, ok := err.(golangsdk.ErrDefault404); ok { + switch target { + case "DELETED": + return nil + default: + return fmt.Errorf("Error: pool %s not found: %s", id, err) + } + } + return fmt.Errorf("Error waiting for pool %s to become %s: %s", id, target, err) + } + + return nil +} + +func resourceLBV2PoolRefreshFunc(lbClient *golangsdk.ServiceClient, poolID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + pool, err := pools.Get(lbClient, poolID).Extract() + if err != nil { + return nil, "", err + } + + // The pool resource has no Status attribute, so a successful Get is the best we can do + return pool, "ACTIVE", nil + } +} + +func waitForLBV2viaPool(lbClient *golangsdk.ServiceClient, id string, target string, timeout time.Duration) error { + pool, err := pools.Get(lbClient, id).Extract() + if err != nil { + return err + } + + if pool.Loadbalancers != nil { + // each pool has an LB in Octavia lbaasv2 API + lbID := pool.Loadbalancers[0].ID + return waitForLBV2LoadBalancer(lbClient, lbID, target, nil, timeout) + } + + if pool.Listeners != nil { + // each pool has a listener in Neutron lbaasv2 API + listenerID := pool.Listeners[0].ID + listener, err := listeners.Get(lbClient, listenerID).Extract() + if err != nil { + return err + } + if listener.Loadbalancers != nil { + lbID := listener.Loadbalancers[0].ID + return waitForLBV2LoadBalancer(lbClient, lbID, target, nil, timeout) + } + } + + // got a pool but no LB - this is wrong + return fmt.Errorf("No Load Balancer on pool %s", id) +} + +func resourceLBV2LoadBalancerStatusRefreshFunc(lbClient *golangsdk.ServiceClient, lbID, resourceType, resourceID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + statuses, err := loadbalancers.GetStatuses(lbClient, lbID).Extract() + if err != nil { + return nil, "", fmt.Errorf("Unable to get statuses from the Load Balancer %s statuses tree: %s", lbID, err) + } + + if !strSliceContains(lbSkipLBStatuses, statuses.Loadbalancer.ProvisioningStatus) { + return statuses.Loadbalancer, statuses.Loadbalancer.ProvisioningStatus, nil + } + + switch resourceType { + case "listener": + for _, listener := range statuses.Loadbalancer.Listeners { + if listener.ID == resourceID { + if listener.ProvisioningStatus != "" { + return listener, listener.ProvisioningStatus, nil + } + } + } + listener, err := listeners.Get(lbClient, resourceID).Extract() + return listener, "ACTIVE", err + + case "pool": + for _, pool := range statuses.Loadbalancer.Pools { + if pool.ID == resourceID { + if pool.ProvisioningStatus != "" { + return pool, pool.ProvisioningStatus, nil + } + } + } + pool, err := pools.Get(lbClient, resourceID).Extract() + return pool, "ACTIVE", err + + case "monitor": + for _, pool := range statuses.Loadbalancer.Pools { + if pool.Monitor.ID == resourceID { + if pool.Monitor.ProvisioningStatus != "" { + return pool.Monitor, pool.Monitor.ProvisioningStatus, nil + } + } + } + monitor, err := monitors.Get(lbClient, resourceID).Extract() + return monitor, "ACTIVE", err + + case "member": + for _, pool := range statuses.Loadbalancer.Pools { + for _, member := range pool.Members { + if member.ID == resourceID { + if member.ProvisioningStatus != "" { + return member, member.ProvisioningStatus, nil + } + } + } + } + return "", "DELETED", nil + + case "l7policy": + for _, listener := range statuses.Loadbalancer.Listeners { + for _, l7policy := range listener.L7Policies { + if l7policy.ID == resourceID { + if l7policy.ProvisioningStatus != "" { + return l7policy, l7policy.ProvisioningStatus, nil + } + } + } + } + l7policy, err := l7policies.Get(lbClient, resourceID).Extract() + return l7policy, "ACTIVE", err + + case "l7rule": + for _, listener := range statuses.Loadbalancer.Listeners { + for _, l7policy := range listener.L7Policies { + for _, l7rule := range l7policy.Rules { + if l7rule.ID == resourceID { + if l7rule.ProvisioningStatus != "" { + return l7rule, l7rule.ProvisioningStatus, nil + } + } + } + } + } + return "", "DELETED", nil + } + + return nil, "", fmt.Errorf("An unexpected error occurred querying the status of %s %s by loadbalancer %s", resourceType, resourceID, lbID) + } +} + +func resourceLBV2L7PolicyRefreshFunc(lbClient *golangsdk.ServiceClient, lbID string, l7policy *l7policies.L7Policy) resource.StateRefreshFunc { + if l7policy.ProvisioningStatus != "" { + return func() (interface{}, string, error) { + lb, status, err := resourceLBV2LoadBalancerRefreshFunc(lbClient, lbID)() + if err != nil { + return lb, status, err + } + if !strSliceContains(lbSkipLBStatuses, status) { + return lb, status, nil + } + + l7policy, err := l7policies.Get(lbClient, l7policy.ID).Extract() + if err != nil { + return nil, "", err + } + + return l7policy, l7policy.ProvisioningStatus, nil + } + } + + return resourceLBV2LoadBalancerStatusRefreshFunc(lbClient, lbID, "l7policy", l7policy.ID) +} + +func waitForLBV2L7Policy(lbClient *golangsdk.ServiceClient, parentListener *listeners.Listener, l7policy *l7policies.L7Policy, target string, pending []string, timeout time.Duration) error { + log.Printf("[DEBUG] Waiting for l7policy %s to become %s.", l7policy.ID, target) + + if len(parentListener.Loadbalancers) == 0 { + return fmt.Errorf("Unable to determine loadbalancer ID from listener %s", parentListener.ID) + } + + lbID := parentListener.Loadbalancers[0].ID + + stateConf := &resource.StateChangeConf{ + Target: []string{target}, + Pending: pending, + Refresh: resourceLBV2L7PolicyRefreshFunc(lbClient, lbID, l7policy), + Timeout: timeout, + Delay: 1 * time.Second, + MinTimeout: 1 * time.Second, + } + + _, err := stateConf.WaitForState() + if err != nil { + if _, ok := err.(golangsdk.ErrDefault404); ok { + if target == "DELETED" { + return nil + } + } + + return fmt.Errorf("Error waiting for l7policy %s to become %s: %s", l7policy.ID, target, err) + } + + return nil +} + +func getListenerIDForL7Policy(lbClient *golangsdk.ServiceClient, id string) (string, error) { + log.Printf("[DEBUG] Trying to get Listener ID associated with the %s L7 Policy ID", id) + lbsPages, err := loadbalancers.List(lbClient, loadbalancers.ListOpts{}).AllPages() + if err != nil { + return "", fmt.Errorf("No Load Balancers were found: %s", err) + } + + lbs, err := loadbalancers.ExtractLoadBalancers(lbsPages) + if err != nil { + return "", fmt.Errorf("Unable to extract Load Balancers list: %s", err) + } + + for _, lb := range lbs { + statuses, err := loadbalancers.GetStatuses(lbClient, lb.ID).Extract() + if err != nil { + return "", fmt.Errorf("Failed to get Load Balancer statuses: %s", err) + } + for _, listener := range statuses.Loadbalancer.Listeners { + for _, l7policy := range listener.L7Policies { + if l7policy.ID == id { + return listener.ID, nil + } + } + } + } + + return "", fmt.Errorf("Unable to find Listener ID associated with the %s L7 Policy ID", id) +} + +func resourceLBV2L7RuleRefreshFunc(lbClient *golangsdk.ServiceClient, lbID string, l7policyID string, l7rule *l7policies.Rule) resource.StateRefreshFunc { + if l7rule.ProvisioningStatus != "" { + return func() (interface{}, string, error) { + lb, status, err := resourceLBV2LoadBalancerRefreshFunc(lbClient, lbID)() + if err != nil { + return lb, status, err + } + if !strSliceContains(lbSkipLBStatuses, status) { + return lb, status, nil + } + + l7rule, err := l7policies.GetRule(lbClient, l7policyID, l7rule.ID).Extract() + if err != nil { + return nil, "", err + } + + return l7rule, l7rule.ProvisioningStatus, nil + } + } + + return resourceLBV2LoadBalancerStatusRefreshFunc(lbClient, lbID, "l7rule", l7rule.ID) +} + +func waitForLBV2L7Rule(lbClient *golangsdk.ServiceClient, parentListener *listeners.Listener, parentL7policy *l7policies.L7Policy, l7rule *l7policies.Rule, target string, pending []string, timeout time.Duration) error { + log.Printf("[DEBUG] Waiting for l7rule %s to become %s.", l7rule.ID, target) + + if len(parentListener.Loadbalancers) == 0 { + return fmt.Errorf("Unable to determine loadbalancer ID from listener %s", parentListener.ID) + } + + lbID := parentListener.Loadbalancers[0].ID + + stateConf := &resource.StateChangeConf{ + Target: []string{target}, + Pending: pending, + Refresh: resourceLBV2L7RuleRefreshFunc(lbClient, lbID, parentL7policy.ID, l7rule), + Timeout: timeout, + Delay: 1 * time.Second, + MinTimeout: 1 * time.Second, + } + + _, err := stateConf.WaitForState() + if err != nil { + if _, ok := err.(golangsdk.ErrDefault404); ok { + if target == "DELETED" { + return nil + } + } + + return fmt.Errorf("Error waiting for l7rule %s to become %s: %s", l7rule.ID, target, err) + } + + return nil +} diff --git a/flexibleengine/resource_flexibleengine_lb_member_v2.go b/flexibleengine/deprecated/resource_flexibleengine_lb_member_v2.go similarity index 95% rename from flexibleengine/resource_flexibleengine_lb_member_v2.go rename to flexibleengine/deprecated/resource_flexibleengine_lb_member_v2.go index 05ed2e62f..c5ede251b 100644 --- a/flexibleengine/resource_flexibleengine_lb_member_v2.go +++ b/flexibleengine/deprecated/resource_flexibleengine_lb_member_v2.go @@ -1,4 +1,4 @@ -package flexibleengine +package deprecated import ( "fmt" @@ -7,10 +7,12 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" "github.com/chnsz/golangsdk/openstack/networking/v2/extensions/lbaas_v2/pools" ) +// flexibleengine_lb_member_v2 have deprecated, use flexibleengine_lb_member instead. func resourceMemberV2() *schema.Resource { return &schema.Resource{ Create: resourceMemberV2Create, @@ -94,7 +96,7 @@ func resourceMemberV2() *schema.Resource { } func resourceMemberV2Create(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) + config := meta.(*config.Config) lbClient, err := config.ElbV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) @@ -157,7 +159,7 @@ func resourceMemberV2Create(d *schema.ResourceData, meta interface{}) error { } func resourceMemberV2Read(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) + config := meta.(*config.Config) lbClient, err := config.ElbV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) @@ -184,7 +186,7 @@ func resourceMemberV2Read(d *schema.ResourceData, meta interface{}) error { } func resourceMemberV2Update(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) + config := meta.(*config.Config) lbClient, err := config.ElbV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) @@ -232,7 +234,7 @@ func resourceMemberV2Update(d *schema.ResourceData, meta interface{}) error { } func resourceMemberV2Delete(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) + config := meta.(*config.Config) lbClient, err := config.ElbV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) diff --git a/flexibleengine/resource_flexibleengine_lb_monitor_v2.go b/flexibleengine/deprecated/resource_flexibleengine_lb_monitor_v2.go similarity index 94% rename from flexibleengine/resource_flexibleengine_lb_monitor_v2.go rename to flexibleengine/deprecated/resource_flexibleengine_lb_monitor_v2.go index 2bf0781ed..7c0346952 100644 --- a/flexibleengine/resource_flexibleengine_lb_monitor_v2.go +++ b/flexibleengine/deprecated/resource_flexibleengine_lb_monitor_v2.go @@ -1,4 +1,4 @@ -package flexibleengine +package deprecated import ( "fmt" @@ -7,10 +7,12 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" "github.com/chnsz/golangsdk/openstack/networking/v2/extensions/lbaas_v2/monitors" ) +// flexibleengine_lb_monitor_v2 has deprecated, use flexibleengine_lb_monitor instead. func resourceMonitorV2() *schema.Resource { return &schema.Resource{ Create: resourceMonitorV2Create, @@ -99,8 +101,8 @@ func resourceMonitorV2() *schema.Resource { } func resourceMonitorV2Create(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) - lbClient, err := config.ElbV2Client(GetRegion(d, config)) + config := meta.(*config.Config) + lbClient, err := config.ElbV2Client(config.GetRegion(d)) if err != nil { return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) } @@ -154,7 +156,7 @@ func resourceMonitorV2Create(d *schema.ResourceData, meta interface{}) error { } func resourceMonitorV2Read(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) + config := meta.(*config.Config) lbClient, err := config.ElbV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) @@ -184,7 +186,7 @@ func resourceMonitorV2Read(d *schema.ResourceData, meta interface{}) error { } func resourceMonitorV2Update(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) + config := meta.(*config.Config) lbClient, err := config.ElbV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) @@ -250,7 +252,7 @@ func resourceMonitorV2Update(d *schema.ResourceData, meta interface{}) error { } func resourceMonitorV2Delete(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) + config := meta.(*config.Config) lbClient, err := config.ElbV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) diff --git a/flexibleengine/resource_flexibleengine_lb_whitelist_v2.go b/flexibleengine/deprecated/resource_flexibleengine_lb_whitelist_v2.go similarity index 85% rename from flexibleengine/resource_flexibleengine_lb_whitelist_v2.go rename to flexibleengine/deprecated/resource_flexibleengine_lb_whitelist_v2.go index 67c068497..86224aff7 100644 --- a/flexibleengine/resource_flexibleengine_lb_whitelist_v2.go +++ b/flexibleengine/deprecated/resource_flexibleengine_lb_whitelist_v2.go @@ -1,14 +1,19 @@ -package flexibleengine +package deprecated import ( "fmt" "log" + "reflect" + "sort" + "strings" "time" "github.com/chnsz/golangsdk/openstack/networking/v2/extensions/lbaas_v2/whitelists" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" ) +// flexibleengine_lb_whitelist_v2 has deprecated, use flexibleengine_lb_whitelist instead. func resourceWhitelistV2() *schema.Resource { return &schema.Resource{ Create: resourceWhitelistV2Create, @@ -52,7 +57,7 @@ func resourceWhitelistV2() *schema.Resource { } func resourceWhitelistV2Create(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) + config := meta.(*config.Config) lbClient, err := config.ElbV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) @@ -77,7 +82,7 @@ func resourceWhitelistV2Create(d *schema.ResourceData, meta interface{}) error { } func resourceWhitelistV2Read(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) + config := meta.(*config.Config) lbClient, err := config.ElbV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) @@ -100,7 +105,7 @@ func resourceWhitelistV2Read(d *schema.ResourceData, meta interface{}) error { } func resourceWhitelistV2Update(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) + config := meta.(*config.Config) lbClient, err := config.ElbV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) @@ -125,7 +130,7 @@ func resourceWhitelistV2Update(d *schema.ResourceData, meta interface{}) error { } func resourceWhitelistV2Delete(d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) + config := meta.(*config.Config) lbClient, err := config.ElbV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) @@ -139,3 +144,15 @@ func resourceWhitelistV2Delete(d *schema.ResourceData, meta interface{}) error { d.SetId("") return nil } + +func suppressLBWhitelistDiffs(k, old, new string, d *schema.ResourceData) bool { + if len(old) != len(new) { + return false + } + old_array := strings.Split(old, ",") + new_array := strings.Split(new, ",") + sort.Strings(old_array) + sort.Strings(new_array) + + return reflect.DeepEqual(old_array, new_array) +} diff --git a/flexibleengine/deprecated/tags.go b/flexibleengine/deprecated/tags.go new file mode 100644 index 000000000..815f3d2df --- /dev/null +++ b/flexibleengine/deprecated/tags.go @@ -0,0 +1,98 @@ +package deprecated + +import ( + "fmt" + + "github.com/chnsz/golangsdk" + "github.com/chnsz/golangsdk/openstack/common/tags" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +const ( + tagVPCEP string = "endpoint" + tagVPCEPService string = "endpoint_service" +) + +// tagsSchema returns the schema to use for tags. +func tagsSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + } +} + +// UpdateResourceTags is a helper to update the tags for a resource. +// It expects the tags field to be named "tags" +func UpdateResourceTags(conn *golangsdk.ServiceClient, d *schema.ResourceData, resourceType, id string) error { + if d.HasChange("tags") { + oRaw, nRaw := d.GetChange("tags") + oMap := oRaw.(map[string]interface{}) + nMap := nRaw.(map[string]interface{}) + + // remove old tags + if len(oMap) > 0 { + taglist := expandResourceTags(oMap) + err := tags.Delete(conn, resourceType, id, taglist).ExtractErr() + if err != nil { + return err + } + } + + // set new tags + if len(nMap) > 0 { + taglist := expandResourceTags(nMap) + err := tags.Create(conn, resourceType, id, taglist).ExtractErr() + if err != nil { + return err + } + } + } + + return nil +} + +// tagsToMap returns the list of tags into a map. +func tagsToMap(tags []tags.ResourceTag) map[string]string { + result := make(map[string]string) + for _, val := range tags { + result[val.Key] = val.Value + } + + return result +} + +// expandResourceTags returns the tags for the given map of data. +func expandResourceTags(tagmap map[string]interface{}) []tags.ResourceTag { + var taglist []tags.ResourceTag + + for k, v := range tagmap { + tag := tags.ResourceTag{ + Key: k, + Value: v.(string), + } + taglist = append(taglist, tag) + } + + return taglist +} + +// get resource tag type of DNS zone by zoneType +func getDNSZoneTagType(zoneType string) (string, error) { + if zoneType == "public" { + return "DNS-public_zone", nil + } else if zoneType == "private" { + return "DNS-private_zone", nil + } + return "", fmt.Errorf("invalid zone type: %s", zoneType) +} + +// get resource tag type of DNS record set by zoneType +func getDNSRecordSetTagType(zoneType string) (string, error) { + if zoneType == "public" { + return "DNS-public_recordset", nil + } else if zoneType == "private" { + return "DNS-private_recordset", nil + } + return "", fmt.Errorf("invalid zone type: %s", zoneType) +} diff --git a/flexibleengine/deprecated/utils.go b/flexibleengine/deprecated/utils.go index caae7007f..082663327 100644 --- a/flexibleengine/deprecated/utils.go +++ b/flexibleengine/deprecated/utils.go @@ -1,11 +1,21 @@ package deprecated import ( + "bytes" + "encoding/json" "fmt" + "log" "net" "reflect" "regexp" "strings" + + "github.com/chnsz/golangsdk" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" ) func validateName(v interface{}, k string) (ws []string, errors []error) { @@ -95,3 +105,208 @@ func navigateValue(d interface{}, index []string, arrayIndex map[string]int) (in return d, nil } + +// ErrorResp is the response when API failed +type ErrorResp struct { + ErrorCode string `json:"error_code"` + ErrorMsg string `json:"error_msg"` +} + +// ParseErrorMsg is used to unmarshal the error body to ErrorResp +// usage: resp, pErr := ParseErrorMsg(err.Body) +func ParseErrorMsg(body []byte) (ErrorResp, error) { + resp := ErrorResp{} + err := json.Unmarshal(body, &resp) + return resp, err +} + +// CheckDeleted checks the error to see if it's a 404 (Not Found) and, if so, +// sets the resource ID to the empty string instead of throwing an error. +func CheckDeleted(d *schema.ResourceData, err error, msg string) error { + if _, ok := err.(golangsdk.ErrDefault404); ok { + d.SetId("") + return nil + } + + return fmt.Errorf("%s: %s", msg, err) +} + +// CheckDeletedDiag checks the error to see if it's a 404 (Not Found) and, if so, +// sets the resource ID to the empty string instead of throwing an error. +func CheckDeletedDiag(d *schema.ResourceData, err error, msg string) diag.Diagnostics { + if _, ok := err.(golangsdk.ErrDefault404); ok { + d.SetId("") + return nil + } + + return diag.Errorf("%s: %s", msg, err) +} + +// GetRegion returns the region that was specified in the resource. If a +// region was not set, the provider-level region is checked. The provider-level +// region can either be set by the region argument or by OS_REGION_NAME. +func GetRegion(d *schema.ResourceData, config *config.Config) string { + if v, ok := d.GetOk("region"); ok { + return v.(string) + } + + return config.Region +} + +func checkForRetryableError(err error) *resource.RetryError { + switch errCode := err.(type) { + case golangsdk.ErrDefault500: + return resource.RetryableError(err) + case golangsdk.ErrUnexpectedResponseCode: + switch errCode.Actual { + case 409, 503: + return resource.RetryableError(err) + default: + return resource.NonRetryableError(err) + } + default: + return resource.NonRetryableError(err) + } +} + +func isResourceNotFound(err error) bool { + if err == nil { + return false + } + _, ok := err.(golangsdk.ErrDefault404) + return ok +} + +func hasFilledOpt(d *schema.ResourceData, param string) bool { + _, b := d.GetOkExists(param) + return b +} + +// strSliceContains checks if a given string is contained in a slice +// When anybody asks why Go needs generics, here you go. +func strSliceContains(haystack []string, needle string) bool { + for _, s := range haystack { + if s == needle { + return true + } + } + return false +} + +func jsonBytesEqual(b1, b2 []byte) bool { + var o1 interface{} + if err := json.Unmarshal(b1, &o1); err != nil { + return false + } + + var o2 interface{} + if err := json.Unmarshal(b2, &o2); err != nil { + return false + } + + return reflect.DeepEqual(o1, o2) +} + +// convertStructToMap converts an instance of struct to a map object, and +// changes each key of fileds to the value of 'nameMap' if the key in it +// or to its corresponding lowercase. +func convertStructToMap(obj interface{}, nameMap map[string]string) (map[string]interface{}, error) { + b, err := json.Marshal(obj) + if err != nil { + return nil, fmt.Errorf("Error converting struct to map, marshal failed:%v", err) + } + + m, err := regexp.Compile(`"[a-z0-9A-Z_]+":`) + if err != nil { + return nil, fmt.Errorf("Error converting struct to map, compile regular express failed") + } + nb := m.ReplaceAllFunc( + b, + func(src []byte) []byte { + k := fmt.Sprintf("%s", src[1:len(src)-2]) + v, ok := nameMap[k] + if !ok { + v = strings.ToLower(k) + } + return []byte(fmt.Sprintf("\"%s\":", v)) + }, + ) + log.Printf("[DEBUG]convertStructToMap:: before change b =%s", b) + log.Printf("[DEBUG]convertStructToMap:: after change nb=%s", nb) + + p := make(map[string]interface{}) + err = json.Unmarshal(nb, &p) + if err != nil { + return nil, fmt.Errorf("Error converting struct to map, unmarshal failed:%v", err) + } + log.Printf("[DEBUG]convertStructToMap:: map= %#v\n", p) + return p, nil +} + +func looksLikeJsonString(s interface{}) bool { + return regexp.MustCompile(`^\s*{`).MatchString(s.(string)) +} + +func compareJsonTemplateAreEquivalent(tem1, tem2 string) (bool, error) { + var obj1 interface{} + err := json.Unmarshal([]byte(tem1), &obj1) + if err != nil { + return false, err + } + + canonicalJson1, _ := json.Marshal(obj1) + + var obj2 interface{} + err = json.Unmarshal([]byte(tem2), &obj2) + if err != nil { + return false, err + } + + canonicalJson2, _ := json.Marshal(obj2) + + equal := bytes.Compare(canonicalJson1, canonicalJson2) == 0 + if !equal { + log.Printf("[DEBUG] Canonical template are not equal.\nFirst: %s\nSecond: %s\n", + canonicalJson1, canonicalJson2) + } + return equal, nil +} + +// HashStrings hashes a list of strings to a unique hashcode. +func HashStrings(strings []string) string { + var buf bytes.Buffer + + for _, s := range strings { + buf.WriteString(fmt.Sprintf("%s-", s)) + } + + return fmt.Sprintf("%d", schema.HashString(buf.String())) +} + +func IsUUIDFormat(str string) bool { + if _, err := uuid.ParseUUID(str); err != nil { + log.Printf("[WARN] '%s' is not a valid UUID: %s", str, err) + return false + } + return true +} + +// isStrContainsSliceElement returns true if the string exists in given slice or contains in one of slice elements when +// open exact flag. Also you can ignore case for this check. +func isStrContainsSliceElement(str string, sl []string, ignoreCase, isExcat bool) bool { + if ignoreCase { + str = strings.ToLower(str) + } + for _, s := range sl { + if ignoreCase { + s = strings.ToLower(s) + } + if isExcat && s == str { + return true + } + if !isExcat && strings.Contains(str, s) { + return true + } + } + return false +} diff --git a/flexibleengine/provider.go b/flexibleengine/provider.go index 5a861c878..be2c02440 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(), @@ -348,6 +347,7 @@ func Provider() *schema.Provider { "flexibleengine_fgs_dependencies": fgs.DataSourceFunctionGraphDependencies(), "flexibleengine_lb_listeners_v2": lb.DataSourceListeners(), + "flexibleengine_lb_loadbalancer": 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": lb.ResourceMemberV2(), + "flexibleengine_lb_monitor": lb.ResourceMonitorV2(), + "flexibleengine_lb_whitelist": lb.ResourceWhitelistV2(), + "flexibleengine_modelarts_dataset": modelarts.ResourceDataset(), "flexibleengine_modelarts_dataset_version": modelarts.ResourceDatasetVersion(), "flexibleengine_smn_message_template": smn.ResourceSmnMessageTemplate(), diff --git a/flexibleengine/resource_flexibleengine_lb_member_v2_test.go b/flexibleengine/resource_flexibleengine_lb_member_v2_test.go deleted file mode 100644 index 2f105ce2b..000000000 --- a/flexibleengine/resource_flexibleengine_lb_member_v2_test.go +++ /dev/null @@ -1,168 +0,0 @@ -package flexibleengine - -import ( - "fmt" - "testing" - - "github.com/chnsz/golangsdk/openstack/networking/v2/extensions/lbaas_v2/pools" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -func TestAccLBV2Member_basic(t *testing.T) { - var member_1 pools.Member - var member_2 pools.Member - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckLBV2MemberDestroy, - Steps: []resource.TestStep{ - { - Config: testAccLBV2MemberConfig_basic, - ExpectNonEmptyPlan: true, // Because admin_state_up remains false, unfinished elb? - Check: resource.ComposeTestCheckFunc( - testAccCheckLBV2MemberExists("flexibleengine_lb_member_v2.member_1", &member_1), - testAccCheckLBV2MemberExists("flexibleengine_lb_member_v2.member_2", &member_2), - ), - }, - { - Config: testAccLBV2MemberConfig_update, - ExpectNonEmptyPlan: true, // Because admin_state_up remains false, unfinished elb? - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("flexibleengine_lb_member_v2.member_1", "weight", "10"), - resource.TestCheckResourceAttr("flexibleengine_lb_member_v2.member_2", "weight", "15"), - ), - }, - }, - }) -} - -func testAccCheckLBV2MemberDestroy(s *terraform.State) error { - config := testAccProvider.Meta().(*Config) - lbClient, err := config.ElbV2Client(OS_REGION_NAME) - if err != nil { - return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) - } - - for _, rs := range s.RootModule().Resources { - if rs.Type != "flexibleengine_lb_member_v2" { - continue - } - - poolId := rs.Primary.Attributes["pool_id"] - _, err := pools.GetMember(lbClient, poolId, rs.Primary.ID).Extract() - if err == nil { - return fmt.Errorf("Member still exists: %s", rs.Primary.ID) - } - } - - return nil -} - -func testAccCheckLBV2MemberExists(n string, member *pools.Member) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("Not found: %s", n) - } - - if rs.Primary.ID == "" { - return fmt.Errorf("No ID is set") - } - - config := testAccProvider.Meta().(*Config) - lbClient, err := config.ElbV2Client(OS_REGION_NAME) - if err != nil { - return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) - } - - poolId := rs.Primary.Attributes["pool_id"] - found, err := pools.GetMember(lbClient, poolId, rs.Primary.ID).Extract() - if err != nil { - return err - } - - if found.ID != rs.Primary.ID { - return fmt.Errorf("Member not found") - } - - *member = *found - - return nil - } -} - -var testAccLBV2MemberConfig_basic = fmt.Sprintf(` -resource "flexibleengine_lb_loadbalancer_v2" "loadbalancer_1" { - name = "loadbalancer_1" - vip_subnet_id = "%[1]s" -} - -resource "flexibleengine_lb_listener_v2" "listener_1" { - name = "listener_1" - protocol = "HTTP" - protocol_port = 8080 - loadbalancer_id = flexibleengine_lb_loadbalancer_v2.loadbalancer_1.id -} - -resource "flexibleengine_lb_pool_v2" "pool_1" { - name = "pool_1" - protocol = "HTTP" - lb_method = "ROUND_ROBIN" - listener_id = flexibleengine_lb_listener_v2.listener_1.id -} - -resource "flexibleengine_lb_member_v2" "member_1" { - address = "172.16.10.10" - protocol_port = 8080 - pool_id = flexibleengine_lb_pool_v2.pool_1.id - subnet_id = "%[1]s" -} - -resource "flexibleengine_lb_member_v2" "member_2" { - address = "172.16.10.11" - protocol_port = 8080 - pool_id = flexibleengine_lb_pool_v2.pool_1.id - subnet_id = "%[1]s" -} -`, OS_SUBNET_ID) - -var testAccLBV2MemberConfig_update = fmt.Sprintf(` -resource "flexibleengine_lb_loadbalancer_v2" "loadbalancer_1" { - name = "loadbalancer_1" - vip_subnet_id = "%[1]s" -} - -resource "flexibleengine_lb_listener_v2" "listener_1" { - name = "listener_1" - protocol = "HTTP" - protocol_port = 8080 - loadbalancer_id = flexibleengine_lb_loadbalancer_v2.loadbalancer_1.id -} - -resource "flexibleengine_lb_pool_v2" "pool_1" { - name = "pool_1" - protocol = "HTTP" - lb_method = "ROUND_ROBIN" - listener_id = flexibleengine_lb_listener_v2.listener_1.id -} - -resource "flexibleengine_lb_member_v2" "member_1" { - address = "172.16.10.10" - protocol_port = 8080 - weight = 10 - admin_state_up = "true" - pool_id = flexibleengine_lb_pool_v2.pool_1.id - subnet_id = "%[1]s" -} - -resource "flexibleengine_lb_member_v2" "member_2" { - address = "172.16.10.11" - protocol_port = 8080 - weight = 15 - admin_state_up = "true" - pool_id = flexibleengine_lb_pool_v2.pool_1.id - subnet_id = "%[1]s" -} -`, OS_SUBNET_ID) diff --git a/flexibleengine/resource_flexibleengine_lb_monitor_v2_test.go b/flexibleengine/resource_flexibleengine_lb_monitor_v2_test.go deleted file mode 100644 index 6ba97bc37..000000000 --- a/flexibleengine/resource_flexibleengine_lb_monitor_v2_test.go +++ /dev/null @@ -1,166 +0,0 @@ -package flexibleengine - -import ( - "fmt" - "testing" - - "github.com/chnsz/golangsdk/openstack/networking/v2/extensions/lbaas_v2/monitors" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -func TestAccLBV2Monitor_basic(t *testing.T) { - var monitor monitors.Monitor - rand := acctest.RandString(5) - resourceName := "flexibleengine_lb_monitor_v2.monitor_1" - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckLBV2MonitorDestroy, - Steps: []resource.TestStep{ - { - Config: testAccLBV2MonitorConfig_basic(rand), - Check: resource.ComposeTestCheckFunc( - testAccCheckLBV2MonitorExists(t, resourceName, &monitor), - resource.TestCheckResourceAttr(resourceName, "name", fmt.Sprintf("monitor_%s", rand)), - resource.TestCheckResourceAttr(resourceName, "delay", "20"), - resource.TestCheckResourceAttr(resourceName, "timeout", "10"), - resource.TestCheckResourceAttr(resourceName, "max_retries", "5"), - resource.TestCheckResourceAttr(resourceName, "port", "8888"), - ), - }, - { - Config: testAccLBV2MonitorConfig_update(rand), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", fmt.Sprintf("monitor_%s_updated", rand)), - resource.TestCheckResourceAttr(resourceName, "delay", "30"), - resource.TestCheckResourceAttr(resourceName, "timeout", "15"), - resource.TestCheckResourceAttr(resourceName, "max_retries", "10"), - resource.TestCheckResourceAttr(resourceName, "port", "9999"), - ), - }, - }, - }) -} - -func testAccCheckLBV2MonitorDestroy(s *terraform.State) error { - config := testAccProvider.Meta().(*Config) - lbClient, err := config.ElbV2Client(OS_REGION_NAME) - if err != nil { - return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) - } - - for _, rs := range s.RootModule().Resources { - if rs.Type != "flexibleengine_lb_monitor_v2" { - continue - } - - _, err := monitors.Get(lbClient, rs.Primary.ID).Extract() - if err == nil { - return fmt.Errorf("Monitor still exists: %s", rs.Primary.ID) - } - } - - return nil -} - -func testAccCheckLBV2MonitorExists(t *testing.T, n string, monitor *monitors.Monitor) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("Not found: %s", n) - } - - if rs.Primary.ID == "" { - return fmt.Errorf("No ID is set") - } - - config := testAccProvider.Meta().(*Config) - lbClient, err := config.ElbV2Client(OS_REGION_NAME) - if err != nil { - return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) - } - - found, err := monitors.Get(lbClient, rs.Primary.ID).Extract() - if err != nil { - return err - } - - if found.ID != rs.Primary.ID { - return fmt.Errorf("Monitor not found") - } - - *monitor = *found - - return nil - } -} - -func testAccLBV2MonitorConfig_basic(rand string) string { - return fmt.Sprintf(` -resource "flexibleengine_lb_loadbalancer_v2" "loadbalancer_1" { - name = "loadbalancer_%s" - vip_subnet_id = "%s" -} - -resource "flexibleengine_lb_listener_v2" "listener_1" { - name = "listener_%s" - protocol = "HTTP" - protocol_port = 8080 - loadbalancer_id = flexibleengine_lb_loadbalancer_v2.loadbalancer_1.id -} - -resource "flexibleengine_lb_pool_v2" "pool_1" { - name = "pool_%s" - protocol = "HTTP" - lb_method = "ROUND_ROBIN" - listener_id = flexibleengine_lb_listener_v2.listener_1.id -} - -resource "flexibleengine_lb_monitor_v2" "monitor_1" { - name = "monitor_%s" - type = "PING" - delay = 20 - timeout = 10 - max_retries = 5 - pool_id = flexibleengine_lb_pool_v2.pool_1.id - port = 8888 -} -`, rand, OS_SUBNET_ID, rand, rand, rand) -} - -func testAccLBV2MonitorConfig_update(rand string) string { - return fmt.Sprintf(` -resource "flexibleengine_lb_loadbalancer_v2" "loadbalancer_1" { - name = "loadbalancer_%s" - vip_subnet_id = "%s" -} - -resource "flexibleengine_lb_listener_v2" "listener_1" { - name = "listener_%s" - protocol = "HTTP" - protocol_port = 8080 - loadbalancer_id = flexibleengine_lb_loadbalancer_v2.loadbalancer_1.id -} - -resource "flexibleengine_lb_pool_v2" "pool_1" { - name = "pool_%s" - protocol = "HTTP" - lb_method = "ROUND_ROBIN" - listener_id = flexibleengine_lb_listener_v2.listener_1.id -} - -resource "flexibleengine_lb_monitor_v2" "monitor_1" { - name = "monitor_%s_updated" - type = "PING" - delay = 30 - timeout = 15 - max_retries = 10 - admin_state_up = "true" - pool_id = flexibleengine_lb_pool_v2.pool_1.id - port = 9999 -} -`, rand, OS_SUBNET_ID, rand, rand, rand) -} diff --git a/flexibleengine/resource_flexibleengine_lb_whitelist_v2_test.go b/flexibleengine/resource_flexibleengine_lb_whitelist_v2_test.go deleted file mode 100644 index 9f0ddb128..000000000 --- a/flexibleengine/resource_flexibleengine_lb_whitelist_v2_test.go +++ /dev/null @@ -1,127 +0,0 @@ -package flexibleengine - -import ( - "fmt" - "testing" - - "github.com/chnsz/golangsdk/openstack/networking/v2/extensions/lbaas_v2/whitelists" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -func TestAccLBV2Whitelist_basic(t *testing.T) { - var whitelist whitelists.Whitelist - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckLBV2WhitelistDestroy, - Steps: []resource.TestStep{ - { - Config: testAccLBV2WhitelistConfig_basic, - Check: resource.ComposeTestCheckFunc( - testAccCheckLBV2WhitelistExists("flexibleengine_lb_whitelist_v2.whitelist_1", &whitelist), - ), - }, - { - Config: testAccLBV2WhitelistConfig_update, - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("flexibleengine_lb_whitelist_v2.whitelist_1", "enable_whitelist", "true"), - ), - }, - }, - }) -} - -func testAccCheckLBV2WhitelistDestroy(s *terraform.State) error { - config := testAccProvider.Meta().(*Config) - lbClient, err := config.ElbV2Client(OS_REGION_NAME) - if err != nil { - return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) - } - - for _, rs := range s.RootModule().Resources { - if rs.Type != "flexibleengine_lb_whitelist_v2" { - continue - } - - _, err := whitelists.Get(lbClient, rs.Primary.ID).Extract() - if err == nil { - return fmt.Errorf("Whitelist still exists: %s", rs.Primary.ID) - } - } - - return nil -} - -func testAccCheckLBV2WhitelistExists(n string, whitelist *whitelists.Whitelist) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("Not found: %s", n) - } - - if rs.Primary.ID == "" { - return fmt.Errorf("No ID is set") - } - - config := testAccProvider.Meta().(*Config) - lbClient, err := config.ElbV2Client(OS_REGION_NAME) - if err != nil { - return fmt.Errorf("Error creating FlexibleEngine ELB v2.0 client: %s", err) - } - - found, err := whitelists.Get(lbClient, rs.Primary.ID).Extract() - if err != nil { - return err - } - - if found.ID != rs.Primary.ID { - return fmt.Errorf("Whitelist not found") - } - - *whitelist = *found - - return nil - } -} - -var testAccLBV2WhitelistConfig_basic = fmt.Sprintf(` -resource "flexibleengine_lb_loadbalancer_v2" "loadbalancer_1" { - name = "loadbalancer_1" - vip_subnet_id = "%s" -} - -resource "flexibleengine_lb_listener_v2" "listener_1" { - name = "listener_1" - 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 -} -`, OS_SUBNET_ID) - -var testAccLBV2WhitelistConfig_update = fmt.Sprintf(` -resource "flexibleengine_lb_loadbalancer_v2" "loadbalancer_1" { - name = "loadbalancer_1" - vip_subnet_id = "%s" -} - -resource "flexibleengine_lb_listener_v2" "listener_1" { - name = "listener_1" - 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 -} -`, OS_SUBNET_ID)