vmware-nsx/neutron/db/l3_hascheduler_db.py
Sylvain Afchain 74262dffb8 Add a new scheduler for the l3 HA
This patch updates all schedulers in order to support the
scheduling of HA routers. It also refactors and adds tests for
the auto scheduling part.

The schedulers aren't expected to work when creating a router
that's both distributed and highly available. Specific issues
will be reported as bugs and fixed in a future patch.

Partially-implements: blueprint l3-high-availability
Change-Id: I2f80f45adeffa1a4eebcb375a4c8326177e84e83
Co-Authored-By: Assaf Muller <amuller@redhat.com>
2014-09-12 16:22:28 +03:00

60 lines
2.4 KiB
Python

# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
#
# 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 sqlalchemy import func
from sqlalchemy import sql
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 import l3_db
class L3_HA_scheduler_db_mixin(l3_sch_db.L3AgentSchedulerDbMixin):
def get_ha_routers_l3_agents_count(self, context):
"""Return a map between HA routers and how many agents every
router is scheduled to.
"""
# Postgres requires every column in the select to be present in
# 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
sub_query = (context.session.query(
binding_model.router_id,
func.count(binding_model.router_id).label('count')).
join(l3_attrs_db.RouterExtraAttributes,
binding_model.router_id ==
l3_attrs_db.RouterExtraAttributes.router_id).
join(l3_db.Router).
filter(l3_attrs_db.RouterExtraAttributes.ha == sql.true()).
group_by(binding_model.router_id).subquery())
query = (context.session.query(
l3_db.Router.id, l3_db.Router.tenant_id, sub_query.c.count).
join(sub_query))
return query
def get_l3_agents_ordered_by_num_routers(self, context, agent_ids):
query = (context.session.query(agents_db.Agent, func.count(
l3_sch_db.RouterL3AgentBinding.router_id).label('count')).
outerjoin(l3_sch_db.RouterL3AgentBinding).
group_by(agents_db.Agent.id).
filter(agents_db.Agent.id.in_(agent_ids)).
order_by('count'))
return [record[0] for record in query]