コード例 #1
0
        def notify(create_result):
            # Ensure usage trackers for all resources affected by this API
            # operation are marked as dirty
            # Commit the reservation(s)
            for reservation in reservations:
                quota.QUOTAS.commit_reservation(request.context,
                                                reservation.reservation_id)
            resource_registry.set_resources_dirty(request.context)

            notifier_method = self._resource + '.create.end'
            self._notifier.info(request.context, notifier_method,
                                create_result)
            registry.publish(self._resource,
                             events.BEFORE_RESPONSE,
                             self,
                             payload=events.APIEventPayload(
                                 request.context,
                                 notifier_method,
                                 action,
                                 request_body=body,
                                 states=(
                                     {},
                                     create_result,
                                 ),
                                 collection_name=self._collection))
            return create_result
コード例 #2
0
    def after(self, state):
        resource_name = state.request.context.get('resource')
        collection_name = state.request.context.get('collection')
        neutron_context = state.request.context.get('neutron_context')
        action = pecan_constants.ACTION_MAP.get(state.request.method)
        if not action or action not in ('create', 'update', 'delete'):
            return
        if utils.is_member_action(utils.get_controller(state)):
            return
        if not resource_name:
            LOG.debug("Skipping NotifierHook processing as there was no "
                      "resource associated with the request")
            return
        if state.response.status_int > 300:
            LOG.debug(
                "No notification will be sent due to unsuccessful "
                "status code: %s", state.response.status_int)
            return

        original = {}
        if (action in ('delete', 'update')
                and state.request.context.get('original_resources', [])):
            # We only need the original resource for updates and deletes
            original = state.request.context.get('original_resources')[0]
        if action == 'delete':
            # The object has been deleted, so we must notify the agent with the
            # data of the original object as the payload, but we do not need
            # to pass it in as the original
            result = {resource_name: original}
            original = {}
        else:
            if not state.response.body:
                result = {}
            else:
                result = state.response.json

        notifier_method = '%s.%s.end' % (resource_name, action)
        notifier_action = utils.get_controller(state).plugin_handlers[action]
        registry.publish(resource_name,
                         events.BEFORE_RESPONSE,
                         self,
                         payload=events.APIEventPayload(
                             neutron_context,
                             notifier_method,
                             notifier_action,
                             request_body=state.request.body,
                             states=(
                                 original,
                                 result,
                             ),
                             collection_name=collection_name))

        if action == 'delete':
            resource_id = state.request.context.get('resource_id')
            result[resource_name + '_id'] = resource_id

        self._notifier.info(neutron_context, notifier_method, result)
コード例 #3
0
    def _delete(self, request, id, **kwargs):
        action = self._plugin_handlers[self.DELETE]

        # Check authz
        policy.init()
        parent_id = kwargs.get(self._parent_id_name)
        obj = self._item(request, id, parent_id=parent_id)
        try:
            policy.enforce(request.context,
                           action,
                           obj,
                           pluralized=self._collection)
        except oslo_policy.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist if policy does not authorize SHOW
            with excutils.save_and_reraise_exception() as ctxt:
                if not policy.check(request.context,
                                    self._plugin_handlers[self.SHOW],
                                    obj,
                                    pluralized=self._collection):
                    ctxt.reraise = False
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        obj_deleter = getattr(self._plugin, action)
        obj_deleter(request.context, id, **kwargs)
        # A delete operation usually alters resource usage, so mark affected
        # usage trackers as dirty
        resource_registry.set_resources_dirty(request.context)
        notifier_method = self._resource + '.delete.end'
        result = {self._resource: self._view(request.context, obj)}
        notifier_payload = {self._resource + '_id': id}
        notifier_payload.update(result)
        self._notifier.info(request.context, notifier_method, notifier_payload)

        registry.publish(self._resource,
                         events.BEFORE_RESPONSE,
                         self,
                         payload=events.APIEventPayload(
                             request.context,
                             notifier_method,
                             action,
                             states=(
                                 {},
                                 obj,
                                 result,
                             ),
                             collection_name=self._collection))
コード例 #4
0
    def _update(self, request, id, body, **kwargs):
        try:
            body = Controller.prepare_request_body(request.context,
                                                   body,
                                                   False,
                                                   self._resource,
                                                   self._attr_info,
                                                   allow_bulk=self._allow_bulk)
        except Exception as e:
            LOG.warning(
                "An exception happened while processing the request "
                "body. The exception message is [%s].", e)
            raise e

        action = self._plugin_handlers[self.UPDATE]
        # Load object to check authz
        # but pass only attributes in the original body and required
        # by the policy engine to the policy 'brain'
        field_list = [
            name for (name, value) in self._attr_info.items()
            if (value.get('required_by_policy') or value.get('primary_key')
                or 'default' not in value)
        ]
        # Ensure policy engine is initialized
        policy.init()
        parent_id = kwargs.get(self._parent_id_name)
        # If the parent_id exist, we should get orig_obj with
        # self._parent_id_name field.
        if parent_id and self._parent_id_name not in field_list:
            field_list.append(self._parent_id_name)
        orig_obj = self._item(request,
                              id,
                              field_list=field_list,
                              parent_id=parent_id)
        orig_object_copy = copy.copy(orig_obj)
        orig_obj.update(body[self._resource])
        # Make a list of attributes to be updated to inform the policy engine
        # which attributes are set explicitly so that it can distinguish them
        # from the ones that are set to their default values.
        orig_obj[constants.ATTRIBUTES_TO_UPDATE] = body[self._resource].keys()
        # Then get the ext_parent_id, format to ext_parent_parent_resource_id
        if self._parent_id_name in orig_obj:
            self._set_parent_id_into_ext_resources_request(
                request, orig_obj, parent_id)
        try:
            policy.enforce(request.context,
                           action,
                           orig_obj,
                           pluralized=self._collection)
        except oslo_policy.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist if policy does not authorize SHOW
            with excutils.save_and_reraise_exception() as ctxt:
                if not policy.check(request.context,
                                    self._plugin_handlers[self.SHOW],
                                    orig_obj,
                                    pluralized=self._collection):
                    ctxt.reraise = False
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        if self._native_bulk and hasattr(self._plugin, "%s_bulk" % action):
            obj_updater = getattr(self._plugin, "%s_bulk" % action)
        else:
            obj_updater = getattr(self._plugin, action)

        kwargs = {self._resource: body}
        if parent_id:
            kwargs[self._parent_id_name] = parent_id
        obj = obj_updater(request.context, id, **kwargs)
        # Usually an update operation does not alter resource usage, but as
        # there might be side effects it might be worth checking for changes
        # in resource usage here as well (e.g: a tenant port is created when a
        # router interface is added)
        resource_registry.set_resources_dirty(request.context)

        result = {self._resource: self._view(request.context, obj)}
        notifier_method = self._resource + '.update.end'
        self._notifier.info(request.context, notifier_method, result)
        registry.publish(self._resource,
                         events.BEFORE_RESPONSE,
                         self,
                         payload=events.APIEventPayload(
                             request.context,
                             notifier_method,
                             action,
                             request_body=body,
                             states=(
                                 orig_object_copy,
                                 result,
                             ),
                             collection_name=self._collection))
        return result
コード例 #5
0
 def test_method_name(self):
     e = events.APIEventPayload(mock.ANY, 'post.end', 'POST')
     self.assertEqual('post.end', e.method_name)
コード例 #6
0
 def test_action(self):
     e = events.APIEventPayload(mock.ANY, 'post.end', 'POST')
     self.assertEqual('POST', e.action)