Beispiel #1
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
            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'
        self._notifier.info(request.context, notifier_method,
                            {self._resource + '_id': id})
        result = {self._resource: self._view(request.context, obj)}
        self._send_nova_notification(action, {}, result)
        self._send_dhcp_notification(request.context, result, notifier_method)
Beispiel #2
0
 def _handle_action(request, id, **kwargs):
     arg_list = [request.context, id]
     # Ensure policy engine is initialized
     policy.init()
     # Fetch the resource and verify if the user can access it
     try:
         parent_id = kwargs.get(self._parent_id_name)
         resource = self._item(request,
                               id,
                               do_authz=True,
                               field_list=None,
                               parent_id=parent_id)
     except oslo_policy.PolicyNotAuthorized:
         msg = _('The resource could not be found.')
         raise webob.exc.HTTPNotFound(msg)
     body = copy.deepcopy(kwargs.pop('body', None))
     # Explicit comparison with None to distinguish from {}
     if body is not None:
         arg_list.append(body)
     # It is ok to raise a 403 because accessibility to the
     # object was checked earlier in this method
     policy.enforce(request.context,
                    name,
                    resource,
                    pluralized=self._collection)
     ret_value = getattr(self._plugin, name)(*arg_list, **kwargs)
     # It is simply impossible to predict whether one of this
     # actions alters resource usage. For instance a tenant port
     # is created when a router interface is added. Therefore it is
     # important to mark as dirty resources whose counters have
     # been altered by this operation
     resource_registry.set_resources_dirty(request.context)
     return ret_value
Beispiel #3
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
Beispiel #4
0
    def _update(self, request, id, body, **kwargs):
        body = Controller.prepare_request_body(
            request.context, copy.deepcopy(body), False, self._resource, self._attr_info, allow_bulk=self._allow_bulk
        )
        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 six.iteritems(self._attr_info)
            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)
        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[n_const.ATTRIBUTES_TO_UPDATE] = body[self._resource].keys()
        try:
            policy.enforce(request.context, action, orig_obj, pluralized=self._collection)
        except oslo_policy.PolicyNotAuthorized:
            with excutils.save_and_reraise_exception() as ctxt:
                # If a tenant is modifying it's own object, it's safe to return
                # a 403. Otherwise, pretend that it doesn't exist to avoid
                # giving away information.
                if request.context.tenant_id != orig_obj["tenant_id"]:
                    ctxt.reraise = False
            msg = _("The resource could not be found.")
            raise webob.exc.HTTPNotFound(msg)

        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.notify(
            self._resource,
            events.BEFORE_RESPONSE,
            self,
            context=request.context,
            data=result,
            method_name=notifier_method,
            action=action,
            original=orig_object_copy,
        )
        return result
Beispiel #5
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
            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'
        self._notifier.info(request.context,
                            notifier_method,
                            {self._resource + '_id': id})
        result = {self._resource: self._view(request.context, obj)}
        self._send_nova_notification(action, {}, result)
        self._send_dhcp_notification(request.context,
                                     result,
                                     notifier_method)
Beispiel #6
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
            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.notify(
            self._resource,
            events.BEFORE_RESPONSE,
            self,
            context=request.context,
            data=result,
            method_name=notifier_method,
            action=action,
            original={},
        )
Beispiel #7
0
    def _update(self, request, id, body, **kwargs):
        body = Controller.prepare_request_body(request.context,
                                               body, False,
                                               self._resource, self._attr_info,
                                               allow_bulk=self._allow_bulk)
        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 six.iteritems(self._attr_info)
                      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)
        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[n_const.ATTRIBUTES_TO_UPDATE] = body[self._resource].keys()
        try:
            policy.enforce(request.context,
                           action,
                           orig_obj,
                           pluralized=self._collection)
        except oslo_policy.PolicyNotAuthorized:
            with excutils.save_and_reraise_exception() as ctxt:
                # If a tenant is modifying its own object, it's safe to return
                # a 403. Otherwise, pretend that it doesn't exist to avoid
                # giving away information.
                orig_obj_tenant_id = orig_obj.get("tenant_id")
                if (request.context.tenant_id != orig_obj_tenant_id or
                    orig_obj_tenant_id is None):
                    ctxt.reraise = False
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        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.notify(self._resource, events.BEFORE_RESPONSE, self,
                        context=request.context, data=result,
                        method_name=notifier_method, action=action,
                        original=orig_object_copy)
        return result
