Skip to content

Commit

Permalink
Octavia: Add tags to loadbalancer
Browse files Browse the repository at this point in the history
Add support for tags for openstack_lb_loadbalancer_v2
For #1300
  • Loading branch information
nikParasyr committed Nov 25, 2021
1 parent 3a235ee commit 1984365
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 14 deletions.
68 changes: 68 additions & 0 deletions openstack/lb_v2_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/gophercloud/gophercloud"
octavialisteners "github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/listeners"
octavialoadbalancers "github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers"
octaviamonitors "github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/monitors"
octaviapools "github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/pools"
neutronl7policies "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/l7policies"
Expand Down Expand Up @@ -66,6 +67,73 @@ func chooseLBV2AccTestClient(config *Config, region string) (*gophercloud.Servic
return config.NetworkingV2Client(region)
}

// chooseLBV2LoadbalancerUpdateOpts will determine which load balancer update options to use:
// either the Octavia/LBaaS or the Neutron/Networking v2.
func chooseLBV2LoadbalancerUpdateOpts(d *schema.ResourceData, config *Config) (neutronloadbalancers.UpdateOptsBuilder, error) {
var hasChange bool

if config.UseOctavia {
// Use Octavia.
var updateOpts octavialoadbalancers.UpdateOpts

if d.HasChange("name") {
hasChange = true
name := d.Get("name").(string)
updateOpts.Name = &name
}
if d.HasChange("description") {
hasChange = true
description := d.Get("description").(string)
updateOpts.Description = &description
}
if d.HasChange("admin_state_up") {
hasChange = true
asu := d.Get("admin_state_up").(bool)
updateOpts.AdminStateUp = &asu
}

if d.HasChange("tags") {
hasChange = true
if v, ok := d.GetOk("tags"); ok {
tags := v.(*schema.Set).List()
tagsToUpdate := expandToStringSlice(tags)
updateOpts.Tags = &tagsToUpdate
} else {
updateOpts.Tags = &[]string{}
}
}

if hasChange {
return updateOpts, nil
}
}

// Use Neutron.
var updateOpts neutronloadbalancers.UpdateOpts

if d.HasChange("name") {
hasChange = true
name := d.Get("name").(string)
updateOpts.Name = &name
}
if d.HasChange("description") {
hasChange = true
description := d.Get("description").(string)
updateOpts.Description = &description
}
if d.HasChange("admin_state_up") {
hasChange = true
asu := d.Get("admin_state_up").(bool)
updateOpts.AdminStateUp = &asu
}

if hasChange {
return updateOpts, nil
}

return nil, nil
}

// chooseLBV2ListenerCreateOpts will determine which load balancer listener Create options to use:
// either the Octavia/LBaaS or the Neutron/Networking v2.
func chooseLBV2ListenerCreateOpts(d *schema.ResourceData, config *Config) (neutronlisteners.CreateOptsBuilder, error) {
Expand Down
29 changes: 16 additions & 13 deletions openstack/resource_openstack_lb_loadbalancer_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ func resourceLoadBalancerV2() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"tags": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
},
}
}
Expand Down Expand Up @@ -158,6 +164,11 @@ func resourceLoadBalancerV2Create(ctx context.Context, d *schema.ResourceData, m
createOpts.AvailabilityZone = aZ
}

if v, ok := d.GetOk("tags"); ok {
tags := v.(*schema.Set).List()
createOpts.Tags = expandToStringSlice(tags)
}

