Browse Source

Fix LB failover when IP addresses exhausted

When a load balancer failover was performed on a load balancer where
the VIP address is on a subnet that has no IP addresses available,
the VIP address may be deactivated.
This patch corrects the failover flow to not deallocate the VIP
address on a failover revert flow due to the subnet being out of
IP addresses.

Story: 2008625
Task: 41827
Change-Id: I1fe342d2bdf1301dd89ab7dfaa8e6a23e69c252b
(cherry picked from commit e3ab49c60aa835cb4034568ea25f06472127388c)
changes/88/778988/1
Michael Johnson 2 months ago
parent
commit
4c9d7405af
4 changed files with 37 additions and 2 deletions
  1. +2
    -2
      octavia/controller/worker/v1/flows/load_balancer_flows.py
  2. +14
    -0
      octavia/controller/worker/v1/tasks/network_tasks.py
  3. +16
    -0
      octavia/tests/unit/controller/worker/v1/tasks/test_network_tasks.py
  4. +5
    -0
      releasenotes/notes/Fix-failover-ip-addresses-exhausted-69110b2fa4683e1a.yaml

+ 2
- 2
octavia/controller/worker/v1/flows/load_balancer_flows.py View File

@ -420,8 +420,8 @@ class LoadBalancerFlows(object):
# Check that the VIP port exists and is ok
failover_LB_flow.add(
network_tasks.AllocateVIP(requires=constants.LOADBALANCER,
provides=constants.VIP))
network_tasks.AllocateVIPforFailover(
requires=constants.LOADBALANCER, provides=constants.VIP))
# Update the database with the VIP information
failover_LB_flow.add(database_tasks.UpdateVIPAfterAllocation(


+ 14
- 0
octavia/controller/worker/v1/tasks/network_tasks.py View File

@ -462,6 +462,20 @@ class AllocateVIP(BaseNetworkTask):
{'vip': vip.ip_address, 'except': e})
class AllocateVIPforFailover(AllocateVIP):
"""Task to allocate/validate the VIP for a failover flow."""
def revert(self, result, loadbalancer, *args, **kwargs):
"""Handle a failure to allocate vip."""
if isinstance(result, failure.Failure):
LOG.exception("Unable to allocate VIP")
return
vip = result
LOG.info("Failover revert is not deallocating vip %s because this is "
"a failover.", vip.ip_address)
class DeallocateVIP(BaseNetworkTask):
"""Task to deallocate a VIP."""


+ 16
- 0
octavia/tests/unit/controller/worker/v1/tasks/test_network_tasks.py View File

@ -716,6 +716,22 @@ class TestNetworkTasks(base.TestCase):
net.revert(vip_mock, LB)
mock_driver.deallocate_vip.assert_called_once_with(vip_mock)
def test_allocate_vip_for_failover(self, mock_get_net_driver):
mock_driver = mock.MagicMock()
mock_get_net_driver.return_value = mock_driver
net = network_tasks.AllocateVIPforFailover()
mock_driver.allocate_vip.return_value = LB.vip
mock_driver.reset_mock()
self.assertEqual(LB.vip, net.execute(LB))
mock_driver.allocate_vip.assert_called_once_with(LB)
# revert
vip_mock = mock.MagicMock()
net.revert(vip_mock, LB)
mock_driver.deallocate_vip.assert_not_called()
def test_deallocate_vip(self, mock_get_net_driver):
mock_driver = mock.MagicMock()
mock_get_net_driver.return_value = mock_driver


+ 5
- 0
releasenotes/notes/Fix-failover-ip-addresses-exhausted-69110b2fa4683e1a.yaml View File

@ -0,0 +1,5 @@
---
fixes:
- |
Fixes an issue with load balancer failover, when the VIP subnet is out of
IP addresses, that could lead to the VIP being deallocated.

Loading…
Cancel
Save