Beispiel #8
0
 def _handle_action(request, id, **kwargs):
     arg_list = [request.context, id]
     # Ensure policy engine is initialized
     policy.init()
     # Fetch the resource and verify if the user can access it
     try:
         parent_id = kwargs.get(self._parent_id_name)
         resource = self._item(request,
                               id,
                               do_authz=True,
                               field_list=None,
                               parent_id=parent_id)
     except oslo_policy.PolicyNotAuthorized:
         msg = _('The resource could not be found.')
         raise webob.exc.HTTPNotFound(msg)
     body = copy.deepcopy(kwargs.pop('body', None))
     # Explicit comparison with None to distinguish from {}
     if body is not None:
         arg_list.append(body)
     # It is ok to raise a 403 because accessibility to the
     # object was checked earlier in this method
     policy.enforce(request.context,
                    name,
                    resource,
                    pluralized=self._collection)
     ret_value = getattr(self._plugin, name)(*arg_list, **kwargs)
     # It is simply impossible to predict whether one of this
     # actions alters resource usage. For instance a tenant port
     # is created when a router interface is added. Therefore it is
     # important to mark as dirty resources whose counters have
     # been altered by this operation
     resource_registry.set_resources_dirty(request.context)
     return ret_value
 def test_set_resources_dirty_no_tracked_resource(self):
     ctx = context.Context('user_id', 'tenant_id',
                           is_admin=False, is_advsvc=False)
     with mock.patch('neutron.quota.resource.'
                     'TrackedResource.mark_dirty') as mock_mark_dirty:
         self.registry.register_resource_by_name('meh')
         resource_registry.set_resources_dirty(ctx)
         self.assertEqual(0, mock_mark_dirty.call_count)
 def test_set_resources_dirty_no_tracked_resource(self):
     ctx = context.Context('user_id', 'tenant_id',
                           is_admin=False, is_advsvc=False)
     with mock.patch('neutron.quota.resource.'
                     'TrackedResource.mark_dirty') as mock_mark_dirty:
         self.registry.register_resource_by_name('meh')
         resource_registry.set_resources_dirty(ctx)
         self.assertEqual(0, mock_mark_dirty.call_count)
 def test_set_resources_dirty_invoked_with_tracking_disabled(self):
     cfg.CONF.set_override("track_quota_usage", False, group="QUOTAS")
     # DietTestCase does not automatically cleans configuration overrides
     self.addCleanup(cfg.CONF.reset)
     with mock.patch("neutron.quota.resource." "TrackedResource.mark_dirty") as mock_mark_dirty:
         self.registry.set_tracked_resource("meh", test_quota.MehModel)
         self.registry.register_resource_by_name("meh")
         resource_registry.set_resources_dirty(mock.ANY)
         self.assertEqual(0, mock_mark_dirty.call_count)
 def test_set_resources_dirty(self):
     ctx = context.Context("user_id", "tenant_id", is_admin=False, is_advsvc=False)
     with mock.patch("neutron.quota.resource." "TrackedResource.mark_dirty") as mock_mark_dirty:
         self.registry.set_tracked_resource("meh", test_quota.MehModel)
         self.registry.register_resource_by_name("meh")
         res = self.registry.get_resource("meh")
         # This ensures dirty is true
         res._dirty_tenants.add("tenant_id")
         resource_registry.set_resources_dirty(ctx)
         mock_mark_dirty.assert_called_once_with(ctx)
 def test_set_resources_dirty_no_dirty_resource(self):
     ctx = context.Context("user_id", "tenant_id", is_admin=False, is_advsvc=False)
     with mock.patch("neutron.quota.resource." "TrackedResource.mark_dirty") as mock_mark_dirty:
         self.registry.set_tracked_resource("meh", test_quota.MehModel)
         self.registry.register_resource_by_name("meh")
         res = self.registry.get_resource("meh")
         # This ensures dirty is false
         res._dirty_tenants.clear()
         resource_registry.set_resources_dirty(ctx)
         self.assertEqual(0, mock_mark_dirty.call_count)
