Example #1
0
    def delete(self, request, id, **kwargs):
        """Deletes the specified entity"""
        notifier_api.notify(request.context, self._publisher_id,
                            self._resource + '.delete.start',
                            notifier_api.CONF.default_notification_level,
                            {self._resource + '_id': id})
        action = self._plugin_handlers[self.DELETE]

        # Check authz
        parent_id = kwargs.get(self._parent_id_name)
        obj = self._item(request, id, parent_id=parent_id)
        try:
            policy.enforce(request.context, action, obj, plugin=self._plugin)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            raise webob.exc.HTTPNotFound()

        obj_deleter = getattr(self._plugin, action)
        obj_deleter(request.context, id, **kwargs)
        notifier_method = self._resource + '.delete.end'
        notifier_api.notify(request.context, self._publisher_id,
                            notifier_method,
                            notifier_api.CONF.default_notification_level,
                            {self._resource + '_id': id})
        result = {self._resource: self._view(obj)}
        self._send_dhcp_notification(request.context, result, notifier_method)
Example #2
0
    def delete(self, request, id, **kwargs):
        """Deletes the specified entity"""
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.delete.start',
                            notifier_api.INFO,
                            {self._resource + '_id': id})
        action = self._plugin_handlers[self.DELETE]

        # Check authz
        parent_id = kwargs.get(self._parent_id_name)
        obj = self._item(request, id, parent_id=parent_id)
        try:
            policy.enforce(request.context,
                           action,
                           obj,
                           plugin=self._plugin)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            raise webob.exc.HTTPNotFound()

        obj_deleter = getattr(self._plugin, action)
        obj_deleter(request.context, id, **kwargs)
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.delete.end',
                            notifier_api.INFO,
                            {self._resource + '_id': id})
Example #3
0
    def remove_router_interface(self, context, router_id, interface_info):
        # make sure router exists
        router = self._get_router(context, router_id)
        try:
            policy.enforce(context, "extension:router:remove_router_interface", self._make_router_dict(router))
        except q_exc.PolicyNotAuthorized:
            raise l3.RouterNotFound(router_id=router_id)

        if not interface_info:
            msg = _("Either subnet_id or port_id must be specified")
            raise q_exc.BadRequest(resource="router", msg=msg)
        if "port_id" in interface_info:
            port_id = interface_info["port_id"]
            port_db = self._get_port(context, port_id)
            if not (port_db["device_owner"] == DEVICE_OWNER_ROUTER_INTF and port_db["device_id"] == router_id):
                raise l3.RouterInterfaceNotFound(router_id=router_id, port_id=port_id)
            if "subnet_id" in interface_info:
                port_subnet_id = port_db["fixed_ips"][0]["subnet_id"]
                if port_subnet_id != interface_info["subnet_id"]:
                    raise q_exc.SubnetMismatchForPort(port_id=port_id, subnet_id=interface_info["subnet_id"])
            subnet_id = port_db["fixed_ips"][0]["subnet_id"]
            self._confirm_router_interface_not_in_use(context, router_id, subnet_id)
            _network_id = port_db["network_id"]
            self.delete_port(context, port_db["id"], l3_port_check=False)
        elif "subnet_id" in interface_info:
            subnet_id = interface_info["subnet_id"]
            self._confirm_router_interface_not_in_use(context, router_id, subnet_id)

            subnet = self._get_subnet(context, subnet_id)
            found = False

            try:
                rport_qry = context.session.query(models_v2.Port)
                ports = rport_qry.filter_by(
                    device_id=router_id, device_owner=DEVICE_OWNER_ROUTER_INTF, network_id=subnet["network_id"]
                ).all()

                for p in ports:
                    if p["fixed_ips"][0]["subnet_id"] == subnet_id:
                        port_id = p["id"]
                        _network_id = p["network_id"]
                        self.delete_port(context, p["id"], l3_port_check=False)
                        found = True
                        break
            except exc.NoResultFound:
                pass

            if not found:
                raise l3.RouterInterfaceNotFoundForSubnet(router_id=router_id, subnet_id=subnet_id)
        routers = self.get_sync_data(context.elevated(), [router_id])
        l3_rpc_agent_api.L3AgentNotify.routers_updated(
            context, routers, "remove_router_interface", {"network_id": _network_id, "subnet_id": subnet_id}
        )
        notifier_api.notify(
            context,
            notifier_api.publisher_id("network"),
            "router.interface.delete",
            notifier_api.CONF.default_notification_level,
            {"router.interface": {"port_id": port_id, "subnet_id": subnet_id}},
        )
Example #4
0
    def delete(self, request, id, **kwargs):
        """Deletes the specified entity."""
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.delete.start',
                            notifier_api.CONF.default_notification_level,
                            {self._resource + '_id': id})
        action = self._plugin_handlers[self.DELETE]

        # Check authz
        parent_id = kwargs.get(self._parent_id_name)
        obj = self._item(request, id, parent_id=parent_id)
        try:
            policy.enforce(request.context,
                           action,
                           obj)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            raise webob.exc.HTTPNotFound()

        obj_deleter = getattr(self._plugin, action)
        obj_deleter(request.context, id, **kwargs)
        notifier_method = self._resource + '.delete.end'
        notifier_api.notify(request.context,
                            self._publisher_id,
                            notifier_method,
                            notifier_api.CONF.default_notification_level,
                            {self._resource + '_id': id})
        result = {self._resource: self._view(request.context, obj)}
        self._send_dhcp_notification(request.context,
                                     result,
                                     notifier_method)
