From 38a4ffbfe045b2658abaf9459b5c8ade1f3e5429 Mon Sep 17 00:00:00 2001 From: Brent Eagles Date: Wed, 9 Nov 2016 17:19:14 -0330 Subject: Add support for name replacement in OVS_EXTRA While primarily to work around a heat issue that prevents intrinsic functions from being used for parameters being passed to NetworkConfig resources, this could be generally useful in other ways. Partial-Bug: #1640812 Change-Id: Ie9001f1d41f514666a44c8d9295b78a13e2108dc --- os_net_config/objects.py | 24 ++++++++------- os_net_config/tests/test_impl_eni.py | 21 +++++++++++-- os_net_config/tests/test_impl_ifcfg.py | 16 ++++++++++ os_net_config/tests/test_objects.py | 54 ++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 13 deletions(-) (limited to 'os_net_config') diff --git a/os_net_config/objects.py b/os_net_config/objects.py index 8d7ee4c..330b695 100644 --- a/os_net_config/objects.py +++ b/os_net_config/objects.py @@ -131,6 +131,12 @@ def _mapped_nics(nic_mapping=None): return _MAPPED_NICS +def format_ovs_extra(obj, templates): + """Map OVS object properties into a string to be used for ovs_extra.""" + + return [t.format(name=obj.name) for t in templates or []] + + class Route(object): """Base class for network routes.""" @@ -395,7 +401,6 @@ class OvsBridge(_BaseOpts): addresses = addresses or [] routes = routes or [] members = members or [] - ovs_extra = ovs_extra or [] dns_servers = dns_servers or [] super(OvsBridge, self).__init__(name, use_dhcp, use_dhcpv6, addresses, routes, mtu, False, nic_mapping, @@ -403,7 +408,7 @@ class OvsBridge(_BaseOpts): dhclient_args, dns_servers) self.members = members self.ovs_options = ovs_options - self.ovs_extra = ovs_extra + self.ovs_extra = format_ovs_extra(self, ovs_extra) for member in self.members: member.bridge_name = name if not isinstance(member, OvsTunnel): @@ -460,7 +465,7 @@ class OvsUserBridge(_BaseOpts): dns_servers) self.members = members or [] self.ovs_options = ovs_options - self.ovs_extra = ovs_extra or [] + self.ovs_extra = format_ovs_extra(self, ovs_extra) for member in self.members: member.bridge_name = name if not isinstance(member, OvsTunnel) and \ @@ -808,7 +813,6 @@ class OvsBond(_BaseOpts): addresses = addresses or [] routes = routes or [] members = members or [] - ovs_extra = ovs_extra or [] dns_servers = dns_servers or [] super(OvsBond, self).__init__(name, use_dhcp, use_dhcpv6, addresses, routes, mtu, primary, nic_mapping, @@ -816,7 +820,7 @@ class OvsBond(_BaseOpts): dns_servers) self.members = members self.ovs_options = ovs_options - self.ovs_extra = ovs_extra + self.ovs_extra = format_ovs_extra(self, ovs_extra) for member in self.members: if member.primary: if self.primary_interface_name: @@ -870,7 +874,6 @@ class OvsTunnel(_BaseOpts): ovs_extra=None): addresses = addresses or [] routes = routes or [] - ovs_extra = ovs_extra or [] dns_servers = dns_servers or [] super(OvsTunnel, self).__init__(name, use_dhcp, use_dhcpv6, addresses, routes, mtu, primary, nic_mapping, @@ -878,7 +881,7 @@ class OvsTunnel(_BaseOpts): dhclient_args, dns_servers) self.tunnel_type = tunnel_type self.ovs_options = ovs_options or [] - self.ovs_extra = ovs_extra or [] + self.ovs_extra = format_ovs_extra(self, ovs_extra) @staticmethod def from_json(json): @@ -902,7 +905,6 @@ class OvsPatchPort(_BaseOpts): ovs_options=None, ovs_extra=None): addresses = addresses or [] routes = routes or [] - ovs_extra = ovs_extra or [] dns_servers = dns_servers or [] super(OvsPatchPort, self).__init__(name, use_dhcp, use_dhcpv6, addresses, routes, mtu, primary, @@ -912,7 +914,7 @@ class OvsPatchPort(_BaseOpts): self.bridge_name = bridge_name self.peer = peer self.ovs_options = ovs_options or [] - self.ovs_extra = ovs_extra or [] + self.ovs_extra = format_ovs_extra(self, ovs_extra) @staticmethod def from_json(json): @@ -967,7 +969,7 @@ class OvsDpdkPort(_BaseOpts): dns_servers) self.members = members or [] self.ovs_options = ovs_options or [] - self.ovs_extra = ovs_extra or [] + self.ovs_extra = format_ovs_extra(self, ovs_extra) self.driver = driver @staticmethod @@ -1024,7 +1026,7 @@ class OvsDpdkBond(_BaseOpts): defroute, dhclient_args, dns_servers) self.members = members or [] self.ovs_options = ovs_options - self.ovs_extra = ovs_extra or [] + self.ovs_extra = format_ovs_extra(self, ovs_extra) for member in self.members: if member.primary: diff --git a/os_net_config/tests/test_impl_eni.py b/os_net_config/tests/test_impl_eni.py index 5d3bb8c..086be95 100644 --- a/os_net_config/tests/test_impl_eni.py +++ b/os_net_config/tests/test_impl_eni.py @@ -72,7 +72,7 @@ _OVS_BRIDGE_DHCP_PRIMARY_INTERFACE = _OVS_BRIDGE_DHCP + \ _OVS_BRIDGE_DHCP_OVS_EXTRA = _OVS_BRIDGE_DHCP + \ " ovs_extra set bridge br0 other-config:hwaddr=a1:b2:c3:d4:e5" + \ - " -- br-set-external-id br-ctlplane bridge-id br-ctlplane\n" + " -- br-set-external-id br0 bridge-id br0\n" _VLAN_NO_IP = """auto vlan5 @@ -210,7 +210,24 @@ class TestENINetConfig(base.TestCase): self.stubs.Set(utils, 'interface_mac', test_interface_mac) interface = objects.Interface(self.if_name, primary=True) - ovs_extra = "br-set-external-id br-ctlplane bridge-id br-ctlplane" + ovs_extra = "br-set-external-id br0 bridge-id br0" + bridge = objects.OvsBridge('br0', use_dhcp=True, + members=[interface], + ovs_extra=[ovs_extra]) + self.provider.add_bridge(bridge) + self.provider.add_interface(interface) + self.assertEqual(_OVS_PORT_IFACE, self.get_interface_config()) + self.assertEqual(_OVS_BRIDGE_DHCP_OVS_EXTRA, + self.provider.bridges['br0']) + + def test_network_ovs_bridge_with_dhcp_and_primary_with_ovs_format(self): + + def test_interface_mac(name): + return "a1:b2:c3:d4:e5" + self.stubs.Set(utils, 'interface_mac', test_interface_mac) + + interface = objects.Interface(self.if_name, primary=True) + ovs_extra = "br-set-external-id {name} bridge-id {name}" bridge = objects.OvsBridge('br0', use_dhcp=True, members=[interface], ovs_extra=[ovs_extra]) diff --git a/os_net_config/tests/test_impl_ifcfg.py b/os_net_config/tests/test_impl_ifcfg.py index 2e79aa1..bfbe5b8 100644 --- a/os_net_config/tests/test_impl_ifcfg.py +++ b/os_net_config/tests/test_impl_ifcfg.py @@ -577,6 +577,22 @@ class TestIfcfgNetConfig(base.TestCase): self.assertEqual(_OVS_BRIDGE_DHCP_OVS_EXTRA, self.provider.bridge_data['br-ctlplane']) + def test_network_ovs_bridge_with_dhcp_primary_interface_with_format(self): + def test_interface_mac(name): + return "a1:b2:c3:d4:e5" + self.stubs.Set(utils, 'interface_mac', test_interface_mac) + + interface = objects.Interface('em1', primary=True) + ovs_extra = "br-set-external-id {name} bridge-id {name}" + bridge = objects.OvsBridge('br-ctlplane', use_dhcp=True, + members=[interface], + ovs_extra=[ovs_extra]) + self.provider.add_interface(interface) + self.provider.add_bridge(bridge) + self.assertEqual(_OVS_INTERFACE, self.get_interface_config()) + self.assertEqual(_OVS_BRIDGE_DHCP_OVS_EXTRA, + self.provider.bridge_data['br-ctlplane']) + def test_network_ivs_with_uplink_and_interface(self): interface = objects.Interface('em1') v4_addr = objects.Address('172.16.2.7/24') diff --git a/os_net_config/tests/test_objects.py b/os_net_config/tests/test_objects.py index 3911ef3..870a3e4 100644 --- a/os_net_config/tests/test_objects.py +++ b/os_net_config/tests/test_objects.py @@ -646,6 +646,42 @@ class TestOvsTunnel(base.TestCase): ["ovs extra"], tun0.ovs_extra) + def test_ovs_extra_formatting(self): + data = """{ +"type": "ovs_bridge", +"name": "br-foo", +"ovs_extra": [ + "set {name} fail_mode=standalone" +], +"members": [{ + "type": "ovs_tunnel", + "name": "tun0", + "tunnel_type": "gre", + "ovs_options": [ + "remote_ip=192.168.1.1" + ], + "ovs_extra": [ + "ovs extra", + "ovs {name} extra" + ] +}] +} +""" + bridge = objects.object_from_json(json.loads(data)) + self.assertEqual("br-foo", bridge.name) + self.assertEqual(["set br-foo fail_mode=standalone"], bridge.ovs_extra) + tun0 = bridge.members[0] + self.assertEqual("tun0", tun0.name) + self.assertFalse(tun0.ovs_port) + self.assertEqual("br-foo", tun0.bridge_name) + self.assertEqual("gre", tun0.tunnel_type) + self.assertEqual( + ["options:remote_ip=192.168.1.1"], + tun0.ovs_options) + self.assertEqual( + ["ovs extra", "ovs tun0 extra"], + tun0.ovs_extra) + class TestOvsPatchPort(base.TestCase): @@ -662,6 +698,24 @@ class TestOvsPatchPort(base.TestCase): self.assertEqual("br-ex", patch_port.bridge_name) self.assertEqual("br-ex-patch", patch_port.peer) + def test_from_json_with_extra(self): + data = """{ +"type": "ovs_patch_port", +"name": "br-pub-patch", +"bridge_name": "br-ex", +"peer": "br-ex-patch", +"ovs_extra": [ + "ovs {name} extra" +] +} +""" + patch_port = objects.object_from_json(json.loads(data)) + self.assertEqual(["ovs br-pub-patch extra"], + patch_port.ovs_extra) + self.assertEqual("br-pub-patch", patch_port.name) + self.assertEqual("br-ex", patch_port.bridge_name) + self.assertEqual("br-ex-patch", patch_port.peer) + class TestIbInterface(base.TestCase): -- cgit 1.2.3-korg