Beispiel #14
0
 def test_set_resources_dirty_invoked_with_tracking_disabled(self):
     cfg.CONF.set_override('track_quota_usage', False, group='QUOTAS')
     # DietTestCase does not automatically cleans configuration overrides
     self.addCleanup(cfg.CONF.reset)
     with mock.patch('neutron.quota.resource.'
                     'TrackedResource.mark_dirty') as mock_mark_dirty:
         self.registry.set_tracked_resource('meh', test_quota.MehModel)
         self.registry.register_resource_by_name('meh')
         resource_registry.set_resources_dirty(mock.ANY)
         self.assertEqual(0, mock_mark_dirty.call_count)
 def test_set_resources_dirty(self):
     ctx = context.Context('user_id', 'tenant_id',
                           is_admin=False, is_advsvc=False)
     with mock.patch('neutron.quota.resource.'
                     'TrackedResource.mark_dirty') as mock_mark_dirty:
         self.registry.set_tracked_resource('meh', test_quota.MehModel)
         self.registry.register_resource_by_name('meh')
         res = self.registry.get_resource('meh')
         # This ensures dirty is true
         res._dirty_tenants.add('tenant_id')
         resource_registry.set_resources_dirty(ctx)
         mock_mark_dirty.assert_called_once_with(ctx, nested=True)
 def after(self, state):
     # Commit reservation(s)
     reservations = state.request.context.get('reservations')
     if not reservations:
         return
     neutron_context = state.request.context.get('neutron_context')
     with db_api.context_manager.writer.using(neutron_context):
         # Commit the reservation(s)
         for reservation in reservations:
             quota.QUOTAS.commit_reservation(
                 neutron_context, reservation.reservation_id)
         resource_registry.set_resources_dirty(neutron_context)
 def test_set_resources_dirty(self):
     ctx = context.Context('user_id', 'tenant_id',
                           is_admin=False, is_advsvc=False)
     with mock.patch('neutron.quota.resource.'
                     'TrackedResource.mark_dirty') as mock_mark_dirty:
         self.registry.set_tracked_resource('meh', test_quota.MehModel)
         self.registry.register_resource_by_name('meh')
         res = self.registry.get_resource('meh')
         # This ensures dirty is true
         res._dirty_tenants.add('tenant_id')
         resource_registry.set_resources_dirty(ctx)
         mock_mark_dirty.assert_called_once_with(ctx)
 def test_set_resources_dirty_no_dirty_resource(self):
     ctx = context.Context('user_id', 'tenant_id',
                           is_admin=False, is_advsvc=False)
     with mock.patch('neutron.quota.resource.'
                     'TrackedResource.mark_dirty') as mock_mark_dirty:
         self.registry.set_tracked_resource('meh', test_quota.MehModel)
         self.registry.register_resource_by_name('meh')
         res = self.registry.get_resource('meh')
         # This ensures dirty is false
         res._dirty_tenants.clear()
         resource_registry.set_resources_dirty(ctx)
         self.assertEqual(0, mock_mark_dirty.call_count)
Beispiel #19
0
 def after(self, state):
     # Commit reservation(s)
     reservations = state.request.context.get('reservations')
     if not reservations:
         return
     neutron_context = state.request.context.get('neutron_context')
     with db_api.context_manager.writer.using(neutron_context):
         # Commit the reservation(s)
         for reservation in reservations:
             quota.QUOTAS.commit_reservation(neutron_context,
                                             reservation.reservation_id)
         resource_registry.set_resources_dirty(neutron_context)
Beispiel #20
0
        def notify(create_result):
            # Ensure usage trackers for all resources affected by this API
            # operation are marked as dirty
            # TODO(salv-orlando): This operation will happen in a single
            # transaction with reservation commit once that is implemented
            resource_registry.set_resources_dirty(request.context)

            notifier_method = self._resource + '.create.end'
            self._notifier.info(request.context, notifier_method,
                                create_result)
            self._send_dhcp_notification(request.context, create_result,
                                         notifier_method)
            return create_result
Beispiel #21
0
        def notify(create_result):
            # Ensure usage trackers for all resources affected by this API
            # operation are marked as dirty
            # TODO(salv-orlando): This operation will happen in a single
            # transaction with reservation commit once that is implemented
            resource_registry.set_resources_dirty(request.context)

            notifier_method = self._resource + '.create.end'
            self._notifier.info(request.context,
                                notifier_method,
                                create_result)
            self._send_dhcp_notification(request.context,
                                         create_result,
                                         notifier_method)
            return create_result
Beispiel #22
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))
Beispiel #23
0
        def notify(create_result):
            # Ensure usage trackers for all resources affected by this API
            # operation are marked as dirty
            with request.context.session.begin():
                # 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)
            self._send_dhcp_notification(request.context, create_result,
                                         notifier_method)
            return create_result
Beispiel #24
0
 def _call_on_drivers(self, method_name, context,
         continue_on_failure=False, raise_db_retriable=False):
     super(MechanismManager, self)._call_on_drivers(
             method_name, context, continue_on_failure=False,
             raise_db_retriable=False)
     if method_name.endswith('_precommit'):
         # This does the same thing as:
         # https://github.com/openstack/neutron/blob/newton-eol/neutron/
         # api/v2/base.py#L489
         # but from within the scope of the plugin's transaction, such
         # that if it fails, everything that happened prior to this in
         # precommit phase can also be rolled back.
         resource_name = method_name.replace('_precommit', '').replace(
                 'create_', '').replace('update_', '').replace(
                         'delete_', '')
         tracked_resource = resource_registry.get_resource(resource_name)
         tracked_resource._dirty_tenants.add(context.current['tenant_id'])
         resource_registry.set_resources_dirty(context._plugin_context)
