func waitForLBVIPDelete(networkingClient *gophercloud.ServiceClient, vipId string) resource.StateRefreshFunc { return func() (interface{}, string, error) { log.Printf("[DEBUG] Attempting to delete OpenStack LB VIP %s", vipId) p, err := vips.Get(networkingClient, vipId).Extract() if err != nil { if _, ok := err.(gophercloud.ErrDefault404); ok { log.Printf("[DEBUG] Successfully deleted OpenStack LB VIP %s", vipId) return p, "DELETED", nil } return p, "ACTIVE", err } log.Printf("[DEBUG] OpenStack LB VIP: %+v", p) err = vips.Delete(networkingClient, vipId).ExtractErr() if err != nil { if _, ok := err.(gophercloud.ErrDefault404); ok { log.Printf("[DEBUG] Successfully deleted OpenStack LB VIP %s", vipId) return p, "DELETED", nil } return p, "ACTIVE", err } log.Printf("[DEBUG] OpenStack LB VIP %s still active.", vipId) return p, "ACTIVE", nil } }
// DeleteVIP will delete a specified vip. A fatal error will occur if the vip // could not be deleted. This works best when used as a deferred function. func DeleteVIP(t *testing.T, client *gophercloud.ServiceClient, vipID string) { t.Logf("Attempting to delete vip %s", vipID) if err := vips.Delete(client, vipID).ExtractErr(); err != nil { t.Fatalf("Unable to delete vip: %v", err) } t.Logf("Successfully deleted vip %s", vipID) }
// Delete load balancer func (os *OpenStack) DeleteLoadBalancer(name string) error { vip, err := os.getVipByName(name) if err != nil && err != ErrNotFound { return err } // We have to delete the VIP before the pool can be deleted, // so no point continuing if this fails. if vip != nil { err = vips.Delete(os.network, vip.ID).ExtractErr() if err != nil && !isNotFound(err) { return err } } var pool *pools.Pool if vip != nil { pool, err = pools.Get(os.network, vip.PoolID).Extract() if err != nil && !isNotFound(err) { return err } } else { // The VIP is gone, but it is conceivable that a Pool // still exists that we failed to delete on some // previous occasion. Make a best effort attempt to // cleanup any pools with the same name as the VIP. pool, err = os.getPoolByName(name) if err != nil && err != ErrNotFound { return err } } if pool != nil { for _, monId := range pool.MonitorIDs { _, err = pools.DisassociateMonitor(os.network, pool.ID, monId).Extract() if err != nil { return err } err = monitors.Delete(os.network, monId).ExtractErr() if err != nil && !isNotFound(err) { return err } } err = pools.Delete(os.network, pool.ID).ExtractErr() if err != nil && !isNotFound(err) { return err } } return nil }
func TestDelete(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() th.Mux.HandleFunc("/v2.0/lb/vips/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "DELETE") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.WriteHeader(http.StatusNoContent) }) res := vips.Delete(fake.ServiceClient(), "4ec89087-d057-4e2c-911f-60a3b47ee304") th.AssertNoErr(t, res.Err) }
// Create load balancer func (os *OpenStack) CreateLoadBalancer(loadBalancer *provider.LoadBalancer, affinity string) (string, error) { if len(loadBalancer.ExternalIPs) > 1 { return "", fmt.Errorf("multiple floatingips are not yet supported by openstack") } servicePort := 0 for _, p := range loadBalancer.Hosts { if servicePort == 0 { servicePort = int(p.ServicePort) } else if int(p.ServicePort) != servicePort { return "", fmt.Errorf("multiple ports are not yet supported in openstack load balancers") } } var persistence *vips.SessionPersistence switch affinity { case ServiceAffinityNone: persistence = nil case ServiceAffinityClientIP: persistence = &vips.SessionPersistence{Type: "SOURCE_IP"} default: return "", fmt.Errorf("unsupported load balancer affinity: %v", affinity) } glog.V(2).Info("Checking if openstack load balancer already exists: ", loadBalancer.Name) _, err := os.getPoolByName(loadBalancer.Name) if err != nil && err != ErrNotFound { return "", fmt.Errorf("error checking if openstack load balancer already exists: %v", err) } if err == nil { err := os.DeleteLoadBalancer(loadBalancer.Name) if err != nil { return "", fmt.Errorf("error deleting existing openstack load balancer: %v", err) } } lbmethod := pools.LBMethodRoundRobin if os.lbOpts.LBMethod != "" { lbmethod = pools.LBMethod(os.lbOpts.LBMethod) } pool, err := pools.Create(os.network, pools.CreateOpts{ Name: loadBalancer.Name, Protocol: pools.ProtocolTCP, SubnetID: loadBalancer.Subnets[0].Uid, LBMethod: lbmethod, TenantID: loadBalancer.TenantID, }).Extract() if err != nil { return "", err } for _, host := range loadBalancer.Hosts { _, err = members.Create(os.network, members.CreateOpts{ PoolID: pool.ID, ProtocolPort: int(host.TargetPort), Address: host.Ipaddress, TenantID: loadBalancer.TenantID, }).Extract() if err != nil { pools.Delete(os.network, pool.ID) return "", err } } var mon *monitors.Monitor if os.lbOpts.CreateMonitor { mon, err = monitors.Create(os.network, monitors.CreateOpts{ Type: monitors.TypeTCP, TenantID: loadBalancer.TenantID, Delay: int(os.lbOpts.MonitorDelay.Duration.Seconds()), Timeout: int(os.lbOpts.MonitorTimeout.Duration.Seconds()), MaxRetries: int(os.lbOpts.MonitorMaxRetries), }).Extract() if err != nil { pools.Delete(os.network, pool.ID) return "", err } _, err = pools.AssociateMonitor(os.network, pool.ID, mon.ID).Extract() if err != nil { monitors.Delete(os.network, mon.ID) pools.Delete(os.network, pool.ID) return "", err } } createOpts := vips.CreateOpts{ Name: loadBalancer.Name, Description: fmt.Sprintf("Kubernetes service %s", loadBalancer.Name), Protocol: "TCP", ProtocolPort: servicePort, PoolID: pool.ID, SubnetID: loadBalancer.Subnets[0].Uid, Persistence: persistence, TenantID: loadBalancer.TenantID, } //if loadBalancer.Vip != "" { // createOpts.Address = loadBalancer.Vip //} vip, err := vips.Create(os.network, createOpts).Extract() if err != nil { if mon != nil { monitors.Delete(os.network, mon.ID) } pools.Delete(os.network, pool.ID) return "", err } // bind external ip if len(loadBalancer.ExternalIPs) > 0 { err := os.BindPortToFloatingip(vip.PortID, loadBalancer.ExternalIPs[0], vip.TenantID) if err != nil { vips.Delete(os.network, vip.ID) if mon != nil { monitors.Delete(os.network, mon.ID) } pools.Delete(os.network, pool.ID) return "", err } } return vip.Address, nil }