Example #5
0
 def notify(create_result):
     notifier_api.notify(request.context,
                         self._publisher_id,
                         self._resource + '.create.end',
                         notifier_api.INFO,
                         create_result)
     return create_result
Example #6
0
    def delete(self, request, id):
        """Deletes the specified entity"""
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.delete.start',
                            notifier_api.INFO,
                            {self._resource + '_id': id})
        action = "delete_%s" % self._resource

        # Check authz
        obj = self._item(request, id)
        try:
            policy.enforce(request.context,
                           action,
                           obj,
                           plugin=self._plugin)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            raise webob.exc.HTTPNotFound()

        obj_deleter = getattr(self._plugin, action)
        obj_deleter(request.context, id)
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.delete.end',
                            notifier_api.INFO,
                            {self._resource + '_id': id})
Example #7
0
 def notify(create_result):
     notifier_api.notify(request.context,
                         self._publisher_id,
                         self._resource + '.create.end',
                         notifier_api.INFO,
                         create_result)
     return create_result
Example #8
0
    def update(self, request, id, body=None):
        """Updates the specified entity's attributes"""
        payload = body.copy()
        payload['id'] = id
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.update.start',
                            notifier_api.INFO,
                            payload)
        body = self._prepare_request_body(request.context, body, False)
        action = "update_%s" % self._resource

        # Check authz
        orig_obj = self._item(request, id)[self._resource]
        try:
            policy.enforce(request.context, action, orig_obj)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            raise webob.exc.HTTPNotFound()

        obj_updater = getattr(self._plugin, action)
        kwargs = {self._resource: body}
        obj = obj_updater(request.context, id, **kwargs)
        result = {self._resource: self._view(obj)}
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.update.end',
                            notifier_api.INFO,
                            result)
        return result
Example #9
0
    def delete(self, request, id):
        """Deletes the specified entity"""
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.delete.start',
                            notifier_api.INFO,
                            {self._resource + '_id': id})
        action = "delete_%s" % self._resource

        # Check authz
        obj = self._item(request, id)[self._resource]
        try:
            policy.enforce(request.context, action, obj)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            raise webob.exc.HTTPNotFound()

        obj_deleter = getattr(self._plugin, action)
        obj_deleter(request.context, id)
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.delete.end',
                            notifier_api.INFO,
                            {self._resource + '_id': id})
Example #10
0
 def notify(create_result):
     notifier_api.notify(request.context,
                         self._publisher_id,
                         self._resource + '.create.end',
                         notifier_api.CONF.default_notification_level,
                         create_result)
     return create_result
Example #11
0
 def notify(create_result):
     notifier_method = self._resource + '.create.end'
     notifier_api.notify(request.context, self._publisher_id,
                         notifier_method,
                         notifier_api.CONF.default_notification_level,
                         create_result)
     self._send_dhcp_notification(request.context, create_result,
                                  notifier_method)
     return create_result
Example #12
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
        notifier_api.notify(request.context, self._publisher_id,
                            self._resource + '.update.start',
                            notifier_api.CONF.default_notification_level,
                            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 self._attr_info.iteritems()
            if ('required_by_policy' in value and value['required_by_policy']
                or 'default' not in value)
        ]
        orig_obj = self._item(request,
                              id,
                              field_list=field_list,
                              parent_id=parent_id)
        orig_obj.update(body[self._resource])
        try:
            policy.enforce(request.context,
                           action,
                           orig_obj,
                           plugin=self._plugin)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            raise webob.exc.HTTPNotFound()

        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)
        result = {self._resource: self._view(obj)}
        notifier_method = self._resource + '.update.end'
        notifier_api.notify(request.context, self._publisher_id,
                            notifier_method,
                            notifier_api.CONF.default_notification_level,
                            result)
        self._send_dhcp_notification(request.context, result, notifier_method)
        return result
Example #13
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
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.update.start',
                            notifier_api.CONF.default_notification_level,
                            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 self._attr_info.iteritems()
                      if ('required_by_policy' in value and
                          value['required_by_policy'] or
                          'default' not in value)]
        orig_obj = self._item(request, id, field_list=field_list,
                              parent_id=parent_id)
        orig_obj.update(body[self._resource])
        try:
            policy.enforce(request.context,
                           action,
                           orig_obj,
                           plugin=self._plugin)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            raise webob.exc.HTTPNotFound()

        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)
        result = {self._resource: self._view(request.context, obj)}
        notifier_method = self._resource + '.update.end'
        notifier_api.notify(request.context,
                            self._publisher_id,
                            notifier_method,
                            notifier_api.CONF.default_notification_level,
                            result)
        self._send_dhcp_notification(request.context,
                                     result,
                                     notifier_method)
        return result
Example #14
0
 def notify(create_result):
     notifier_method = self._resource + '.create.end'
     notifier_api.notify(request.context,
                         self._publisher_id,
                         notifier_method,
                         notifier_api.CONF.default_notification_level,
                         create_result)
     self._send_dhcp_notification(request.context,
                                  create_result,
                                  notifier_method)
     return create_result
