doc: Document for ryu.lib.ovs
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
bd384997ac
commit
09d2811569
@ -15,3 +15,4 @@ Ryu provides some useful library for your network applications.
|
||||
library_bgp_speaker_ref.rst
|
||||
library_mrt.rst
|
||||
library_ovsdb_manager.rst
|
||||
library_ovsdb.rst
|
||||
|
76
doc/source/library_ovsdb.rst
Normal file
76
doc/source/library_ovsdb.rst
Normal file
@ -0,0 +1,76 @@
|
||||
*************
|
||||
OVSDB library
|
||||
*************
|
||||
|
||||
Path: ``ryu.lib.ovs``
|
||||
|
||||
Similar to the :doc:`library_ovsdb_manager`, this library enables your
|
||||
application to speak the OVSDB protocol (RFC7047_), but differ from the
|
||||
:doc:`library_ovsdb_manager`, this library will initiate connections from
|
||||
controller side as ovs-vsctl_ command does.
|
||||
Please make sure that your devices are listening on either the Unix domain
|
||||
socket or TCP/SSL port before calling the APIs of this library.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Show current configuration
|
||||
$ ovs-vsctl get-manager
|
||||
|
||||
# Set TCP listen address
|
||||
$ ovs-vsctl set-manager "ptcp:6640"
|
||||
|
||||
See manpage of ovs-vsctl_ command for more details.
|
||||
|
||||
.. _RFC7047: https://tools.ietf.org/html/rfc7047
|
||||
.. _ovs-vsctl: http://openvswitch.org/support/dist-docs/ovs-vsctl.8.txt
|
||||
|
||||
Basic Usage
|
||||
===========
|
||||
|
||||
1. Instantiate :py:mod:`ryu.lib.ovs.vsctl.VSCtl`.
|
||||
|
||||
2. Construct commands with :py:mod:`ryu.lib.ovs.vsctl.VSCtlCommand`.
|
||||
The syntax is almost the same as ovs-vsctl_ command.
|
||||
|
||||
3. Execute commands via :py:mod:`ryu.lib.ovs.vsctl.VSCtl.run_command`.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from ryu.lib.ovs import vsctl
|
||||
|
||||
OVSDB_ADDR = 'tcp:127.0.0.1:6640'
|
||||
ovs_vsctl = vsctl.VSCtl(OVSDB_ADDR)
|
||||
|
||||
# Equivalent to
|
||||
# $ ovs-vsctl show
|
||||
command = vsctl.VSCtlCommand('show')
|
||||
ovs_vsctl.run_command([command])
|
||||
print(command)
|
||||
# >>> VSCtlCommand(args=[],command='show',options=[],result='830d781f-c3c8-4b4f-837e-106e1b33d058\n ovs_version: "2.8.90"\n')
|
||||
|
||||
# Equivalent to
|
||||
# $ ovs-vsctl list Port s1-eth1
|
||||
command = vsctl.VSCtlCommand('list', ('Port', 's1-eth1'))
|
||||
ovs_vsctl.run_command([command])
|
||||
print(command)
|
||||
# >>> VSCtlCommand(args=('Port', 's1-eth1'),command='list',options=[],result=[<ovs.db.idl.Row object at 0x7f525fb682e8>])
|
||||
print(command.result[0].name)
|
||||
# >>> s1-eth1
|
||||
|
||||
API Reference
|
||||
=============
|
||||
|
||||
ryu.lib.ovs.vsctl
|
||||
-----------------
|
||||
|
||||
.. automodule:: ryu.lib.ovs.vsctl
|
||||
:members:
|
||||
|
||||
ryu.lib.ovs.bridge
|
||||
------------------
|
||||
|
||||
.. automodule:: ryu.lib.ovs.bridge
|
||||
:members:
|
@ -15,7 +15,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
slimmed down version of OVSBridge in quantum agent
|
||||
Wrapper utility library of :py:mod:`ryu.lib.ovs.vsctl`
|
||||
"""
|
||||
|
||||
import functools
|
||||
@ -92,6 +92,26 @@ class TunnelPort(object):
|
||||
|
||||
|
||||
class OVSBridge(object):
|
||||
"""
|
||||
Class to provide wrapper utilities of :py:mod:`ryu.lib.ovs.vsctl.VSCtl`
|
||||
|
||||
``CONF`` is a instance of ``oslo_config.cfg.ConfigOpts``.
|
||||
Mostly ``self.CONF`` is sufficient to instantiate this class from your Ryu
|
||||
application.
|
||||
|
||||
``datapath_id`` specifies Datapath ID of the target OVS instance.
|
||||
|
||||
``ovsdb_addr`` specifies the address of the OVS instance.
|
||||
Automatically validated when you call ``init()`` method.
|
||||
Refer to :py:mod:`ryu.lib.ovs.vsctl.valid_ovsdb_addr` for the format of
|
||||
this address.
|
||||
|
||||
if ``timeout`` is omitted, ``CONF.ovsdb_timeout`` will be used as the
|
||||
default value.
|
||||
|
||||
Usage of ``timeout`` and ``exception`` is the same with ``timeout_sec``
|
||||
and ``exception`` of :py:mod:`ryu.lib.ovs.vsctl.VSCtl.run_command`.
|
||||
"""
|
||||
|
||||
def __init__(self, CONF, datapath_id, ovsdb_addr, timeout=None,
|
||||
exception=None):
|
||||
@ -105,9 +125,25 @@ class OVSBridge(object):
|
||||
self.br_name = None
|
||||
|
||||
def run_command(self, commands):
|
||||
"""
|
||||
Executes the given commands and sends OVSDB messages.
|
||||
|
||||
``commands`` must be a list of
|
||||
:py:mod:`ryu.lib.ovs.vsctl.VSCtlCommand`.
|
||||
|
||||
The given ``timeout`` and ``exception`` when instantiation will be used
|
||||
to call :py:mod:`ryu.lib.ovs.vsctl.VSCtl.run_command`.
|
||||
"""
|
||||
self.vsctl.run_command(commands, self.timeout, self.exception)
|
||||
|
||||
def init(self):
|
||||
"""
|
||||
Validates the given ``ovsdb_addr`` and connects to OVS instance.
|
||||
|
||||
If failed to connect to OVS instance or the given ``datapath_id`` does
|
||||
not match with the Datapath ID of the connected OVS instance, raises
|
||||
:py:mod:`ryu.lib.ovs.bridge.OVSBridgeNotFound` exception.
|
||||
"""
|
||||
if not valid_ovsdb_addr(self.ovsdb_addr):
|
||||
raise ValueError('Invalid OVSDB address: %s' % self.ovsdb_addr)
|
||||
if self.br_name is None:
|
||||
@ -126,16 +162,37 @@ class OVSBridge(object):
|
||||
return command.result[0].name
|
||||
|
||||
def get_controller(self):
|
||||
"""
|
||||
Gets the configured OpenFlow controller address.
|
||||
|
||||
This method is corresponding to the following ovs-vsctl command::
|
||||
|
||||
$ ovs-vsctl get-controller <bridge>
|
||||
"""
|
||||
command = ovs_vsctl.VSCtlCommand('get-controller', [self.br_name])
|
||||
self.run_command([command])
|
||||
return command.result[0]
|
||||
|
||||
def set_controller(self, controllers):
|
||||
"""
|
||||
Sets the OpenFlow controller address.
|
||||
|
||||
This method is corresponding to the following ovs-vsctl command::
|
||||
|
||||
$ ovs-vsctl set-controller <bridge> <target>...
|
||||
"""
|
||||
command = ovs_vsctl.VSCtlCommand('set-controller', [self.br_name])
|
||||
command.args.extend(controllers)
|
||||
self.run_command([command])
|
||||
|
||||
def del_controller(self):
|
||||
"""
|
||||
Deletes the configured OpenFlow controller address.
|
||||
|
||||
This method is corresponding to the following ovs-vsctl command::
|
||||
|
||||
$ ovs-vsctl del-controller <bridge>
|
||||
"""
|
||||
command = ovs_vsctl.VSCtlCommand('del-controller', [self.br_name])
|
||||
self.run_command([command])
|
||||
|
||||
@ -245,30 +302,72 @@ class OVSBridge(object):
|
||||
self.run_command([command])
|
||||
|
||||
def db_get_val(self, table, record, column):
|
||||
"""
|
||||
Gets values of 'column' in 'record' in 'table'.
|
||||
|
||||
This method is corresponding to the following ovs-vsctl command::
|
||||
|
||||
$ ovs-vsctl get TBL REC COL
|
||||
"""
|
||||
command = ovs_vsctl.VSCtlCommand('get', (table, record, column))
|
||||
self.run_command([command])
|
||||
assert len(command.result) == 1
|
||||
return command.result[0]
|
||||
|
||||
def db_get_map(self, table, record, column):
|
||||
"""
|
||||
Gets dict type value of 'column' in 'record' in 'table'.
|
||||
|
||||
This method is corresponding to the following ovs-vsctl command::
|
||||
|
||||
$ ovs-vsctl get TBL REC COL
|
||||
"""
|
||||
val = self.db_get_val(table, record, column)
|
||||
assert isinstance(val, dict)
|
||||
return val
|
||||
|
||||
def get_datapath_id(self):
|
||||
"""
|
||||
Gets Datapath ID of OVS instance.
|
||||
|
||||
This method is corresponding to the following ovs-vsctl command::
|
||||
|
||||
$ ovs-vsctl get Bridge <bridge> datapath_id
|
||||
"""
|
||||
return self.db_get_val('Bridge', self.br_name, 'datapath_id')
|
||||
|
||||
def delete_port(self, port_name):
|
||||
"""
|
||||
Deletes a port on the OVS instance.
|
||||
|
||||
This method is corresponding to the following ovs-vsctl command::
|
||||
|
||||
$ ovs-vsctl --if-exists del-port <bridge> <port>
|
||||
"""
|
||||
command = ovs_vsctl.VSCtlCommand(
|
||||
'del-port', (self.br_name, port_name), '--if-exists')
|
||||
self.run_command([command])
|
||||
|
||||
def get_ofport(self, port_name):
|
||||
"""
|
||||
Gets the OpenFlow port number.
|
||||
|
||||
This method is corresponding to the following ovs-vsctl command::
|
||||
|
||||
$ ovs-vsctl get Interface <port> ofport
|
||||
"""
|
||||
ofport_list = self.db_get_val('Interface', port_name, 'ofport')
|
||||
assert len(ofport_list) == 1
|
||||
return int(ofport_list[0])
|
||||
|
||||
def get_port_name_list(self):
|
||||
"""
|
||||
Gets a list of all ports on OVS instance.
|
||||
|
||||
This method is corresponding to the following ovs-vsctl command::
|
||||
|
||||
$ ovs-vsctl list-ports <bridge>
|
||||
"""
|
||||
command = ovs_vsctl.VSCtlCommand('list-ports', (self.br_name, ))
|
||||
self.run_command([command])
|
||||
return command.result
|
||||
@ -297,6 +396,16 @@ class OVSBridge(object):
|
||||
|
||||
def add_tunnel_port(self, name, tunnel_type, remote_ip,
|
||||
local_ip=None, key=None, ofport=None):
|
||||
"""
|
||||
Creates a tunnel port.
|
||||
|
||||
:param name: Port name to be created
|
||||
:param tunnel_type: Type of tunnel (gre or vxlan)
|
||||
:param remote_ip: Remote IP address of tunnel
|
||||
:param local_ip: Local IP address of tunnel
|
||||
:param key: Key of GRE or VNI of VxLAN
|
||||
:param ofport: Requested OpenFlow port number
|
||||
"""
|
||||
options = 'remote_ip=%(remote_ip)s' % locals()
|
||||
if key:
|
||||
options += ',key=%(key)s' % locals()
|
||||
@ -314,15 +423,32 @@ class OVSBridge(object):
|
||||
|
||||
def add_gre_port(self, name, remote_ip,
|
||||
local_ip=None, key=None, ofport=None):
|
||||
"""
|
||||
Creates a GRE tunnel port.
|
||||
|
||||
See the description of ``add_tunnel_port()``.
|
||||
"""
|
||||
self.add_tunnel_port(name, 'gre', remote_ip,
|
||||
local_ip=local_ip, key=key, ofport=ofport)
|
||||
|
||||
def add_vxlan_port(self, name, remote_ip,
|
||||
local_ip=None, key=None, ofport=None):
|
||||
"""
|
||||
Creates a VxLAN tunnel port.
|
||||
|
||||
See the description of ``add_tunnel_port()``.
|
||||
"""
|
||||
self.add_tunnel_port(name, 'vxlan', remote_ip,
|
||||
local_ip=local_ip, key=key, ofport=ofport)
|
||||
|
||||
def del_port(self, port_name):
|
||||
"""
|
||||
Deletes a port on OVS instance.
|
||||
|
||||
This method is corresponding to the following ovs-vsctl command::
|
||||
|
||||
$ ovs-vsctl del-port <bridge> <port>
|
||||
"""
|
||||
command = ovs_vsctl.VSCtlCommand('del-port', (self.br_name, port_name))
|
||||
self.run_command([command])
|
||||
|
||||
@ -396,6 +522,9 @@ class OVSBridge(object):
|
||||
return None
|
||||
|
||||
def set_qos(self, port_name, type='linux-htb', max_rate=None, queues=None):
|
||||
"""
|
||||
Sets a Qos rule and creates Queues on the given port.
|
||||
"""
|
||||
queues = queues if queues else []
|
||||
command_qos = ovs_vsctl.VSCtlCommand(
|
||||
'set-qos',
|
||||
@ -409,6 +538,9 @@ class OVSBridge(object):
|
||||
return None
|
||||
|
||||
def del_qos(self, port_name):
|
||||
"""
|
||||
Deletes the Qos rule on the given port.
|
||||
"""
|
||||
command = ovs_vsctl.VSCtlCommand(
|
||||
'del-qos',
|
||||
[port_name])
|
||||
|
@ -14,6 +14,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
``ovs-vsctl`` command like library to speak OVSDB protocol
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
@ -53,9 +56,9 @@ def valid_ovsdb_addr(addr):
|
||||
|
||||
The valid formats are:
|
||||
|
||||
- unix:file
|
||||
- tcp:ip:port
|
||||
- ssl:ip:port
|
||||
- ``unix:file``
|
||||
- ``tcp:ip:port``
|
||||
- ``ssl:ip:port``
|
||||
|
||||
If ip is IPv6 address, wrap ip with brackets (e.g., ssl:[::1]:6640).
|
||||
|
||||
@ -959,6 +962,34 @@ class _VSCtlTable(object):
|
||||
|
||||
|
||||
class VSCtlCommand(StringifyMixin):
|
||||
"""
|
||||
Class to describe artgumens similar to those of ``ovs-vsctl`` command.
|
||||
|
||||
``command`` specifies the command of ``ovs-vsctl``.
|
||||
|
||||
``args`` specifies a list or tuple of arguments for the given command.
|
||||
|
||||
``options`` specifies a list or tuple of options for the given command.
|
||||
Please note that NOT all options of ``ovs-vsctl`` are supported.
|
||||
For example, ``--id`` option is not yet supported.
|
||||
This class supports the followings.
|
||||
|
||||
================= =========================================================
|
||||
Option Description
|
||||
================= =========================================================
|
||||
``--may-exist`` Does nothing when the given port already exists.
|
||||
The supported commands are ``add-port`` and
|
||||
``add-bond``.
|
||||
``--fake-iface`` Creates a port as a fake interface.
|
||||
The supported command is ``add-bond``.
|
||||
``--must-exist`` Raises exception if the given port does not exist.
|
||||
The supported command is ``del-port``.
|
||||
``--with-iface`` Takes effect to the interface which has the same name.
|
||||
The supported command is ``del-port``.
|
||||
``--if-exists`` Ignores exception when not found.
|
||||
The supported command is ``get``.
|
||||
================= =========================================================
|
||||
"""
|
||||
|
||||
def __init__(self, command, args=None, options=None):
|
||||
super(VSCtlCommand, self).__init__()
|
||||
@ -978,6 +1009,13 @@ class VSCtlCommand(StringifyMixin):
|
||||
|
||||
|
||||
class VSCtl(object):
|
||||
"""
|
||||
A class to describe an Open vSwitch instance.
|
||||
|
||||
``remote`` specifies the address of the OVS instance.
|
||||
:py:mod:`ryu.lib.ovs.vsctl.valid_ovsdb_addr` is a convenient function to
|
||||
validate this address.
|
||||
"""
|
||||
|
||||
def _reset(self):
|
||||
self.schema_helper = None
|
||||
@ -1237,6 +1275,19 @@ class VSCtl(object):
|
||||
self._do_main(commands)
|
||||
|
||||
def run_command(self, commands, timeout_sec=None, exception=None):
|
||||
"""
|
||||
Executes the given commands and sends OVSDB messages.
|
||||
|
||||
``commands`` must be a list of
|
||||
:py:mod:`ryu.lib.ovs.vsctl.VSCtlCommand`.
|
||||
|
||||
If ``timeout_sec`` is specified, raises exception after the given
|
||||
timeout [sec]. Additionally, if ``exception`` is specified, this
|
||||
function will wraps exception using the given exception class.
|
||||
|
||||
Retruns ``None`` but fills ``result`` attribute for each command
|
||||
instance.
|
||||
"""
|
||||
if timeout_sec is None:
|
||||
self._run_command(commands)
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user