Make openstack's impl of DeleteTCPLoadBalancer idempotent with respect

to load balancers having already been deleted.
This commit is contained in:
Alex Robinson 2015-05-06 18:52:21 +00:00
parent edf5a78604
commit dc2f10d51b

View File

@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"io" "io"
"net" "net"
"net/http"
"regexp" "regexp"
"time" "time"
@ -633,28 +634,46 @@ func (lb *LoadBalancer) UpdateTCPLoadBalancer(name, region string, hosts []strin
func (lb *LoadBalancer) DeleteTCPLoadBalancer(name, region string) error { func (lb *LoadBalancer) DeleteTCPLoadBalancer(name, region string) error {
glog.V(4).Infof("DeleteTCPLoadBalancer(%v, %v)", name, region) glog.V(4).Infof("DeleteTCPLoadBalancer(%v, %v)", name, region)
vip, err := getVipByName(lb.network, name) // TODO(#8352): Because we look up the pool using the VIP object, if the VIP
if err != nil { // is already gone we can't attempt to delete the pool. We should instead
return err // continue even if the VIP doesn't exist and attempt to delete the pool by
// name.
vip, vipErr := getVipByName(lb.network, name)
if vipErr == ErrNotFound {
return nil
} else if vipErr != nil {
return vipErr
} }
pool, err := pools.Get(lb.network, vip.PoolID).Extract() // It's ok if the pool doesn't exist, as we may still need to delete the vip
if err != nil { // (although I don't believe the system should ever be in that state).
return err pool, poolErr := pools.Get(lb.network, vip.PoolID).Extract()
if poolErr != nil {
detailedErr, ok := poolErr.(*gophercloud.UnexpectedResponseCodeError)
if !ok || detailedErr.Actual != http.StatusNotFound {
return poolErr
}
} }
poolExists := (poolErr == nil)
// Have to delete VIP before pool can be deleted // We have to delete the VIP before the pool can be deleted, so we can't
err = vips.Delete(lb.network, vip.ID).ExtractErr() // continue on if this fails.
if err != nil { // TODO(#8352): Only do this if the VIP exists once we can delete pools by
// name rather than by ID.
err := vips.Delete(lb.network, vip.ID).ExtractErr()
if err != nil && err != ErrNotFound {
return err return err
} }
// Ignore errors for everything following here // Ignore errors for everything following here
for _, monId := range pool.MonitorIDs { if poolExists {
pools.DisassociateMonitor(lb.network, pool.ID, monId) for _, monId := range pool.MonitorIDs {
// TODO(#8352): Delete the monitor, don't just disassociate it.
pools.DisassociateMonitor(lb.network, pool.ID, monId)
}
pools.Delete(lb.network, pool.ID)
} }
pools.Delete(lb.network, pool.ID)
return nil return nil
} }