RouterL3AgentBinding.l3_agent_id == agent_id)
query.delete()
+ def _unschedule_router(self, context, router_id, agents_ids):
+ with context.session.begin(subtransactions=True):
+ for agent_id in agents_ids:
+ self._unbind_router(context, router_id, agent_id)
+
def reschedule_router(self, context, router_id, candidates=None):
"""Reschedule router to (a) new l3 agent(s)
cur_agents = self.list_l3_agents_hosting_router(
context, router_id)['agents']
with context.session.begin(subtransactions=True):
- for agent in cur_agents:
- self._unbind_router(context, router_id, agent['id'])
+ cur_agents_ids = [agent['id'] for agent in cur_agents]
+ self._unschedule_router(context, router_id, cur_agents_ids)
self.schedule_router(context, router_id, candidates=candidates)
new_agents = self.list_l3_agents_hosting_router(
context, router_id, chosen_agent)
return chosen_agent
- def _unbind_router(self, context, router_id, agent_id):
+ def _unschedule_router(self, context, router_id, agents_ids):
router = self.get_router(context, router_id)
- super(L3_DVRsch_db_mixin, self)._unbind_router(context, router_id,
- agent_id)
if router.get('distributed', False):
- self.unbind_snat(context, router_id, agent_id)
+ # for DVR router unscheduling means just unscheduling SNAT portion
+ self.unbind_snat_servicenode(context, router_id)
+ else:
+ super(L3_DVRsch_db_mixin, self)._unschedule_router(
+ context, router_id, agents_ids)
def _get_active_l3_agent_routers_sync_data(self, context, host, agent,
router_ids):
self.assertFalse(ret_b)
def test_router_is_not_rescheduled_from_dvr_agent(self):
- router = {'name': 'router1',
- 'admin_state_up': True,
- 'distributed': True}
- subnet_ids = {'id': '1234'}
- r = self.l3plugin.create_router(
- self.adminContext, {'router': router})
- dvr_agent = self._register_dvr_agents()[1]
+ with self.subnet() as s, \
+ mock.patch.object(
+ self.l3plugin,
+ 'check_ports_exist_on_l3agent') as port_exists:
+ net_id = s['subnet']['network_id']
+ self._set_net_external(net_id)
+ router = {'name': 'router1',
+ 'admin_state_up': True,
+ 'external_gateway_info': {'network_id': net_id},
+ 'distributed': True}
+ r = self.l3plugin.create_router(
+ self.adminContext, {'router': router})
+ dvr_snat_agent, dvr_agent = self._register_dvr_agents()
- with mock.patch.object(
- self.l3plugin,
- 'check_ports_exist_on_l3agent') as port_exists,\
- mock.patch.object(
- self.l3plugin,
- 'get_subnet_ids_on_router') as rtr_subnets:
- rtr_subnets.return_value = [subnet_ids]
port_exists.return_value = True
self.l3plugin.schedule_router(
self.adminContext, r['id'])
self.assertEqual(2, len(agents['agents']))
self.assertIn(dvr_agent['host'],
[a['host'] for a in agents['agents']])
+ # router should not be unscheduled from dvr agent
self._take_down_agent_and_run_reschedule(dvr_agent['host'])
agents = self._list_l3_agents_hosting_router(r['id'])
self.assertEqual(2, len(agents['agents']))
self.assertIn(dvr_agent['host'],
[a['host'] for a in agents['agents']])
+ # another dvr_snat agent is needed to test that router is not
+ # unscheduled from dead dvr agent in case rescheduling between
+ # dvr_snat agents happens
+ helpers.register_l3_agent(
+ host='hostC', agent_mode=constants.L3_AGENT_MODE_DVR_SNAT)
+ self._take_down_agent_and_run_reschedule(dvr_snat_agent['host'])
+ agents = self._list_l3_agents_hosting_router(r['id'])
+ self.assertEqual(2, len(agents['agents']))
+ self.assertIn(dvr_agent['host'],
+ [a['host'] for a in agents['agents']])
+
def test_router_reschedule_succeeded_after_failed_notification(self):
l3_plugin = (manager.NeutronManager.get_service_plugins()
[service_constants.L3_ROUTER_NAT])