Example #15
0
    def create(self, request, body=None):
        """Creates a new instance of the requested entity"""
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.create.start',
                            notifier_api.INFO,
                            body)
        body = self._prepare_request_body(request.context, body, True,
                                          allow_bulk=True)
        action = "create_%s" % self._resource

        # Check authz
        try:
            if self._collection in body:
                # Have to account for bulk create
                for item in body[self._collection]:
                    self._validate_network_tenant_ownership(
                        request,
                        item[self._resource],
                    )
                    policy.enforce(
                        request.context,
                        action,
                        item[self._resource],
                    )
                    count = QUOTAS.count(request.context, self._resource,
                                         self._plugin, self._collection,
                                         item[self._resource]['tenant_id'])
                    kwargs = {self._resource: count + 1}
                    QUOTAS.limit_check(request.context, **kwargs)
            else:
                self._validate_network_tenant_ownership(
                    request,
                    body[self._resource]
                )
                policy.enforce(request.context, action, body[self._resource])
                count = QUOTAS.count(request.context, self._resource,
                                     self._plugin, self._collection,
                                     body[self._resource]['tenant_id'])
                kwargs = {self._resource: count + 1}
                QUOTAS.limit_check(request.context, **kwargs)
        except exceptions.PolicyNotAuthorized:
            raise webob.exc.HTTPForbidden()

        obj_creator = getattr(self._plugin, action)
        kwargs = {self._resource: body}
        obj = obj_creator(request.context, **kwargs)
        result = {self._resource: self._view(obj)}
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.create.end',
                            notifier_api.INFO,
                            result)
        return result
Example #16
0
    def update(self, request, id, body=None):
        """Updates the specified entity's attributes"""
        payload = body.copy()
        payload['id'] = id
        notifier_api.notify(request.context, self._publisher_id,
                            self._resource + '.update.start',
                            notifier_api.INFO, payload)
        body = Controller.prepare_request_body(request.context,
                                               body,
                                               False,
                                               self._resource,
                                               self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = "update_%s" % self._resource
        # 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.iteritems()
            if ('required_by_policy' in value and value['required_by_policy']
                or not 'default' in value)
        ]
        orig_obj = self._item(request, id, field_list=field_list)
        orig_obj.update(body)

        try:
            policy.enforce(request.context,
                           action,
                           orig_obj,
                           plugin=self._plugin)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            raise webob.exc.HTTPNotFound()

        obj_updater = getattr(self._plugin, action)
        kwargs = {self._resource: body}
        obj = obj_updater(request.context, id, **kwargs)
        result = {self._resource: self._view(obj)}
        notifier_api.notify(request.context, self._publisher_id,
                            self._resource + '.update.end', notifier_api.INFO,
                            result)
        return result
Example #17
0
    def update(self, request, id, body=None):
        """Updates the specified entity's attributes"""
        payload = body.copy()
        payload['id'] = id
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.update.start',
                            notifier_api.INFO,
                            payload)
        body = Controller.prepare_request_body(request.context, body, False,
                                               self._resource, self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = "update_%s" % self._resource
        # 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.iteritems()
                      if ('required_by_policy' in value and
                          value['required_by_policy'] or
                          not 'default' in value)]
        orig_obj = self._item(request, id, field_list=field_list)
        orig_obj.update(body)

        try:
            policy.enforce(request.context,
                           action,
                           orig_obj,
                           plugin=self._plugin)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            raise webob.exc.HTTPNotFound()

        obj_updater = getattr(self._plugin, action)
        kwargs = {self._resource: body}
        obj = obj_updater(request.context, id, **kwargs)
        result = {self._resource: self._view(obj)}
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.update.end',
                            notifier_api.INFO,
                            result)
        return result
Example #18
0
    def _create_metadata_access_network(self, context, router_id):
        # This will still ensure atomicity on Quantum DB
        # context.elevated() creates a deep-copy context
        ctx_elevated = context.elevated()
        with ctx_elevated.session.begin(subtransactions=True):
            # Add network
            # Network name is likely to be truncated on NVP

            net_data = {'name': ('meta-%s' % router_id)[:40],
                        'tenant_id': '',  # intentionally not set
                        'admin_state_up': True,
                        'port_security_enabled': False,
                        'shared': False,
                        'status': constants.NET_STATUS_ACTIVE}
            meta_net = self.create_network(ctx_elevated,
                                           {'network': net_data})
            # Add subnet
            subnet_data = {'network_id': meta_net['id'],
                           'tenant_id': '',  # intentionally not set
                           'name': 'meta-%s' % router_id,
                           'ip_version': 4,
                           'shared': False,
                           'cidr': METADATA_SUBNET_CIDR,
                           'enable_dhcp': True,
                           # Ensure default allocation pool is generated
                           'allocation_pools': attributes.ATTR_NOT_SPECIFIED,
                           'gateway_ip': METADATA_GATEWAY_IP,
                           'dns_nameservers': [],
                           'host_routes': []}
            meta_sub = self.create_subnet(ctx_elevated,
                                          {'subnet': subnet_data})
            self.add_router_interface(ctx_elevated, router_id,
                                      {'subnet_id': meta_sub['id']})
            # We need to send a notification to the dhcp agent in order
            # to start the metadata agent proxy
            # Note: the publisher id is the same used in the api module
            notifier_api.notify(context,
                                notifier_api.publisher_id('network'),
                                'network.create.end',
                                notifier_api.CONF.default_notification_level,
                                {'network': meta_net})
