aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Flusche <mflusche@redhat.com>2016-10-19 18:10:08 +0000
committerMatthew Flusche <mflusche@redhat.com>2016-10-19 22:19:17 +0000
commit4fdb0a6a2b355750ae8071e53a74b9257b18eeee (patch)
tree44ea7032fa922ec7dc4181b5512901da5917a99b
parent191a3b042cf303d70df5badefe9defe81ae4bd6d (diff)
Add route_options parameter
route_options will append additional options to route definitions. Change-Id: I2b70efdd9c6df7ea252576e245fbc0e9c46ea4bd
-rw-r--r--etc/os-net-config/samples/interface.json5
-rw-r--r--etc/os-net-config/samples/interface.yaml6
-rw-r--r--os_net_config/impl_eni.py11
-rw-r--r--os_net_config/impl_ifcfg.py25
-rw-r--r--os_net_config/objects.py7
-rw-r--r--os_net_config/tests/test_impl_eni.py18
-rw-r--r--os_net_config/tests/test_impl_ifcfg.py33
-rw-r--r--os_net_config/tests/test_objects.py18
8 files changed, 87 insertions, 36 deletions
diff --git a/etc/os-net-config/samples/interface.json b/etc/os-net-config/samples/interface.json
index 8a942b5..9ae0b76 100644
--- a/etc/os-net-config/samples/interface.json
+++ b/etc/os-net-config/samples/interface.json
@@ -13,6 +13,11 @@
"ip_netmask": "0.0.0.0/0",
"next_hop": "192.0.2.254",
"default": "true"
+ },
+ {
+ "ip_netmask": "10.1.2.0/24",
+ "next_hop": "192.0.2.5",
+ "route_options": "metric 10"
}
]
},
diff --git a/etc/os-net-config/samples/interface.yaml b/etc/os-net-config/samples/interface.yaml
index 4f76e07..6b366e2 100644
--- a/etc/os-net-config/samples/interface.yaml
+++ b/etc/os-net-config/samples/interface.yaml
@@ -11,8 +11,12 @@ network_config:
ip_netmask: 0.0.0.0/0
next_hop: 192.0.2.254
default: true
+ -
+ ip_netmask: 10.1.2.0/24
+ next_hop: 192.0.2.5
+ route_options: "metric 10"
-
type: interface
name: em2
use_dhcp: true
- defroute: no \ No newline at end of file
+ defroute: no
diff --git a/os_net_config/impl_eni.py b/os_net_config/impl_eni.py
index ae60099..1d59b57 100644
--- a/os_net_config/impl_eni.py
+++ b/os_net_config/impl_eni.py
@@ -181,14 +181,17 @@ class ENINetConfig(os_net_config.NetConfig):
logger.info('adding custom route for interface: %s' % interface_name)
data = ""
for route in routes:
+ options = ""
+ if route.route_options:
+ options = " %s" % (route.route_options)
if route.default and not route.ip_netmask:
rt = netaddr.IPNetwork("0.0.0.0/0")
else:
rt = netaddr.IPNetwork(route.ip_netmask)
- data += "up route add -net %s netmask %s gw %s\n" % (
- str(rt.ip), str(rt.netmask), route.next_hop)
- data += "down route del -net %s netmask %s gw %s\n" % (
- str(rt.ip), str(rt.netmask), route.next_hop)
+ data += "up route add -net %s netmask %s gw %s%s\n" % (
+ str(rt.ip), str(rt.netmask), route.next_hop, options)
+ data += "down route del -net %s netmask %s gw %s%s\n" % (
+ str(rt.ip), str(rt.netmask), route.next_hop, options)
self.routes[interface_name] = data
logger.debug('route data: %s' % self.routes[interface_name])
diff --git a/os_net_config/impl_ifcfg.py b/os_net_config/impl_ifcfg.py
index 56f2b33..4a4caaa 100644
--- a/os_net_config/impl_ifcfg.py
+++ b/os_net_config/impl_ifcfg.py
@@ -313,24 +313,29 @@ class IfcfgNetConfig(os_net_config.NetConfig):
data6 = ""
first_line6 = ""
for route in routes:
+ options = ""
+ if route.route_options:
+ options = " %s" % (route.route_options)
if ":" not in route.next_hop:
# Route is an IPv4 route
if route.default:
- first_line = "default via %s dev %s\n" % (route.next_hop,
- interface_name)
+ first_line = "default via %s dev %s%s\n" % (
+ route.next_hop, interface_name,
+ options)
else:
- data += "%s via %s dev %s\n" % (route.ip_netmask,
- route.next_hop,
- interface_name)
+ data += "%s via %s dev %s%s\n" % (
+ route.ip_netmask, route.next_hop,
+ interface_name, options)
else:
# Route is an IPv6 route
if route.default:
- first_line6 = "default via %s dev %s\n" % (route.next_hop,
- interface_name)
+ first_line6 = "default via %s dev %s%s\n" % (
+ route.next_hop, interface_name,
+ options)
else:
- data6 += "%s via %s dev %s\n" % (route.ip_netmask,
- route.next_hop,
- interface_name)
+ data6 += "%s via %s dev %s%s\n" % (
+ route.ip_netmask, route.next_hop,
+ interface_name, options)
self.route_data[interface_name] = first_line + data
self.route6_data[interface_name] = first_line6 + data6
logger.debug('route data: %s' % self.route_data[interface_name])
diff --git a/os_net_config/objects.py b/os_net_config/objects.py
index 3c67ada..0e5ce08 100644
--- a/os_net_config/objects.py
+++ b/os_net_config/objects.py
@@ -134,17 +134,20 @@ def _mapped_nics(nic_mapping=None):
class Route(object):
"""Base class for network routes."""
- def __init__(self, next_hop, ip_netmask="", default=False):
+ def __init__(self, next_hop, ip_netmask="", default=False,
+ route_options=""):
self.next_hop = next_hop
self.ip_netmask = ip_netmask
self.default = default
+ self.route_options = route_options
@staticmethod
def from_json(json):
next_hop = _get_required_field(json, 'next_hop', 'Route')
ip_netmask = json.get('ip_netmask', "")
+ route_options = json.get('route_options', "")
default = strutils.bool_from_string(str(json.get('default', False)))
- return Route(next_hop, ip_netmask, default)
+ return Route(next_hop, ip_netmask, default, route_options)
class Address(object):
diff --git a/os_net_config/tests/test_impl_eni.py b/os_net_config/tests/test_impl_eni.py
index 7f909ff..5d3bb8c 100644
--- a/os_net_config/tests/test_impl_eni.py
+++ b/os_net_config/tests/test_impl_eni.py
@@ -90,6 +90,8 @@ iface vlan5 inet manual
_RTS = """up route add -net 172.19.0.0 netmask 255.255.255.0 gw 192.168.1.1
down route del -net 172.19.0.0 netmask 255.255.255.0 gw 192.168.1.1
+up route add -net 172.20.0.0 netmask 255.255.255.0 gw 192.168.1.5 metric 100
+down route del -net 172.20.0.0 netmask 255.255.255.0 gw 192.168.1.5 metric 100
"""
@@ -169,8 +171,10 @@ class TestENINetConfig(base.TestCase):
def test_network_with_routes(self):
route1 = objects.Route('192.168.1.1', '172.19.0.0/24')
+ route2 = objects.Route('192.168.1.5', '172.20.0.0/24',
+ route_options="metric 100")
v4_addr = objects.Address('192.168.1.2/24')
- interface = self._default_interface([v4_addr], [route1])
+ interface = self._default_interface([v4_addr], [route1, route2])
self.provider.add_interface(interface)
self.assertEqual(_V4_IFACE_STATIC_IP, self.get_interface_config())
self.assertEqual(_RTS, self.get_route_config())
@@ -261,10 +265,12 @@ class TestENINetConfigApply(base.TestCase):
super(TestENINetConfigApply, self).tearDown()
def test_network_apply(self):
- route = objects.Route('192.168.1.1', '172.19.0.0/24')
+ route1 = objects.Route('192.168.1.1', '172.19.0.0/24')
+ route2 = objects.Route('192.168.1.5', '172.20.0.0/24',
+ route_options="metric 100")
v4_addr = objects.Address('192.168.1.2/24')
interface = objects.Interface('eth0', addresses=[v4_addr],
- routes=[route])
+ routes=[route1, route2])
self.provider.add_interface(interface)
self.provider.apply()
@@ -273,10 +279,12 @@ class TestENINetConfigApply(base.TestCase):
self.assertIn('eth0', self.ifup_interface_names)
def test_apply_noactivate(self):
- route = objects.Route('192.168.1.1', '172.19.0.0/24')
+ route1 = objects.Route('192.168.1.1', '172.19.0.0/24')
+ route2 = objects.Route('192.168.1.5', '172.20.0.0/24',
+ route_options="metric 100")
v4_addr = objects.Address('192.168.1.2/24')
interface = objects.Interface('eth0', addresses=[v4_addr],
- routes=[route])
+ routes=[route1, route2])
self.provider.add_interface(interface)
self.provider.apply(activate=False)
diff --git a/os_net_config/tests/test_impl_ifcfg.py b/os_net_config/tests/test_impl_ifcfg.py
index 8586daa..0c14418 100644
--- a/os_net_config/tests/test_impl_ifcfg.py
+++ b/os_net_config/tests/test_impl_ifcfg.py
@@ -115,12 +115,14 @@ _OVS_BRIDGE_IFCFG = _BASE_IFCFG + "DEVICETYPE=ovs\n"
_LINUX_BRIDGE_IFCFG = _BASE_IFCFG + "BRIDGE=br-ctlplane\nBOOTPROTO=none\n"
-_ROUTES = """default via 192.168.1.1 dev em1
+_ROUTES = """default via 192.168.1.1 dev em1 metric 10
172.19.0.0/24 via 192.168.1.1 dev em1
+172.20.0.0/24 via 192.168.1.5 dev em1 metric 100
"""
_ROUTES_V6 = """default via 2001:db8::1 dev em1
2001:db8:dead:beef:cafe::/56 via fd00:fd00:2000::1 dev em1
+2001:db8:dead:beff::/64 via fd00:fd00:2000::1 dev em1 metric 100
"""
@@ -454,25 +456,35 @@ class TestIfcfgNetConfig(base.TestCase):
self.assertEqual(_V6_IFCFG_MULTIPLE, self.get_interface_config())
def test_network_with_routes(self):
- route1 = objects.Route('192.168.1.1', default=True)
+ route1 = objects.Route('192.168.1.1', default=True,
+ route_options="metric 10")
route2 = objects.Route('192.168.1.1', '172.19.0.0/24')
+ route3 = objects.Route('192.168.1.5', '172.20.0.0/24',
+ route_options="metric 100")
v4_addr = objects.Address('192.168.1.2/24')
interface = objects.Interface('em1', addresses=[v4_addr],
- routes=[route1, route2])
+ routes=[route1, route2, route3])
self.provider.add_interface(interface)
self.assertEqual(_V4_IFCFG, self.get_interface_config())
self.assertEqual(_ROUTES, self.get_route_config())
def test_network_with_ipv6_routes(self):
- route1 = objects.Route('192.168.1.1', default=True)
+ route1 = objects.Route('192.168.1.1', default=True,
+ route_options="metric 10")
route2 = objects.Route('192.168.1.1', '172.19.0.0/24')
- route3 = objects.Route('2001:db8::1', default=True)
- route4 = objects.Route('fd00:fd00:2000::1',
+ route3 = objects.Route('192.168.1.5', '172.20.0.0/24',
+ route_options="metric 100")
+ route4 = objects.Route('2001:db8::1', default=True)
+ route5 = objects.Route('fd00:fd00:2000::1',
'2001:db8:dead:beef:cafe::/56')
+ route6 = objects.Route('fd00:fd00:2000::1',
+ '2001:db8:dead:beff::/64',
+ route_options="metric 100")
v4_addr = objects.Address('192.168.1.2/24')
v6_addr = objects.Address('2001:abc:a::/64')
interface = objects.Interface('em1', addresses=[v4_addr, v6_addr],
- routes=[route1, route2, route3, route4])
+ routes=[route1, route2, route3,
+ route4, route5, route6])
self.provider.add_interface(interface)
self.assertEqual(_V4_V6_IFCFG, self.get_interface_config())
self.assertEqual(_ROUTES_V6, self.get_route6_config())
@@ -884,11 +896,14 @@ class TestIfcfgNetConfigApply(base.TestCase):
super(TestIfcfgNetConfigApply, self).tearDown()
def test_network_apply(self):
- route1 = objects.Route('192.168.1.1', default=True)
+ route1 = objects.Route('192.168.1.1', default=True,
+ route_options="metric 10")
route2 = objects.Route('192.168.1.1', '172.19.0.0/24')
+ route3 = objects.Route('192.168.1.5', '172.20.0.0/24',
+ route_options="metric 100")
v4_addr = objects.Address('192.168.1.2/24')
interface = objects.Interface('em1', addresses=[v4_addr],
- routes=[route1, route2])
+ routes=[route1, route2, route3])
self.provider.add_interface(interface)
self.provider.apply()
diff --git a/os_net_config/tests/test_objects.py b/os_net_config/tests/test_objects.py
index 7500392..4c71265 100644
--- a/os_net_config/tests/test_objects.py
+++ b/os_net_config/tests/test_objects.py
@@ -25,26 +25,30 @@ from os_net_config import utils
class TestRoute(base.TestCase):
def test_from_json(self):
- data = '{"next_hop": "172.19.0.1", "ip_netmask": "172.19.0.0/24"}'
+ data = '{"next_hop": "172.19.0.1", "ip_netmask": "172.19.0.0/24", ' \
+ '"route_options": "metric 10"}'
route = objects.Route.from_json(json.loads(data))
self.assertEqual("172.19.0.1", route.next_hop)
self.assertEqual("172.19.0.0/24", route.ip_netmask)
self.assertFalse(route.default)
+ self.assertEqual("metric 10", route.route_options)
def test_from_json_default_route(self):
data = '{"next_hop": "172.19.0.1", "ip_netmask": "172.19.0.0/24", ' \
- '"default": true}'
+ '"default": true, "route_options": "metric 10"}'
route = objects.Route.from_json(json.loads(data))
self.assertEqual("172.19.0.1", route.next_hop)
self.assertEqual("172.19.0.0/24", route.ip_netmask)
self.assertTrue(route.default)
+ self.assertEqual("metric 10", route.route_options)
data = '{"next_hop": "172.19.0.1", "ip_netmask": "172.19.0.0/24", ' \
- '"default": "true"}'
+ '"default": "true", "route_options": "metric 10"}'
route = objects.Route.from_json(json.loads(data))
self.assertEqual("172.19.0.1", route.next_hop)
self.assertEqual("172.19.0.0/24", route.ip_netmask)
self.assertTrue(route.default)
+ self.assertEqual("metric 10", route.route_options)
class TestAddress(base.TestCase):
@@ -151,7 +155,8 @@ class TestInterface(base.TestCase):
}],
"routes": [{
"next_hop": "192.0.2.1",
- "ip_netmask": "192.0.2.1/24"
+ "ip_netmask": "192.0.2.1/24",
+ "route_options": "metric 10"
}]
}
"""
@@ -166,6 +171,7 @@ class TestInterface(base.TestCase):
route1 = interface.routes[0]
self.assertEqual("192.0.2.1", route1.next_hop)
self.assertEqual("192.0.2.1/24", route1.ip_netmask)
+ self.assertEqual("metric 10", route1.route_options)
class TestVlan(base.TestCase):
@@ -727,7 +733,8 @@ class TestIbInterface(base.TestCase):
}],
"routes": [{
"next_hop": "192.0.2.1",
- "ip_netmask": "192.0.2.1/24"
+ "ip_netmask": "192.0.2.1/24",
+ "route_options": "metric 10"
}]
}
"""
@@ -742,6 +749,7 @@ class TestIbInterface(base.TestCase):
route1 = ib_interface.routes[0]
self.assertEqual("192.0.2.1", route1.next_hop)
self.assertEqual("192.0.2.1/24", route1.ip_netmask)
+ self.assertEqual("metric 10", route1.route_options)
class TestNicMapping(base.TestCase):