6dee4c5942
All of the additional lookup logic was essentially duplicating a relationship property of 'load_on_pending=True', which tells SQLAlchemy to lookup the relationship during object creation [1]. So we can dump all of this logic and just use that option. 1. http://docs.sqlalchemy.org/en/latest/orm/relationship_api.html #sqlalchemy.orm.relationship.params.load_on_pending Related: blueprint push-notifications Change-Id: I0e495a50f5cab9b6449825039d7683d77de1e763
119 lines
5.1 KiB
Python
119 lines
5.1 KiB
Python
# 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.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
|
|
from neutron.extensions import l3
|
|
|
|
|
|
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='dynamic')
|
|
l3_agents = orm.relationship(
|
|
'Agent', lazy='subquery', viewonly=True,
|
|
secondary=rb_model.RouterL3AgentBinding.__table__)
|
|
api_collections = [l3.ROUTERS]
|
|
|
|
|
|
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='FloatingIP.floating_port_id')
|
|
fixed_port_id = sa.Column(sa.String(36), sa.ForeignKey('ports.id'))
|
|
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.FLOATINGIPS]
|
|
|
|
|
|
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', )
|