DVR: delete stale devices after router update
After the external network change of router gateway, the l3 agent deletes stale external devices in the qrouter namespace only. This doesn't apply to distributed router. This patch extract a method named _delete_stale_external_devices from RouterInfo and override it in DvrEdgeRouter. Change-Id: I2602efd5be92ec57410e54cf9c26641330a52ee6 Partial-Bug: #1651813
This commit is contained in:
parent
eb5871535c
commit
dcd4c8b8de
@ -242,3 +242,18 @@ class DvrEdgeRouter(dvr_local_router.DvrLocalRouter):
|
|||||||
with self.snat_iptables_manager.defer_apply():
|
with self.snat_iptables_manager.defer_apply():
|
||||||
self._add_address_scope_mark(
|
self._add_address_scope_mark(
|
||||||
self.snat_iptables_manager, ports_scopemark)
|
self.snat_iptables_manager, ports_scopemark)
|
||||||
|
|
||||||
|
def _delete_stale_external_devices(self, interface_name):
|
||||||
|
if not self.snat_namespace.exists():
|
||||||
|
return
|
||||||
|
|
||||||
|
ns_ip = ip_lib.IPWrapper(namespace=self.snat_namespace.name)
|
||||||
|
for d in ns_ip.get_devices(exclude_loopback=True):
|
||||||
|
if (d.name.startswith(router.EXTERNAL_DEV_PREFIX) and
|
||||||
|
d.name != interface_name):
|
||||||
|
LOG.debug('Deleting stale external router device: %s', d.name)
|
||||||
|
self.driver.unplug(
|
||||||
|
d.name,
|
||||||
|
bridge=self.agent_conf.external_network_bridge,
|
||||||
|
namespace=self.snat_namespace.name,
|
||||||
|
prefix=router.EXTERNAL_DEV_PREFIX)
|
||||||
|
@ -713,6 +713,19 @@ class RouterInfo(object):
|
|||||||
def _gateway_ports_equal(port1, port2):
|
def _gateway_ports_equal(port1, port2):
|
||||||
return port1 == port2
|
return port1 == port2
|
||||||
|
|
||||||
|
def _delete_stale_external_devices(self, interface_name):
|
||||||
|
existing_devices = self._get_existing_devices()
|
||||||
|
stale_devs = [dev for dev in existing_devices
|
||||||
|
if dev.startswith(EXTERNAL_DEV_PREFIX)
|
||||||
|
and dev != interface_name]
|
||||||
|
for stale_dev in stale_devs:
|
||||||
|
LOG.debug('Deleting stale external router device: %s', stale_dev)
|
||||||
|
self.agent.pd.remove_gw_interface(self.router['id'])
|
||||||
|
self.driver.unplug(stale_dev,
|
||||||
|
bridge=self.agent_conf.external_network_bridge,
|
||||||
|
namespace=self.ns_name,
|
||||||
|
prefix=EXTERNAL_DEV_PREFIX)
|
||||||
|
|
||||||
def _process_external_gateway(self, ex_gw_port):
|
def _process_external_gateway(self, ex_gw_port):
|
||||||
# TODO(Carl) Refactor to clarify roles of ex_gw_port vs self.ex_gw_port
|
# TODO(Carl) Refactor to clarify roles of ex_gw_port vs self.ex_gw_port
|
||||||
ex_gw_port_id = (ex_gw_port and ex_gw_port['id'] or
|
ex_gw_port_id = (ex_gw_port and ex_gw_port['id'] or
|
||||||
@ -736,17 +749,7 @@ class RouterInfo(object):
|
|||||||
interface_name = self.get_internal_device_name(p['id'])
|
interface_name = self.get_internal_device_name(p['id'])
|
||||||
self.gateway_redirect_cleanup(interface_name)
|
self.gateway_redirect_cleanup(interface_name)
|
||||||
|
|
||||||
existing_devices = self._get_existing_devices()
|
self._delete_stale_external_devices(interface_name)
|
||||||
stale_devs = [dev for dev in existing_devices
|
|
||||||
if dev.startswith(EXTERNAL_DEV_PREFIX)
|
|
||||||
and dev != interface_name]
|
|
||||||
for stale_dev in stale_devs:
|
|
||||||
LOG.debug('Deleting stale external router device: %s', stale_dev)
|
|
||||||
self.agent.pd.remove_gw_interface(self.router['id'])
|
|
||||||
self.driver.unplug(stale_dev,
|
|
||||||
bridge=self.agent_conf.external_network_bridge,
|
|
||||||
namespace=self.ns_name,
|
|
||||||
prefix=EXTERNAL_DEV_PREFIX)
|
|
||||||
|
|
||||||
# Process SNAT rules for external gateway
|
# Process SNAT rules for external gateway
|
||||||
gw_port = self._router.get('gw_port')
|
gw_port = self._router.get('gw_port')
|
||||||
|
@ -1871,6 +1871,35 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
|||||||
namespace=ri.ns_name,
|
namespace=ri.ns_name,
|
||||||
prefix=namespaces.EXTERNAL_DEV_PREFIX)
|
prefix=namespaces.EXTERNAL_DEV_PREFIX)
|
||||||
|
|
||||||
|
def test_process_dvr_router_delete_stale_external_devices(self):
|
||||||
|
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
|
||||||
|
stale_devlist = [l3_test_common.FakeDev('qg-a1b2c3d4-e5')]
|
||||||
|
stale_devnames = [dev.name for dev in stale_devlist]
|
||||||
|
|
||||||
|
router = l3_test_common.prepare_router_data(enable_snat=True,
|
||||||
|
num_internal_ports=1)
|
||||||
|
self._set_ri_kwargs(agent, router['id'], router)
|
||||||
|
ri = dvr_router.DvrEdgeRouter(HOSTNAME, **self.ri_kwargs)
|
||||||
|
self.mock_ip.get_devices.return_value = stale_devlist
|
||||||
|
|
||||||
|
ri.process()
|
||||||
|
|
||||||
|
self.mock_driver.unplug.assert_called_with(
|
||||||
|
stale_devnames[0],
|
||||||
|
bridge=agent.conf.external_network_bridge,
|
||||||
|
namespace=ri.snat_namespace.name,
|
||||||
|
prefix=namespaces.EXTERNAL_DEV_PREFIX)
|
||||||
|
|
||||||
|
def test_process_dvr_router_delete_stale_external_devices_no_snat_ns(self):
|
||||||
|
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
|
||||||
|
router = l3_test_common.prepare_router_data(enable_gw=False,
|
||||||
|
num_internal_ports=1)
|
||||||
|
self._set_ri_kwargs(agent, router['id'], router)
|
||||||
|
ri = dvr_router.DvrEdgeRouter(HOSTNAME, **self.ri_kwargs)
|
||||||
|
self.mock_ip.netns.exists.return_value = False
|
||||||
|
ri._delete_stale_external_devices('qg-a1b2c3d4-e5')
|
||||||
|
self.assertFalse(self.mock_ip.get_devices.called)
|
||||||
|
|
||||||
def test_router_deleted(self):
|
def test_router_deleted(self):
|
||||||
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
|
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
|
||||||
agent._queue = mock.Mock()
|
agent._queue = mock.Mock()
|
||||||
|
Loading…
Reference in New Issue
Block a user