Example #19
0
    def _destroy_metadata_access_network(self, context, router_id, ports):

        # context.elevated() creates a deep-copy context
        ctx_elevated = context.elevated()
        # This will still ensure atomicity on Quantum DB
        with ctx_elevated.session.begin(subtransactions=True):
            if ports:
                meta_port = self._find_metadata_port(ctx_elevated, ports)
                if not meta_port:
                    return
                meta_net_id = meta_port['network_id']
                self.remove_router_interface(
                    ctx_elevated, router_id, {'port_id': meta_port['id']})
                # Remove network (this will remove the subnet too)
                self.delete_network(ctx_elevated, meta_net_id)
                # We need to send a notification to the dhcp agent in order
                # to stop the metadata agent proxy
                # Note: the publisher id is the same used in the api module
                notifier_api.notify(
                    context,
                    notifier_api.publisher_id('network'),
                    'network.delete.end',
                    notifier_api.CONF.default_notification_level,
                    {'network_id': meta_net_id})
Example #20
0
    def add_router_interface(self, context, router_id, interface_info):
        # make sure router exists
        router = self._get_router(context, router_id)
        if not interface_info:
            msg = _("Either subnet_id or port_id must be specified")
            raise q_exc.BadRequest(resource="router", msg=msg)

        try:
            policy.enforce(context, "extension:router:add_router_interface", self._make_router_dict(router))
        except q_exc.PolicyNotAuthorized:
            raise l3.RouterNotFound(router_id=router_id)

        if "port_id" in interface_info:
            if "subnet_id" in interface_info:
                msg = _("Cannot specify both subnet-id and port-id")
                raise q_exc.BadRequest(resource="router", msg=msg)

            port = self._get_port(context, interface_info["port_id"])
            if port["device_id"]:
                raise q_exc.PortInUse(net_id=port["network_id"], port_id=port["id"], device_id=port["device_id"])
            fixed_ips = [ip for ip in port["fixed_ips"]]
            if len(fixed_ips) != 1:
                msg = _("Router port must have exactly one fixed IP")
                raise q_exc.BadRequest(resource="router", msg=msg)
            subnet_id = fixed_ips[0]["subnet_id"]
            subnet = self._get_subnet(context, subnet_id)
            self._check_for_dup_router_subnet(context, router_id, port["network_id"], subnet["id"], subnet["cidr"])
            port.update({"device_id": router_id, "device_owner": DEVICE_OWNER_ROUTER_INTF})
        elif "subnet_id" in interface_info:
            subnet_id = interface_info["subnet_id"]
            subnet = self._get_subnet(context, subnet_id)
            # Ensure the subnet has a gateway
            if not subnet["gateway_ip"]:
                msg = _("Subnet for router interface must have a gateway IP")
                raise q_exc.BadRequest(resource="router", msg=msg)
            self._check_for_dup_router_subnet(context, router_id, subnet["network_id"], subnet_id, subnet["cidr"])
            fixed_ip = {"ip_address": subnet["gateway_ip"], "subnet_id": subnet["id"]}
            port = self.create_port(
                context,
                {
                    "port": {
                        "tenant_id": subnet["tenant_id"],
                        "network_id": subnet["network_id"],
                        "fixed_ips": [fixed_ip],
                        "mac_address": attributes.ATTR_NOT_SPECIFIED,
                        "admin_state_up": True,
                        "device_id": router_id,
                        "device_owner": DEVICE_OWNER_ROUTER_INTF,
                        "name": "",
                    }
                },
            )

        routers = self.get_sync_data(context.elevated(), [router_id])
        l3_rpc_agent_api.L3AgentNotify.routers_updated(
            context, routers, "add_router_interface", {"network_id": port["network_id"], "subnet_id": subnet_id}
        )
        info = {"port_id": port["id"], "subnet_id": port["fixed_ips"][0]["subnet_id"]}
        notifier_api.notify(
            context,
            notifier_api.publisher_id("network"),
            "router.interface.create",
            notifier_api.CONF.default_notification_level,
            {"router.interface": info},
        )
        return info
