Expose ha_state per router to agent binding via API
l3-agent-list-hosting-router will now return with a new 'ha_state' attribute, per agent. It signifies the HA state of the router on that agent. Implements: blueprint report-ha-router-master Change-Id: Ie0f53b7565d53ff791b0cdcca20be2b4415b49cc
This commit is contained in:
parent
de3bd2e61a
commit
c8dfdb47a8
|
@ -342,14 +342,9 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
|
|||
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)
|
||||
|
|
|
@ -436,6 +436,12 @@ class L3_HA_NAT_db_mixin(l3_dvr_db.L3_NAT_with_dvr_db_mixin):
|
|||
|
||||
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)
|
||||
|
||||
|
|
|
@ -59,3 +59,24 @@ class L3_HA_scheduler_db_mixin(l3_sch_db.L3AgentSchedulerDbMixin):
|
|||
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)
|
||||
|
|
|
@ -26,6 +26,7 @@ from neutron.extensions import l3
|
|||
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
|
||||
|
||||
|
@ -93,12 +94,43 @@ class L3HATestFramework(testlib_api.SqlTestCase,
|
|||
|
||||
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])
|
||||
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)
|
||||
|
||||
for agent_id, binding in zip(
|
||||
[self.agent1['id'], self.agent2['id']], bindings):
|
||||
binding.l3_agent_id = agent_id
|
||||
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):
|
||||
|
|
|
@ -1239,6 +1239,37 @@ class L3AgentSchedulerDbMixinTestCase(L3HATestCaseMixin):
|
|||
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):
|
||||
|
||||
|
|
Loading…
Reference in New Issue