Ensure kuryr-controller recover from lb in ERROR status

This patch ensures kuryr controller can recover from the situation
when the created lb goes into ERROR status (instead of ACTIVE). Now,
when the kuryr-controller finds the created lb, it checks its
provisioning_status and if in ERROR status it will delete it and
ensure a ResourceNotReady exception is triggered so that a new
creation action is triggered after the deletion of the lb in ERROR
status.

Closes-Bug: 1815880
Change-Id: I3f5de710a5ff37dee05f5f8826cb37c343141a08
This commit is contained in:
Luis Tomas Bolivar 2019-02-14 10:57:21 +01:00
parent 5a6a396854
commit 33594b8702
2 changed files with 33 additions and 1 deletions

View File

@ -74,6 +74,8 @@ class LBaaSv2Driver(base.LBaaSDriver):
if not response: if not response:
# NOTE(ivc): load balancer was present before 'create', but got # NOTE(ivc): load balancer was present before 'create', but got
# deleted externally between 'create' and 'find' # deleted externally between 'create' and 'find'
# NOTE(ltomasbo): or it is in ERROR status, so we deleted and
# trigger the retry
raise k_exc.ResourceNotReady(request) raise k_exc.ResourceNotReady(request)
return response return response
@ -521,6 +523,10 @@ class LBaaSv2Driver(base.LBaaSDriver):
loadbalancer.id = response['loadbalancers'][0]['id'] loadbalancer.id = response['loadbalancers'][0]['id']
loadbalancer.port_id = self._get_vip_port(loadbalancer).get("id") loadbalancer.port_id = self._get_vip_port(loadbalancer).get("id")
loadbalancer.provider = response['loadbalancers'][0]['provider'] loadbalancer.provider = response['loadbalancers'][0]['provider']
if (response['loadbalancers'][0]['provisioning_status'] ==
'ERROR'):
self.release_loadbalancer(loadbalancer)
return None
except (KeyError, IndexError): except (KeyError, IndexError):
return None return None

View File

@ -343,7 +343,8 @@ class TestLBaaSv2Driver(test_base.TestCase):
provider='haproxy', security_groups=[]) provider='haproxy', security_groups=[])
loadbalancer_id = '00EE9E11-91C2-41CF-8FD4-7970579E5C4C' loadbalancer_id = '00EE9E11-91C2-41CF-8FD4-7970579E5C4C'
resp = {'loadbalancers': [{'id': loadbalancer_id, resp = {'loadbalancers': [{'id': loadbalancer_id,
'provider': 'haproxy'}]} 'provider': 'haproxy',
'provisioning_status': 'ACTIVE'}]}
lbaas.list_loadbalancers.return_value = resp lbaas.list_loadbalancers.return_value = resp
m_driver._get_vip_port.return_value = {'id': mock.sentinel.port_id} m_driver._get_vip_port.return_value = {'id': mock.sentinel.port_id}
@ -357,6 +358,7 @@ class TestLBaaSv2Driver(test_base.TestCase):
self.assertEqual(getattr(loadbalancer, attr), self.assertEqual(getattr(loadbalancer, attr),
getattr(ret, attr)) getattr(ret, attr))
self.assertEqual(loadbalancer_id, ret.id) self.assertEqual(loadbalancer_id, ret.id)
m_driver.release_loadbalancer.assert_not_called()
def test_find_loadbalancer_not_found(self): def test_find_loadbalancer_not_found(self):
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
@ -375,6 +377,30 @@ class TestLBaaSv2Driver(test_base.TestCase):
vip_address=str(loadbalancer.ip), vip_address=str(loadbalancer.ip),
vip_subnet_id=loadbalancer.subnet_id) vip_subnet_id=loadbalancer.subnet_id)
self.assertIsNone(ret) self.assertIsNone(ret)
m_driver.release_loadbalancer.assert_not_called()
def test_find_loadbalancer_error(self):
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
loadbalancer = obj_lbaas.LBaaSLoadBalancer(
name='TEST_NAME', project_id='TEST_PROJECT', ip='1.2.3.4',
subnet_id='D3FA400A-F543-4B91-9CD3-047AF0CE42D1')
loadbalancer_id = '00EE9E11-91C2-41CF-8FD4-7970579E5C4C'
resp = {'loadbalancers': [{'id': loadbalancer_id,
'provider': 'haproxy',
'provisioning_status': 'ERROR'}]}
lbaas.list_loadbalancers.return_value = resp
m_driver._get_vip_port.return_value = {'id': mock.sentinel.port_id}
ret = cls._find_loadbalancer(m_driver, loadbalancer)
lbaas.list_loadbalancers.assert_called_once_with(
name=loadbalancer.name,
project_id=loadbalancer.project_id,
vip_address=str(loadbalancer.ip),
vip_subnet_id=loadbalancer.subnet_id)
self.assertIsNone(ret)
m_driver.release_loadbalancer.assert_called_once()
def test_create_listener(self): def test_create_listener(self):
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client lbaas = self.useFixture(k_fix.MockLBaaSClient()).client