Fix hm operating status to ONLINE in single lb call

So far, Health Monitor was not set to ONLINE when single-call-creates
were used.

This patch adds a database task which sets the operating status of all
the enabled Health Monitors of a LB to ONLINE.

Story 2008400
Task 41333

Change-Id: I9deaea182568a23e8c1104d806273dc87f5caa72
(cherry picked from commit e20ceebcf2)
(cherry picked from commit 0681d6f9f5)
(cherry picked from commit 713edbc792)
This commit is contained in:
Omer 2022-12-20 16:58:23 +01:00 committed by Omer Schwartz
parent 09e0beb66f
commit b555ffc2a2
7 changed files with 170 additions and 0 deletions

View File

@ -60,6 +60,9 @@ class ListenerFlows(object):
requires=constants.LOADBALANCER)) requires=constants.LOADBALANCER))
create_all_listeners_flow.add(network_tasks.UpdateVIP( create_all_listeners_flow.add(network_tasks.UpdateVIP(
requires=constants.LOADBALANCER)) requires=constants.LOADBALANCER))
create_all_listeners_flow.add(
database_tasks.MarkHealthMonitorsOnlineInDB(
requires=constants.LOADBALANCER))
return create_all_listeners_flow return create_all_listeners_flow
def get_delete_listener_flow(self): def get_delete_listener_flow(self):

View File

@ -1739,6 +1739,38 @@ class MarkHealthMonitorPendingUpdateInDB(BaseDatabaseTask):
self.task_utils.mark_health_mon_prov_status_error(health_mon.id) self.task_utils.mark_health_mon_prov_status_error(health_mon.id)
class MarkHealthMonitorsOnlineInDB(BaseDatabaseTask):
"""Mark all enabled health monitors Online
:param loadbalancer: The Load Balancer that has associated health monitors
:returns: None
"""
def execute(self, loadbalancer):
db_lb = self.loadbalancer_repo.get(
db_apis.get_session(),
id=loadbalancer.id)
# Update the healthmonitors of either attached listeners or l7policies
hms_to_update = []
for listener in db_lb.listeners:
if listener.default_pool and listener.default_pool.health_monitor:
hm = listener.default_pool.health_monitor
if hm.enabled:
hms_to_update.append(hm.id)
for l7policy in listener.l7policies:
if l7policy.redirect_pool and (
l7policy.redirect_pool.health_monitor):
hm = l7policy.redirect_pool.health_monitor
if hm.enabled:
hms_to_update.append(hm.id)
for hm_id in hms_to_update:
self.health_mon_repo.update(db_apis.get_session(), hm_id,
operating_status=constants.ONLINE)
class MarkL7PolicyActiveInDB(BaseDatabaseTask): class MarkL7PolicyActiveInDB(BaseDatabaseTask):
"""Mark the l7policy ACTIVE in the DB. """Mark the l7policy ACTIVE in the DB.

View File

@ -60,6 +60,9 @@ class ListenerFlows(object):
requires=constants.LOADBALANCER_ID)) requires=constants.LOADBALANCER_ID))
create_all_listeners_flow.add(network_tasks.UpdateVIP( create_all_listeners_flow.add(network_tasks.UpdateVIP(
requires=constants.LISTENERS)) requires=constants.LISTENERS))
create_all_listeners_flow.add(
database_tasks.MarkHealthMonitorsOnlineInDB(
requires=constants.LOADBALANCER))
return create_all_listeners_flow return create_all_listeners_flow
def get_delete_listener_flow(self): def get_delete_listener_flow(self):

View File

@ -1887,6 +1887,39 @@ class MarkHealthMonitorPendingUpdateInDB(BaseDatabaseTask):
health_mon[constants.HEALTHMONITOR_ID]) health_mon[constants.HEALTHMONITOR_ID])
class MarkHealthMonitorsOnlineInDB(BaseDatabaseTask):
"""Mark all enabled health monitors Online
:param loadbalancer: Dictionary of a Load Balancer that has associated
health monitors
:returns: None
"""
def execute(self, loadbalancer: dict):
db_lb = self.loadbalancer_repo.get(
db_apis.get_session(),
id=loadbalancer[constants.LOADBALANCER_ID])
# Update the healthmonitors of either attached listeners or l7policies
hms_to_update = []
for listener in db_lb.listeners:
if listener.default_pool and listener.default_pool.health_monitor:
hm = listener.default_pool.health_monitor
if hm.enabled:
hms_to_update.append(hm.id)
for l7policy in listener.l7policies:
if l7policy.redirect_pool and (
l7policy.redirect_pool.health_monitor):
hm = l7policy.redirect_pool.health_monitor
if hm.enabled:
hms_to_update.append(hm.id)
for hm_id in hms_to_update:
self.health_mon_repo.update(db_apis.get_session(), hm_id,
operating_status=constants.ONLINE)
class MarkL7PolicyActiveInDB(BaseDatabaseTask): class MarkL7PolicyActiveInDB(BaseDatabaseTask):
"""Mark the l7policy ACTIVE in the DB. """Mark the l7policy ACTIVE in the DB.

View File

