From 8245f5385c4845f54df8bf95f8caec571aa7fc5d Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Wed, 3 Jan 2024 10:57:15 +0100 Subject: [PATCH] Fix panic on failure to get loadbalancer status (#2512) After loadbalancer creation, the controller calls a wait function that polls the Octavia API until its state turns ACTIVE, or timeout is reached. Before this patch, a failure to GET the loadbalancer in the wait function would result in a nil loadbalancer to be returned to the caller, resulting in an immediate panic when accessing its members. With this patch: * GET failures are logged and don't break the polling; * if the wait timeout is reached while GET is failing, the behaviour exactly matches what happens when reaching the timeout. --- pkg/openstack/loadbalancer.go | 4 ++-- pkg/util/openstack/loadbalancer.go | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/openstack/loadbalancer.go b/pkg/openstack/loadbalancer.go index 286ee2b05b..ca411fca62 100644 --- a/pkg/openstack/loadbalancer.go +++ b/pkg/openstack/loadbalancer.go @@ -302,7 +302,7 @@ func (lbaas *LbaasV2) createOctaviaLoadBalancer(name, clusterName string, servic } if loadbalancer, err = openstackutil.WaitActiveAndGetLoadBalancer(lbaas.lb, loadbalancer.ID); err != nil { - if loadbalancer.ProvisioningStatus == errorStatus { + if loadbalancer != nil && loadbalancer.ProvisioningStatus == errorStatus { // If LB landed in ERROR state we should delete it and retry the creation later. if err = lbaas.deleteLoadBalancer(loadbalancer, service, svcConf, true); err != nil { return nil, fmt.Errorf("loadbalancer %s is in ERROR state and there was an error when removing it: %v", loadbalancer.ID, err) @@ -1896,7 +1896,7 @@ func (lbaas *LbaasV2) deleteFIPIfCreatedByProvider(fip *floatingips.FloatingIP, return true, nil } -// deleteLoadBalancer removes the LB and it's children either by using Octavia cascade deletion or manually +// deleteLoadBalancer removes the LB and its children either by using Octavia cascade deletion or manually func (lbaas *LbaasV2) deleteLoadBalancer(loadbalancer *loadbalancers.LoadBalancer, service *corev1.Service, svcConf *serviceConfig, needDeleteLB bool) error { if needDeleteLB && lbaas.opts.CascadeDelete { klog.InfoS("Deleting load balancer", "lbID", loadbalancer.ID, "service", klog.KObj(service)) diff --git a/pkg/util/openstack/loadbalancer.go b/pkg/util/openstack/loadbalancer.go index 3734f81858..9cdebd173e 100644 --- a/pkg/util/openstack/loadbalancer.go +++ b/pkg/util/openstack/loadbalancer.go @@ -177,7 +177,8 @@ func WaitActiveAndGetLoadBalancer(client *gophercloud.ServiceClient, loadbalance var err error loadbalancer, err = loadbalancers.Get(client, loadbalancerID).Extract() if mc.ObserveRequest(err) != nil { - return false, err + klog.Warningf("Failed to fetch loadbalancer status from OpenStack (lbID %q): %s", loadbalancerID, err) + return false, nil } if loadbalancer.ProvisioningStatus == activeStatus { klog.InfoS("Load balancer ACTIVE", "lbID", loadbalancerID)