Handle host notification without host status

If an user sends host notification without host status:
openstack notification create COMPUTE_HOST <host> <date> '{"event": "STOPPED"}'
logging registers silly error like object None has not method 'upper' and
notification gets status 'running', host is set in maintenance status.
It's impossible to set manually host status to non-maintanence
until there are host-related running notifications.
Running notifications are expired in 24 hours by default.
The patch makes engine to set 'ignore' status for such
notifications.

Closes-Bug: 1960619
Change-Id: Id873b3300b6de49082805654c85414a8868dd925
This commit is contained in:
Mitya_Eremeev 2022-02-11 14:36:12 +03:00 committed by Radosław Piliszek
parent 607da5931a
commit 0837d7787c
3 changed files with 42 additions and 4 deletions

View File

@ -177,11 +177,16 @@ class MasakariManager(manager.Manager):
notification_event = notification.payload.get('event')
exception_info = None
if host_status.upper() != fields.HostStatusType.NORMAL:
if host_status is None:
LOG.warning("Notification '%(uuid)s' ignored as host_status is "
"not provided.",
{'uuid': notification.notification_uuid})
notification_status = fields.NotificationStatus.IGNORED
elif host_status.upper() != fields.HostStatusType.NORMAL:
# NOTE(shilpasd): Avoid host recovery for host_status other than
# 'NORMAL' otherwise it could lead to unsafe evacuation of
# instances running on the failed source host.
LOG.warning("Notification '%(uuid)s' ignored as host_status"
LOG.warning("Notification '%(uuid)s' ignored as host_status "
"is '%(host_status)s'",
{'uuid': notification.notification_uuid,
'host_status': host_status.upper()})

View File

@ -841,8 +841,8 @@ class EngineManagerUnitTestCase(test.NoDBTestCase):
notification=notification)
mock_log.assert_called_once()
args = mock_log.call_args[0]
expected_log = ("Notification '%(uuid)s' ignored as host_status"
"is '%(host_status)s'")
expected_log = ("Notification '%(uuid)s' ignored as host_status "
"is '%(host_status)s'")
expected_log_args_1 = {
'uuid': notification.notification_uuid,
'host_status': fields.HostStatusType.UNKNOWN}
@ -852,6 +852,31 @@ class EngineManagerUnitTestCase(test.NoDBTestCase):
self.assertEqual(
fields.NotificationStatus.IGNORED, notification.status)
@mock.patch.object(notification_obj.Notification, "save")
def test_process_notification_host_failure_without_host_status(
self, mock_get_noti, mock_notification_save):
notification = fakes.create_fake_notification(
type="COMPUTE_HOST",
payload={'event': 'stopped', 'cluster_status': 'ONLINE'},
source_host_uuid=uuidsentinel.fake_host,
generated_time=NOW, status=fields.NotificationStatus.NEW,
notification_uuid=uuidsentinel.fake_notification)
mock_get_noti.return_value = notification
notification_new = notification.obj_clone()
notification_new.status = fields.NotificationStatus.IGNORED
mock_notification_save.side_effect = [notification, notification_new]
with mock.patch("masakari.engine.manager.LOG.warning") as mock_log:
self.engine._process_notification(self.context,
notification=notification)
mock_log.assert_called_once_with(
"Notification '%(uuid)s' ignored as host_status is not "
"provided.",
{'uuid': notification.notification_uuid})
self.assertEqual(
fields.NotificationStatus.IGNORED, notification.status)
@mock.patch('masakari.compute.nova.novaclient')
@mock.patch.object(nova.API, "enable_disable_service")
@mock.patch('masakari.engine.drivers.taskflow.host_failure.'

View File

@ -0,0 +1,8 @@
---
fixes:
- |
Fixes an issue that could be caused by a user sending a malformed
host notification missing host status. Such notification would
block the host from being added back from maintenance until
manual intervention or notification expiration.
`LP#1960619 <https://launchpad.net/bugs/1960619>`__