def test_key(self):
     event = external_event_obj.InstanceExternalEvent(
         name='network-changed', tag='bar')
     with mock.patch.object(event, 'make_key') as make_key:
         make_key.return_value = 'key'
         self.assertEqual('key', event.key)
         make_key.assert_called_once_with('network-changed', 'bar')
    def test_event_names(self):
        for event in external_event_obj.EVENT_NAMES:
            external_event_obj.InstanceExternalEvent(name=event, tag='bar')

        self.assertRaises(ValueError,
                          external_event_obj.InstanceExternalEvent,
                          name='foo',
                          tag='bar')
Example #3
0
    def create(self, req, body):
        """Creates a new instance event."""
        context = req.environ['nova.context']
        authorize(context, action='create')

        events = []
        accepted = []
        instances = {}
        result = 200

        body_events = body.get('events', [])
        if not isinstance(body_events, list) or not len(body_events):
            raise webob.exc.HTTPBadRequest()

        for _event in body_events:
            client_event = dict(_event)
            event = external_event_obj.InstanceExternalEvent()

            try:
                event.instance_uuid = client_event.pop('server_uuid')
                event.name = client_event.pop('name')
                event.status = client_event.pop('status', 'completed')
                event.tag = client_event.pop('tag', None)
            except KeyError as missing_key:
                msg = _('event entity requires key %(key)s') % missing_key
                raise webob.exc.HTTPBadRequest(explanation=msg)

            if client_event:
                msg = (_('event entity contains unsupported items: %s') %
                       ', '.join(client_event.keys()))
                raise webob.exc.HTTPBadRequest(explanation=msg)

            if event.status not in external_event_obj.EVENT_STATUSES:
                raise webob.exc.HTTPBadRequest(
                    _('Invalid event status `%s\'') % event.status)

            events.append(_event)
            if event.instance_uuid not in instances:
                try:
                    instance = instance_obj.Instance.get_by_uuid(
                        context, event.instance_uuid)
                    instances[event.instance_uuid] = instance
                except exception.InstanceNotFound:
                    LOG.debug(
                        'Dropping event %(name)s:%(tag)s for unknown '
                        'instance %(instance_uuid)s', dict(event.iteritems()))
                    _event['status'] = 'failed'
                    _event['code'] = 404
                    result = 207

            if event.instance_uuid in instances:
                accepted.append(event)
                _event['code'] = 200
                LOG.audit(
                    _('Create event %(name)s:%(tag)s for instance '
                      '%(instance_uuid)s'), dict(event.iteritems()))

        if accepted:
            self.compute_api.external_instance_event(context,
                                                     instances.values(),
                                                     accepted)
        else:
            msg = _('No instances found for any event')
            raise webob.exc.HTTPNotFound(explanation=msg)

        # FIXME(cyeoh): This needs some infrastructure support so that
        # we have a general way to do this
        robj = wsgi.ResponseObject({'events': events})
        robj._code = result
        return robj