with context.session.begin(subtransactions=True):
bindings = self._get_l3_bindings_hosting_routers(
context, [router_id])
- results = []
- for binding in bindings:
- l3_agent_dict = self._make_agent_dict(binding.l3_agent)
- results.append(l3_agent_dict)
- if results:
- return {'agents': results}
- else:
- return {'agents': []}
+
+ return {'agents': [self._make_agent_dict(binding.l3_agent) for
+ binding in bindings]}
def get_l3_agents(self, context, active=None, filters=None):
query = context.session.query(agents_db.Agent)
return query.all()
+ def get_l3_bindings_hosting_router_with_ha_states(
+ self, context, router_id):
+ """Return a list of [(agent, ha_state), ...]."""
+ bindings = self.get_ha_router_port_bindings(context, [router_id])
+ return [(binding.agent, binding.state) for binding in bindings]
+
def _process_sync_ha_data(self, context, routers, host):
routers_dict = dict((router['id'], router) for router in routers)
order_by('count'))
return [record[0] for record in query]
+
+ def _get_agents_dict_for_router(self, agents_and_states):
+ agents = []
+ for agent, ha_state in agents_and_states:
+ l3_agent_dict = self._make_agent_dict(agent)
+ l3_agent_dict['ha_state'] = ha_state
+ agents.append(l3_agent_dict)
+ return {'agents': agents}
+
+ def list_l3_agents_hosting_router(self, context, router_id):
+ with context.session.begin(subtransactions=True):
+ router_db = self._get_router(context, router_id)
+ if router_db.extra_attributes.ha:
+ bindings = self.get_l3_bindings_hosting_router_with_ha_states(
+ context, router_id)
+ else:
+ bindings = self._get_l3_bindings_hosting_routers(
+ context, [router_id])
+ bindings = [(binding.l3_agent, None) for binding in bindings]
+
+ return self._get_agents_dict_for_router(bindings)
from neutron.extensions import l3_ext_ha_mode
from neutron import manager
from neutron.openstack.common import uuidutils
+from neutron.scheduler import l3_agent_scheduler
from neutron.tests.unit import testlib_api
from neutron.tests.unit import testlib_plugin
def _bind_router(self, router_id):
with self.admin_ctx.session.begin(subtransactions=True):
- bindings = self.plugin.get_ha_router_port_bindings(self.admin_ctx,
- [router_id])
-
- for agent_id, binding in zip(
- [self.agent1['id'], self.agent2['id']], bindings):
- binding.l3_agent_id = agent_id
+ scheduler = l3_agent_scheduler.ChanceScheduler()
+ agents_db = self.plugin.get_agents_db(self.admin_ctx)
+ scheduler.bind_ha_router_to_agents(
+ self.plugin,
+ self.admin_ctx,
+ router_id,
+ agents_db)
+
+ def test_get_ha_router_port_bindings(self):
+ router = self._create_router()
+ self._bind_router(router['id'])
+ bindings = self.plugin.get_ha_router_port_bindings(
+ self.admin_ctx, [router['id']])
+ binding_dicts = [{'router_id': binding['router_id'],
+ 'l3_agent_id': binding['l3_agent_id']}
+ for binding in bindings]
+ self.assertIn({'router_id': router['id'],
+ 'l3_agent_id': self.agent1['id']}, binding_dicts)
+ self.assertIn({'router_id': router['id'],
+ 'l3_agent_id': self.agent2['id']}, binding_dicts)
+
+ def test_get_l3_bindings_hosting_router_with_ha_states_ha_router(self):
+ router = self._create_router()
+ self._bind_router(router['id'])
+ self.plugin.update_routers_states(
+ self.admin_ctx, {router['id']: 'active'}, self.agent1['host'])
+ bindings = self.plugin.get_l3_bindings_hosting_router_with_ha_states(
+ self.admin_ctx, router['id'])
+ agent_ids = [(agent[0]['id'], agent[1]) for agent in bindings]
+ self.assertIn((self.agent1['id'], 'active'), agent_ids)
+ self.assertIn((self.agent2['id'], 'standby'), agent_ids)
+
+ def test_get_l3_bindings_hosting_router_with_ha_states_not_scheduled(self):
+ router = self._create_router(ha=False)
+ bindings = self.plugin.get_l3_bindings_hosting_router_with_ha_states(
+ self.admin_ctx, router['id'])
+ self.assertEqual([], bindings)
class L3HATestCase(L3HATestFramework):
self.plugin.reschedule_routers_from_down_agents()
self.assertFalse(reschedule.called)
+ def test_list_l3_agents_hosting_ha_router(self):
+ router = self._create_ha_router()
+ self.plugin.schedule_router(self.adminContext, router['id'])
+
+ agents = self.plugin.list_l3_agents_hosting_router(
+ self.adminContext, router['id'])['agents']
+ for agent in agents:
+ self.assertEqual('standby', agent['ha_state'])
+
+ self.plugin.update_routers_states(
+ self.adminContext, {router['id']: 'active'}, self.agent1.host)
+ agents = self.plugin.list_l3_agents_hosting_router(
+ self.adminContext, router['id'])['agents']
+ for agent in agents:
+ expected_state = ('active' if agent['host'] == self.agent1.host
+ else 'standby')
+ self.assertEqual(expected_state, agent['ha_state'])
+
+ def test_list_l3_agents_hosting_legacy_router(self):
+ router = self._create_ha_router(ha=False)
+ self.plugin.schedule_router(self.adminContext, router['id'])
+
+ agents = self.plugin.list_l3_agents_hosting_router(
+ self.adminContext, router['id'])['agents']
+ for agent in agents:
+ self.assertIsNone(agent['ha_state'])
+
+ def test_get_agents_dict_for_router_unscheduled_returns_empty_list(self):
+ self.assertEqual({'agents': []},
+ self.plugin._get_agents_dict_for_router([]))
+
class L3HAChanceSchedulerTestCase(L3HATestCaseMixin):