mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-14 17:44:26 -06:00
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.
257 lines
7.0 KiB
Go
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
|
|
}
|
|
}
|