in pkg/openstack/loadbalancer.go [3047:3234]
func (lbaas *LbaasV2) ensureLoadBalancerDeleted(ctx context.Context, clusterName string, service *corev1.Service) error {
lbName := lbaas.GetLoadBalancerName(ctx, clusterName, service)
legacyName := lbaas.getLoadBalancerLegacyName(ctx, clusterName, service)
var err error
var loadbalancer *loadbalancers.LoadBalancer
isSharedLB := false
updateLBTag := false
isCreatedByOCCM := false
svcConf := new(serviceConfig)
if err := lbaas.checkServiceDelete(service, svcConf); err != nil {
return err
}
if svcConf.lbID != "" {
loadbalancer, err = openstackutil.GetLoadbalancerByID(lbaas.lb, svcConf.lbID)
} else {
// This may happen when this Service creation was failed previously.
loadbalancer, err = getLoadbalancerByName(lbaas.lb, lbName, legacyName)
}
if err != nil && err != cpoerrors.ErrNotFound {
return err
}
if loadbalancer == nil {
return nil
}
if loadbalancer.ProvisioningStatus != activeStatus {
return fmt.Errorf("load balancer %s is not ACTIVE, current provisioning status: %s", loadbalancer.ID, loadbalancer.ProvisioningStatus)
}
if strings.HasPrefix(loadbalancer.Name, servicePrefix) {
isCreatedByOCCM = true
}
if svcConf.supportLBTags {
for _, tag := range loadbalancer.Tags {
if tag == lbName {
updateLBTag = true
} else if strings.HasPrefix(tag, servicePrefix) {
isSharedLB = true
}
}
}
// If the LB is shared by other Service or the LB was not created by occm, the LB should not be deleted.
needDeleteLB := true
if isSharedLB || !isCreatedByOCCM {
needDeleteLB = false
}
klog.V(4).InfoS("Deleting service", "service", klog.KObj(service), "needDeleteLB", needDeleteLB, "isSharedLB", isSharedLB, "updateLBTag", updateLBTag, "isCreatedByOCCM", isCreatedByOCCM)
keepFloatingAnnotation := getBoolFromServiceAnnotation(service, ServiceAnnotationLoadBalancerKeepFloatingIP, false)
if needDeleteLB && !keepFloatingAnnotation {
if loadbalancer.VipPortID != "" {
portID := loadbalancer.VipPortID
fip, err := openstackutil.GetFloatingIPByPortID(lbaas.network, portID)
if err != nil {
return fmt.Errorf("failed to get floating IP for loadbalancer VIP port %s: %v", portID, err)
}
// Delete the floating IP only if it was created dynamically by the controller manager.
if fip != nil {
klog.InfoS("Matching floating IP", "floatingIP", fip.FloatingIP, "description", fip.Description)
matched, err := regexp.Match("Floating IP for Kubernetes external service", []byte(fip.Description))
if err != nil {
return err
}
if matched {
klog.InfoS("Deleting floating IP for service", "floatingIP", fip.FloatingIP, "service", klog.KObj(service))
mc := metrics.NewMetricContext("floating_ip", "delete")
err := floatingips.Delete(lbaas.network, fip.ID).ExtractErr()
if mc.ObserveRequest(err) != nil {
return fmt.Errorf("failed to delete floating IP %s for loadbalancer VIP port %s: %v", fip.FloatingIP, portID, err)
}
klog.InfoS("Deleted floating IP for service", "floatingIP", fip.FloatingIP, "service", klog.KObj(service))
}
}
}
}
// For neutron-lbaas
if !lbaas.opts.UseOctavia {
return lbaas.ensureLoadBalancerDeletedLegacy(loadbalancer)
}
if needDeleteLB && lbaas.opts.CascadeDelete {
klog.InfoS("Deleting load balancer", "lbID", loadbalancer.ID, "service", klog.KObj(service))
if err := openstackutil.DeleteLoadbalancer(lbaas.lb, loadbalancer.ID, true); err != nil {
return err
}
klog.InfoS("Deleted load balancer", "lbID", loadbalancer.ID, "service", klog.KObj(service))
} else {
// get all listeners associated with this loadbalancer
listenerList, err := openstackutil.GetListenersByLoadBalancerID(lbaas.lb, loadbalancer.ID)
if err != nil {
return fmt.Errorf("error getting LB %s listeners: %v", loadbalancer.ID, err)
}
if !needDeleteLB {
var listenersToDelete []listeners.Listener
curListenerMapping := make(map[listenerKey]*listeners.Listener)
for i, l := range listenerList {
key := listenerKey{Protocol: listeners.Protocol(l.Protocol), Port: l.ProtocolPort}
curListenerMapping[key] = &listenerList[i]
}
for _, port := range service.Spec.Ports {
proto := getListenerProtocol(port.Protocol, svcConf)
listener, isPresent := curListenerMapping[listenerKey{
Protocol: proto,
Port: int(port.Port),
}]
if isPresent && cpoutil.Contains(listener.Tags, lbName) {
listenersToDelete = append(listenersToDelete, *listener)
}
}
listenerList = listenersToDelete
}
// get all pools (and health monitors) associated with this loadbalancer
var monitorIDs []string
for _, listener := range listenerList {
pool, err := openstackutil.GetPoolByListener(lbaas.lb, loadbalancer.ID, listener.ID)
if err != nil && err != openstackutil.ErrNotFound {
return fmt.Errorf("error getting pool for listener %s: %v", listener.ID, err)
}
if pool != nil {
if pool.MonitorID != "" {
monitorIDs = append(monitorIDs, pool.MonitorID)
}
}
}
// delete monitors
for _, monitorID := range monitorIDs {
klog.InfoS("Deleting health monitor", "monitorID", monitorID, "lbID", loadbalancer.ID)
if err := openstackutil.DeleteHealthMonitor(lbaas.lb, monitorID, loadbalancer.ID); err != nil {
return err
}
klog.InfoS("Deleted health monitor", "monitorID", monitorID, "lbID", loadbalancer.ID)
}
// delete listeners
if err := lbaas.deleteListeners(loadbalancer.ID, listenerList); err != nil {
return err
}
if needDeleteLB {
// delete the loadbalancer in old way, i.e. no cascading.
klog.InfoS("Deleting load balancer", "lbID", loadbalancer.ID, "service", klog.KObj(service))
if err := openstackutil.DeleteLoadbalancer(lbaas.lb, loadbalancer.ID, false); err != nil {
return err
}
klog.InfoS("Deleted load balancer", "lbID", loadbalancer.ID, "service", klog.KObj(service))
}
}
// Remove the Service's tag from the load balancer.
if !needDeleteLB && updateLBTag {
var newTags []string
for _, tag := range loadbalancer.Tags {
if tag != lbName {
newTags = append(newTags, tag)
}
}
// An empty list won't trigger tags update.
if len(newTags) == 0 {
newTags = []string{""}
}
klog.InfoS("Updating load balancer tags", "lbID", loadbalancer.ID, "tags", newTags)
if err := openstackutil.UpdateLoadBalancerTags(lbaas.lb, loadbalancer.ID, newTags); err != nil {
return err
}
klog.InfoS("Updated load balancer tags", "lbID", loadbalancer.ID)
}
// Delete the Security Group
if lbaas.opts.ManageSecurityGroups {
if err := lbaas.EnsureSecurityGroupDeleted(clusterName, service); err != nil {
return err
}
}
return nil
}