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]