diff --git a/docs/resources/lb_listener_v2.md b/docs/resources/lb_listener_v2.md index 7bd1096d6f..8d8cb61918 100644 --- a/docs/resources/lb_listener_v2.md +++ b/docs/resources/lb_listener_v2.md @@ -13,6 +13,10 @@ resource "huaweicloud_lb_listener_v2" "listener_1" { protocol = "HTTP" protocol_port = 8080 loadbalancer_id = "d9415786-5f1a-428b-b35f-2f1523e146d2" + + tags = { + key = "value" + } } ``` @@ -63,6 +67,8 @@ The following arguments are supported: * `admin_state_up` - (Optional) The administrative state of the Listener. A valid value is true (UP) or false (DOWN). +* `tags` - (Optional) The key/value pairs to associate with the listener. + ## Attributes Reference The following attributes are exported: @@ -79,3 +85,4 @@ The following attributes are exported: * `default_tls_container_ref` - See Argument Reference above. * `sni_container_refs` - See Argument Reference above. * `admin_state_up` - See Argument Reference above. +* `tags` - See Argument Reference above. diff --git a/docs/resources/lb_loadbalancer_v2.md b/docs/resources/lb_loadbalancer_v2.md index 6d340c78f3..01d712beda 100644 --- a/docs/resources/lb_loadbalancer_v2.md +++ b/docs/resources/lb_loadbalancer_v2.md @@ -13,6 +13,10 @@ Manages a V2 loadbalancer resource within HuaweiCloud. ```hcl resource "huaweicloud_lb_loadbalancer_v2" "lb_1" { vip_subnet_id = "d9415786-5f1a-428b-b35f-2f1523e146d2" + + tags = { + key = "value" + } } ``` @@ -33,22 +37,24 @@ resource "huaweicloud_networking_eip_associate" "eip_1" { The following arguments are supported: -* `name` - (Optional) Human-readable name for the Loadbalancer. Does not have +* `name` - (Optional) Human-readable name for the loadbalancer. Does not have to be unique. -* `description` - (Optional) Human-readable description for the Loadbalancer. +* `description` - (Optional) Human-readable description for the loadbalancer. * `vip_subnet_id` - (Required) The network on which to allocate the - Loadbalancer's address. A tenant can only create Loadbalancers on networks + loadbalancer's address. A tenant can only create Loadbalancers on networks authorized by policy (e.g. networks that belong to them or networks that are shared). Changing this creates a new loadbalancer. * `vip_address` - (Optional) The ip address of the load balancer. Changing this creates a new loadbalancer. -* `admin_state_up` - (Optional) The administrative state of the Loadbalancer. +* `admin_state_up` - (Optional) The administrative state of the loadbalancer. A valid value is true (UP) or false (DOWN). +* `tags` - (Optional) The key/value pairs to associate with the loadbalancer. + ## Attributes Reference The following attributes are exported: @@ -59,4 +65,5 @@ The following attributes are exported: * `tenant_id` - See Argument Reference above. * `vip_address` - See Argument Reference above. * `admin_state_up` - See Argument Reference above. +* `tags` - See Argument Reference above. * `vip_port_id` - The Port ID of the Load Balancer IP. diff --git a/huaweicloud/config.go b/huaweicloud/config.go index a8ef69ddb3..9824854e14 100644 --- a/huaweicloud/config.go +++ b/huaweicloud/config.go @@ -549,6 +549,10 @@ func (c *Config) elasticLBClient(region string) (*golangsdk.ServiceClient, error return c.NewServiceClient("elb", region) } +func (c *Config) elbV2Client(region string) (*golangsdk.ServiceClient, error) { + return c.NewServiceClient("elbv2", region) +} + func (c *Config) fwV2Client(region string) (*golangsdk.ServiceClient, error) { return c.NewServiceClient("networkv2", region) } diff --git a/huaweicloud/endpoints.go b/huaweicloud/endpoints.go index e57dce5597..0b3c72f721 100644 --- a/huaweicloud/endpoints.go +++ b/huaweicloud/endpoints.go @@ -139,6 +139,10 @@ var allServiceCatalog = map[string]ServiceCatalog{ Version: "v1.0", WithOutProjectID: true, }, + "elbv2": ServiceCatalog{ + Name: "elb", + Version: "v2.0", + }, "fwv2": ServiceCatalog{ Name: "vpc", Version: "v2.0", diff --git a/huaweicloud/endpoints_test.go b/huaweicloud/endpoints_test.go index 9d858ba07a..c8cc0bf0d7 100644 --- a/huaweicloud/endpoints_test.go +++ b/huaweicloud/endpoints_test.go @@ -603,16 +603,26 @@ func TestAccServiceEndpoints_Network(t *testing.T) { actualURL = serviceClient.ResourceBaseURL() compareURL(expectedURL, actualURL, "vpc", "v1", t) - // test endpoint of loadElasticLoadBalancer v1.0 + // test endpoint of elb v1.0 serviceClient, err = nil, nil serviceClient, err = config.elasticLBClient(OS_REGION_NAME) if err != nil { - t.Fatalf("Error creating HuaweiCloud loadElasticLoadBalancer v1.0 client: %s", err) + t.Fatalf("Error creating HuaweiCloud ELB v1.0 client: %s", err) } expectedURL = fmt.Sprintf("https://elb.%s.%s/v1.0/", OS_REGION_NAME, config.Cloud) actualURL = serviceClient.ResourceBaseURL() compareURL(expectedURL, actualURL, "elb", "v1.0", t) + // test endpoint of elb v2.0 + serviceClient, err = nil, nil + serviceClient, err = config.elbV2Client(OS_REGION_NAME) + if err != nil { + t.Fatalf("Error creating HuaweiCloud ELB v2.0 client: %s", err) + } + expectedURL = fmt.Sprintf("https://elb.%s.%s/v2.0/%s/", OS_REGION_NAME, config.Cloud, config.TenantID) + actualURL = serviceClient.ResourceBaseURL() + compareURL(expectedURL, actualURL, "elb", "v2.0", t) + // test the endpoint of fw v2 service serviceClient, err = config.fwV2Client(OS_REGION_NAME) if err != nil { diff --git a/huaweicloud/resource_huaweicloud_lb_listener_v2.go b/huaweicloud/resource_huaweicloud_lb_listener_v2.go index 1271a8669d..6ecb6dc720 100644 --- a/huaweicloud/resource_huaweicloud_lb_listener_v2.go +++ b/huaweicloud/resource_huaweicloud_lb_listener_v2.go @@ -7,7 +7,9 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/huaweicloud/golangsdk/openstack/common/tags" "github.com/huaweicloud/golangsdk/openstack/networking/v2/extensions/lbaas_v2/listeners" ) @@ -36,14 +38,9 @@ func resourceListenerV2() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { - value := v.(string) - if value != "TCP" && value != "HTTP" && value != "HTTPS" && value != "TERMINATED_HTTPS" { - errors = append(errors, fmt.Errorf( - "Only 'TCP', 'HTTP', 'HTTPS' and 'TERMINATED_HTTPS' are supported values for 'protocol'")) - } - return - }, + ValidateFunc: validation.StringInSlice([]string{ + "TCP", "UDP", "HTTP", "HTTPS", "TERMINATED_HTTPS", + }, false), }, "protocol_port": { @@ -111,6 +108,7 @@ func resourceListenerV2() *schema.Resource { Default: true, Optional: true, }, + "tags": tagsSchema(), }, } } @@ -181,6 +179,19 @@ func resourceListenerV2Create(d *schema.ResourceData, meta interface{}) error { d.SetId(listener.ID) + //set tags + tagRaw := d.Get("tags").(map[string]interface{}) + if len(tagRaw) > 0 { + elbv2Client, err := config.elbV2Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud elb v2 client: %s", err) + } + taglist := expandResourceTags(tagRaw) + if tagErr := tags.Create(elbv2Client, "listeners", listener.ID, taglist).ExtractErr(); tagErr != nil { + return fmt.Errorf("Error setting tags of elb listener %s: %s", listener.ID, tagErr) + } + } + return resourceListenerV2Read(d, meta) } @@ -211,74 +222,104 @@ func resourceListenerV2Read(d *schema.ResourceData, meta interface{}) error { d.Set("default_tls_container_ref", listener.DefaultTlsContainerRef) d.Set("region", GetRegion(d, config)) + // set tags + elbv2Client, err := config.elbV2Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud elb v2 client: %s", err) + } + + resourceTags, err := tags.Get(elbv2Client, "listeners", d.Id()).Extract() + if err != nil { + return fmt.Errorf("Error fetching tags of elb listener: %s", err) + } + tagmap := tagsToMap(resourceTags.Tags) + d.Set("tags", tagmap) + return nil } func resourceListenerV2Update(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - lbClient, err := config.NetworkingV2Client(GetRegion(d, config)) - if err != nil { - return fmt.Errorf("Error creating HuaweiCloud networking client: %s", err) - } - var updateOpts listeners.UpdateOpts - if d.HasChange("name") { - updateOpts.Name = d.Get("name").(string) - } - if d.HasChange("description") { - updateOpts.Description = d.Get("description").(string) - } - if d.HasChange("connection_limit") { - connLimit := d.Get("connection_limit").(int) - updateOpts.ConnLimit = &connLimit - } - if d.HasChange("default_tls_container_ref") { - updateOpts.DefaultTlsContainerRef = d.Get("default_tls_container_ref").(string) - } - if d.HasChange("sni_container_refs") { - var sniContainerRefs []string - if raw, ok := d.GetOk("sni_container_refs"); ok { - for _, v := range raw.([]interface{}) { - sniContainerRefs = append(sniContainerRefs, v.(string)) + if d.HasChanges("name", "description", "admin_state_up", "connection_limit", + "default_tls_container_ref", "sni_container_refs", "http2_enable") { + lbClient, err := config.NetworkingV2Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud networking client: %s", err) + } + + var updateOpts listeners.UpdateOpts + if d.HasChange("name") { + updateOpts.Name = d.Get("name").(string) + } + if d.HasChange("description") { + updateOpts.Description = d.Get("description").(string) + } + if d.HasChange("connection_limit") { + connLimit := d.Get("connection_limit").(int) + updateOpts.ConnLimit = &connLimit + } + if d.HasChange("default_tls_container_ref") { + updateOpts.DefaultTlsContainerRef = d.Get("default_tls_container_ref").(string) + } + if d.HasChange("sni_container_refs") { + var sniContainerRefs []string + if raw, ok := d.GetOk("sni_container_refs"); ok { + for _, v := range raw.([]interface{}) { + sniContainerRefs = append(sniContainerRefs, v.(string)) + } } + updateOpts.SniContainerRefs = sniContainerRefs + } + if d.HasChange("admin_state_up") { + asu := d.Get("admin_state_up").(bool) + updateOpts.AdminStateUp = &asu + } + if d.HasChange("http2_enable") { + http2 := d.Get("http2_enable").(bool) + updateOpts.Http2Enable = &http2 } - updateOpts.SniContainerRefs = sniContainerRefs - } - if d.HasChange("admin_state_up") { - asu := d.Get("admin_state_up").(bool) - updateOpts.AdminStateUp = &asu - } - if d.HasChange("http2_enable") { - http2 := d.Get("http2_enable").(bool) - updateOpts.Http2Enable = &http2 - } - // Wait for LoadBalancer to become active before continuing - lbID := d.Get("loadbalancer_id").(string) - timeout := d.Timeout(schema.TimeoutUpdate) - err = waitForLBV2LoadBalancer(lbClient, lbID, "ACTIVE", nil, timeout) - if err != nil { - return err - } + // Wait for LoadBalancer to become active before continuing + lbID := d.Get("loadbalancer_id").(string) + timeout := d.Timeout(schema.TimeoutUpdate) + err = waitForLBV2LoadBalancer(lbClient, lbID, "ACTIVE", nil, timeout) + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating listener %s with options: %#v", d.Id(), updateOpts) + //lintignore:R006 + err = resource.Retry(timeout, func() *resource.RetryError { + _, err = listeners.Update(lbClient, d.Id(), updateOpts).Extract() + if err != nil { + return checkForRetryableError(err) + } + return nil + }) - log.Printf("[DEBUG] Updating listener %s with options: %#v", d.Id(), updateOpts) - //lintignore:R006 - err = resource.Retry(timeout, func() *resource.RetryError { - _, err = listeners.Update(lbClient, d.Id(), updateOpts).Extract() if err != nil { - return checkForRetryableError(err) + return fmt.Errorf("Error updating listener %s: %s", d.Id(), err) } - return nil - }) - if err != nil { - return fmt.Errorf("Error updating listener %s: %s", d.Id(), err) + // Wait for LoadBalancer to become active again before continuing + err = waitForLBV2LoadBalancer(lbClient, lbID, "ACTIVE", nil, timeout) + if err != nil { + return err + } } - // Wait for LoadBalancer to become active again before continuing - err = waitForLBV2LoadBalancer(lbClient, lbID, "ACTIVE", nil, timeout) - if err != nil { - return err + // update tags + if d.HasChange("tags") { + elbv2Client, err := config.elbV2Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud elb v2 client: %s", err) + } + + tagErr := UpdateResourceTags(elbv2Client, d, "listeners", d.Id()) + if tagErr != nil { + return fmt.Errorf("Error updating tags of elb listener:%s, err:%s", d.Id(), tagErr) + } } return resourceListenerV2Read(d, meta) diff --git a/huaweicloud/resource_huaweicloud_lb_listener_v2_test.go b/huaweicloud/resource_huaweicloud_lb_listener_v2_test.go index b740866bed..a66b9824b8 100644 --- a/huaweicloud/resource_huaweicloud_lb_listener_v2_test.go +++ b/huaweicloud/resource_huaweicloud_lb_listener_v2_test.go @@ -11,6 +11,7 @@ import ( func TestAccLBV2Listener_basic(t *testing.T) { var listener listeners.Listener + resourceName := "huaweicloud_lb_listener_v2.listener_1" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheckULB(t) }, @@ -20,20 +21,19 @@ func TestAccLBV2Listener_basic(t *testing.T) { { Config: TestAccLBV2ListenerConfig_basic, Check: resource.ComposeTestCheckFunc( - testAccCheckLBV2ListenerExists("huaweicloud_lb_listener_v2.listener_1", &listener), - resource.TestCheckResourceAttr( - "huaweicloud_lb_listener_v2.listener_1", "name", "listener_1"), - resource.TestCheckResourceAttr( - "huaweicloud_lb_listener_v2.listener_1", "connection_limit", "-1"), + testAccCheckLBV2ListenerExists(resourceName, &listener), + resource.TestCheckResourceAttr(resourceName, "name", "listener_1"), + resource.TestCheckResourceAttr(resourceName, "tags.key", "value"), + resource.TestCheckResourceAttr(resourceName, "tags.owner", "terraform"), + resource.TestCheckResourceAttr(resourceName, "connection_limit", "-1"), ), }, { Config: TestAccLBV2ListenerConfig_update, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr( - "huaweicloud_lb_listener_v2.listener_1", "name", "listener_1_updated"), - resource.TestCheckResourceAttr( - "huaweicloud_lb_listener_v2.listener_1", "name", "listener_1_updated"), + resource.TestCheckResourceAttr(resourceName, "name", "listener_1_updated"), + resource.TestCheckResourceAttr(resourceName, "tags.foo", "bar"), + resource.TestCheckResourceAttr(resourceName, "tags.owner", "terraform_update"), ), }, }, @@ -103,13 +103,12 @@ resource "huaweicloud_lb_listener_v2" "listener_1" { name = "listener_1" protocol = "HTTP" protocol_port = 8080 - loadbalancer_id = "${huaweicloud_lb_loadbalancer_v2.loadbalancer_1.id}" + loadbalancer_id = huaweicloud_lb_loadbalancer_v2.loadbalancer_1.id - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } + tags = { + key = "value" + owner = "terraform" + } } `, OS_SUBNET_ID) @@ -124,12 +123,11 @@ resource "huaweicloud_lb_listener_v2" "listener_1" { protocol = "HTTP" protocol_port = 8080 admin_state_up = "true" - loadbalancer_id = "${huaweicloud_lb_loadbalancer_v2.loadbalancer_1.id}" + loadbalancer_id = huaweicloud_lb_loadbalancer_v2.loadbalancer_1.id - timeouts { - create = "5m" - update = "5m" - delete = "5m" - } + tags = { + foo = "bar" + owner = "terraform_update" + } } `, OS_SUBNET_ID) diff --git a/huaweicloud/resource_huaweicloud_lb_loadbalancer_v2.go b/huaweicloud/resource_huaweicloud_lb_loadbalancer_v2.go index 89d0fa52cd..4f64b5a620 100644 --- a/huaweicloud/resource_huaweicloud_lb_loadbalancer_v2.go +++ b/huaweicloud/resource_huaweicloud_lb_loadbalancer_v2.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/openstack/common/tags" "github.com/huaweicloud/golangsdk/openstack/networking/v2/extensions/lbaas_v2/loadbalancers" "github.com/huaweicloud/golangsdk/openstack/networking/v2/ports" ) @@ -81,6 +82,7 @@ func resourceLoadBalancerV2() *schema.Resource { ForceNew: true, }, + "tags": tagsSchema(), "loadbalancer_provider": { Type: schema.TypeString, Optional: true, @@ -101,7 +103,7 @@ func resourceLoadBalancerV2() *schema.Resource { func resourceLoadBalancerV2Create(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - lbClient, err := config.NetworkingV2Client(GetRegion(d, config)) + networkingClient, err := config.NetworkingV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating HuaweiCloud networking client: %s", err) } @@ -124,22 +126,18 @@ func resourceLoadBalancerV2Create(d *schema.ResourceData, meta interface{}) erro } log.Printf("[DEBUG] Create Options: %#v", createOpts) - lb, err := loadbalancers.Create(lbClient, createOpts).Extract() + lb, err := loadbalancers.Create(networkingClient, createOpts).Extract() if err != nil { return fmt.Errorf("Error creating LoadBalancer: %s", err) } // Wait for LoadBalancer to become active before continuing timeout := d.Timeout(schema.TimeoutCreate) - err = waitForLBV2LoadBalancer(lbClient, lb.ID, "ACTIVE", nil, timeout) + err = waitForLBV2LoadBalancer(networkingClient, lb.ID, "ACTIVE", nil, timeout) if err != nil { return err } - networkingClient, err := config.NetworkingV2Client(GetRegion(d, config)) - if err != nil { - return fmt.Errorf("Error creating HuaweiCloud networking client: %s", err) - } // Once the loadbalancer has been created, apply any requested security groups // to the port that was created behind the scenes. if err := resourceLoadBalancerV2SecurityGroups(networkingClient, lb.VipPortID, d); err != nil { @@ -149,17 +147,30 @@ func resourceLoadBalancerV2Create(d *schema.ResourceData, meta interface{}) erro // If all has been successful, set the ID on the resource d.SetId(lb.ID) + //set tags + tagRaw := d.Get("tags").(map[string]interface{}) + if len(tagRaw) > 0 { + elbClient, err := config.elbV2Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud elb v2 client: %s", err) + } + taglist := expandResourceTags(tagRaw) + if tagErr := tags.Create(elbClient, "loadbalancers", lb.ID, taglist).ExtractErr(); tagErr != nil { + return fmt.Errorf("Error setting tags of load balancer %s: %s", lb.ID, tagErr) + } + } + return resourceLoadBalancerV2Read(d, meta) } func resourceLoadBalancerV2Read(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - lbClient, err := config.NetworkingV2Client(GetRegion(d, config)) + networkingClient, err := config.NetworkingV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating HuaweiCloud networking client: %s", err) } - lb, err := loadbalancers.Get(lbClient, d.Id()).Extract() + lb, err := loadbalancers.Get(networkingClient, d.Id()).Extract() if err != nil { return CheckDeleted(d, err, "loadbalancer") } @@ -179,10 +190,6 @@ func resourceLoadBalancerV2Read(d *schema.ResourceData, meta interface{}) error // Get any security groups on the VIP Port if lb.VipPortID != "" { - networkingClient, err := config.NetworkingV2Client(GetRegion(d, config)) - if err != nil { - return fmt.Errorf("Error creating HuaweiCloud networking client: %s", err) - } port, err := ports.Get(networkingClient, lb.VipPortID).Extract() if err != nil { return err @@ -191,63 +198,87 @@ func resourceLoadBalancerV2Read(d *schema.ResourceData, meta interface{}) error d.Set("security_group_ids", port.SecurityGroups) } + // set tags + elbClient, err := config.elbV2Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud elb v2 client: %s", err) + } + + resourceTags, err := tags.Get(elbClient, "loadbalancers", d.Id()).Extract() + if err != nil { + return fmt.Errorf("Error fetching tags of load balancer: %s", err) + } + tagmap := tagsToMap(resourceTags.Tags) + d.Set("tags", tagmap) + return nil } func resourceLoadBalancerV2Update(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - lbClient, err := config.NetworkingV2Client(GetRegion(d, config)) + networkingClient, err := config.NetworkingV2Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating HuaweiCloud networking client: %s", err) } - var updateOpts loadbalancers.UpdateOpts - if d.HasChange("name") { - updateOpts.Name = d.Get("name").(string) - } - if d.HasChange("description") { - updateOpts.Description = d.Get("description").(string) - } - if d.HasChange("admin_state_up") { - asu := d.Get("admin_state_up").(bool) - updateOpts.AdminStateUp = &asu - } - - // Wait for LoadBalancer to become active before continuing - timeout := d.Timeout(schema.TimeoutUpdate) - err = waitForLBV2LoadBalancer(lbClient, d.Id(), "ACTIVE", nil, timeout) - if err != nil { - return err - } + if d.HasChanges("name", "description", "admin_state_up") { + var updateOpts loadbalancers.UpdateOpts + if d.HasChange("name") { + updateOpts.Name = d.Get("name").(string) + } + if d.HasChange("description") { + updateOpts.Description = d.Get("description").(string) + } + if d.HasChange("admin_state_up") { + asu := d.Get("admin_state_up").(bool) + updateOpts.AdminStateUp = &asu + } - log.Printf("[DEBUG] Updating loadbalancer %s with options: %#v", d.Id(), updateOpts) - //lintignore:R006 - err = resource.Retry(timeout, func() *resource.RetryError { - _, err = loadbalancers.Update(lbClient, d.Id(), updateOpts).Extract() + // Wait for LoadBalancer to become active before continuing + timeout := d.Timeout(schema.TimeoutUpdate) + err = waitForLBV2LoadBalancer(networkingClient, d.Id(), "ACTIVE", nil, timeout) if err != nil { - return checkForRetryableError(err) + return err } - return nil - }) - // Wait for LoadBalancer to become active before continuing - err = waitForLBV2LoadBalancer(lbClient, d.Id(), "ACTIVE", nil, timeout) - if err != nil { - return err + log.Printf("[DEBUG] Updating loadbalancer %s with options: %#v", d.Id(), updateOpts) + //lintignore:R006 + err = resource.Retry(timeout, func() *resource.RetryError { + _, err = loadbalancers.Update(networkingClient, d.Id(), updateOpts).Extract() + if err != nil { + return checkForRetryableError(err) + } + return nil + }) + + // Wait for LoadBalancer to become active before continuing + err = waitForLBV2LoadBalancer(networkingClient, d.Id(), "ACTIVE", nil, timeout) + if err != nil { + return err + } } // Security Groups get updated separately if d.HasChange("security_group_ids") { - networkingClient, err := config.NetworkingV2Client(GetRegion(d, config)) - if err != nil { - return fmt.Errorf("Error creating HuaweiCloud networking client: %s", err) - } vipPortID := d.Get("vip_port_id").(string) if err := resourceLoadBalancerV2SecurityGroups(networkingClient, vipPortID, d); err != nil { return err } } + // update tags + if d.HasChange("tags") { + elbClient, err := config.elbV2Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud elb v2 client: %s", err) + } + + tagErr := UpdateResourceTags(elbClient, d, "loadbalancers", d.Id()) + if tagErr != nil { + return fmt.Errorf("Error updating tags of load balancer:%s, err:%s", d.Id(), tagErr) + } + } + return resourceLoadBalancerV2Read(d, meta) } diff --git a/huaweicloud/resource_huaweicloud_lb_loadbalancer_v2_test.go b/huaweicloud/resource_huaweicloud_lb_loadbalancer_v2_test.go index 97af37894a..97d30dc0e9 100644 --- a/huaweicloud/resource_huaweicloud_lb_loadbalancer_v2_test.go +++ b/huaweicloud/resource_huaweicloud_lb_loadbalancer_v2_test.go @@ -15,6 +15,7 @@ import ( func TestAccLBV2LoadBalancer_basic(t *testing.T) { var lb loadbalancers.LoadBalancer + resourceName := "huaweicloud_lb_loadbalancer_v2.loadbalancer_1" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheckULB(t) }, @@ -24,17 +25,20 @@ func TestAccLBV2LoadBalancer_basic(t *testing.T) { { Config: testAccLBV2LoadBalancerConfig_basic, Check: resource.ComposeTestCheckFunc( - testAccCheckLBV2LoadBalancerExists("huaweicloud_lb_loadbalancer_v2.loadbalancer_1", &lb), + testAccCheckLBV2LoadBalancerExists(resourceName, &lb), + resource.TestCheckResourceAttr(resourceName, "name", "loadbalancer_1"), + resource.TestCheckResourceAttr(resourceName, "tags.key", "value"), + resource.TestCheckResourceAttr(resourceName, "tags.owner", "terraform"), + resource.TestMatchResourceAttr(resourceName, "vip_port_id", + regexp.MustCompile("^[a-f0-9-]+")), ), }, { Config: testAccLBV2LoadBalancerConfig_update, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr( - "huaweicloud_lb_loadbalancer_v2.loadbalancer_1", "name", "loadbalancer_1_updated"), - resource.TestMatchResourceAttr( - "huaweicloud_lb_loadbalancer_v2.loadbalancer_1", "vip_port_id", - regexp.MustCompile("^[a-f0-9-]+")), + resource.TestCheckResourceAttr(resourceName, "name", "loadbalancer_1_updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + resource.TestCheckResourceAttr(resourceName, "tags.owner", "terraform_update"), ), }, }, @@ -56,9 +60,9 @@ func TestAccLBV2LoadBalancer_secGroup(t *testing.T) { testAccCheckLBV2LoadBalancerExists( "huaweicloud_lb_loadbalancer_v2.loadbalancer_1", &lb), testAccCheckNetworkingV2SecGroupExists( - "huaweicloud_networking_secgroup_v2.secgroup_1", &sg_1), + "huaweicloud_networking_secgroup.secgroup_1", &sg_1), testAccCheckNetworkingV2SecGroupExists( - "huaweicloud_networking_secgroup_v2.secgroup_1", &sg_2), + "huaweicloud_networking_secgroup.secgroup_1", &sg_2), resource.TestCheckResourceAttr( "huaweicloud_lb_loadbalancer_v2.loadbalancer_1", "security_group_ids.#", "1"), testAccCheckLBV2LoadBalancerHasSecGroup(&lb, &sg_1), @@ -70,9 +74,9 @@ func TestAccLBV2LoadBalancer_secGroup(t *testing.T) { testAccCheckLBV2LoadBalancerExists( "huaweicloud_lb_loadbalancer_v2.loadbalancer_1", &lb), testAccCheckNetworkingV2SecGroupExists( - "huaweicloud_networking_secgroup_v2.secgroup_2", &sg_1), + "huaweicloud_networking_secgroup.secgroup_2", &sg_1), testAccCheckNetworkingV2SecGroupExists( - "huaweicloud_networking_secgroup_v2.secgroup_2", &sg_2), + "huaweicloud_networking_secgroup.secgroup_2", &sg_2), resource.TestCheckResourceAttr( "huaweicloud_lb_loadbalancer_v2.loadbalancer_1", "security_group_ids.#", "2"), testAccCheckLBV2LoadBalancerHasSecGroup(&lb, &sg_1), @@ -85,9 +89,9 @@ func TestAccLBV2LoadBalancer_secGroup(t *testing.T) { testAccCheckLBV2LoadBalancerExists( "huaweicloud_lb_loadbalancer_v2.loadbalancer_1", &lb), testAccCheckNetworkingV2SecGroupExists( - "huaweicloud_networking_secgroup_v2.secgroup_2", &sg_1), + "huaweicloud_networking_secgroup.secgroup_2", &sg_1), testAccCheckNetworkingV2SecGroupExists( - "huaweicloud_networking_secgroup_v2.secgroup_2", &sg_2), + "huaweicloud_networking_secgroup.secgroup_2", &sg_2), resource.TestCheckResourceAttr( "huaweicloud_lb_loadbalancer_v2.loadbalancer_1", "security_group_ids.#", "1"), testAccCheckLBV2LoadBalancerHasSecGroup(&lb, &sg_2), @@ -180,6 +184,11 @@ resource "huaweicloud_lb_loadbalancer_v2" "loadbalancer_1" { name = "loadbalancer_1" vip_subnet_id = "%s" + tags = { + key = "value" + owner = "terraform" + } + timeouts { create = "5m" update = "5m" @@ -194,6 +203,11 @@ resource "huaweicloud_lb_loadbalancer_v2" "loadbalancer_1" { admin_state_up = "true" vip_subnet_id = "%s" + tags = { + key1 = "value1" + owner = "terraform_update" + } + timeouts { create = "5m" update = "5m" @@ -203,12 +217,12 @@ resource "huaweicloud_lb_loadbalancer_v2" "loadbalancer_1" { `, OS_SUBNET_ID) var testAccLBV2LoadBalancer_secGroup = fmt.Sprintf(` -resource "huaweicloud_networking_secgroup_v2" "secgroup_1" { +resource "huaweicloud_networking_secgroup" "secgroup_1" { name = "secgroup_1" description = "secgroup_1" } -resource "huaweicloud_networking_secgroup_v2" "secgroup_2" { +resource "huaweicloud_networking_secgroup" "secgroup_2" { name = "secgroup_2" description = "secgroup_2" } @@ -217,18 +231,18 @@ resource "huaweicloud_lb_loadbalancer_v2" "loadbalancer_1" { name = "loadbalancer_1" vip_subnet_id = "%s" security_group_ids = [ - "${huaweicloud_networking_secgroup_v2.secgroup_1.id}" + huaweicloud_networking_secgroup.secgroup_1.id ] } `, OS_SUBNET_ID) var testAccLBV2LoadBalancer_secGroup_update1 = fmt.Sprintf(` -resource "huaweicloud_networking_secgroup_v2" "secgroup_1" { +resource "huaweicloud_networking_secgroup" "secgroup_1" { name = "secgroup_1" description = "secgroup_1" } -resource "huaweicloud_networking_secgroup_v2" "secgroup_2" { +resource "huaweicloud_networking_secgroup" "secgroup_2" { name = "secgroup_2" description = "secgroup_2" } @@ -237,19 +251,19 @@ resource "huaweicloud_lb_loadbalancer_v2" "loadbalancer_1" { name = "loadbalancer_1" vip_subnet_id = "%s" security_group_ids = [ - "${huaweicloud_networking_secgroup_v2.secgroup_1.id}", - "${huaweicloud_networking_secgroup_v2.secgroup_2.id}" + huaweicloud_networking_secgroup.secgroup_1.id, + huaweicloud_networking_secgroup.secgroup_2.id ] } `, OS_SUBNET_ID) var testAccLBV2LoadBalancer_secGroup_update2 = fmt.Sprintf(` -resource "huaweicloud_networking_secgroup_v2" "secgroup_1" { +resource "huaweicloud_networking_secgroup" "secgroup_1" { name = "secgroup_1" description = "secgroup_1" } -resource "huaweicloud_networking_secgroup_v2" "secgroup_2" { +resource "huaweicloud_networking_secgroup" "secgroup_2" { name = "secgroup_2" description = "secgroup_2" } @@ -258,8 +272,7 @@ resource "huaweicloud_lb_loadbalancer_v2" "loadbalancer_1" { name = "loadbalancer_1" vip_subnet_id = "%s" security_group_ids = [ - "${huaweicloud_networking_secgroup_v2.secgroup_2.id}" + huaweicloud_networking_secgroup.secgroup_2.id ] - depends_on = ["huaweicloud_networking_secgroup_v2.secgroup_1"] } `, OS_SUBNET_ID)