From 4570c1cd4928a0fb5c9203fb669dedac465a6623 Mon Sep 17 00:00:00 2001 From: Carl Baldwin Date: Thu, 2 Jul 2015 21:43:25 +0000 Subject: [PATCH] Allow passing table argument to construct IpRouteCommand The various methods of IpRouteCommand also work with a non-default table. Instead of passing an explicit table argument to each command, this change allows constructing an instance of IpRouteCommand which always works on the given table much like we pass the namespace on creation instead of passing it to each command individually. Change-Id: I503aa986208347ccc1cb5f37bdb36f77553eee70 Partially-Implements: blueprint address-scopes --- neutron/agent/linux/ip_lib.py | 37 +++++++++++----- neutron/tests/unit/agent/linux/test_ip_lib.py | 44 +++++++++++++++++++ 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/neutron/agent/linux/ip_lib.py b/neutron/agent/linux/ip_lib.py index 890444a01..fb44c8a4c 100644 --- a/neutron/agent/linux/ip_lib.py +++ b/neutron/agent/linux/ip_lib.py @@ -464,6 +464,17 @@ class IpAddrCommand(IpDeviceCommandBase): class IpRouteCommand(IpDeviceCommandBase): COMMAND = 'route' + def __init__(self, parent, table=None): + super(IpRouteCommand, self).__init__(parent) + self._table = table + + def table(self, table): + """Return an instance of IpRouteCommand which works on given table""" + return IpRouteCommand(self._parent, table) + + def _table_args(self): + return ['table', self._table] if self._table else [] + def add_gateway(self, gateway, metric=None, table=None): ip_version = get_ip_version(gateway) args = ['replace', 'default', 'via', gateway] @@ -472,6 +483,8 @@ class IpRouteCommand(IpDeviceCommandBase): args += ['dev', self.name] if table: args += ['table', table] + else: + args += self._table_args() self._as_root([ip_version], tuple(args)) def delete_gateway(self, gateway, table=None): @@ -481,6 +494,8 @@ class IpRouteCommand(IpDeviceCommandBase): 'dev', self.name] if table: args += ['table', table] + else: + args += self._table_args() try: self._as_root([ip_version], tuple(args)) except RuntimeError as rte: @@ -492,10 +507,9 @@ class IpRouteCommand(IpDeviceCommandBase): def list_onlink_routes(self, ip_version): def iterate_routes(): - output = self._run([ip_version], - ('list', - 'dev', self.name, - 'scope', 'link')) + args = ['list', 'dev', self.name, 'scope', 'link'] + args += self._table_args() + output = self._run([ip_version], tuple(args)) for line in output.split('\n'): line = line.strip() if line and not line.count('src'): @@ -505,22 +519,21 @@ class IpRouteCommand(IpDeviceCommandBase): def add_onlink_route(self, cidr): ip_version = get_ip_version(cidr) - self._as_root([ip_version], - ('replace', cidr, - 'dev', self.name, - 'scope', 'link')) + args = ['replace', cidr, 'dev', self.name, 'scope', 'link'] + args += self._table_args() + self._as_root([ip_version], tuple(args)) def delete_onlink_route(self, cidr): ip_version = get_ip_version(cidr) - self._as_root([ip_version], - ('del', cidr, - 'dev', self.name, - 'scope', 'link')) + args = ['del', cidr, 'dev', self.name, 'scope', 'link'] + args += self._table_args() + self._as_root([ip_version], tuple(args)) def get_gateway(self, scope=None, filters=None, ip_version=None): options = [ip_version] if ip_version else [] args = ['list', 'dev', self.name] + args += self._table_args() if filters: args += filters diff --git a/neutron/tests/unit/agent/linux/test_ip_lib.py b/neutron/tests/unit/agent/linux/test_ip_lib.py index 42c3befa3..f48fe813d 100644 --- a/neutron/tests/unit/agent/linux/test_ip_lib.py +++ b/neutron/tests/unit/agent/linux/test_ip_lib.py @@ -799,6 +799,15 @@ class TestIpRouteCommand(TestIPCmdBase): 'dev', self.parent.name, 'table', self.table)) + def test_add_gateway_subtable(self): + self.route_cmd.table(self.table).add_gateway(self.gateway, self.metric) + self._assert_sudo([self.ip_version], + ('replace', 'default', + 'via', self.gateway, + 'metric', self.metric, + 'dev', self.parent.name, + 'table', self.table)) + def test_del_gateway_success(self): self.route_cmd.delete_gateway(self.gateway, table=self.table) self._assert_sudo([self.ip_version], @@ -807,6 +816,14 @@ class TestIpRouteCommand(TestIPCmdBase): 'dev', self.parent.name, 'table', self.table)) + def test_del_gateway_success_subtable(self): + self.route_cmd.table(table=self.table).delete_gateway(self.gateway) + self._assert_sudo([self.ip_version], + ('del', 'default', + 'via', self.gateway, + 'dev', self.parent.name, + 'table', self.table)) + def test_del_gateway_cannot_find_device(self): self.parent._as_root.side_effect = RuntimeError("Cannot find device") @@ -879,6 +896,33 @@ class TestIpRouteCommand(TestIPCmdBase): 'dev', self.parent.name, 'table', self.table)) + def test_list_onlink_routes_subtable(self): + self.parent._run.return_value = ( + "10.0.0.0/22\n" + "172.24.4.0/24 proto kernel src 172.24.4.2\n") + routes = self.route_cmd.table(self.table).list_onlink_routes( + self.ip_version) + self.assertEqual(['10.0.0.0/22'], routes) + self._assert_call([self.ip_version], + ('list', 'dev', self.parent.name, 'scope', 'link', + 'table', self.table)) + + def test_add_onlink_route_subtable(self): + self.route_cmd.table(self.table).add_onlink_route(self.cidr) + self._assert_sudo([self.ip_version], + ('replace', self.cidr, + 'dev', self.parent.name, + 'scope', 'link', + 'table', self.table)) + + def test_delete_onlink_route_subtable(self): + self.route_cmd.table(self.table).delete_onlink_route(self.cidr) + self._assert_sudo([self.ip_version], + ('del', self.cidr, + 'dev', self.parent.name, + 'scope', 'link', + 'table', self.table)) + class TestIPv6IpRouteCommand(TestIpRouteCommand): def setUp(self): -- 2.45.2