opentofu/builtin/providers/openstack/resource_openstack_lb_loadbalancer_v2.go
Joe Topjian f563b24002 provider/openstack: lbaas v2 updates
This commit cleans up the acceptance test formatting for the lbaas v2
resources. It also modifies the devstack script to enable the lbaas
v2 service for testing. Finally, this commit increases the timeout
for load balancer creation since it takes some time to do within
devstack.
2016-06-11 04:20:44 +00:00

257 lines
7.0 KiB
Go

package openstack
import (
"fmt"
"log"
"time"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers"
)
func resourceLoadBalancerV2() *schema.Resource {
return &schema.Resource{
Create: resourceLoadBalancerV2Create,
Read: resourceLoadBalancerV2Read,
Update: resourceLoadBalancerV2Update,
Delete: resourceLoadBalancerV2Delete,
Schema: map[string]*schema.Schema{
"region": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""),
},
"name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"description": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"vip_subnet_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"tenant_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"vip_address": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"admin_state_up": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
"flavor": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"provider": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
},
}
}
func resourceLoadBalancerV2Create(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(d.Get("region").(string))
if err != nil {
return fmt.Errorf("Error creating OpenStack networking client: %s", err)
}
adminStateUp := d.Get("admin_state_up").(bool)
createOpts := loadbalancers.CreateOpts{
Name: d.Get("name").(string),
Description: d.Get("description").(string),
VipSubnetID: d.Get("vip_subnet_id").(string),
TenantID: d.Get("tenant_id").(string),
VipAddress: d.Get("vip_address").(string),
AdminStateUp: &adminStateUp,
Flavor: d.Get("flavor").(string),
Provider: d.Get("provider").(string),
}
log.Printf("[DEBUG] Create Options: %#v", createOpts)
lb, err := loadbalancers.Create(networkingClient, createOpts).Extract()
if err != nil {
return fmt.Errorf("Error creating OpenStack LoadBalancer: %s", err)
}
log.Printf("[INFO] LoadBalancer ID: %s", lb.ID)
log.Printf("[DEBUG] Waiting for Openstack LoadBalancer (%s) to become available.", lb.ID)
stateConf := &resource.StateChangeConf{
Pending: []string{"PENDING_CREATE"},
Target: []string{"ACTIVE"},
Refresh: waitForLoadBalancerActive(networkingClient, lb.ID),
Timeout: 20 * time.Minute,
Delay: 5 * time.Second,
MinTimeout: 3 * time.Second,
}
_, err = stateConf.WaitForState()
if err != nil {
return err
}
d.SetId(lb.ID)
return resourceLoadBalancerV2Read(d, meta)
}
func resourceLoadBalancerV2Read(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(d.Get("region").(string))
if err != nil {
return fmt.Errorf("Error creating OpenStack networking client: %s", err)
}
lb, err := loadbalancers.Get(networkingClient, d.Id()).Extract()
if err != nil {
return CheckDeleted(d, err, "LoadBalancerV2")
}
log.Printf("[DEBUG] Retreived OpenStack LoadBalancerV2 %s: %+v", d.Id(), lb)
d.Set("name", lb.Name)
d.Set("description", lb.Description)
d.Set("vip_subnet_id", lb.VipSubnetID)
d.Set("tenant_id", lb.TenantID)
d.Set("vip_address", lb.VipAddress)
d.Set("admin_state_up", lb.AdminStateUp)
d.Set("flavor", lb.Flavor)
d.Set("provider", lb.Provider)
return nil
}
func resourceLoadBalancerV2Update(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(d.Get("region").(string))
if err != nil {
return fmt.Errorf("Error creating OpenStack 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
}
log.Printf("[DEBUG] Updating OpenStack LBaaSV2 LoadBalancer %s with options: %+v", d.Id(), updateOpts)
_, err = loadbalancers.Update(networkingClient, d.Id(), updateOpts).Extract()
if err != nil {
return fmt.Errorf("Error updating OpenStack LBaaSV2 LoadBalancer: %s", err)
}
return resourceLoadBalancerV2Read(d, meta)
}
func resourceLoadBalancerV2Delete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
networkingClient, err := config.networkingV2Client(d.Get("region").(string))
if err != nil {
return fmt.Errorf("Error creating OpenStack networking client: %s", err)
}
stateConf := &resource.StateChangeConf{
Pending: []string{"ACTIVE", "PENDING_DELETE"},
Target: []string{"DELETED"},
Refresh: waitForLoadBalancerDelete(networkingClient, d.Id()),
Timeout: 2 * time.Minute,
Delay: 5 * time.Second,
MinTimeout: 3 * time.Second,
}
_, err = stateConf.WaitForState()
if err != nil {
return fmt.Errorf("Error deleting OpenStack LB Pool: %s", err)
}
d.SetId("")
return nil
}
func waitForLoadBalancerActive(networkingClient *gophercloud.ServiceClient, lbID string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
lb, err := loadbalancers.Get(networkingClient, lbID).Extract()
if err != nil {
return nil, "", err
}
log.Printf("[DEBUG] OpenStack LoadBalancer: %+v", lb)
if lb.ProvisioningStatus == "ACTIVE" {
return lb, "ACTIVE", nil
}
return lb, lb.ProvisioningStatus, nil
}
}
func waitForLoadBalancerDelete(networkingClient *gophercloud.ServiceClient, lbID string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
log.Printf("[DEBUG] Attempting to delete OpenStack LoadBalancerV2 %s", lbID)
lb, err := loadbalancers.Get(networkingClient, lbID).Extract()
if err != nil {
errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError)
if !ok {
return lb, "ACTIVE", err
}
if errCode.Actual == 404 {
log.Printf("[DEBUG] Successfully deleted OpenStack LoadBalancerV2 %s", lbID)
return lb, "DELETED", nil
}
}
log.Printf("[DEBUG] Openstack LoadBalancerV2: %+v", lb)
err = loadbalancers.Delete(networkingClient, lbID).ExtractErr()
if err != nil {
errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError)
if !ok {
return lb, "ACTIVE", err
}
if errCode.Actual == 404 {
log.Printf("[DEBUG] Successfully deleted OpenStack LoadBalancerV2 %s", lbID)
return lb, "DELETED", nil
}
}
log.Printf("[DEBUG] OpenStack LoadBalancerV2 %s still active.", lbID)
return lb, "ACTIVE", nil
}
}