Relocate RouterL3AgentBinding DB model

As there would be issue of cyclic imports while
implementation of objects for l3agentbinding which has
db models definition and mixins in same file, this patch will
relocate l3agentbinding models.

Change-Id: Idef2fe3e16b245da849e2d29c5578e5f5d081dc4
Partial-Bug: #1597913
This commit is contained in:
sindhudevale 2016-08-16 04:44:52 +00:00 committed by Sindhu Devale
parent cae38fb392
commit 930655cf57
9 changed files with 100 additions and 64 deletions

View File

@ -15,7 +15,6 @@
import debtcollector
from neutron_lib import constants
from neutron_lib.db import model_base
from oslo_config import cfg
from oslo_db import exception as db_exc
from oslo_log import log as logging
@ -29,19 +28,23 @@ from sqlalchemy.orm import joinedload
from sqlalchemy import sql
from neutron._i18n import _, _LI
from neutron.common import _deprecate
from neutron.common import utils as n_utils
from neutron.db import agents_db
from neutron.db import agentschedulers_db
from neutron.db import l3_attrs_db
from neutron.db.models import l3agent as rb_model
from neutron.extensions import l3agentscheduler
from neutron.extensions import router_availability_zone as router_az
from neutron import manager
from neutron.plugins.common import constants as service_constants
_deprecate._moved_global('RouterL3AgentBinding',
new_module=rb_model)
LOG = logging.getLogger(__name__)
LOWEST_BINDING_INDEX = 1
L3_AGENTS_SCHEDULER_OPTS = [
cfg.StrOpt('router_scheduler_driver',
@ -59,27 +62,6 @@ L3_AGENTS_SCHEDULER_OPTS = [
cfg.CONF.register_opts(L3_AGENTS_SCHEDULER_OPTS)
class RouterL3AgentBinding(model_base.BASEV2):
"""Represents binding between neutron routers and L3 agents."""
__table_args__ = (
sa.UniqueConstraint(
'router_id', 'binding_index',
name='uniq_router_l3_agent_binding0router_id0binding_index0'),
model_base.BASEV2.__table_args__
)
router_id = sa.Column(sa.String(36),
sa.ForeignKey("routers.id", ondelete='CASCADE'),
primary_key=True)
l3_agent = orm.relation(agents_db.Agent)
l3_agent_id = sa.Column(sa.String(36),
sa.ForeignKey("agents.id", ondelete='CASCADE'),
primary_key=True)
binding_index = sa.Column(sa.Integer, nullable=False,
server_default=str(LOWEST_BINDING_INDEX))
class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
agentschedulers_db.AgentSchedulerDbMixin):
"""Mixin class to add l3 agent scheduler extension to plugins
@ -123,13 +105,14 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
def get_down_router_bindings(self, context, agent_dead_limit):
cutoff = self.get_cutoff_time(agent_dead_limit)
return (context.session.query(RouterL3AgentBinding).
return (context.session.query(
rb_model.RouterL3AgentBinding).
join(agents_db.Agent).
filter(agents_db.Agent.heartbeat_timestamp < cutoff,
agents_db.Agent.admin_state_up).
outerjoin(l3_attrs_db.RouterExtraAttributes,
l3_attrs_db.RouterExtraAttributes.router_id ==
RouterL3AgentBinding.router_id).filter(
rb_model.RouterL3AgentBinding.router_id).filter(
sa.or_(
l3_attrs_db.RouterExtraAttributes.ha == sql.false(),
l3_attrs_db.RouterExtraAttributes.ha == sql.null())))
@ -179,7 +162,7 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
"""
router_id = router['id']
agent_id = agent['id']
query = context.session.query(RouterL3AgentBinding)
query = context.session.query(rb_model.RouterL3AgentBinding)
bindings = query.filter_by(router_id=router_id).all()
if not bindings:
return True
@ -270,10 +253,10 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
def _unbind_router(self, context, router_id, agent_id):
with context.session.begin(subtransactions=True):
query = context.session.query(RouterL3AgentBinding)
query = context.session.query(rb_model.RouterL3AgentBinding)
query = query.filter(
RouterL3AgentBinding.router_id == router_id,
RouterL3AgentBinding.l3_agent_id == agent_id)
rb_model.RouterL3AgentBinding.router_id == router_id,
rb_model.RouterL3AgentBinding.l3_agent_id == agent_id)
query.delete()
def _unschedule_router(self, context, router_id, agents_ids):
@ -325,8 +308,9 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
router_id=router_id)
def list_routers_on_l3_agent(self, context, agent_id):
query = context.session.query(RouterL3AgentBinding.router_id)
query = query.filter(RouterL3AgentBinding.l3_agent_id == agent_id)
query = context.session.query(rb_model.RouterL3AgentBinding.router_id)
query = query.filter(
rb_model.RouterL3AgentBinding.l3_agent_id == agent_id)
router_ids = [item[0] for item in query]
if router_ids:
@ -362,13 +346,13 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
Overridden for DVR to handle agents in 'dvr' mode which have
no explicit bindings with routers
"""
query = context.session.query(RouterL3AgentBinding.router_id)
query = context.session.query(rb_model.RouterL3AgentBinding.router_id)
query = query.filter(
RouterL3AgentBinding.l3_agent_id == agent.id)
rb_model.RouterL3AgentBinding.l3_agent_id == agent.id)
if router_ids:
query = query.filter(
RouterL3AgentBinding.router_id.in_(router_ids))
rb_model.RouterL3AgentBinding.router_id.in_(router_ids))
return [item[0] for item in query]
@ -399,11 +383,12 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
active=None):
if not router_ids:
return []
query = context.session.query(RouterL3AgentBinding)
query = context.session.query(rb_model.RouterL3AgentBinding)
query = query.options(orm.contains_eager(
RouterL3AgentBinding.l3_agent))
query = query.join(RouterL3AgentBinding.l3_agent)
query = query.filter(RouterL3AgentBinding.router_id.in_(router_ids))
rb_model.RouterL3AgentBinding.l3_agent))
query = query.join(rb_model.RouterL3AgentBinding.l3_agent)
query = query.filter(
rb_model.RouterL3AgentBinding.router_id.in_(router_ids))
if admin_state_up is not None:
query = (query.filter(agents_db.Agent.admin_state_up ==
admin_state_up))
@ -418,9 +403,9 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
def _get_l3_bindings_hosting_routers(self, context, router_ids):
if not router_ids:
return []
query = context.session.query(RouterL3AgentBinding)
query = context.session.query(rb_model.RouterL3AgentBinding)
query = query.options(joinedload('l3_agent')).filter(
RouterL3AgentBinding.router_id.in_(router_ids))
rb_model.RouterL3AgentBinding.router_id.in_(router_ids))
return query.all()
def list_l3_agents_hosting_router(self, context, router_id):
@ -523,10 +508,12 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
query = context.session.query(
agents_db.Agent,
func.count(
RouterL3AgentBinding.router_id
).label('count')).outerjoin(RouterL3AgentBinding).group_by(
rb_model.RouterL3AgentBinding.router_id
).label('count')).outerjoin(
rb_model.RouterL3AgentBinding).group_by(
agents_db.Agent.id,
RouterL3AgentBinding.l3_agent_id).order_by('count')
rb_model.RouterL3AgentBinding
.l3_agent_id).order_by('count')
res = query.filter(agents_db.Agent.id.in_(agent_ids)).first()
return res[0]
@ -550,14 +537,16 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
"""
num_agents = self.get_number_of_agents_for_scheduling(context)
query = context.session.query(RouterL3AgentBinding)
query = context.session.query(rb_model.RouterL3AgentBinding)
query = query.filter(
RouterL3AgentBinding.router_id == router_id)
query = query.order_by(RouterL3AgentBinding.binding_index.asc())
rb_model.RouterL3AgentBinding.router_id == router_id)
query = query.order_by(rb_model.
RouterL3AgentBinding.binding_index.asc())
bindings = query.all()
binding_indices = [b.binding_index for b in bindings]
all_indicies = set(range(LOWEST_BINDING_INDEX, num_agents + 1))
all_indicies = set(range(rb_model.LOWEST_BINDING_INDEX,
num_agents + 1))
open_slots = sorted(list(all_indicies - set(binding_indices)))
if open_slots:
@ -578,3 +567,6 @@ class AZL3AgentSchedulerDbMixin(L3AgentSchedulerDbMixin,
def get_router_availability_zones(self, router):
return list({agent.availability_zone for agent in router.l3_agents})
_deprecate._MovedGlobals()

View File

@ -30,11 +30,11 @@ from neutron.callbacks import resources
from neutron.common import constants as l3_const
from neutron.common import utils as n_utils
from neutron.db import api as db_api
from neutron.db import l3_agentschedulers_db as l3_sched_db
from neutron.db import l3_attrs_db
from neutron.db import l3_db
from neutron.db.models import allowed_address_pair as aap_models
from neutron.db.models import l3 as l3_models
from neutron.db.models import l3agent as rb_model
from neutron.db import models_v2
from neutron.extensions import l3
from neutron.extensions import portbindings
@ -514,7 +514,7 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
if removed_hosts:
agents = plugin.get_l3_agents(context,
filters={'host': removed_hosts})
binding_table = l3_sched_db.RouterL3AgentBinding
binding_table = rb_model.RouterL3AgentBinding
snat_binding = context.session.query(binding_table).filter_by(
router_id=router_id).first()
for agent in agents:
@ -557,7 +557,7 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
if not routers:
return []
router_ids = [r['id'] for r in routers]
snat_binding = l3_sched_db.RouterL3AgentBinding
snat_binding = rb_model.RouterL3AgentBinding
query = (context.session.query(snat_binding).
filter(snat_binding.router_id.in_(router_ids))).all()
bindings = dict((b.router_id, b) for b in query)

View File

@ -24,6 +24,7 @@ from neutron.common import utils as n_utils
from neutron.db import agentschedulers_db
from neutron.db import l3_agentschedulers_db as l3agent_sch_db
from neutron.db.models import l3agent as rb_model
from neutron.db import models_v2
from neutron.extensions import portbindings
from neutron import manager
@ -165,7 +166,7 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
removed_router_info = []
for router_id in router_ids:
snat_binding = context.session.query(
l3agent_sch_db.RouterL3AgentBinding).filter_by(
rb_model.RouterL3AgentBinding).filter_by(
router_id=router_id).filter_by(
l3_agent_id=agent.id).first()
if snat_binding:

View File

@ -23,6 +23,7 @@ from neutron.db import agents_db
from neutron.db import l3_agentschedulers_db as l3_sch_db
from neutron.db import l3_attrs_db
from neutron.db.models import l3 as l3_models
from neutron.db.models import l3agent as rb_model
from neutron.extensions import portbindings
from neutron import manager
from neutron.plugins.common import constants as service_constants
@ -39,7 +40,7 @@ class L3_HA_scheduler_db_mixin(l3_sch_db.AZL3AgentSchedulerDbMixin):
# the group by statement when using an aggregate function.
# One solution is to generate a subquery and join it with the desired
# columns.
binding_model = l3_sch_db.RouterL3AgentBinding
binding_model = rb_model.RouterL3AgentBinding
sub_query = (context.session.query(
binding_model.router_id,
func.count(binding_model.router_id).label('count')).
@ -60,8 +61,9 @@ class L3_HA_scheduler_db_mixin(l3_sch_db.AZL3AgentSchedulerDbMixin):
if not agent_ids:
return []
query = (context.session.query(agents_db.Agent, func.count(
l3_sch_db.RouterL3AgentBinding.router_id).label('count')).
outerjoin(l3_sch_db.RouterL3AgentBinding).
rb_model.RouterL3AgentBinding.router_id)
.label('count')).
outerjoin(rb_model.RouterL3AgentBinding).
group_by(agents_db.Agent.id).
filter(agents_db.Agent.id.in_(agent_ids)).
order_by('count'))

