Don't failover amphora with LB in PENDING_*

This patch updates the health manager to update the amphora_health timestamp
even if the listener count does not match if the load balancer is in PENDING_*
provisioning status. This will stop failovers for occuring on load balancers
being updated or deleted.

Change-Id: I7d483d764bd841c6977afa0bcf3227e02c573b91
Co-Authored-By: Adam Harwell <flux.adam@gmail.com>
This commit is contained in:
Michael Johnson 2018-03-20 12:48:06 -07:00
parent df9770a773
commit f7f8050c1c
2 changed files with 43 additions and 3 deletions

View File

@ -111,6 +111,7 @@ class UpdateHealthDb(update_base.HealthUpdateBase):
expected_listener_count = 0
db_lbs_on_amp = self.amphora_repo.get_all_lbs_on_amphora(session,
health['id'])
ignore_listener_count = False
listeners = health['listeners']
# We need to loop over the lbs here to make sure we update the
@ -118,10 +119,12 @@ class UpdateHealthDb(update_base.HealthUpdateBase):
# failovers. Unfortunately that means looping over this list twice.
for db_lb in db_lbs_on_amp:
expected_listener_count += len(db_lb.listeners)
if 'PENDING' in db_lb.provisioning_status:
ignore_listener_count = True
# Do not update amphora health if the reporting listener count
# does not match the expected listener count
if len(listeners) == expected_listener_count:
if len(listeners) == expected_listener_count or ignore_listener_count:
lock_session = db_api.get_session(autocommit=False)

View File

@ -74,12 +74,13 @@ class TestUpdateHealthDb(base.TestCase):
self.hm.member_repo = self.member_repo
self.hm.pool_repo = self.pool_repo
def _make_mock_lb_tree(self, listener=True, pool=True, members=1):
def _make_mock_lb_tree(self, listener=True, pool=True, members=1,
lb_prov_status=constants.ACTIVE):
mock_lb = mock.Mock()
mock_lb.id = self.FAKE_UUID_1
mock_lb.pools = []
mock_lb.listeners = []
mock_lb.provisioning_status = constants.ACTIVE
mock_lb.provisioning_status = lb_prov_status
mock_lb.operating_status = 'blah'
mock_listener1 = None
@ -153,6 +154,42 @@ class TestUpdateHealthDb(base.TestCase):
self.hm.update_health(health)
self.assertTrue(self.amphora_repo.get_all_lbs_on_amphora.called)
self.assertTrue(self.loadbalancer_repo.update.called)
self.assertTrue(self.amphora_health_repo.replace.called)
def test_update_health_lb_pending_no_listener(self):
health = {
"id": self.FAKE_UUID_1,
"listeners": {},
"recv_time": time.time()
}
mock_lb, mock_listener1, mock_pool1, mock_members = (
self._make_mock_lb_tree(listener=True, pool=False,
lb_prov_status=constants.PENDING_UPDATE))
self.hm.amphora_repo.get_all_lbs_on_amphora.return_value = [mock_lb]
self.hm.update_health(health)
self.assertTrue(self.amphora_repo.get_all_lbs_on_amphora.called)
self.assertTrue(self.loadbalancer_repo.update.called)
self.assertTrue(self.amphora_health_repo.replace.called)
def test_update_health_missing_listener(self):
health = {
"id": self.FAKE_UUID_1,
"listeners": {},
"recv_time": time.time()
}
mock_lb, mock_listener1, mock_pool1, mock_members = (
self._make_mock_lb_tree(listener=True, pool=False))
self.hm.amphora_repo.get_all_lbs_on_amphora.return_value = [mock_lb]
self.hm.update_health(health)
self.assertTrue(self.amphora_repo.get_all_lbs_on_amphora.called)
self.assertTrue(self.loadbalancer_repo.update.called)
self.assertFalse(self.amphora_health_repo.replace.called)
def test_update_health_recv_time_stale(self):
hb_interval = cfg.CONF.health_manager.heartbeat_interval