@ -1974,6 +1974,53 @@ class TestDatabaseTasks(base.TestCase):
id=HM_ID, id=HM_ID,
provisioning_status=constants.ERROR) provisioning_status=constants.ERROR)
@mock.patch('octavia.db.repositories.LoadBalancerRepository.get')
@mock.patch('octavia.db.repositories.HealthMonitorRepository.update')
def test_mark_health_monitors_online_in_db(self,
mock_health_mon_repo_update,
mock_loadbalancer_repo_get,
mock_generate_uuid,
mock_LOG,
mock_get_session,
mock_loadbalancer_repo_update,
mock_listener_repo_update,
mock_amphora_repo_update,
mock_amphora_repo_delete):
# Creating a mock hm for a default pool
mock_lb = mock.MagicMock()
mock_listener = mock.MagicMock()
mock_default_pool = mock_listener.default_pool
mock_hm_def_pool = mock_default_pool.health_monitor
mock_hm_def_pool.id = uuidutils.generate_uuid()
mock_lb.listeners = [mock_listener]
# Creating a mock hm for a redirect pool of an l7policy
mock_l7policy = mock.MagicMock()
mock_redirect_pool = mock_l7policy.redirect_pool
mock_hm_l7_policy = mock_redirect_pool.health_monitor
mock_hm_l7_policy.id = uuidutils.generate_uuid()
mock_listener.l7policies = [mock_l7policy]
# Creating a mock hm for a non default pool - we check its health
# monitor won't be updated
mock_pool = mock.MagicMock()
mock_hm_non_def_pool = mock_pool.health_monitor
mock_hm_non_def_pool.id = uuidutils.generate_uuid()
mock_lb.pools = [mock_pool]
mock_loadbalancer_repo_get.return_value = mock_lb
mark_health_mon_online = (database_tasks.
MarkHealthMonitorsOnlineInDB())
mark_health_mon_online.execute(mock_lb)
mock_session = 'TEST'
for mock_id in [mock_hm_def_pool.id, mock_hm_l7_policy.id]:
mock_health_mon_repo_update.assert_called_with(
mock_session,
mock_id,
operating_status=constants.ONLINE)
self.assertEqual(2, mock_health_mon_repo_update.call_count)
@mock.patch('octavia.db.repositories.L7PolicyRepository.update') @mock.patch('octavia.db.repositories.L7PolicyRepository.update')
def test_mark_l7policy_active_in_db(self, def test_mark_l7policy_active_in_db(self,
mock_l7policy_repo_update, mock_l7policy_repo_update,

View File

@ -2099,6 +2099,53 @@ class TestDatabaseTasks(base.TestCase):
id=HM_ID, id=HM_ID,
provisioning_status=constants.ERROR) provisioning_status=constants.ERROR)
@mock.patch('octavia.db.repositories.LoadBalancerRepository.get')
@mock.patch('octavia.db.repositories.HealthMonitorRepository.update')
def test_mark_health_monitors_online_in_db(self,
mock_health_mon_repo_update,
mock_loadbalancer_repo_get,
mock_generate_uuid,
mock_LOG,
mock_get_session,
mock_loadbalancer_repo_update,
mock_listener_repo_update,
mock_amphora_repo_update,
mock_amphora_repo_delete):
# Creating a mock hm for a default pool
mock_lb = mock.MagicMock()
mock_listener = mock.MagicMock()
mock_default_pool = mock_listener.default_pool
mock_hm_def_pool = mock_default_pool.health_monitor
mock_hm_def_pool.id = uuidutils.generate_uuid()
mock_lb.listeners = [mock_listener]
# Creating a mock hm for a redirect pool of an l7policy
mock_l7policy = mock.MagicMock()
mock_redirect_pool = mock_l7policy.redirect_pool
mock_hm_l7_policy = mock_redirect_pool.health_monitor
mock_hm_l7_policy.id = uuidutils.generate_uuid()
mock_listener.l7policies = [mock_l7policy]
# Creating a mock hm for a non default pool - we check its health
# monitor won't be updated
mock_pool = mock.MagicMock()
mock_hm_non_def_pool = mock_pool.health_monitor
mock_hm_non_def_pool.id = uuidutils.generate_uuid()
mock_lb.pools = [mock_pool]
mock_loadbalancer_repo_get.return_value = mock_lb
mark_health_mon_online = (database_tasks.
MarkHealthMonitorsOnlineInDB())
mark_health_mon_online.execute(mock_lb)
mock_session = 'TEST'
for mock_id in [mock_hm_def_pool.id, mock_hm_l7_policy.id]:
mock_health_mon_repo_update.assert_called_with(
mock_session,
mock_id,
operating_status=constants.ONLINE)
self.assertEqual(2, mock_health_mon_repo_update.call_count)
@mock.patch('octavia.db.repositories.L7PolicyRepository.update') @mock.patch('octavia.db.repositories.L7PolicyRepository.update')
@mock.patch('octavia.db.repositories.L7PolicyRepository.get') @mock.patch('octavia.db.repositories.L7PolicyRepository.get')
def test_mark_l7policy_active_in_db(self, def test_mark_l7policy_active_in_db(self,

View File

@ -0,0 +1,5 @@
---
fixes:
- |
Fixed a bug that didn't set all the active load balancer Health Monitors
ONLINE in populated LB single-create calls.