View File

@ -34,7 +34,6 @@ from neutron.db import external_net_db # noqa
from neutron.db.extra_dhcp_opt import models as edo_models # noqa
from neutron.db import extraroute_db # noqa
from neutron.db import flavors_db # noqa
from neutron.db import l3_agentschedulers_db # noqa
from neutron.db import l3_attrs_db # noqa
from neutron.db import l3_dvrscheduler_db # noqa
from neutron.db import l3_gwmode_db # noqa

View File

@ -0,0 +1,41 @@
# 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 model_base
import sqlalchemy as sa
from sqlalchemy import orm
from neutron.db import agents_db
LOWEST_BINDING_INDEX = 1
class RouterL3AgentBinding(model_base.BASEV2):
"""Represents binding between neutron routers and L3 agents."""
__table_args__ = (
sa.UniqueConstraint(
'router_id', 'binding_index',
name='uniq_router_l3_agent_binding0router_id0binding_index0'),
model_base.BASEV2.__table_args__
)
router_id = sa.Column(sa.String(36),
sa.ForeignKey("routers.id", ondelete='CASCADE'),
primary_key=True)
l3_agent = orm.relation(agents_db.Agent)
l3_agent_id = sa.Column(sa.String(36),
sa.ForeignKey("agents.id", ondelete='CASCADE'),
primary_key=True)
binding_index = sa.Column(sa.Integer, nullable=False,
server_default=str(LOWEST_BINDING_INDEX))

