aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2016-07-05 09:15:23 +0000
committerGerrit Code Review <review@openstack.org>2016-07-05 09:15:23 +0000
commit6bb8412ef3d3f163d91f2884081b743f07a78f18 (patch)
tree32e7e4eff7683febce73b771d5bf2eaec8f0539c
parentf742dcbda0d92bee0278b4a1614d65f2ad5b1a78 (diff)
parent789bd1ea089314b49db02ddd517809a82c380cf1 (diff)
Merge "Add support for OVS patch ports"
-rw-r--r--etc/os-net-config/samples/ovs_patch_port.json37
-rw-r--r--etc/os-net-config/samples/ovs_patch_port.yaml23
-rw-r--r--os_net_config/__init__.py9
-rw-r--r--os_net_config/impl_ifcfg.py17
-rw-r--r--os_net_config/objects.py37
-rw-r--r--os_net_config/tests/test_impl_ifcfg.py21
-rw-r--r--os_net_config/tests/test_objects.py16
7 files changed, 160 insertions, 0 deletions
diff --git a/etc/os-net-config/samples/ovs_patch_port.json b/etc/os-net-config/samples/ovs_patch_port.json
new file mode 100644
index 0000000..d457371
--- /dev/null
+++ b/etc/os-net-config/samples/ovs_patch_port.json
@@ -0,0 +1,37 @@
+{
+ "network_config": [
+ {
+ "name": "br-ctlplane",
+ "type": "ovs_bridge",
+ "members": [
+ {
+ "mtu": 1500,
+ "primary": "true",
+ "name": "eth1",
+ "type": "interface"
+ }
+ ],
+ "ovs_extra": [
+ "br-set-external-id br-ctlplane bridge-id br-ctlplane"
+ ],
+ "mtu": 1500,
+ "addresses": [
+ {
+ "ip_netmask": "192.0.2.1/24"
+ }
+ ]
+ },
+ {
+ "name": "br_pub-patch",
+ "type": "ovs_patch_port",
+ "bridge_name": "br-ctlplane",
+ "peer": "br-ctlplane-patch"
+ },
+ {
+ "name": "br-ctlplane-patch",
+ "type": "ovs_patch_port",
+ "bridge_name": "br_pub",
+ "peer": "br_pub-patch"
+ }
+ ]
+}
diff --git a/etc/os-net-config/samples/ovs_patch_port.yaml b/etc/os-net-config/samples/ovs_patch_port.yaml
new file mode 100644
index 0000000..91858be
--- /dev/null
+++ b/etc/os-net-config/samples/ovs_patch_port.yaml
@@ -0,0 +1,23 @@
+network_config:
+ -
+ type: ovs_bridge
+ name: br-ctlplane
+ mtu: 1500
+ members:
+ -
+ type: interface
+ name: eth1
+ # force the MAC address of the bridge to this interface
+ primary: true
+ mtu: 1500
+ ovs_extra: "br-set-external-id br-ctlplane bridge-id br-ctlplane"
+ -
+ type: ovs_patch_port
+ name: br_pub-patch
+ bridge_name: br-ctlplane
+ peer: br-ctlplane-patch
+ -
+ type: ovs_patch_port
+ name: br-ctlplane-patch
+ bridge_name: br_pub
+ peer: br_pub-patch
diff --git a/os_net_config/__init__.py b/os_net_config/__init__.py
index 700a09d..88e8900 100644
--- a/os_net_config/__init__.py
+++ b/os_net_config/__init__.py
@@ -73,6 +73,8 @@ class NetConfig(object):
self.add_object(member)
elif isinstance(obj, objects.OvsTunnel):
self.add_ovs_tunnel(obj)
+ elif isinstance(obj, objects.OvsPatchPort):
+ self.add_ovs_patch_port(obj)
def add_interface(self, interface):
"""Add an Interface object to the net config object.
@@ -130,6 +132,13 @@ class NetConfig(object):
"""
raise NotImplemented("add_ovs_tunnel is not implemented.")
+ def add_ovs_patch_port(self, ovs_patch_port):
+ """Add a OvsPatchPort object to the net config object.
+
+ :param ovs_patch_port: The OvsPatchPort object to add.
+ """
+ raise NotImplemented("add_ovs_patch_port is not implemented.")
+
def apply(self, cleanup=False):
"""Apply the network configuration.
diff --git a/os_net_config/impl_ifcfg.py b/os_net_config/impl_ifcfg.py
index f6b4617..fbd1c3a 100644
--- a/os_net_config/impl_ifcfg.py
+++ b/os_net_config/impl_ifcfg.py
@@ -185,11 +185,18 @@ class IfcfgNetConfig(os_net_config.NetConfig):
data += "OVS_TUNNEL_TYPE=%s\n" % base_opt.tunnel_type
data += "OVS_TUNNEL_OPTIONS=\"%s\"\n" % \
' '.join(base_opt.ovs_options)
+ elif isinstance(base_opt, objects.OvsPatchPort):
+ ovs_extra.extend(base_opt.ovs_extra)
+ data += "DEVICETYPE=ovs\n"
+ data += "TYPE=OVSPatchPort\n"
+ data += "OVS_BRIDGE=%s\n" % base_opt.bridge_name
+ data += "OVS_PATCH_PEER=%s\n" % base_opt.peer
else:
if base_opt.use_dhcp:
data += "BOOTPROTO=dhcp\n"
elif not base_opt.addresses:
data += "BOOTPROTO=none\n"
+
if base_opt.mtu:
data += "MTU=%i\n" % base_opt.mtu
if base_opt.use_dhcpv6 or base_opt.v6_addresses():
@@ -374,6 +381,16 @@ class IfcfgNetConfig(os_net_config.NetConfig):
logger.debug('ovs tunnel data: %s' % data)
self.interface_data[tunnel.name] = data
+ def add_ovs_patch_port(self, ovs_patch_port):
+ """Add a OvsPatchPort object to the net config object.
+
+ :param ovs_patch_port: The OvsPatchPort object to add.
+ """
+ logger.info('adding ovs patch port: %s' % ovs_patch_port.name)
+ data = self._add_common(ovs_patch_port)
+ logger.debug('ovs patch port data: %s' % data)
+ self.interface_data[ovs_patch_port.name] = data
+
def generate_ivs_config(self, ivs_uplinks, ivs_interfaces):
"""Generate configuration content for ivs."""
diff --git a/os_net_config/objects.py b/os_net_config/objects.py
index 2958f84..9815832 100644
--- a/os_net_config/objects.py
+++ b/os_net_config/objects.py
@@ -50,6 +50,8 @@ def object_from_json(json):
return IvsInterface.from_json(json)
elif obj_type == "ovs_tunnel":
return OvsTunnel.from_json(json)
+ elif obj_type == "ovs_patch_port":
+ return OvsPatchPort.from_json(json)
def _get_required_field(json, name, object_name):
@@ -652,3 +654,38 @@ class OvsTunnel(_BaseOpts):
opts = _BaseOpts.base_opts_from_json(json)
return OvsTunnel(name, *opts, tunnel_type=tunnel_type,
ovs_options=ovs_options, ovs_extra=ovs_extra)
+
+
+class OvsPatchPort(_BaseOpts):
+ """Base class for OVS Patch Ports."""
+
+ def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None,
+ routes=None, mtu=None, primary=False, nic_mapping=None,
+ persist_mapping=False, defroute=True, dhclient_args=None,
+ dns_servers=None, bridge_name=None, peer=None,
+ 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,
+ nic_mapping, persist_mapping,
+ defroute, dhclient_args,
+ dns_servers)
+ self.bridge_name = bridge_name
+ self.peer = peer
+ self.ovs_options = ovs_options or []
+ self.ovs_extra = ovs_extra or []
+
+ @staticmethod
+ def from_json(json):
+ name = _get_required_field(json, 'name', 'OvsPatchPort')
+ bridge_name = _get_required_field(json, 'bridge_name', 'OvsPatchPort')
+ peer = _get_required_field(json, 'peer', 'OvsPatchPort')
+ ovs_options = json.get('ovs_options', [])
+ ovs_options = ['options:%s' % opt for opt in ovs_options]
+ ovs_extra = json.get('ovs_extra', [])
+ opts = _BaseOpts.base_opts_from_json(json)
+ return OvsPatchPort(name, *opts, bridge_name=bridge_name, peer=peer,
+ ovs_options=ovs_options, 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 f4701a0..71ad9ae 100644
--- a/os_net_config/tests/test_impl_ifcfg.py
+++ b/os_net_config/tests/test_impl_ifcfg.py
@@ -258,6 +258,18 @@ NETMASK=255.255.255.0
_IVS_CONFIG = ('DAEMON_ARGS=\"--hitless --certificate /etc/ivs '
'--inband-vlan 4092 -u em1 --internal-port=storage5\"')
+_OVS_IFCFG_PATCH_PORT = """# This file is autogenerated by os-net-config
+DEVICE=br-pub-patch
+ONBOOT=yes
+HOTPLUG=no
+NM_CONTROLLED=no
+PEERDNS=no
+DEVICETYPE=ovs
+TYPE=OVSPatchPort
+OVS_BRIDGE=br-ex
+OVS_PATCH_PEER=br-ex-patch
+"""
+
class TestIfcfgNetConfig(base.TestCase):
@@ -309,6 +321,15 @@ class TestIfcfgNetConfig(base.TestCase):
self.provider.add_interface(interface)
self.assertEqual(_OVS_IFCFG_TUNNEL, self.get_interface_config('tun0'))
+ def test_add_ovs_patch_port(self):
+ patch_port = objects.OvsPatchPort("br-pub-patch")
+ patch_port.type = 'ovs_patch_port'
+ patch_port.bridge_name = 'br-ex'
+ patch_port.peer = 'br-ex-patch'
+ self.provider.add_interface(patch_port)
+ self.assertEqual(_OVS_IFCFG_PATCH_PORT,
+ self.get_interface_config('br-pub-patch'))
+
def test_add_interface_with_v4(self):
v4_addr = objects.Address('192.168.1.2/24')
interface = objects.Interface('em1', addresses=[v4_addr])
diff --git a/os_net_config/tests/test_objects.py b/os_net_config/tests/test_objects.py
index 3367df0..7d8d3b3 100644
--- a/os_net_config/tests/test_objects.py
+++ b/os_net_config/tests/test_objects.py
@@ -548,6 +548,22 @@ class TestOvsTunnel(base.TestCase):
tun0.ovs_extra)
+class TestOvsPatchPort(base.TestCase):
+
+ def test_from_json(self):
+ data = """{
+"type": "ovs_patch_port",
+"name": "br-pub-patch",
+"bridge_name": "br-ex",
+"peer": "br-ex-patch"
+}
+"""
+ patch_port = objects.object_from_json(json.loads(data))
+ 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 TestNumberedNicsMapping(base.TestCase):
# We want to test the function, not the dummy..