# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from neutron_lib.api.definitions import l3 as l3_apidef from neutron_lib.db import constants as db_const from neutron_lib.db import model_base import sqlalchemy as sa from sqlalchemy import orm from neutron.db.models import l3agent as rb_model from neutron.db import models_v2 from neutron.db import standard_attr class RouterPort(model_base.BASEV2): router_id = sa.Column( sa.String(36), sa.ForeignKey('routers.id', ondelete="CASCADE"), primary_key=True) port_id = sa.Column( sa.String(36), sa.ForeignKey('ports.id', ondelete="CASCADE"), primary_key=True, unique=True) revises_on_change = ('router', ) # The port_type attribute is redundant as the port table already specifies # it in DEVICE_OWNER.However, this redundancy enables more efficient # queries on router ports, and also prevents potential error-prone # conditions which might originate from users altering the DEVICE_OWNER # property of router ports. port_type = sa.Column(sa.String(db_const.DEVICE_OWNER_FIELD_SIZE)) port = orm.relationship( models_v2.Port, backref=orm.backref('routerport', uselist=False, cascade="all,delete"), lazy='joined') class Router(standard_attr.HasStandardAttributes, model_base.BASEV2, model_base.HasId, model_base.HasProject): """Represents a v2 neutron router.""" name = sa.Column(sa.String(db_const.NAME_FIELD_SIZE)) status = sa.Column(sa.String(16)) admin_state_up = sa.Column(sa.Boolean) gw_port_id = sa.Column(sa.String(36), sa.ForeignKey('ports.id')) gw_port = orm.relationship(models_v2.Port, lazy='joined') flavor_id = sa.Column(sa.String(36), sa.ForeignKey("flavors.id"), nullable=True) attached_ports = orm.relationship( RouterPort, backref=orm.backref('router', load_on_pending=True), lazy='subquery') l3_agents = orm.relationship( 'Agent', lazy='subquery', viewonly=True, secondary=rb_model.RouterL3AgentBinding.__table__) api_collections = [l3_apidef.ROUTERS] collection_resource_map = {l3_apidef.ROUTERS: l3_apidef.ROUTER} tag_support = True class FloatingIP(standard_attr.HasStandardAttributes, model_base.BASEV2, model_base.HasId, model_base.HasProject): """Represents a floating IP address. This IP address may or may not be allocated to a tenant, and may or may not be associated with an internal port/ip address/router. """ floating_ip_address = sa.Column(sa.String(64), nullable=False) floating_network_id = sa.Column(sa.String(36), nullable=False) floating_port_id = sa.Column(sa.String(36), sa.ForeignKey('ports.id', ondelete="CASCADE"), nullable=False) # The ORM-level "delete" cascade relationship between port and floating_ip # is required for causing the in-Python event "after_delete" that needs for # proper quota management in case when cascade removal of the floating_ip # happens after removal of the floating_port port = orm.relationship(models_v2.Port, backref=orm.backref('floating_ips', cascade='all,delete-orphan'), foreign_keys=floating_port_id) fixed_port_id = sa.Column(sa.String(36), sa.ForeignKey('ports.id')) fixed_port = orm.relationship(models_v2.Port, foreign_keys=fixed_port_id, lazy='joined', viewonly=True) fixed_ip_address = sa.Column(sa.String(64)) router_id = sa.Column(sa.String(36), sa.ForeignKey('routers.id')) # Additional attribute for keeping track of the router where the floating # ip was associated in order to be able to ensure consistency even if an # asynchronous backend is unavailable when the floating IP is disassociated last_known_router_id = sa.Column(sa.String(36)) status = sa.Column(sa.String(16)) router = orm.relationship(Router, backref='floating_ips') __table_args__ = ( sa.UniqueConstraint( floating_network_id, fixed_port_id, fixed_ip_address, name=('uniq_floatingips0floatingnetworkid' '0fixedportid0fixedipaddress')), model_base.BASEV2.__table_args__,) api_collections = [l3_apidef.FLOATINGIPS] collection_resource_map = {l3_apidef.FLOATINGIPS: l3_apidef.FLOATINGIP} tag_support = True class RouterRoute(model_base.BASEV2, models_v2.Route): router_id = sa.Column(sa.String(36), sa.ForeignKey('routers.id', ondelete="CASCADE"), primary_key=True) router = orm.relationship(Router, load_on_pending=True, backref=orm.backref("route_list", lazy='subquery', cascade='delete')) revises_on_change = ('router', )