View File

@ -33,6 +33,7 @@ from neutron.db import api as db_api
from neutron.db import l3_agentschedulers_db
from neutron.db import l3_hamode_db
from neutron.db.models import l3 as l3_models
from neutron.db.models import l3agent as rb_model
from neutron.extensions import availability_zone as az_ext
from neutron.extensions import l3
@ -58,7 +59,7 @@ class L3Scheduler(object):
pass
def _router_has_binding(self, context, router_id, l3_agent_id):
router_binding_model = l3_agentschedulers_db.RouterL3AgentBinding
router_binding_model = rb_model.RouterL3AgentBinding
query = context.session.query(router_binding_model)
query = query.filter(router_binding_model.router_id == router_id,
@ -202,7 +203,7 @@ class L3Scheduler(object):
self.bind_router(context, router['id'], l3_agent)
def bind_router(self, context, router_id, chosen_agent,
binding_index=l3_agentschedulers_db.LOWEST_BINDING_INDEX):
binding_index=rb_model.LOWEST_BINDING_INDEX):
"""Bind the router to the l3 agent which has been chosen."""
# Pre-cache the agent's id so that if an exception is raised we can
# safely access its value. Otherwise, sqlalchemy will try to fetch it
@ -211,7 +212,7 @@ class L3Scheduler(object):
try:
with context.session.begin(subtransactions=True):
binding = l3_agentschedulers_db.RouterL3AgentBinding()
binding = rb_model.RouterL3AgentBinding()
binding.l3_agent = chosen_agent
binding.router_id = router_id
binding.binding_index = binding_index
@ -359,7 +360,7 @@ class L3Scheduler(object):
chosen_agents):
port_bindings = plugin.get_ha_router_port_bindings(context,
[router_id])
binding_indices = range(l3_agentschedulers_db.LOWEST_BINDING_INDEX,
binding_indices = range(rb_model.LOWEST_BINDING_INDEX,
len(port_bindings) + 1)
for port_binding, agent, binding_index in zip(
port_bindings, chosen_agents, binding_indices):

View File

@ -32,7 +32,7 @@ from neutron.common import constants as n_const
from neutron import context
from neutron.db import agents_db
from neutron.db import agentschedulers_db
from neutron.db import l3_agentschedulers_db
from neutron.db.models import l3agent as rb_model
from neutron.extensions import agent
from neutron.extensions import dhcpagentscheduler
from neutron.extensions import l3agentscheduler
@ -797,7 +797,7 @@ class OvsAgentSchedulerTestCase(OvsAgentSchedulerTestCaseBase):
# A should still have it even though it was inactive due to the
# admin_state being down
rab = l3_agentschedulers_db.RouterL3AgentBinding
rab = rb_model.RouterL3AgentBinding
binding = (self.adminContext.session.query(rab).
filter(rab.router_id == r['router']['id']).first())
self.assertEqual(binding.l3_agent.host, L3_HOSTA)

View File

@ -30,12 +30,12 @@ import testtools
from neutron import context as n_context
from neutron.db import agents_db
from neutron.db import db_base_plugin_v2 as db_v2
from neutron.db import l3_agentschedulers_db
from neutron.db import l3_db
from neutron.db import l3_dvr_ha_scheduler_db
from neutron.db import l3_dvrscheduler_db
from neutron.db import l3_hamode_db
from neutron.db import l3_hascheduler_db
from neutron.db.models import l3agent as rb_model
from neutron.extensions import l3
from neutron.extensions import l3_ext_ha_mode as l3_ha
from neutron.extensions import l3agentscheduler as l3agent
@ -572,7 +572,7 @@ class L3SchedulerTestBaseMixin(object):
def _test_schedule_bind_router(self, agent, router):
ctx = self.adminContext
session = ctx.session
db = l3_agentschedulers_db.RouterL3AgentBinding
db = rb_model.RouterL3AgentBinding
scheduler = l3_agent_scheduler.ChanceScheduler()
rid = router['router']['id']
@ -1457,7 +1457,7 @@ class L3HATestCaseMixin(testlib_api.SqlTestCase,
@staticmethod
def get_router_l3_agent_binding(context, router_id, l3_agent_id=None,
binding_index=None):
model = l3_agentschedulers_db.RouterL3AgentBinding
model = rb_model.RouterL3AgentBinding
query = context.session.query(model)
query = query.filter(model.router_id == router_id)
if l3_agent_id: