Merge "Resolve issue where router can't be removed from L3-agent in dvr mode" into stable/kilo
This commit is contained in:
commit
ebc6649cd6
|
@ -426,16 +426,20 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
|
||||||
context, agent, router)
|
context, agent, router)
|
||||||
|
|
||||||
def remove_router_from_l3_agent(self, context, agent_id, router_id):
|
def remove_router_from_l3_agent(self, context, agent_id, router_id):
|
||||||
|
binding = None
|
||||||
router = self.get_router(context, router_id)
|
router = self.get_router(context, router_id)
|
||||||
if router['external_gateway_info'] and router.get('distributed'):
|
if router['external_gateway_info'] and router.get('distributed'):
|
||||||
binding = self.unbind_snat(context, router_id, agent_id=agent_id)
|
binding = self.unbind_snat(context, router_id, agent_id=agent_id)
|
||||||
|
# binding only exists when agent mode is dvr_snat
|
||||||
if binding:
|
if binding:
|
||||||
notification_not_sent = self.unbind_router_servicenode(context,
|
notification_not_sent = self.unbind_router_servicenode(context,
|
||||||
router_id, binding)
|
router_id, binding)
|
||||||
if notification_not_sent:
|
if notification_not_sent:
|
||||||
self.l3_rpc_notifier.routers_updated(
|
self.l3_rpc_notifier.routers_updated(
|
||||||
context, [router_id], schedule_routers=False)
|
context, [router_id], schedule_routers=False)
|
||||||
else:
|
|
||||||
|
# Below Needs to be done when agent mode is legacy or dvr.
|
||||||
|
if not binding:
|
||||||
super(L3_DVRsch_db_mixin,
|
super(L3_DVRsch_db_mixin,
|
||||||
self).remove_router_from_l3_agent(
|
self).remove_router_from_l3_agent(
|
||||||
context, agent_id, router_id)
|
context, agent_id, router_id)
|
||||||
|
|
|
@ -1560,6 +1560,101 @@ class L3DvrSchedulerTestCase(testlib_api.SqlTestCase):
|
||||||
core_plugin.assert_called_once_with()
|
core_plugin.assert_called_once_with()
|
||||||
l3_notifier.assert_called_once_with()
|
l3_notifier.assert_called_once_with()
|
||||||
|
|
||||||
|
def _test_remove_router_from_l3_agent_dvr_snat(self, ursn_return):
|
||||||
|
agent_id = 'dvr_snat_l3_agent_id'
|
||||||
|
router_id = 'dvr-router-1'
|
||||||
|
router = {
|
||||||
|
'id': router_id,
|
||||||
|
'distributed': True,
|
||||||
|
'external_gateway_info': {'network_id': str(uuid.uuid4()),
|
||||||
|
'enable_snat': True}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding = l3_dvrscheduler_db.CentralizedSnatL3AgentBinding(
|
||||||
|
router_id=router_id, l3_agent_id=agent_id,
|
||||||
|
l3_agent=agents_db.Agent())
|
||||||
|
|
||||||
|
self.dut.l3_rpc_notifier = mock.Mock()
|
||||||
|
with mock.patch.object(self.dut, 'get_router') as mock_gr,\
|
||||||
|
mock.patch.object(self.dut, 'unbind_snat') as mock_us,\
|
||||||
|
mock.patch.object(
|
||||||
|
self.dut,
|
||||||
|
'unbind_router_servicenode') as mock_ursn,\
|
||||||
|
mock.patch('neutron.db.l3_agentschedulers_db.'
|
||||||
|
'L3AgentSchedulerDbMixin.'
|
||||||
|
'remove_router_from_l3_agent') as mock_super_rrl3a:
|
||||||
|
mock_gr.return_value = router
|
||||||
|
mock_us.return_value = binding
|
||||||
|
mock_ursn.return_value = ursn_return
|
||||||
|
|
||||||
|
self.dut.remove_router_from_l3_agent(self.adminContext,
|
||||||
|
agent_id,
|
||||||
|
router_id)
|
||||||
|
mock_gr.assert_called_once_with(self.adminContext, router_id)
|
||||||
|
|
||||||
|
us_params = {'agent_id': agent_id}
|
||||||
|
mock_us.assert_called_once_with(self.adminContext,
|
||||||
|
router_id,
|
||||||
|
**us_params)
|
||||||
|
mock_ursn.assert_called_once_with(self.adminContext,
|
||||||
|
router_id,
|
||||||
|
binding)
|
||||||
|
self.assertFalse(mock_super_rrl3a.called)
|
||||||
|
|
||||||
|
if ursn_return:
|
||||||
|
routers_updated_params = {'schedule_routers': False}
|
||||||
|
(self.dut.l3_rpc_notifier.routers_updated.
|
||||||
|
assert_called_once_with(self.adminContext,
|
||||||
|
[router_id],
|
||||||
|
**routers_updated_params))
|
||||||
|
else:
|
||||||
|
self.assertFalse(self.dut.l3_rpc_notifier.
|
||||||
|
routers_updated.called)
|
||||||
|
|
||||||
|
def test_remove_router_from_l3_agent_dvr_snat_mode(self):
|
||||||
|
self._test_remove_router_from_l3_agent_dvr_snat(True)
|
||||||
|
self._test_remove_router_from_l3_agent_dvr_snat(False)
|
||||||
|
|
||||||
|
def test_remove_router_from_l3_agent_dvr_mode(self):
|
||||||
|
agent_id = 'dvr_l3_agent_id'
|
||||||
|
router_id = 'dvr-router-1'
|
||||||
|
router = {
|
||||||
|
'id': router_id,
|
||||||
|
'distributed': True,
|
||||||
|
'external_gateway_info': {'network_id': str(uuid.uuid4()),
|
||||||
|
'enable_snat': True}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.dut.l3_rpc_notifier = mock.Mock()
|
||||||
|
with mock.patch.object(self.dut, 'get_router') as mock_gr,\
|
||||||
|
mock.patch.object(self.dut, 'unbind_snat') as mock_us,\
|
||||||
|
mock.patch.object(
|
||||||
|
self.dut,
|
||||||
|
'unbind_router_servicenode') as mock_ursn,\
|
||||||
|
mock.patch('neutron.db.l3_agentschedulers_db.'
|
||||||
|
'L3AgentSchedulerDbMixin.'
|
||||||
|
'remove_router_from_l3_agent') as mock_super_rrl3a:
|
||||||
|
mock_gr.return_value = router
|
||||||
|
mock_us.return_value = None
|
||||||
|
mock_ursn.return_value = True
|
||||||
|
|
||||||
|
self.dut.remove_router_from_l3_agent(self.adminContext,
|
||||||
|
agent_id,
|
||||||
|
router_id)
|
||||||
|
|
||||||
|
mock_gr.assert_called_once_with(self.adminContext, router_id)
|
||||||
|
|
||||||
|
us_params = {'agent_id': agent_id}
|
||||||
|
mock_us.assert_called_once_with(self.adminContext,
|
||||||
|
router_id,
|
||||||
|
**us_params)
|
||||||
|
|
||||||
|
self.assertFalse(self.dut.l3_rpc_notifier.routers_updated.called)
|
||||||
|
self.assertFalse(mock_ursn.called)
|
||||||
|
mock_super_rrl3a.assert_called_with(self.adminContext,
|
||||||
|
agent_id,
|
||||||
|
router_id)
|
||||||
|
|
||||||
|
|
||||||
class L3HAPlugin(db_v2.NeutronDbPluginV2,
|
class L3HAPlugin(db_v2.NeutronDbPluginV2,
|
||||||
l3_hamode_db.L3_HA_NAT_db_mixin,
|
l3_hamode_db.L3_HA_NAT_db_mixin,
|
||||||
|
|
Loading…
Reference in New Issue