# Copyright (C) 2014 eNovance SAS # # 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]