OVSDB 管理器库

路径: os_ken.services.protocols.ovsdb

介绍

OS-Ken OVSDB 管理器库允许您的代码与使用 OVSDB 协议通信的设备进行交互。这使得您的代码能够对设备进行远程管理,并对设备上的拓扑变化做出反应。

请注意,此库将在 6640 端口(IANA 为 OVSDB 协议注册的端口)上启动一个服务器监听,但不会从控制器端发起连接。因此,要使您的设备连接到 OS-Ken,您需要将控制器的 IP 地址和端口告知您的设备。

# Show current configuration
$ ovs-vsctl get-manager

# Set manager (controller) address
$ ovs-vsctl set-manager "tcp:127.0.0.1:6640"

# If you want to specify IPv6 address, wrap ip with brackets
$ ovs-vsctl set-manager "tcp:[::1]:6640"

此外,此库通过“system-id”来识别设备,该 ID 应该是连接到单个控制器的所有设备中唯一且持久的标识符。请确保在连接之前配置“system-id”。

# Show current configuration
$ ovs-vsctl get Open_vSwitch . external_ids:system-id

# Set system-id manually
$ ovs-vsctl set Open_vSwitch . external_ids:system-id=<SYSTEM-ID>

示例

以下日志记录所有新的 OVSDB 连接,记录在“handle_new_ovsdb_connection”中,并提供“create_port”API 用于在桥接器上创建端口。

import uuid

from os_ken.base import app_manager
from os_ken.controller.handler import set_ev_cls
from os_ken.services.protocols.ovsdb import api as ovsdb
from os_ken.services.protocols.ovsdb import event as ovsdb_event


class MyApp(app_manager.OSKenApp):
    @set_ev_cls(ovsdb_event.EventNewOVSDBConnection)
    def handle_new_ovsdb_connection(self, ev):
        system_id = ev.system_id
        address = ev.client.address
        self.logger.info(
            'New OVSDB connection from system-id=%s, address=%s',
            system_id, address)

        # Example: If device has bridge "s1", add port "s1-eth99"
        if ovsdb.bridge_exists(self, system_id, "s1"):
            self.create_port(system_id, "s1", "s1-eth99")

    def create_port(self, system_id, bridge_name, name):
        new_iface_uuid = uuid.uuid4()
        new_port_uuid = uuid.uuid4()

        bridge = ovsdb.row_by_name(self, system_id, bridge_name)

        def _create_port(tables, insert):
            iface = insert(tables['Interface'], new_iface_uuid)
            iface.name = name
            iface.type = 'internal'

            port = insert(tables['Port'], new_port_uuid)
            port.name = name
            port.interfaces = [iface]

            bridge.ports = bridge.ports + [port]

            return new_port_uuid, new_iface_uuid

        req = ovsdb_event.EventModifyRequest(system_id, _create_port)
        rep = self.send_request(req)

        if rep.status != 'success':
            self.logger.error('Error creating port %s on bridge %s: %s',
                              name, bridge, rep.status)
            return None

        return rep.insert_uuids[new_port_uuid]