Beispiel #25
0
        def notify(create_result):
            # Ensure usage trackers for all resources affected by this API
            # operation are marked as dirty
            with request.context.session.begin():
                # 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)
            self._send_dhcp_notification(request.context,
                                         create_result,
                                         notifier_method)
            return create_result
Beispiel #26
0
        def notify(create_result):
            # Ensure usage trackers for all resources affected by this API
            # operation are marked as dirty
            with request.context.session.begin():
                # 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.notify(self._resource, events.BEFORE_RESPONSE, self,
                            context=request.context, data=create_result,
                            method_name=notifier_method,
                            collection=self._collection)
            return create_result
Beispiel #27
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))
Beispiel #28
0
 def after(self, state):
     neutron_context = state.request.context.get('neutron_context')
     if not neutron_context:
         return
     collection = state.request.context.get('collection')
     resource = state.request.context.get('resource')
     if state.request.method == 'GET' and collection:
         # resync on list operations to preserve behavior of old API
         resource_registry.resync_resource(
             neutron_context, resource, neutron_context.tenant_id)
     # Commit reservation(s)
     reservations = state.request.context.get('reservations') or []
     if not reservations and state.request.method != 'DELETE':
         return
     with db_api.CONTEXT_WRITER.using(neutron_context):
         # Commit the reservation(s)
         for reservation in reservations:
             quota.QUOTAS.commit_reservation(
                 neutron_context, reservation.reservation_id)
         resource_registry.set_resources_dirty(neutron_context)
Beispiel #29
0
        def notify(create_result):
            # Ensure usage trackers for all resources affected by this API
            # operation are marked as dirty
            with request.context.session.begin():
                # 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.notify(self._resource, events.BEFORE_RESPONSE, self,
                            context=request.context, data=create_result,
                            method_name=notifier_method,
                            collection=self._collection,
                            action=action, original={})
            return create_result
 def after(self, state):
     neutron_context = state.request.context.get('neutron_context')
     if not neutron_context:
         return
     collection = state.request.context.get('collection')
     resource = state.request.context.get('resource')
     if state.request.method == 'GET' and collection:
         # resync on list operations to preserve behavior of old API
         resource_registry.resync_resource(neutron_context, resource,
                                           neutron_context.tenant_id)
     # Commit reservation(s)
     reservations = state.request.context.get('reservations') or []
     if not reservations and state.request.method != 'DELETE':
         return
     with db_api.CONTEXT_WRITER.using(neutron_context):
         # Commit the reservation(s)
         for reservation in reservations:
             quota.QUOTAS.commit_reservation(neutron_context,
                                             reservation.reservation_id)
         resource_registry.set_resources_dirty(neutron_context)
Beispiel #31
0
        def notify(create_result):
            # Ensure usage trackers for all resources affected by this API
            # operation are marked as dirty
            with db_api.CONTEXT_WRITER.using(request.context):
                # 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
Beispiel #32
0
    def update(self, request, id, body=None, **kwargs):
        """Updates the specified entity's attributes."""
        parent_id = kwargs.get(self._parent_id_name)
        try:
            payload = body.copy()
        except AttributeError:
            msg = _("Invalid format: %s") % request.body
            raise exceptions.BadRequest(resource='body', msg=msg)
        payload['id'] = id
        self._notifier.info(request.context,
                            self._resource + '.update.start',
                            payload)
        body = Controller.prepare_request_body(request.context, body, False,
                                               self._resource, self._attr_info,
                                               allow_bulk=self._allow_bulk)
        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 six.iteritems(self._attr_info)
                      if (value.get('required_by_policy') or
                          value.get('primary_key') or
                          'default' not in value)]
        # Ensure policy engine is initialized
        policy.init()
        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[const.ATTRIBUTES_TO_UPDATE] = body[self._resource].keys()
        try:
            policy.enforce(request.context,
                           action,
                           orig_obj,
                           pluralized=self._collection)
        except oslo_policy.PolicyNotAuthorized:
            with excutils.save_and_reraise_exception() as ctxt:
                # If a tenant is modifying it's own object, it's safe to return
                # a 403. Otherwise, pretend that it doesn't exist to avoid
                # giving away information.
                if request.context.tenant_id != orig_obj['tenant_id']:
                    ctxt.reraise = False
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        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)
        self._send_dhcp_notification(request.context,
                                     result,
                                     notifier_method)
        self._send_nova_notification(action, orig_object_copy, result)
        return result
Beispiel #33
0
    def _update(self, request, id, body, **kwargs):
        body = Controller.prepare_request_body(request.context,
                                               body, False,
                                               self._resource, self._attr_info,
                                               allow_bulk=self._allow_bulk)
        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[n_const.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)

        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
Beispiel #34
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