diff --git a/masakari/engine/manager.py b/masakari/engine/manager.py index 9e6f310f..d5700ab6 100644 --- a/masakari/engine/manager.py +++ b/masakari/engine/manager.py @@ -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()}) diff --git a/masakari/tests/unit/engine/test_engine_mgr.py b/masakari/tests/unit/engine/test_engine_mgr.py index 18cc1efb..03566528 100644 --- a/masakari/tests/unit/engine/test_engine_mgr.py +++ b/masakari/tests/unit/engine/test_engine_mgr.py @@ -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.' diff --git a/releasenotes/notes/bug-1960619-4c2cc73483bdff86.yaml b/releasenotes/notes/bug-1960619-4c2cc73483bdff86.yaml new file mode 100644 index 00000000..4175e38c --- /dev/null +++ b/releasenotes/notes/bug-1960619-4c2cc73483bdff86.yaml @@ -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 `__