Merge "Delete duplicate internal devices in router namespace"
This commit is contained in:
commit
076dd95b2c
@ -414,6 +414,13 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback, manager.Manager):
|
|||||||
prefixlen = netaddr.IPNetwork(port['subnet']['cidr']).prefixlen
|
prefixlen = netaddr.IPNetwork(port['subnet']['cidr']).prefixlen
|
||||||
port['ip_cidr'] = "%s/%s" % (ips[0]['ip_address'], prefixlen)
|
port['ip_cidr'] = "%s/%s" % (ips[0]['ip_address'], prefixlen)
|
||||||
|
|
||||||
|
def _get_existing_internal_devices(self, ri):
|
||||||
|
ip_wrapper = ip_lib.IPWrapper(root_helper=self.root_helper,
|
||||||
|
namespace=ri.ns_name())
|
||||||
|
ip_devs = ip_wrapper.get_devices(exclude_loopback=True)
|
||||||
|
return [ip_dev.name for ip_dev in ip_devs if
|
||||||
|
ip_dev.name.startswith(INTERNAL_DEV_PREFIX)]
|
||||||
|
|
||||||
def process_router(self, ri):
|
def process_router(self, ri):
|
||||||
ri.iptables_manager.defer_apply_on()
|
ri.iptables_manager.defer_apply_on()
|
||||||
ex_gw_port = self._get_ex_gw_port(ri)
|
ex_gw_port = self._get_ex_gw_port(ri)
|
||||||
@ -436,6 +443,17 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback, manager.Manager):
|
|||||||
self.internal_network_removed(ri, p['id'], p['ip_cidr'])
|
self.internal_network_removed(ri, p['id'], p['ip_cidr'])
|
||||||
ri.internal_ports.remove(p)
|
ri.internal_ports.remove(p)
|
||||||
|
|
||||||
|
current_internal_devs = set(self._get_existing_internal_devices(ri))
|
||||||
|
current_port_devs = set([self.get_internal_device_name(id) for
|
||||||
|
id in current_port_ids])
|
||||||
|
stale_devs = current_internal_devs - current_port_devs
|
||||||
|
for stale_dev in stale_devs:
|
||||||
|
LOG.debug(_('Deleting stale internal router device: %s'),
|
||||||
|
stale_dev)
|
||||||
|
self.driver.unplug(stale_dev,
|
||||||
|
namespace=ri.ns_name(),
|
||||||
|
prefix=INTERNAL_DEV_PREFIX)
|
||||||
|
|
||||||
internal_cidrs = [p['ip_cidr'] for p in ri.internal_ports]
|
internal_cidrs = [p['ip_cidr'] for p in ri.internal_ports]
|
||||||
# TODO(salv-orlando): RouterInfo would be a better place for
|
# TODO(salv-orlando): RouterInfo would be a better place for
|
||||||
# this logic too
|
# this logic too
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import contextlib
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
@ -785,6 +786,64 @@ class TestBasicRouterOperations(base.BaseTestCase):
|
|||||||
self.assertThat(nat_rules.index(jump_float_rule),
|
self.assertThat(nat_rules.index(jump_float_rule),
|
||||||
matchers.LessThan(nat_rules.index(internal_net_rule)))
|
matchers.LessThan(nat_rules.index(internal_net_rule)))
|
||||||
|
|
||||||
|
def test_process_router_delete_stale_internal_devices(self):
|
||||||
|
class FakeDev(object):
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
|
||||||
|
stale_devlist = [FakeDev('qr-a1b2c3d4-e5'),
|
||||||
|
FakeDev('qr-b2c3d4e5-f6')]
|
||||||
|
stale_devnames = [dev.name for dev in stale_devlist]
|
||||||
|
|
||||||
|
get_devices_return = [FakeDev('qg-a1b2c3d4-e5'),
|
||||||
|
FakeDev('qg-b2c3d4e5-f6')]
|
||||||
|
get_devices_return.extend(stale_devlist)
|
||||||
|
self.mock_ip.get_devices.return_value = get_devices_return
|
||||||
|
|
||||||
|
router = self._prepare_router_data(enable_snat=True,
|
||||||
|
num_internal_ports=1)
|
||||||
|
ri = l3_agent.RouterInfo(router['id'],
|
||||||
|
self.conf.root_helper,
|
||||||
|
self.conf.use_namespaces,
|
||||||
|
router=router)
|
||||||
|
|
||||||
|
internal_ports = ri.router.get(l3_constants.INTERFACE_KEY, [])
|
||||||
|
self.assertEqual(len(internal_ports), 1)
|
||||||
|
internal_port = internal_ports[0]
|
||||||
|
|
||||||
|
with contextlib.nested(mock.patch.object(l3_agent.L3NATAgent,
|
||||||
|
'internal_network_removed'),
|
||||||
|
mock.patch.object(l3_agent.L3NATAgent,
|
||||||
|
'internal_network_added'),
|
||||||
|
mock.patch.object(l3_agent.L3NATAgent,
|
||||||
|
'external_gateway_removed'),
|
||||||
|
mock.patch.object(l3_agent.L3NATAgent,
|
||||||
|
'external_gateway_added')
|
||||||
|
) as (internal_network_removed,
|
||||||
|
internal_network_added,
|
||||||
|
external_gateway_removed,
|
||||||
|
external_gateway_added):
|
||||||
|
|
||||||
|
agent.process_router(ri)
|
||||||
|
|
||||||
|
self.assertEqual(external_gateway_added.call_count, 1)
|
||||||
|
self.assertFalse(external_gateway_removed.called)
|
||||||
|
self.assertFalse(internal_network_removed.called)
|
||||||
|
internal_network_added.assert_called_once_with(
|
||||||
|
ri,
|
||||||
|
internal_port['network_id'],
|
||||||
|
internal_port['id'],
|
||||||
|
internal_port['ip_cidr'],
|
||||||
|
internal_port['mac_address'])
|
||||||
|
self.assertEqual(self.mock_driver.unplug.call_count,
|
||||||
|
len(stale_devnames))
|
||||||
|
calls = [mock.call(stale_devname,
|
||||||
|
namespace=ri.ns_name(),
|
||||||
|
prefix=l3_agent.INTERNAL_DEV_PREFIX)
|
||||||
|
for stale_devname in stale_devnames]
|
||||||
|
self.mock_driver.unplug.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
def test_routers_with_admin_state_down(self):
|
def test_routers_with_admin_state_down(self):
|
||||||
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
|
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
|
||||||
self.plugin_api.get_external_network_id.return_value = None
|
self.plugin_api.get_external_network_id.return_value = None
|
||||||
|
Loading…
x
Reference in New Issue
Block a user