def test_emit_notification(self, mock_notifier):
        self.config(notification_level='debug')
        payload = self.TestNotificationPayload(an_extra_field='extra',
                                               an_optional_field=1)
        payload.populate_schema(test_obj=self.fake_obj)
        notif = self.TestNotification(
            event_type=notification.EventType(
                object='test_object',
                action='test',
                status=fields.NotificationStatus.START),
            level=fields.NotificationLevel.DEBUG,
            publisher=notification.NotificationPublisher(
                service='ironic-conductor', host='host'),
            payload=payload)

        mock_context = mock.Mock()
        notif.emit(mock_context)

        self._verify_notification(
            mock_notifier,
            mock_context,
            expected_event_type='baremetal.test_object.test.start',
            expected_payload={
                'ironic_object.name': 'TestNotificationPayload',
                'ironic_object.data': {
                    'fake_field_a': 'fake1',
                    'fake_field_b': 2,
                    'an_extra_field': 'extra',
                    'an_optional_field': 1
                },
                'ironic_object.version': '1.0',
                'ironic_object.namespace': 'ironic'
            },
            expected_publisher='ironic-conductor.host',
            notif_level=fields.NotificationLevel.DEBUG)
    def test_event_type_make_status_invalid(self):
        def make_status_invalid():
            event_type.status = "Roar"

        event_type = notification.EventType(
            object='test_object', action='test', status='start')
        self.assertRaises(ValueError, make_status_invalid)
    def test_emit_notification_empty_schema(self, mock_notifier):
        self.config(notification_level='debug')
        payload = self.TestNotificationPayloadEmptySchema(fake_field='123')
        notif = self.TestNotificationEmptySchema(
            event_type=notification.EventType(
                object='test_object',
                action='test',
                status=fields.NotificationStatus.ERROR),
            level=fields.NotificationLevel.ERROR,
            publisher=notification.NotificationPublisher(
                service='ironic-conductor', host='host'),
            payload=payload)

        mock_context = mock.Mock()
        notif.emit(mock_context)

        self._verify_notification(
            mock_notifier,
            mock_context,
            expected_event_type='baremetal.test_object.test.error',
            expected_payload={
                'ironic_object.name': 'TestNotificationPayloadEmptySchema',
                'ironic_object.data': {
                    'fake_field': '123',
                },
                'ironic_object.version': '1.0',
                'ironic_object.namespace': 'ironic'
            },
            expected_publisher='ironic-conductor.host',
            notif_level=fields.NotificationLevel.ERROR)
Beispiel #4
0
def _emit_conductor_node_notification(task, notification_method,
                                      payload_method, action, level, status,
                                      **kwargs):
    """Helper for emitting a conductor notification about a node.

    :param task: a TaskManager instance.
    :param notification_method: Constructor for the notification itself.
    :param payload_method: Constructor for the notification payload. Node
                           should be first argument of the method.
    :param action: Action string to go in the EventType.
    :param level: Notification level. One of
                  `ironic.objects.fields.NotificationLevel.ALL`
    :param status: Status to go in the EventType. One of
                   `ironic.objects.fields.NotificationStatus.ALL`
    :param **kwargs: kwargs to use when creating the notification payload.
                     Passed to the payload_method.
    """
    try:
        # Prepare our exception message just in case
        exception_values = {
            "node": task.node.uuid,
            "action": action,
            "status": status,
            "level": level,
            "notification_method": notification_method.__name__,
            "payload_method": payload_method.__name__
        }
        exception_message = (_("Failed to send baremetal.node."
                               "%(action)s.%(status)s notification for node "
                               "%(node)s with level %(level)s, "
                               "notification_method %(notification_method)s, "
                               "payload_method %(payload_method)s, error "
                               "%(error)s"))
        payload = payload_method(task.node, **kwargs)
        notification.mask_secrets(payload)
        notification_method(publisher=notification.NotificationPublisher(
            service='ironic-conductor', host=CONF.host),
                            event_type=notification.EventType(object='node',
                                                              action=action,
                                                              status=status),
                            level=level,
                            payload=payload).emit(task.context)
    except (exception.NotificationSchemaObjectError,
            exception.NotificationSchemaKeyError,
            exception.NotificationPayloadError,
            oslo_msg_exc.MessageDeliveryFailure,
            oslo_vo_exc.VersionedObjectsException) as e:
        exception_values['error'] = e
        LOG.warning(exception_message, exception_values)
    except Exception as e:
        # NOTE(mariojv) For unknown exceptions, also log the traceback.
        exception_values['error'] = e
        LOG.exception(exception_message, exception_values)
Beispiel #5
0
    def test_no_emit_schema_not_populated(self, mock_notifier):
        self.config(notification_level='debug')
        payload = self.TestNotificationPayload(an_extra_field='extra',
                                               an_optional_field=1)
        notif = self.TestNotification(
            event_type=notification.EventType(object='test_object',
                                              action='test',
                                              status='start'),
            level=fields.NotificationLevel.DEBUG,
            publisher=notification.NotificationPublisher(
                service='ironic-conductor', host='host'),
            payload=payload)

        mock_context = mock.Mock()
        self.assertRaises(exception.NotificationPayloadError, notif.emit,
                          mock_context)
        self.assertFalse(mock_notifier.called)