Example #21
0
    def create(self, request, body=None):
        """Creates a new instance of the requested entity"""
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.create.start',
                            notifier_api.INFO,
                            body)
        body = Controller.prepare_request_body(request.context, body, True,
                                               self._resource, self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = "create_%s" % self._resource
        # Check authz
        try:
            if self._collection in body:
                # Have to account for bulk create
                for item in body[self._collection]:
                    self._validate_network_tenant_ownership(
                        request,
                        item[self._resource],
                    )
                    policy.enforce(request.context,
                                   action,
                                   item[self._resource],
                                   plugin=self._plugin)
                    try:
                        count = QUOTAS.count(request.context, self._resource,
                                             self._plugin, self._collection,
                                             item[self._resource]['tenant_id'])
                        kwargs = {self._resource: count + 1}
                    except exceptions.QuotaResourceUnknown as e:
                        # We don't want to quota this resource
                        LOG.debug(e)
                    except Exception:
                        raise
                    else:
                        QUOTAS.limit_check(request.context,
                                           item[self._resource]['tenant_id'],
                                           **kwargs)
            else:
                self._validate_network_tenant_ownership(
                    request,
                    body[self._resource]
                )
                policy.enforce(request.context,
                               action,
                               body[self._resource],
                               plugin=self._plugin)
                try:
                    count = QUOTAS.count(request.context, self._resource,
                                         self._plugin, self._collection,
                                         body[self._resource]['tenant_id'])
                    kwargs = {self._resource: count + 1}
                except exceptions.QuotaResourceUnknown as e:
                    # We don't want to quota this resource
                    LOG.debug(e)
                except Exception:
                    raise
                else:
                    QUOTAS.limit_check(request.context,
                                       body[self._resource]['tenant_id'],
                                       **kwargs)
        except exceptions.PolicyNotAuthorized:
            LOG.exception("Create operation not authorized")
            raise webob.exc.HTTPForbidden()

        def notify(create_result):
            notifier_api.notify(request.context,
                                self._publisher_id,
                                self._resource + '.create.end',
                                notifier_api.INFO,
                                create_result)
            return create_result

        if self._collection in body and self._native_bulk:
            # plugin does atomic bulk create operations
            obj_creator = getattr(self._plugin, "%s_bulk" % action)
            objs = obj_creator(request.context, body)
            return notify({self._collection: [self._view(obj)
                                              for obj in objs]})
        else:
            obj_creator = getattr(self._plugin, action)
            if self._collection in body:
                # Emulate atomic bulk behavior
                objs = self._emulate_bulk_create(obj_creator, request, body)
                return notify({self._collection: objs})
            else:
                kwargs = {self._resource: body}
                obj = obj_creator(request.context, **kwargs)
                return notify({self._resource: self._view(obj)})
Example #22
0
    def create(self, request, body=None, **kwargs):
        """Creates a new instance of the requested entity"""
        parent_id = kwargs.get(self._parent_id_name)
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.create.start',
                            notifier_api.INFO,
                            body)
        body = Controller.prepare_request_body(request.context, body, True,
                                               self._resource, self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = self._plugin_handlers[self.CREATE]
        # Check authz
        if self._collection in body:
            # Have to account for bulk create
            items = body[self._collection]
            deltas = {}
            bulk = True
        else:
            items = [body]
            bulk = False
        for item in items:
            self._validate_network_tenant_ownership(request,
                                                    item[self._resource])
            policy.enforce(request.context,
                           action,
                           item[self._resource],
                           plugin=self._plugin)
            try:
                tenant_id = item[self._resource]['tenant_id']
                count = QUOTAS.count(request.context, self._resource,
                                     self._plugin, self._collection,
                                     tenant_id)
                if bulk:
                    delta = deltas.get(tenant_id, 0) + 1
                    deltas[tenant_id] = delta
                else:
                    delta = 1
                kwargs = {self._resource: count + delta}
            except exceptions.QuotaResourceUnknown as e:
                # We don't want to quota this resource
                LOG.debug(e)
            else:
                QUOTAS.limit_check(request.context,
                                   item[self._resource]['tenant_id'],
                                   **kwargs)

        def notify(create_result):
            notifier_api.notify(request.context,
                                self._publisher_id,
                                self._resource + '.create.end',
                                notifier_api.INFO,
                                create_result)
            return create_result

        kwargs = {self._parent_id_name: parent_id} if parent_id else {}
        if self._collection in body and self._native_bulk:
            # plugin does atomic bulk create operations
            obj_creator = getattr(self._plugin, "%s_bulk" % action)
            objs = obj_creator(request.context, body, **kwargs)
            return notify({self._collection: [self._view(obj)
                                              for obj in objs]})
        else:
            obj_creator = getattr(self._plugin, action)
            if self._collection in body:
                # Emulate atomic bulk behavior
                objs = self._emulate_bulk_create(obj_creator, request,
                                                 body, parent_id)
                return notify({self._collection: objs})
            else:
                kwargs.update({self._resource: body})
                obj = obj_creator(request.context, **kwargs)
                return notify({self._resource: self._view(obj)})
Example #23
0
    def remove_router_interface(self, context, router_id, interface_info):
        if not interface_info:
            msg = _("Either subnet_id or port_id must be specified")
            raise q_exc.BadRequest(resource='router', msg=msg)
        if 'port_id' in interface_info:
            port_id = interface_info['port_id']
            port_db = self._get_port(context, port_id)
            if not (port_db['device_owner'] == DEVICE_OWNER_ROUTER_INTF
                    and port_db['device_id'] == router_id):
                raise l3.RouterInterfaceNotFound(router_id=router_id,
                                                 port_id=port_id)
            if 'subnet_id' in interface_info:
                port_subnet_id = port_db['fixed_ips'][0]['subnet_id']
                if port_subnet_id != interface_info['subnet_id']:
                    raise q_exc.SubnetMismatchForPort(
                        port_id=port_id, subnet_id=interface_info['subnet_id'])
            subnet_id = port_db['fixed_ips'][0]['subnet_id']
            subnet = self._get_subnet(context, subnet_id)
            self._confirm_router_interface_not_in_use(context, router_id,
                                                      subnet_id)
            _network_id = port_db['network_id']
            self.delete_port(context, port_db['id'], l3_port_check=False)
        elif 'subnet_id' in interface_info:
            subnet_id = interface_info['subnet_id']
            self._confirm_router_interface_not_in_use(context, router_id,
                                                      subnet_id)

            subnet = self._get_subnet(context, subnet_id)
            found = False

            try:
                rport_qry = context.session.query(models_v2.Port)
                ports = rport_qry.filter_by(
                    device_id=router_id,
                    device_owner=DEVICE_OWNER_ROUTER_INTF,
                    network_id=subnet['network_id'])

                for p in ports:
                    if p['fixed_ips'][0]['subnet_id'] == subnet_id:
                        port_id = p['id']
                        _network_id = p['network_id']
                        self.delete_port(context, p['id'], l3_port_check=False)
                        found = True
                        break
            except exc.NoResultFound:
                pass

            if not found:
                raise l3.RouterInterfaceNotFoundForSubnet(router_id=router_id,
                                                          subnet_id=subnet_id)
        routers = self.get_sync_data(context.elevated(), [router_id])
        l3_rpc_agent_api.L3AgentNotify.routers_updated(
            context, routers, 'remove_router_interface', {
                'network_id': _network_id,
                'subnet_id': subnet_id
            })
        info = {
            'id': router_id,
            'tenant_id': subnet['tenant_id'],
            'port_id': port_id,
            'subnet_id': subnet_id
        }
        notifier_api.notify(context, notifier_api.publisher_id('network'),
                            'router.interface.delete',
                            notifier_api.CONF.default_notification_level,
                            {'router.interface': info})
        return info
Example #24
0
    def add_router_interface(self, context, router_id, interface_info):
        if not interface_info:
            msg = _("Either subnet_id or port_id must be specified")
            raise q_exc.BadRequest(resource='router', msg=msg)

        if 'port_id' in interface_info:
            if 'subnet_id' in interface_info:
                msg = _("Cannot specify both subnet-id and port-id")
                raise q_exc.BadRequest(resource='router', msg=msg)

            port = self._get_port(context, interface_info['port_id'])
            if port['device_id']:
                raise q_exc.PortInUse(net_id=port['network_id'],
                                      port_id=port['id'],
                                      device_id=port['device_id'])
            fixed_ips = [ip for ip in port['fixed_ips']]
            if len(fixed_ips) != 1:
                msg = _('Router port must have exactly one fixed IP')
                raise q_exc.BadRequest(resource='router', msg=msg)
            subnet_id = fixed_ips[0]['subnet_id']
            subnet = self._get_subnet(context, subnet_id)
            self._check_for_dup_router_subnet(context, router_id,
                                              port['network_id'], subnet['id'],
                                              subnet['cidr'])
            port.update({
                'device_id': router_id,
                'device_owner': DEVICE_OWNER_ROUTER_INTF
            })
        elif 'subnet_id' in interface_info:
            subnet_id = interface_info['subnet_id']
            subnet = self._get_subnet(context, subnet_id)
            # Ensure the subnet has a gateway
            if not subnet['gateway_ip']:
                msg = _('Subnet for router interface must have a gateway IP')
                raise q_exc.BadRequest(resource='router', msg=msg)
            self._check_for_dup_router_subnet(context, router_id,
                                              subnet['network_id'], subnet_id,
                                              subnet['cidr'])
            fixed_ip = {
                'ip_address': subnet['gateway_ip'],
                'subnet_id': subnet['id']
            }
            port = self.create_port(
                context, {
                    'port': {
                        'tenant_id': subnet['tenant_id'],
                        'network_id': subnet['network_id'],
                        'fixed_ips': [fixed_ip],
                        'mac_address': attributes.ATTR_NOT_SPECIFIED,
                        'admin_state_up': True,
                        'device_id': router_id,
                        'device_owner': DEVICE_OWNER_ROUTER_INTF,
                        'name': ''
                    }
                })

        routers = self.get_sync_data(context.elevated(), [router_id])
        l3_rpc_agent_api.L3AgentNotify.routers_updated(
            context, routers, 'add_router_interface', {
                'network_id': port['network_id'],
                'subnet_id': subnet_id
            })
        info = {
            'id': router_id,
            'tenant_id': subnet['tenant_id'],
            'port_id': port['id'],
            'subnet_id': port['fixed_ips'][0]['subnet_id']
        }
        notifier_api.notify(context, notifier_api.publisher_id('network'),
                            'router.interface.create',
                            notifier_api.CONF.default_notification_level,
                            {'router.interface': info})
        return info
Example #25
0
    def create(self, request, body=None, **kwargs):
        """Creates a new instance of the requested entity"""
        parent_id = kwargs.get(self._parent_id_name)
        notifier_api.notify(request.context, self._publisher_id,
                            self._resource + '.create.start',
                            notifier_api.CONF.default_notification_level, body)
        body = Controller.prepare_request_body(request.context,
                                               body,
                                               True,
                                               self._resource,
                                               self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = self._plugin_handlers[self.CREATE]
        # Check authz
        if self._collection in body:
            # Have to account for bulk create
            items = body[self._collection]
            deltas = {}
            bulk = True
        else:
            items = [body]
            bulk = False
        for item in items:
            self._validate_network_tenant_ownership(request,
                                                    item[self._resource])
            policy.enforce(request.context,
                           action,
                           item[self._resource],
                           plugin=self._plugin)
            try:
                tenant_id = item[self._resource]['tenant_id']
                count = quota.QUOTAS.count(request.context, self._resource,
                                           self._plugin, self._collection,
                                           tenant_id)
                if bulk:
                    delta = deltas.get(tenant_id, 0) + 1
                    deltas[tenant_id] = delta
                else:
                    delta = 1
                kwargs = {self._resource: count + delta}
            except exceptions.QuotaResourceUnknown as e:
                # We don't want to quota this resource
                LOG.debug(e)
            else:
                quota.QUOTAS.limit_check(request.context,
                                         item[self._resource]['tenant_id'],
                                         **kwargs)

        def notify(create_result):
            notifier_method = self._resource + '.create.end'
            notifier_api.notify(request.context, self._publisher_id,
                                notifier_method,
                                notifier_api.CONF.default_notification_level,
                                create_result)
            self._send_dhcp_notification(request.context, create_result,
                                         notifier_method)
            return create_result

        kwargs = {self._parent_id_name: parent_id} if parent_id else {}
        if self._collection in body and self._native_bulk:
            # plugin does atomic bulk create operations
            obj_creator = getattr(self._plugin, "%s_bulk" % action)
            objs = obj_creator(request.context, body, **kwargs)
            return notify(
                {self._collection: [self._view(obj) for obj in objs]})
        else:
            obj_creator = getattr(self._plugin, action)
            if self._collection in body:
                # Emulate atomic bulk behavior
                objs = self._emulate_bulk_create(obj_creator, request, body,
                                                 parent_id)
                return notify({self._collection: objs})
            else:
                kwargs.update({self._resource: body})
                obj = obj_creator(request.context, **kwargs)
                return notify({self._resource: self._view(obj)})
Example #26
0
    def create(self, request, body=None):
        """Creates a new instance of the requested entity"""
        notifier_api.notify(request.context,
                            self._publisher_id,
                            self._resource + '.create.start',
                            notifier_api.INFO,
                            body)
        body = Controller.prepare_request_body(request.context, body, True,
                                               self._resource, self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = "create_%s" % self._resource
        # Check authz
        try:
            if self._collection in body:
                # Have to account for bulk create
                for item in body[self._collection]:
                    self._validate_network_tenant_ownership(
                        request,
                        item[self._resource],
                    )
                    policy.enforce(request.context,
                                   action,
                                   item[self._resource],
                                   plugin=self._plugin)
                    try:
                        count = QUOTAS.count(request.context, self._resource,
                                             self._plugin, self._collection,
                                             item[self._resource]['tenant_id'])
                        kwargs = {self._resource: count + 1}
                    except exceptions.QuotaResourceUnknown as e:
                        # We don't want to quota this resource
                        LOG.debug(e)
                    except Exception:
                        raise
                    else:
                        QUOTAS.limit_check(request.context,
                                           item[self._resource]['tenant_id'],
                                           **kwargs)
            else:
                self._validate_network_tenant_ownership(
                    request,
                    body[self._resource]
                )
                policy.enforce(request.context,
                               action,
                               body[self._resource],
                               plugin=self._plugin)
                try:
                    count = QUOTAS.count(request.context, self._resource,
                                         self._plugin, self._collection,
                                         body[self._resource]['tenant_id'])
                    kwargs = {self._resource: count + 1}
                except exceptions.QuotaResourceUnknown as e:
                    # We don't want to quota this resource
                    LOG.debug(e)
                except Exception:
                    raise
                else:
                    QUOTAS.limit_check(request.context,
                                       body[self._resource]['tenant_id'],
                                       **kwargs)
        except exceptions.PolicyNotAuthorized:
            LOG.exception(_("Create operation not authorized"))
            raise webob.exc.HTTPForbidden()

        def notify(create_result):
            notifier_api.notify(request.context,
                                self._publisher_id,
                                self._resource + '.create.end',
                                notifier_api.INFO,
                                create_result)
            return create_result

        if self._collection in body and self._native_bulk:
            # plugin does atomic bulk create operations
            obj_creator = getattr(self._plugin, "%s_bulk" % action)
            objs = obj_creator(request.context, body)
            return notify({self._collection: [self._view(obj)
                                              for obj in objs]})
        else:
            obj_creator = getattr(self._plugin, action)
            if self._collection in body:
                # Emulate atomic bulk behavior
                objs = self._emulate_bulk_create(obj_creator, request, body)
                return notify({self._collection: objs})
            else:
                kwargs = {self._resource: body}
                obj = obj_creator(request.context, **kwargs)
                return notify({self._resource: self._view(obj)})
Example #27
0
    def remove_router_interface(self, context, router_id, interface_info):
        if not interface_info:
            msg = _("Either subnet_id or port_id must be specified")
            raise q_exc.BadRequest(resource='router', msg=msg)
        if 'port_id' in interface_info:
            port_id = interface_info['port_id']
            port_db = self._get_port(context, port_id)
            if not (port_db['device_owner'] == DEVICE_OWNER_ROUTER_INTF and
                    port_db['device_id'] == router_id):
                raise l3.RouterInterfaceNotFound(router_id=router_id,
                                                 port_id=port_id)
            if 'subnet_id' in interface_info:
                port_subnet_id = port_db['fixed_ips'][0]['subnet_id']
                if port_subnet_id != interface_info['subnet_id']:
                    raise q_exc.SubnetMismatchForPort(
                        port_id=port_id,
                        subnet_id=interface_info['subnet_id'])
            subnet_id = port_db['fixed_ips'][0]['subnet_id']
            subnet = self._get_subnet(context, subnet_id)
            self._confirm_router_interface_not_in_use(
                context, router_id, subnet_id)
            _network_id = port_db['network_id']
            self.delete_port(context, port_db['id'], l3_port_check=False)
        elif 'subnet_id' in interface_info:
            subnet_id = interface_info['subnet_id']
            self._confirm_router_interface_not_in_use(context, router_id,
                                                      subnet_id)

            subnet = self._get_subnet(context, subnet_id)
            found = False

            try:
                rport_qry = context.session.query(models_v2.Port)
                ports = rport_qry.filter_by(
                    device_id=router_id,
                    device_owner=DEVICE_OWNER_ROUTER_INTF,
                    network_id=subnet['network_id']).all()

                for p in ports:
                    if p['fixed_ips'][0]['subnet_id'] == subnet_id:
                        port_id = p['id']
                        _network_id = p['network_id']
                        self.delete_port(context, p['id'], l3_port_check=False)
                        found = True
                        break
            except exc.NoResultFound:
                pass

            if not found:
                raise l3.RouterInterfaceNotFoundForSubnet(router_id=router_id,
                                                          subnet_id=subnet_id)
        routers = self.get_sync_data(context.elevated(), [router_id])
        l3_rpc_agent_api.L3AgentNotify.routers_updated(
            context, routers, 'remove_router_interface',
            {'network_id': _network_id,
             'subnet_id': subnet_id})
        info = {'id': router_id,
                'tenant_id': subnet['tenant_id'],
                'port_id': port_id,
                'subnet_id': subnet_id}
        notifier_api.notify(context,
                            notifier_api.publisher_id('network'),
                            'router.interface.delete',
                            notifier_api.CONF.default_notification_level,
                            {'router.interface': info})
Example #28
0
    def add_router_interface(self, context, router_id, interface_info):
        if not interface_info:
            msg = _("Either subnet_id or port_id must be specified")
            raise q_exc.BadRequest(resource='router', msg=msg)

        if 'port_id' in interface_info:
            if 'subnet_id' in interface_info:
                msg = _("Cannot specify both subnet-id and port-id")
                raise q_exc.BadRequest(resource='router', msg=msg)

            port = self._get_port(context, interface_info['port_id'])
            if port['device_id']:
                raise q_exc.PortInUse(net_id=port['network_id'],
                                      port_id=port['id'],
                                      device_id=port['device_id'])
            fixed_ips = [ip for ip in port['fixed_ips']]
            if len(fixed_ips) != 1:
                msg = _('Router port must have exactly one fixed IP')
                raise q_exc.BadRequest(resource='router', msg=msg)
            subnet_id = fixed_ips[0]['subnet_id']
            subnet = self._get_subnet(context, subnet_id)
            self._check_for_dup_router_subnet(context, router_id,
                                              port['network_id'],
                                              subnet['id'],
                                              subnet['cidr'])
            port.update({'device_id': router_id,
                         'device_owner': DEVICE_OWNER_ROUTER_INTF})
        elif 'subnet_id' in interface_info:
            subnet_id = interface_info['subnet_id']
            subnet = self._get_subnet(context, subnet_id)
            # Ensure the subnet has a gateway
            if not subnet['gateway_ip']:
                msg = _('Subnet for router interface must have a gateway IP')
                raise q_exc.BadRequest(resource='router', msg=msg)
            self._check_for_dup_router_subnet(context, router_id,
                                              subnet['network_id'],
                                              subnet_id,
                                              subnet['cidr'])
            fixed_ip = {'ip_address': subnet['gateway_ip'],
                        'subnet_id': subnet['id']}
            port = self.create_port(context, {
                'port':
                {'tenant_id': subnet['tenant_id'],
                 'network_id': subnet['network_id'],
                 'fixed_ips': [fixed_ip],
                 'mac_address': attributes.ATTR_NOT_SPECIFIED,
                 'admin_state_up': True,
                 'device_id': router_id,
                 'device_owner': DEVICE_OWNER_ROUTER_INTF,
                 'name': ''}})

        routers = self.get_sync_data(context.elevated(), [router_id])
        l3_rpc_agent_api.L3AgentNotify.routers_updated(
            context, routers, 'add_router_interface',
            {'network_id': port['network_id'],
             'subnet_id': subnet_id})
        info = {'id': router_id,
                'tenant_id': subnet['tenant_id'],
                'port_id': port['id'],
                'subnet_id': port['fixed_ips'][0]['subnet_id']}
        notifier_api.notify(context,
                            notifier_api.publisher_id('network'),
                            'router.interface.create',
                            notifier_api.CONF.default_notification_level,
                            {'router.interface': info})
        return info