Ensure LB with HM rechecks member status after re-enable
This patch fixes an issue where disabling a LoadBalancer member sets its status to ERROR instead of OFFLINE. While in the ERROR state, re-enabling the member does not update its status, and the member is not reintegrated into the "vips" field of the LoadBalancer row in the OVN NB database. As a result, the Health Monitor does not resume its checks on the member. This patch ensures that re-enabled members are correctly reintegrated and that health checks are properly resumed. Closes-bug: #2112110 Change-Id: If2ca76df87c0f5a713604212ed6cb77792d0010c
This commit is contained in:
@@ -2795,8 +2795,14 @@ class OvnProviderHelper():
|
|||||||
# if HM exists trust on neutron:member_status
|
# if HM exists trust on neutron:member_status
|
||||||
# as the last status valid for the member
|
# as the last status valid for the member
|
||||||
if ovn_lb.health_check:
|
if ovn_lb.health_check:
|
||||||
# search status of member_uuid
|
# Put member ONLINE if was OFFLINE and trust on HM to
|
||||||
member_operating_status = last_status
|
# come back to ERROR in case neccesary, it was already
|
||||||
|
# on ERROR keeps at that way.
|
||||||
|
member_operating_status = (
|
||||||
|
constants.ERROR
|
||||||
|
if last_status == constants.ERROR
|
||||||
|
else constants.ONLINE
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
member_operating_status = constants.NO_MONITOR
|
member_operating_status = constants.NO_MONITOR
|
||||||
else:
|
else:
|
||||||
@@ -2815,12 +2821,18 @@ class OvnProviderHelper():
|
|||||||
) or (
|
) or (
|
||||||
last_status == constants.OFFLINE and
|
last_status == constants.OFFLINE and
|
||||||
member_operating_status != constants.OFFLINE
|
member_operating_status != constants.OFFLINE
|
||||||
|
) or (
|
||||||
|
member[constants.ADMIN_STATE_UP]
|
||||||
):
|
):
|
||||||
commands = []
|
commands = []
|
||||||
commands.extend(self._refresh_lb_vips(ovn_lb,
|
commands.extend(self._refresh_lb_vips(ovn_lb,
|
||||||
ovn_lb.external_ids))
|
ovn_lb.external_ids))
|
||||||
self._execute_commands(commands)
|
self._execute_commands(commands)
|
||||||
|
if ovn_lb.health_check:
|
||||||
|
delete = not member[constants.ADMIN_STATE_UP]
|
||||||
|
self._update_hm_member(
|
||||||
|
ovn_lb, pool_key, member.get(constants.ADDRESS),
|
||||||
|
delete=delete)
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.exception(ovn_const.EXCEPTION_MSG, "update of member")
|
LOG.exception(ovn_const.EXCEPTION_MSG, "update of member")
|
||||||
error_updating_member = True
|
error_updating_member = True
|
||||||
@@ -3983,9 +3995,8 @@ class OvnProviderHelper():
|
|||||||
"ovn_lbs": ovn_lbs,
|
"ovn_lbs": ovn_lbs,
|
||||||
"ip": row.ip,
|
"ip": row.ip,
|
||||||
"port": str(row.port),
|
"port": str(row.port),
|
||||||
"status": row.status
|
"status": row.status,
|
||||||
if not sm_delete_event
|
"delete": sm_delete_event,
|
||||||
else ovn_const.HM_EVENT_MEMBER_PORT_OFFLINE,
|
|
||||||
}
|
}
|
||||||
self.add_request({'type': ovn_const.REQ_TYPE_HM_UPDATE_EVENT,
|
self.add_request({'type': ovn_const.REQ_TYPE_HM_UPDATE_EVENT,
|
||||||
'info': request_info})
|
'info': request_info})
|
||||||
@@ -4130,9 +4141,12 @@ class OvnProviderHelper():
|
|||||||
if not member_id:
|
if not member_id:
|
||||||
LOG.warning('Member for event not found, info: %s', info)
|
LOG.warning('Member for event not found, info: %s', info)
|
||||||
else:
|
else:
|
||||||
member_status = constants.ONLINE
|
if info['delete']:
|
||||||
if info['status'] == ovn_const.HM_EVENT_MEMBER_PORT_OFFLINE:
|
member_status = constants.OFFLINE
|
||||||
|
elif info['status'] == ovn_const.HM_EVENT_MEMBER_PORT_OFFLINE:
|
||||||
member_status = constants.ERROR
|
member_status = constants.ERROR
|
||||||
|
else:
|
||||||
|
member_status = constants.ONLINE
|
||||||
|
|
||||||
self._update_external_ids_member_status(ovn_lb, member_id,
|
self._update_external_ids_member_status(ovn_lb, member_id,
|
||||||
member_status)
|
member_status)
|
||||||
|
|||||||
@@ -991,7 +991,9 @@ class TestOvnOctaviaBase(base.TestOVNFunctionalBase,
|
|||||||
'provisioning_status': 'ACTIVE',
|
'provisioning_status': 'ACTIVE',
|
||||||
'operating_status': o_constants.ONLINE}],
|
'operating_status': o_constants.ONLINE}],
|
||||||
'members': [{"id": member.member_id,
|
'members': [{"id": member.member_id,
|
||||||
'provisioning_status': 'ACTIVE'}],
|
'provisioning_status': 'ACTIVE',
|
||||||
|
'operating_status': o_constants.ONLINE
|
||||||
|
if admin_state_up else o_constants.OFFLINE}],
|
||||||
'loadbalancers': [{'id': pool.loadbalancer_id,
|
'loadbalancers': [{'id': pool.loadbalancer_id,
|
||||||
'provisioning_status': 'ACTIVE',
|
'provisioning_status': 'ACTIVE',
|
||||||
'operating_status': o_constants.ONLINE}],
|
'operating_status': o_constants.ONLINE}],
|
||||||
|
|||||||
@@ -6051,6 +6051,7 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
'logical_port': 'a-logical-port',
|
'logical_port': 'a-logical-port',
|
||||||
'src_ip': src_ip,
|
'src_ip': src_ip,
|
||||||
'port': self.member_port,
|
'port': self.member_port,
|
||||||
|
'delete': False,
|
||||||
'protocol': self.ovn_hm_lb.protocol,
|
'protocol': self.ovn_hm_lb.protocol,
|
||||||
'status': ovn_const.HM_EVENT_MEMBER_PORT_OFFLINE})
|
'status': ovn_const.HM_EVENT_MEMBER_PORT_OFFLINE})
|
||||||
self.hm_update_event.run('update', row, mock.ANY)
|
self.hm_update_event.run('update', row, mock.ANY)
|
||||||
@@ -6059,6 +6060,7 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
{'ovn_lbs': [self.ovn_hm_lb],
|
{'ovn_lbs': [self.ovn_hm_lb],
|
||||||
'ip': self.member_address,
|
'ip': self.member_address,
|
||||||
'port': self.member_port,
|
'port': self.member_port,
|
||||||
|
'delete': False,
|
||||||
'status': ovn_const.HM_EVENT_MEMBER_PORT_OFFLINE},
|
'status': ovn_const.HM_EVENT_MEMBER_PORT_OFFLINE},
|
||||||
'type': 'hm_update_event'}
|
'type': 'hm_update_event'}
|
||||||
self.mock_add_request.assert_called_once_with(expected)
|
self.mock_add_request.assert_called_once_with(expected)
|
||||||
@@ -6087,7 +6089,8 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
{'ovn_lbs': [self.ovn_hm_lb],
|
{'ovn_lbs': [self.ovn_hm_lb],
|
||||||
'ip': self.member_address,
|
'ip': self.member_address,
|
||||||
'port': self.member_port,
|
'port': self.member_port,
|
||||||
'status': ovn_const.HM_EVENT_MEMBER_PORT_OFFLINE},
|
'delete': True,
|
||||||
|
'status': ovn_const.HM_EVENT_MEMBER_PORT_ONLINE},
|
||||||
'type': 'hm_update_event'}
|
'type': 'hm_update_event'}
|
||||||
self.mock_add_request.assert_called_once_with(expected)
|
self.mock_add_request.assert_called_once_with(expected)
|
||||||
self.helper.ovn_nbdb_api.db_find_rows.assert_called_once_with(
|
self.helper.ovn_nbdb_api.db_find_rows.assert_called_once_with(
|
||||||
@@ -6169,13 +6172,14 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
self._test_hm_update_no_member(False, True)
|
self._test_hm_update_no_member(False, True)
|
||||||
|
|
||||||
def _test_hm_update_status(self, ovn_lbs, member_id, ip, port,
|
def _test_hm_update_status(self, ovn_lbs, member_id, ip, port,
|
||||||
mb_status):
|
mb_status, delete=False):
|
||||||
info = {
|
info = {
|
||||||
'ovn_lbs': ovn_lbs,
|
'ovn_lbs': ovn_lbs,
|
||||||
'ip': ip,
|
'ip': ip,
|
||||||
'logical_port': 'a-logical-port',
|
'logical_port': 'a-logical-port',
|
||||||
'src_ip': '10.22.33.4',
|
'src_ip': '10.22.33.4',
|
||||||
'port': port,
|
'port': port,
|
||||||
|
'delete': delete,
|
||||||
'protocol': ovn_lbs[0].protocol,
|
'protocol': ovn_lbs[0].protocol,
|
||||||
'status': [mb_status]}
|
'status': [mb_status]}
|
||||||
mb_status_ovn = 'error' if mb_status == 'offline' else mb_status
|
mb_status_ovn = 'error' if mb_status == 'offline' else mb_status
|
||||||
@@ -6472,6 +6476,7 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
'logical_port': 'a-logical-port',
|
'logical_port': 'a-logical-port',
|
||||||
'src_ip': '10.22.33.4',
|
'src_ip': '10.22.33.4',
|
||||||
'port': '8080',
|
'port': '8080',
|
||||||
|
'delete': False,
|
||||||
'protocol': self.ovn_hm_lb.protocol,
|
'protocol': self.ovn_hm_lb.protocol,
|
||||||
'status': ovn_const.HM_EVENT_MEMBER_PORT_OFFLINE}
|
'status': ovn_const.HM_EVENT_MEMBER_PORT_OFFLINE}
|
||||||
self._update_external_ids_member_status(self.ovn_hm_lb, member['id'],
|
self._update_external_ids_member_status(self.ovn_hm_lb, member['id'],
|
||||||
@@ -6596,6 +6601,7 @@ class TestOvnProviderHelper(ovn_base.TestOvnOctaviaBase):
|
|||||||
'logical_port': 'a-logical-port',
|
'logical_port': 'a-logical-port',
|
||||||
'src_ip': '10.22.33.4',
|
'src_ip': '10.22.33.4',
|
||||||
'port': '8081',
|
'port': '8081',
|
||||||
|
'delete': False,
|
||||||
'protocol': ovn_hm_lb2.protocol,
|
'protocol': ovn_hm_lb2.protocol,
|
||||||
'status': ovn_const.HM_EVENT_MEMBER_PORT_OFFLINE}
|
'status': ovn_const.HM_EVENT_MEMBER_PORT_OFFLINE}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user