Beispiel #6
0
    def test_no_emit_notifs_disabled(self, mock_notifier):
        # Make sure notifications aren't emitted when notification_level
        # isn't defined, indicating notifications should be disabled
        payload = self.TestNotificationPayload(an_extra_field='extra',
                                               an_optional_field=1)
        payload.populate_schema(test_obj=self.fake_obj)
        notif = self.TestNotification(
            event_type=notification.EventType(object='test_object',
                                              action='test',
                                              status='start'),
            level=fields.NotificationLevel.DEBUG,
            publisher=notification.NotificationPublisher(
                service='ironic-conductor', host='host'),
            payload=payload)

        mock_context = mock.Mock()
        notif.emit(mock_context)

        self.assertFalse(mock_notifier.called)
Beispiel #7
0
    def test_no_emit_level_too_low(self, mock_notifier):
        # Make sure notification doesn't emit when set notification
        # level < config level
        self.config(notification_level='warning')
        payload = self.TestNotificationPayload(an_extra_field='extra',
                                               an_optional_field=1)
        payload.populate_schema(test_obj=self.fake_obj)
        notif = self.TestNotification(
            event_type=notification.EventType(object='test_object',
                                              action='test',
                                              status='start'),
            level=fields.NotificationLevel.DEBUG,
            publisher=notification.NotificationPublisher(
                service='ironic-conductor', host='host'),
            payload=payload)

        mock_context = mock.Mock()
        notif.emit(mock_context)

        self.assertFalse(mock_notifier.called)
Beispiel #8
0
def _emit_api_notification(context, obj, action, level, status, **kwargs):
    """Helper for emitting API notifications.

    :param context: request context.
    :param obj: resource rpc object.
    :param action: Action string to go in the EventType.
    :param level: Notification level. One of
                  `ironic.objects.fields.NotificationLevel.ALL`
    :param status: Status to go in the EventType. One of
                   `ironic.objects.fields.NotificationStatus.ALL`
    :param kwargs: kwargs to use when creating the notification payload.
    """
    resource = obj.__class__.__name__.lower()
    extra_args = kwargs
    try:
        try:
            if action == 'maintenance_set':
                notification_method = node_objects.NodeMaintenanceNotification
                payload_method = node_objects.NodePayload
            elif resource not in CRUD_NOTIFY_OBJ:
                notification_name = payload_name = _("is not defined")
                raise KeyError(_("Unsupported resource: %s") % resource)
            else:
                notification_method, payload_method = CRUD_NOTIFY_OBJ[resource]

            notification_name = notification_method.__name__
            payload_name = payload_method.__name__
        finally:
            # Prepare our exception message just in case
            exception_values = {
                "resource": resource,
                "uuid": obj.uuid,
                "action": action,
                "status": status,
                "level": level,
                "notification_method": notification_name,
                "payload_method": payload_name
            }
            exception_message = (_("Failed to send baremetal.%(resource)s."
                                   "%(action)s.%(status)s notification for "
                                   "%(resource)s %(uuid)s with level "
                                   "%(level)s, notification method "
                                   "%(notification_method)s, payload method "
                                   "%(payload_method)s, error %(error)s"))

        payload = payload_method(obj, **extra_args)
        if resource == 'node':
            notification.mask_secrets(payload)
        notification_method(publisher=notification.NotificationPublisher(
            service='ironic-api', host=CONF.host),
                            event_type=notification.EventType(object=resource,
                                                              action=action,
                                                              status=status),
                            level=level,
                            payload=payload).emit(context)
    except (exception.NotificationSchemaObjectError,
            exception.NotificationSchemaKeyError,
            exception.NotificationPayloadError,
            oslo_msg_exc.MessageDeliveryFailure,
            oslo_vo_exc.VersionedObjectsException) as e:
        exception_values['error'] = e
        LOG.warning(exception_message, exception_values)
    except Exception as e:
        exception_values['error'] = e
        LOG.exception(exception_message, exception_values)
 def test_event_type_without_status_fails(self):
     event_type = notification.EventType(object="some_obj",
                                         action="some_action")
     self.assertRaises(NotImplementedError, event_type.to_event_type_field)
 def test_event_type_with_status(self):
     event_type = notification.EventType(object="some_obj",
                                         action="some_action",
                                         status="success")
     self.assertEqual("baremetal.some_obj.some_action.success",
                      event_type.to_event_type_field())
Beispiel #11
0
 def test_event_type_without_phase(self):
     event_type = notification.EventType(
         object="some_obj", action="some_action")
     self.assertEqual("baremetal.some_obj.some_action",
                      event_type.to_event_type_field())