log.Printf("[DEBUG][Octavia] openstack_lb_loadbalancer_v2 create options: %#v", createOpts)
lb, err := octavialoadbalancers.Create(lbClient, createOpts).Extract()
if err != nil {
Expand Down Expand Up @@ -237,6 +248,7 @@ func resourceLoadBalancerV2Read(ctx context.Context, d *schema.ResourceData, met
d.Set("loadbalancer_provider", lb.Provider)
d.Set("availability_zone", lb.AvailabilityZone)
d.Set("region", GetRegion(d, config))
d.Set("tags", lb.Tags)
vipPortID = lb.VipPortID
} else {
lb, err := neutronloadbalancers.Get(lbClient, d.Id()).Extract()
Expand Down Expand Up @@ -280,21 +292,12 @@ func resourceLoadBalancerV2Update(ctx context.Context, d *schema.ResourceData, m
return diag.Errorf("Error creating OpenStack networking client: %s", err)
}

var updateOpts neutronloadbalancers.UpdateOpts
if d.HasChange("name") {
name := d.Get("name").(string)
updateOpts.Name = &name
}
if d.HasChange("description") {
description := d.Get("description").(string)
updateOpts.Description = &description
}
if d.HasChange("admin_state_up") {
asu := d.Get("admin_state_up").(bool)
updateOpts.AdminStateUp = &asu
updateOpts, err := chooseLBV2LoadbalancerUpdateOpts(d, config)
if err != nil {
return diag.Errorf("Error building openstack_lb_loadbalancer_v2 update options: %s", err)
}

if updateOpts != (neutronloadbalancers.UpdateOpts{}) {
if updateOpts != nil {
// Wait for load-balancer to become active before continuing.
timeout := d.Timeout(schema.TimeoutUpdate)
err = waitForLBV2LoadBalancer(ctx, lbClient, d.Id(), "ACTIVE", getLbPendingStatuses(), timeout)
Expand Down
79 changes: 78 additions & 1 deletion openstack/resource_openstack_lb_loadbalancer_v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"

octavialoadbalancers "github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups"
"github.com/gophercloud/gophercloud/openstack/networking/v2/ports"
Expand All @@ -34,11 +35,16 @@ func TestAccLBV2LoadBalancer_basic(t *testing.T) {
Config: testAccLbV2LoadBalancerConfigBasic(lbProvider),
Check: resource.ComposeTestCheckFunc(
testAccCheckLBV2LoadBalancerExists("openstack_lb_loadbalancer_v2.loadbalancer_1", &lb),
testAccCheckLBV2LoadBalancerHasTag("openstack_lb_loadbalancer_v2.loadbalancer_1", "tag1"),
testAccCheckLBV2LoadBalancerTagCount("openstack_lb_loadbalancer_v2.loadbalancer_1", 1),
),
},
{
Config: testAccLbV2LoadBalancerConfigUpdate(lbProvider),
Check: resource.ComposeTestCheckFunc(
testAccCheckLBV2LoadBalancerHasTag("openstack_lb_loadbalancer_v2.loadbalancer_1", "tag1"),
testAccCheckLBV2LoadBalancerHasTag("openstack_lb_loadbalancer_v2.loadbalancer_1", "tag2"),
testAccCheckLBV2LoadBalancerTagCount("openstack_lb_loadbalancer_v2.loadbalancer_1", 2),
resource.TestCheckResourceAttr(
"openstack_lb_loadbalancer_v2.loadbalancer_1", "name", "loadbalancer_1_updated"),
resource.TestMatchResourceAttr(
Expand Down Expand Up @@ -207,14 +213,83 @@ func testAccCheckLBV2LoadBalancerExists(
}

if found.ID != rs.Primary.ID {
return fmt.Errorf("Member not found")
return fmt.Errorf("Loadbalancer not found")
}

*lb = *found

return nil
}
}
func testAccCheckLBV2LoadBalancerHasTag(n, tag string) 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 := chooseLBV2AccTestClient(config, osRegionName)
if err != nil {
return fmt.Errorf("Error creating OpenStack load balancing client: %s", err)
}

found, err := octavialoadbalancers.Get(lbClient, rs.Primary.ID).Extract()
if err != nil {
return err
}

if found.ID != rs.Primary.ID {
return fmt.Errorf("Loadbalancer not found")
}

for _, v := range found.Tags {
if tag == v {
return nil
}
}

return fmt.Errorf("Tag not found: %s", tag)
}
}

func testAccCheckLBV2LoadBalancerTagCount(n string, expected int) 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 := chooseLBV2AccTestClient(config, osRegionName)
if err != nil {
return fmt.Errorf("Error creating OpenStack load balancing client: %s", err)
}

found, err := octavialoadbalancers.Get(lbClient, rs.Primary.ID).Extract()
if err != nil {
return err
}

if found.ID != rs.Primary.ID {
return fmt.Errorf("Loadbalancer not found")
}

if len(found.Tags) != expected {
return fmt.Errorf("Expecting %d tags, found %d", expected, len(found.Tags))
}

return nil
}
}

func testAccCheckLBV2LoadBalancerHasSecGroup(
lb *loadbalancers.LoadBalancer, sg *groups.SecGroup) resource.TestCheckFunc {
Expand Down Expand Up @@ -258,6 +333,7 @@ func testAccLbV2LoadBalancerConfigBasic(lbProvider string) string {
name = "loadbalancer_1"
loadbalancer_provider = "%s"
vip_subnet_id = "${openstack_networking_subnet_v2.subnet_1.id}"
tags = ["tag1"]
timeouts {
create = "15m"
Expand Down Expand Up @@ -286,6 +362,7 @@ func testAccLbV2LoadBalancerConfigUpdate(lbProvider string) string {
loadbalancer_provider = "%s"
admin_state_up = "true"
vip_subnet_id = "${openstack_networking_subnet_v2.subnet_1.id}"
tags = ["tag1", "tag2"]
timeouts {
create = "15m"
Expand Down
4 changes: 4 additions & 0 deletions website/docs/r/lb_loadbalancer_v2.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ The following arguments are supported:
loadbalancer. The security groups must be specified by ID and not name (as
opposed to how they are configured with the Compute Instance).

* `tags` - (Optional) A list of simple strings assigned to the loadbalancer.
Available only for Octavia **minor version 2.5 or later**.

## Attributes Reference

The following attributes are exported:
Expand All @@ -90,6 +93,7 @@ The following attributes are exported:
* `loadbalancer_provider` - See Argument Reference above.
* `availability_zone` - See Argument Reference above.
* `security_group_ids` - See Argument Reference above.
* `tags` - See Argument Reference above.
* `vip_port_id` - The Port ID of the Load Balancer IP.

## Import
Expand Down

0 comments on commit 1984365

Please sign in to comment.