Correct status for disabled members (honest abe edition)

This is *one way* to handle this problem (arguably the "correct" way).

By actively updating the status of members that don't report, we can set
disabled members to OFFLINE exactly when this becomes true.

Change-Id: I908879470e5b7767711c1234063e7959aa6055ef
Closes-Bug: #1706828
This commit is contained in:
Adam Harwell 2017-08-01 15:10:40 -07:00
parent 5c74844ffe
commit 65522f5adf
2 changed files with 60 additions and 17 deletions

View File

@ -165,6 +165,7 @@ class UpdateHealthDb(object):
'%(status)s'), {'pool': pool_id,
'status': pool.get('status')})
# Deal with the members that are reporting from the Amphora
members = pool['members']
for member_id, status in members.items():
@ -200,6 +201,17 @@ class UpdateHealthDb(object):
LOG.error("Member %s is not able to update "
"in DB", member_id)
# Now deal with the members that didn't report from the Amphora
db_pool = self.pool_repo.get(session, id=pool_id)
real_members = [member.id for member in db_pool.members]
reported_members = [member for member in members.keys()]
missing_members = set(real_members) - set(reported_members)
for member_id in missing_members:
self._update_status_and_emit_event(
session, self.member_repo, constants.MEMBER,
member_id, constants.OFFLINE
)
try:
if pool_status is not None:
self._update_status_and_emit_event(

View File

@ -141,9 +141,12 @@ class TestUpdateHealthDb(base.TestCase):
'blah', member_id,
operating_status=constants.ONLINE)
# If the listener count is wrong, make sure we don't update
self.hm.listener_repo.count.return_value = 2
self.amphora_health_repo.replace.reset_mock()
self.hm.update_health(health)
self.assertTrue(not self.amphora_health_repo.replace.called)
def test_update_health_member_drain(self):
@ -181,10 +184,6 @@ class TestUpdateHealthDb(base.TestCase):
'blah', member_id,
operating_status=constants.DRAINING)
self.hm.listener_repo.count.return_value = 2
self.hm.update_health(health)
def test_update_health_member_maint(self):
health = {
@ -221,10 +220,6 @@ class TestUpdateHealthDb(base.TestCase):
'blah', member_id,
operating_status=constants.OFFLINE)
self.hm.listener_repo.count.return_value = 2
self.hm.update_health(health)
def test_update_health_member_unknown(self):
health = {
@ -255,10 +250,6 @@ class TestUpdateHealthDb(base.TestCase):
'blah', pool_id, operating_status=constants.ONLINE)
self.assertTrue(not self.member_repo.update.called)
self.hm.listener_repo.count.return_value = 2
self.hm.update_health(health)
def test_update_health_member_down(self):
health = {
@ -297,10 +288,6 @@ class TestUpdateHealthDb(base.TestCase):
'blah', member_id,
operating_status=constants.ERROR)
self.hm.listener_repo.count.return_value = 2
self.hm.update_health(health)
def test_update_health_member_no_check(self):
health = {
@ -340,9 +327,51 @@ class TestUpdateHealthDb(base.TestCase):
'blah', member_id,
operating_status=constants.NO_MONITOR)
self.hm.listener_repo.count.return_value = 2
def test_update_health_member_admin_down(self):
health = {
"id": self.FAKE_UUID_1,
"listeners": {
"listener-id-1": {
"status": constants.OPEN,
"pools": {
"pool-id-1": {
"status": constants.UP,
"members": {
"member-id-1": constants.UP}}}}}}
self.mock_session.return_value = 'blah'
mock_pool = mock.Mock()
mock_member1 = mock.Mock()
mock_member1.id = 'member-id-1'
mock_member2 = mock.Mock()
mock_member2.id = 'member-id-2'
mock_pool.members = [mock_member1, mock_member2]
self.pool_repo.get.return_value = mock_pool
self.hm.update_health(health)
self.assertTrue(self.amphora_health_repo.replace.called)
# test listener, member
for listener_id, listener in six.iteritems(
health.get('listeners', {})):
self.listener_repo.update.assert_any_call(
'blah', listener_id, operating_status=constants.ONLINE)
for pool_id, pool in six.iteritems(listener.get('pools', {})):
self.hm.pool_repo.update.assert_any_call(
'blah', pool_id, operating_status=constants.ONLINE)
for member_id, member in six.iteritems(
pool.get('members', {})):
self.member_repo.update.assert_any_call(
'blah', member_id,
operating_status=constants.ONLINE)
self.member_repo.update.assert_any_call(
'blah', mock_member2.id, operating_status=constants.OFFLINE)
def test_update_health_list_full_member_down(self):
@ -383,8 +412,10 @@ class TestUpdateHealthDb(base.TestCase):
operating_status=constants.ERROR)
self.hm.listener_repo.count.return_value = 2
self.amphora_health_repo.replace.reset_mock()
self.hm.update_health(health)
self.assertTrue(not self.amphora_health_repo.replace.called)
def test_update_health_error(self):