aboutsummaryrefslogtreecommitdiffstats
path: root/contrail-controller/hooks/charmhelpers/contrib/network/ovs/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'contrail-controller/hooks/charmhelpers/contrib/network/ovs/__init__.py')
-rw-r--r--contrail-controller/hooks/charmhelpers/contrib/network/ovs/__init__.py163
1 files changed, 163 insertions, 0 deletions
diff --git a/contrail-controller/hooks/charmhelpers/contrib/network/ovs/__init__.py b/contrail-controller/hooks/charmhelpers/contrib/network/ovs/__init__.py
new file mode 100644
index 0000000..f044b60
--- /dev/null
+++ b/contrail-controller/hooks/charmhelpers/contrib/network/ovs/__init__.py
@@ -0,0 +1,163 @@
+# Copyright 2014-2015 Canonical Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+''' Helpers for interacting with OpenvSwitch '''
+import subprocess
+import os
+import six
+
+from charmhelpers.fetch import apt_install
+
+
+from charmhelpers.core.hookenv import (
+ log, WARNING, INFO, DEBUG
+)
+from charmhelpers.core.host import (
+ service
+)
+
+BRIDGE_TEMPLATE = """\
+# This veth pair is required when neutron data-port is mapped to an existing linux bridge. lp:1635067
+
+auto {linuxbridge_port}
+iface {linuxbridge_port} inet manual
+ pre-up ip link add name {linuxbridge_port} type veth peer name {ovsbridge_port}
+ pre-up ip link set {ovsbridge_port} master {bridge}
+ pre-up ip link set {ovsbridge_port} up
+ up ip link set {linuxbridge_port} up
+ down ip link del {linuxbridge_port}
+"""
+
+
+def add_bridge(name, datapath_type=None):
+ ''' Add the named bridge to openvswitch '''
+ log('Creating bridge {}'.format(name))
+ cmd = ["ovs-vsctl", "--", "--may-exist", "add-br", name]
+ if datapath_type is not None:
+ cmd += ['--', 'set', 'bridge', name,
+ 'datapath_type={}'.format(datapath_type)]
+ subprocess.check_call(cmd)
+
+
+def del_bridge(name):
+ ''' Delete the named bridge from openvswitch '''
+ log('Deleting bridge {}'.format(name))
+ subprocess.check_call(["ovs-vsctl", "--", "--if-exists", "del-br", name])
+
+
+def add_bridge_port(name, port, promisc=False):
+ ''' Add a port to the named openvswitch bridge '''
+ log('Adding port {} to bridge {}'.format(port, name))
+ subprocess.check_call(["ovs-vsctl", "--", "--may-exist", "add-port",
+ name, port])
+ subprocess.check_call(["ip", "link", "set", port, "up"])
+ if promisc:
+ subprocess.check_call(["ip", "link", "set", port, "promisc", "on"])
+ else:
+ subprocess.check_call(["ip", "link", "set", port, "promisc", "off"])
+
+
+def del_bridge_port(name, port):
+ ''' Delete a port from the named openvswitch bridge '''
+ log('Deleting port {} from bridge {}'.format(port, name))
+ subprocess.check_call(["ovs-vsctl", "--", "--if-exists", "del-port",
+ name, port])
+ subprocess.check_call(["ip", "link", "set", port, "down"])
+ subprocess.check_call(["ip", "link", "set", port, "promisc", "off"])
+
+
+def add_ovsbridge_linuxbridge(name, bridge):
+ ''' Add linux bridge to the named openvswitch bridge
+ :param name: Name of ovs bridge to be added to Linux bridge
+ :param bridge: Name of Linux bridge to be added to ovs bridge
+ :returns: True if veth is added between ovs bridge and linux bridge,
+ False otherwise'''
+ try:
+ import netifaces
+ except ImportError:
+ if six.PY2:
+ apt_install('python-netifaces', fatal=True)
+ else:
+ apt_install('python3-netifaces', fatal=True)
+ import netifaces
+
+ ovsbridge_port = "veth-" + name
+ linuxbridge_port = "veth-" + bridge
+ log('Adding linuxbridge {} to ovsbridge {}'.format(bridge, name),
+ level=INFO)
+ interfaces = netifaces.interfaces()
+ for interface in interfaces:
+ if interface == ovsbridge_port or interface == linuxbridge_port:
+ log('Interface {} already exists'.format(interface), level=INFO)
+ return
+
+ with open('/etc/network/interfaces.d/{}.cfg'.format(
+ linuxbridge_port), 'w') as config:
+ config.write(BRIDGE_TEMPLATE.format(linuxbridge_port=linuxbridge_port,
+ ovsbridge_port=ovsbridge_port,
+ bridge=bridge))
+
+ subprocess.check_call(["ifup", linuxbridge_port])
+ add_bridge_port(name, linuxbridge_port)
+
+
+def is_linuxbridge_interface(port):
+ ''' Check if the interface is a linuxbridge bridge
+ :param port: Name of an interface to check whether it is a Linux bridge
+ :returns: True if port is a Linux bridge'''
+
+ if os.path.exists('/sys/class/net/' + port + '/bridge'):
+ log('Interface {} is a Linux bridge'.format(port), level=DEBUG)
+ return True
+ else:
+ log('Interface {} is not a Linux bridge'.format(port), level=DEBUG)
+ return False
+
+
+def set_manager(manager):
+ ''' Set the controller for the local openvswitch '''
+ log('Setting manager for local ovs to {}'.format(manager))
+ subprocess.check_call(['ovs-vsctl', 'set-manager',
+ 'ssl:{}'.format(manager)])
+
+
+CERT_PATH = '/etc/openvswitch/ovsclient-cert.pem'
+
+
+def get_certificate():
+ ''' Read openvswitch certificate from disk '''
+ if os.path.exists(CERT_PATH):
+ log('Reading ovs certificate from {}'.format(CERT_PATH))
+ with open(CERT_PATH, 'r') as cert:
+ full_cert = cert.read()
+ begin_marker = "-----BEGIN CERTIFICATE-----"
+ end_marker = "-----END CERTIFICATE-----"
+ begin_index = full_cert.find(begin_marker)
+ end_index = full_cert.rfind(end_marker)
+ if end_index == -1 or begin_index == -1:
+ raise RuntimeError("Certificate does not contain valid begin"
+ " and end markers.")
+ full_cert = full_cert[begin_index:(end_index + len(end_marker))]
+ return full_cert
+ else:
+ log('Certificate not found', level=WARNING)
+ return None
+
+
+def full_restart():
+ ''' Full restart and reload of openvswitch '''
+ if os.path.exists('/etc/init/openvswitch-force-reload-kmod.conf'):
+ service('start', 'openvswitch-force-reload-kmod')
+ else:
+ service('force-reload-kmod', 'openvswitch-switch')