Merge "Refactor ensure_routing_table_for_bridge"
This commit is contained in:
commit
2fcf3a4c48
@ -109,3 +109,8 @@ ROUTE_DISCARD = 'discard'
|
|||||||
# Family constants
|
# Family constants
|
||||||
AF_INET = socket.AF_INET
|
AF_INET = socket.AF_INET
|
||||||
AF_INET6 = socket.AF_INET6
|
AF_INET6 = socket.AF_INET6
|
||||||
|
|
||||||
|
# Path to file containing routing tables
|
||||||
|
ROUTING_TABLES_FILE = '/etc/iproute2/rt_tables'
|
||||||
|
ROUTING_TABLE_MIN = 1
|
||||||
|
ROUTING_TABLE_MAX = 252
|
||||||
|
@ -184,12 +184,6 @@ class TestLinuxNet(test_base.TestCase):
|
|||||||
mock_ndp.assert_called_once_with('fake-bridge')
|
mock_ndp.assert_called_once_with('fake-bridge')
|
||||||
mock_arp.assert_called_once_with('fake-bridge')
|
mock_arp.assert_called_once_with('fake-bridge')
|
||||||
|
|
||||||
def test_ensure_routing_table_for_bridge(self):
|
|
||||||
# TODO(lucasagomes): This method is massive and complex, perhaps
|
|
||||||
# break it into helper methods for both readibility and maintenance
|
|
||||||
# of it.
|
|
||||||
pass
|
|
||||||
|
|
||||||
@mock.patch.object(linux_net, 'enable_proxy_arp')
|
@mock.patch.object(linux_net, 'enable_proxy_arp')
|
||||||
@mock.patch.object(linux_net, 'enable_proxy_ndp')
|
@mock.patch.object(linux_net, 'enable_proxy_ndp')
|
||||||
@mock.patch(
|
@mock.patch(
|
||||||
@ -780,3 +774,78 @@ class TestLinuxNet(test_base.TestCase):
|
|||||||
|
|
||||||
self.assertEqual({self.dev: []}, routes)
|
self.assertEqual({self.dev: []}, routes)
|
||||||
mock_route_delete.assert_called_once_with(route)
|
mock_route_delete.assert_called_once_with(route)
|
||||||
|
|
||||||
|
|
||||||
|
class TestEnsureRoutingTableForBridge(test_base.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
self.ovn_routing_tables = {}
|
||||||
|
self.bridge_name = "br-test"
|
||||||
|
self.vrf_table = 4
|
||||||
|
self.generated_number = 2
|
||||||
|
|
||||||
|
self.testing_multiline_file_content = [
|
||||||
|
"1 foo",
|
||||||
|
"# commented line",
|
||||||
|
"random garbage text",
|
||||||
|
"3 another bridge",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
|
||||||
|
self.m_ensure_rt_routes = mock.patch.object(
|
||||||
|
linux_net, '_ensure_routing_table_routes').start()
|
||||||
|
|
||||||
|
# The 'random' generator will always generate number 2 because the
|
||||||
|
# range is 1-4 while 1 and 3 are used in the file and 4 is the vrf
|
||||||
|
mock.patch.object(constants, 'ROUTING_TABLE_MIN', 1).start()
|
||||||
|
mock.patch.object(constants, 'ROUTING_TABLE_MAX', 4).start()
|
||||||
|
|
||||||
|
def _create_fake_file_content(self):
|
||||||
|
return "\n".join(self.testing_multiline_file_content)
|
||||||
|
|
||||||
|
def test_ensure_routing_table_for_bridge_table_missing(self):
|
||||||
|
self._test_ensure_routing_table_for_bridge_table_missing()
|
||||||
|
|
||||||
|
def _test_ensure_routing_table_for_bridge_table_missing(self):
|
||||||
|
with mock.patch(
|
||||||
|
'builtins.open',
|
||||||
|
mock.mock_open(read_data=self._create_fake_file_content())):
|
||||||
|
linux_net.ensure_routing_table_for_bridge(
|
||||||
|
self.ovn_routing_tables, self.bridge_name, self.vrf_table)
|
||||||
|
|
||||||
|
self.assertDictEqual(
|
||||||
|
{self.bridge_name: self.generated_number}, self.ovn_routing_tables)
|
||||||
|
|
||||||
|
def test_ensure_routing_table_for_bridge_table_present(self):
|
||||||
|
present_bridge_value = 5
|
||||||
|
self.testing_multiline_file_content.insert(
|
||||||
|
2, "%d %s" % (present_bridge_value, self.bridge_name))
|
||||||
|
|
||||||
|
with mock.patch(
|
||||||
|
'builtins.open',
|
||||||
|
mock.mock_open(read_data=self._create_fake_file_content())):
|
||||||
|
linux_net.ensure_routing_table_for_bridge(
|
||||||
|
self.ovn_routing_tables, self.bridge_name, self.vrf_table)
|
||||||
|
|
||||||
|
self.assertDictEqual(
|
||||||
|
{self.bridge_name: present_bridge_value}, self.ovn_routing_tables)
|
||||||
|
|
||||||
|
def test_ensure_routing_table_for_bridge_table_vrf_not_generated(self):
|
||||||
|
self.vrf_table = 2
|
||||||
|
self.generated_number = 4
|
||||||
|
self._test_ensure_routing_table_for_bridge_table_missing()
|
||||||
|
|
||||||
|
def test_ensure_routing_table_for_bridge_tables_depleted(self):
|
||||||
|
present_bridge_value = 2
|
||||||
|
self.testing_multiline_file_content.insert(
|
||||||
|
2, "%d %s" % (present_bridge_value, "foo"))
|
||||||
|
|
||||||
|
with mock.patch(
|
||||||
|
'builtins.open',
|
||||||
|
mock.mock_open(read_data=self._create_fake_file_content())):
|
||||||
|
self.assertRaises(
|
||||||
|
SystemExit,
|
||||||
|
linux_net.ensure_routing_table_for_bridge,
|
||||||
|
self.ovn_routing_tables, self.bridge_name, self.vrf_table)
|
||||||
|
|
||||||
|
self.assertDictEqual({}, self.ovn_routing_tables)
|
||||||
|
@ -30,6 +30,8 @@ from ovn_bgp_agent.utils import common as common_utils
|
|||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
RE_TABLE_ROW = re.compile(r"^(?P<table>[0-9]+)\s+(?P<bridge>\S+)")
|
||||||
|
|
||||||
|
|
||||||
def get_ip_version(ip):
|
def get_ip_version(ip):
|
||||||
# IP network can consume both an IP address and a network with cidr
|
# IP network can consume both an IP address and a network with cidr
|
||||||
@ -157,38 +159,39 @@ def ensure_arp_ndp_enabled_for_bridge(bridge, offset, vlan_tag=None):
|
|||||||
def ensure_routing_table_for_bridge(ovn_routing_tables, bridge, vrf_table):
|
def ensure_routing_table_for_bridge(ovn_routing_tables, bridge, vrf_table):
|
||||||
# check a routing table with the bridge name exists on
|
# check a routing table with the bridge name exists on
|
||||||
# /etc/iproute2/rt_tables
|
# /etc/iproute2/rt_tables
|
||||||
regex = r'^[0-9]*[\s]*{}$'.format(bridge)
|
found_tables = {vrf_table}
|
||||||
matching_table = [line.replace('\t', ' ')
|
|
||||||
for line in open('/etc/iproute2/rt_tables')
|
with open(constants.ROUTING_TABLES_FILE, 'r') as rt_file:
|
||||||
if re.findall(regex, line)]
|
for line in rt_file.readlines():
|
||||||
if matching_table:
|
match = RE_TABLE_ROW.match(line)
|
||||||
table_info = matching_table[0].strip().split()
|
if match:
|
||||||
ovn_routing_tables[table_info[1]] = int(table_info[0])
|
if match.group('bridge') == bridge:
|
||||||
LOG.debug("Found routing table for %s with: %s", bridge,
|
# We don't need to catch exception for TypeError because
|
||||||
table_info)
|
# the regular expression matches only integers
|
||||||
# if not configured, add random number for the table
|
ovn_routing_tables[match.group('bridge')] = int(
|
||||||
|
match.group('table'))
|
||||||
|
LOG.debug("Found routing table for %s with: %s",
|
||||||
|
bridge, match.group('table'))
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
LOG.debug("Routing table for bridge %s not configured "
|
found_tables.add(int(match.group('table')))
|
||||||
"at /etc/iproute2/rt_tables", bridge)
|
else:
|
||||||
regex = r'^[0-9]+[\s]*'
|
LOG.debug("Routing table for bridge %s not configured at ", bridge)
|
||||||
existing_routes = [int(line.replace('\t', ' ').split(' ')[0])
|
|
||||||
for line in open('/etc/iproute2/rt_tables')
|
|
||||||
if re.findall(regex, line)]
|
|
||||||
# pick a number between 1 and 252
|
|
||||||
try:
|
try:
|
||||||
table_number = random.choice(list(
|
routing_table_range = set(
|
||||||
{x for x in range(1, 253) if x != int(vrf_table)}.difference(
|
range(constants.ROUTING_TABLE_MIN,
|
||||||
set(existing_routes))))
|
constants.ROUTING_TABLE_MAX + 1))
|
||||||
|
table_number = random.choice(
|
||||||
|
list(routing_table_range - found_tables))
|
||||||
except IndexError:
|
except IndexError:
|
||||||
LOG.error("No more routing tables available for bridge %s "
|
LOG.error("No more routing tables available for bridge %s "
|
||||||
"at /etc/iproute2/rt_tables", bridge)
|
"at %s", constants.ROUTING_TABLES_FILE, bridge)
|
||||||
sys.exit()
|
sys.exit(1)
|
||||||
|
|
||||||
ovn_bgp_agent.privileged.linux_net.create_routing_table_for_bridge(
|
ovn_bgp_agent.privileged.linux_net.create_routing_table_for_bridge(
|
||||||
table_number, bridge)
|
table_number, bridge)
|
||||||
ovn_routing_tables[bridge] = int(table_number)
|
ovn_routing_tables[bridge] = int(table_number)
|
||||||
LOG.debug("Added routing table for %s with number: %s", bridge,
|
LOG.debug("Added routing table for %s with number: %s",
|
||||||
table_number)
|
bridge, table_number)
|
||||||
|
|
||||||
return _ensure_routing_table_routes(ovn_routing_tables, bridge)
|
return _ensure_routing_table_routes(ovn_routing_tables, bridge)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user