vtep: add support for 'hardware_vtep' schema
Added support for the "hardware_vtep" schema. The ``HwVtepApiIdlImpl`` class provides interaction with "hw_vtep.db". Closes-Bug: 1960513 Change-Id: I37138e91f9dd3e42908ac1e7e7c123323177a8e8
This commit is contained in:
parent
06207b33e3
commit
06d25c2980
0
ovsdbapp/schema/hardware_vtep/__init__.py
Normal file
0
ovsdbapp/schema/hardware_vtep/__init__.py
Normal file
222
ovsdbapp/schema/hardware_vtep/api.py
Normal file
222
ovsdbapp/schema/hardware_vtep/api.py
Normal file
@ -0,0 +1,222 @@
|
||||
# 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.
|
||||
|
||||
import abc
|
||||
|
||||
from ovsdbapp import api
|
||||
|
||||
|
||||
class API(api.API, metaclass=abc.ABCMeta):
|
||||
"""An API based off of the vtep-ctl CLI interface
|
||||
|
||||
This API basically mirrors the vtep-ctl operations with these changes:
|
||||
1. Methods that create objects will return a read-only view of the object
|
||||
2. Methods which list objects will return a list of read-only view objects
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def add_ps(self, pswitch, may_exist=False, **columns):
|
||||
"""Create a physical switch named 'pswitch'
|
||||
|
||||
:param pswitch: The name of the switch
|
||||
:type pswitch: string or uuid.UUID
|
||||
:param may_exist: If True, don't fail if the switch already exists
|
||||
:type may_exist: boolean
|
||||
:param columns: Additional columns to directly set on the switch
|
||||
:returns: :class:`Command` with RowView result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def del_ps(self, pswitch, if_exists=False):
|
||||
"""Delete physical switch 'pswitch' and all its ports
|
||||
|
||||
:param pswitch: The name or uuid of the switch
|
||||
:type pswitch: string or uuid.UUID
|
||||
:type if_exists: If True, don't fail if the switch doesn't exist
|
||||
:type if_exists: boolean
|
||||
:returns: :class:`Command` with no result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def list_ps(self):
|
||||
"""Get all physical switches
|
||||
|
||||
:returns: :class:`Command` with RowView list result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_ps(self, pswitch):
|
||||
"""Get physical switch for 'pswitch'
|
||||
|
||||
:param pswitch: The name of the pswitch
|
||||
:type pswitch: string or uuid.UUID
|
||||
:returns: :class:`Command` with RowView result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def add_port(self, pswitch, port, may_exist=False):
|
||||
"""Add a port named 'port' to physical switch named 'pswitch'
|
||||
|
||||
:param pswitch: The name of the switch
|
||||
:type pswitch: string or uuid.UUID
|
||||
:param port: The name of the port
|
||||
:type port: string or uuid.UUID
|
||||
:param may_exist: If True, don't fail if the port already exists in
|
||||
physical switch
|
||||
:type may_exist: boolean
|
||||
:returns: :class:`Command` with RowView result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def del_port(self, pswitch, port, if_exists=False):
|
||||
"""Delete a port named 'port' from physical switch named 'pswitch'
|
||||
|
||||
:param pswitch: The name or uuid of the switch
|
||||
:type pswitch: string or uuid.UUID
|
||||
:param port: The name of the port
|
||||
:type port: string or uuid.UUID
|
||||
:type if_exists: If True, don't fail if the switch doesn't exist in
|
||||
physical switch
|
||||
:type if_exists: boolean
|
||||
:returns: :class:`Command` with no result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def list_ports(self, pswitch):
|
||||
"""Get all ports of physical switch 'pswitch'
|
||||
|
||||
:param pswitch: The name of the pswitch
|
||||
:type pswitch: string or uuid.UUID
|
||||
:returns: :class:`Command` with RowView list result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_port(self, port):
|
||||
"""Get physical port for 'port'
|
||||
|
||||
:param port: The name of the port
|
||||
:type port: string or uuid.UUID
|
||||
:returns: :class:`Command` with RowView result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def add_ls(self, switch, may_exist=False, **columns):
|
||||
"""Create a logical switch named 'switch'
|
||||
|
||||
:param switch: The name of the switch
|
||||
:type switch: string or uuid.UUID
|
||||
:param may_exist: If True, don't fail if the switch already exists
|
||||
:type may_exist: boolean
|
||||
:param columns: Additional columns to directly set on the switch
|
||||
:returns: :class:`Command` with RowView result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def del_ls(self, switch, if_exists=False):
|
||||
"""Delete logical switch 'switch' and all its ports
|
||||
|
||||
:param switch: The name or uuid of the switch
|
||||
:type switch: string or uuid.UUID
|
||||
:type if_exists: If True, don't fail if the switch doesn't exist
|
||||
:type if_exists: boolean
|
||||
:returns: :class:`Command` with no result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def list_ls(self):
|
||||
"""Get all logical switches
|
||||
|
||||
:returns: :class:`Command` with RowView list result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_ls(self, switch):
|
||||
"""Get logical switch for 'switch'
|
||||
|
||||
:returns: :class:`Command` with RowView result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def bind_ls(self, pswitch, port, vlan, switch):
|
||||
"""Bind 'switch' to 'pswitch'
|
||||
|
||||
Bind logical switch to the port/vlan combination on the
|
||||
physical switch 'pswitch'.
|
||||
|
||||
:param pswitch: The name or uuid of the physical switch
|
||||
:type pswitch: string or uuid.UUID
|
||||
:param port: name of port
|
||||
:type port: string
|
||||
:param vlan: number of VLAN
|
||||
:type vlan: int
|
||||
:param switch: The name or uuid of the switch
|
||||
:type switch: string or uuid.UUID
|
||||
:returns: :class:`Command` with no result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def unbind_ls(self, pswitch, port, vlan):
|
||||
"""Unbind 'switch' from 'pswitch'
|
||||
|
||||
Remove the logical switch binding from the port/vlan combination on
|
||||
the physical switch pswitch.
|
||||
|
||||
:param pswitch: The name or uuid of the physical switch
|
||||
:type pswitch: string or uuid.UUID
|
||||
:param port: name of port
|
||||
:type port: string
|
||||
:param vlan: number of VLAN
|
||||
:type vlan: int
|
||||
:param switch: The name or uuid of the switch
|
||||
:type switch: string or uuid.UUID
|
||||
:returns: :class:`Command` with no result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def list_local_macs(self, switch):
|
||||
"""Get all local MACs for 'switch'
|
||||
|
||||
:param switch: The name of the switch
|
||||
:type switch: string or uuid.UUID
|
||||
:returns: :class:`Command` with list of RowView lists result.
|
||||
First list contains 'Ucast_Macs_Local' table records,
|
||||
second list contains 'Mcast_Macs_Local' table records.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def list_remote_macs(self, switch):
|
||||
"""Get all remote MACs for 'switch'
|
||||
|
||||
:param switch: The name of the switch
|
||||
:type switch: string or uuid.UUID
|
||||
:returns: :class:`Command` with list of RowView lists result.
|
||||
First list contains 'Ucast_Macs_Remote' table records,
|
||||
second list contains 'Mcast_Macs_Remote' table records.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def clear_local_macs(self, switch):
|
||||
"""Clear the local MAC bindings for 'switch'
|
||||
|
||||
:param switch: The name of the switch
|
||||
:type switch: string or uuid.UUID
|
||||
:returns: :class:`Command` with RowView result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def clear_remote_macs(self, switch):
|
||||
"""Clear the remote MAC bindings for 'switch'
|
||||
|
||||
:param switch: The name of the switch
|
||||
:type switch: string or uuid.UUID
|
||||
:returns: :class:`Command` with RowView result
|
||||
"""
|
296
ovsdbapp/schema/hardware_vtep/commands.py
Normal file
296
ovsdbapp/schema/hardware_vtep/commands.py
Normal file
@ -0,0 +1,296 @@
|
||||
# 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.
|
||||
|
||||
from ovsdbapp.backend.ovs_idl import command as cmd
|
||||
from ovsdbapp.backend.ovs_idl import idlutils
|
||||
from ovsdbapp.backend.ovs_idl import rowview
|
||||
|
||||
|
||||
class TableGlobalIsEmpty(idlutils.RowNotFound):
|
||||
message = "Table 'Global' is empty"
|
||||
|
||||
|
||||
def get_global_record(api):
|
||||
# there should be only one record in 'Global' table
|
||||
try:
|
||||
return next((r for r in api.tables['Global'].rows.values()))
|
||||
except StopIteration as e:
|
||||
raise TableGlobalIsEmpty from e
|
||||
|
||||
|
||||
class _ListCommand(cmd.ReadOnlyCommand):
|
||||
def run_idl(self, txn):
|
||||
table = self.api.tables[self.table_name]
|
||||
self.result = [rowview.RowView(r) for r in table.rows.values()]
|
||||
|
||||
|
||||
class AddPsCommand(cmd.AddCommand):
|
||||
table_name = 'Physical_Switch'
|
||||
|
||||
def __init__(self, api, pswitch, may_exist=False, **columns):
|
||||
super().__init__(api)
|
||||
self.pswitch = pswitch
|
||||
self.columns = columns
|
||||
self.may_exist = may_exist
|
||||
|
||||
def run_idl(self, txn):
|
||||
config = get_global_record(self.api)
|
||||
pswitch = idlutils.row_by_value(self.api.idl, self.table_name, 'name',
|
||||
self.pswitch, None)
|
||||
if pswitch:
|
||||
if self.may_exist:
|
||||
self.result = rowview.RowView(pswitch)
|
||||
return
|
||||
msg = "Physical switch %s exists" % self.pswitch
|
||||
raise RuntimeError(msg)
|
||||
pswitch = txn.insert(self.api.tables[self.table_name])
|
||||
pswitch.name = self.pswitch
|
||||
self.set_columns(pswitch, **self.columns)
|
||||
config.addvalue('switches', pswitch)
|
||||
self.result = pswitch.uuid
|
||||
|
||||
|
||||
class DelPsCommand(cmd.BaseCommand):
|
||||
table_name = 'Physical_Switch'
|
||||
|
||||
def __init__(self, api, pswitch, if_exists=False):
|
||||
super().__init__(api)
|
||||
self.pswitch = pswitch
|
||||
self.if_exists = if_exists
|
||||
|
||||
def run_idl(self, txn):
|
||||
config = get_global_record(self.api)
|
||||
try:
|
||||
pswitch = self.api.lookup(self.table_name, self.pswitch)
|
||||
config.delvalue('switches', pswitch)
|
||||
pswitch.delete()
|
||||
except idlutils.RowNotFound as e:
|
||||
if self.if_exists:
|
||||
return
|
||||
msg = "Physical switch %s does not exist" % self.pswitch
|
||||
raise RuntimeError(msg) from e
|
||||
|
||||
|
||||
class ListPsCommand(_ListCommand):
|
||||
table_name = 'Physical_Switch'
|
||||
|
||||
|
||||
class GetPsCommand(cmd.BaseGetRowCommand):
|
||||
table = 'Physical_Switch'
|
||||
|
||||
|
||||
class AddPortCommand(cmd.AddCommand):
|
||||
table_name = 'Physical_Port'
|
||||
|
||||
def __init__(self, api, pswitch, port, may_exist=False):
|
||||
super().__init__(api)
|
||||
self.pswitch = pswitch
|
||||
self.port = port
|
||||
self.may_exist = may_exist
|
||||
self.conditions = [('name', '=', self.port)]
|
||||
|
||||
def run_idl(self, txn):
|
||||
pswitch = self.api.lookup('Physical_Switch', self.pswitch)
|
||||
port = next((p for p in pswitch.ports
|
||||
if idlutils.row_match(p, self.conditions)), None)
|
||||
if port:
|
||||
if self.may_exist:
|
||||
self.result = rowview.RowView(port)
|
||||
return
|
||||
msg = "Physical port %s exists in %s" % (self.port, self.pswitch)
|
||||
raise RuntimeError(msg)
|
||||
port = txn.insert(self.api.tables[self.table_name])
|
||||
port.name = self.port
|
||||
pswitch.addvalue('ports', port)
|
||||
self.result = port.uuid
|
||||
|
||||
|
||||
class DelPortCommand(cmd.BaseCommand):
|
||||
table_name = 'Physical_Port'
|
||||
|
||||
def __init__(self, api, pswitch, port, if_exists=False):
|
||||
super().__init__(api)
|
||||
self.pswitch = pswitch
|
||||
self.port = port
|
||||
self.if_exists = if_exists
|
||||
self.conditions = [('name', '=', self.port)]
|
||||
|
||||
def run_idl(self, txn):
|
||||
pswitch = self.api.lookup('Physical_Switch', self.pswitch)
|
||||
port = next((p for p in pswitch.ports
|
||||
if idlutils.row_match(p, self.conditions)), None)
|
||||
if not port:
|
||||
if self.if_exists:
|
||||
return
|
||||
msg = "Physical port %s does not exist in %s" % (self.port,
|
||||
self.pswitch)
|
||||
raise RuntimeError(msg)
|
||||
pswitch.delvalue('ports', port)
|
||||
port.delete()
|
||||
|
||||
|
||||
class ListPortsCommand(cmd.ReadOnlyCommand):
|
||||
table_name = 'Physical_Switch'
|
||||
|
||||
def __init__(self, api, pswitch):
|
||||
super().__init__(api)
|
||||
self.pswitch = pswitch
|
||||
|
||||
def run_idl(self, txn):
|
||||
pswitch = self.api.lookup(self.table_name, self.pswitch)
|
||||
self.result = [rowview.RowView(port) for port in pswitch.ports]
|
||||
|
||||
|
||||
class GetPortCommand(cmd.BaseGetRowCommand):
|
||||
table = 'Physical_Port'
|
||||
|
||||
|
||||
class AddLsCommand(cmd.AddCommand):
|
||||
table_name = 'Logical_Switch'
|
||||
|
||||
def __init__(self, api, switch, may_exist=False, **columns):
|
||||
super().__init__(api)
|
||||
self.switch = switch
|
||||
self.columns = columns
|
||||
self.may_exist = may_exist
|
||||
|
||||
def run_idl(self, txn):
|
||||
switch = idlutils.row_by_value(self.api.idl, self.table_name, 'name',
|
||||
self.switch, None)
|
||||
if switch:
|
||||
if self.may_exist:
|
||||
self.result = rowview.RowView(switch)
|
||||
return
|
||||
msg = "Logical switch %s exists" % self.switch
|
||||
raise RuntimeError(msg)
|
||||
switch = txn.insert(self.api.tables[self.table_name])
|
||||
switch.name = self.switch
|
||||
self.set_columns(switch, **self.columns)
|
||||
self.result = switch.uuid
|
||||
|
||||
|
||||
class DelLsCommand(cmd.BaseCommand):
|
||||
table_name = 'Logical_Switch'
|
||||
|
||||
def __init__(self, api, switch, if_exists=False):
|
||||
super().__init__(api)
|
||||
self.switch = switch
|
||||
self.if_exists = if_exists
|
||||
|
||||
def run_idl(self, txn):
|
||||
try:
|
||||
entity = self.api.lookup(self.table_name, self.switch)
|
||||
entity.delete()
|
||||
except idlutils.RowNotFound as e:
|
||||
if self.if_exists:
|
||||
return
|
||||
msg = "Logical switch %s does not exist" % self.switch
|
||||
raise RuntimeError(msg) from e
|
||||
|
||||
|
||||
class ListLsCommand(_ListCommand):
|
||||
table_name = 'Logical_Switch'
|
||||
|
||||
|
||||
class GetLsCommand(cmd.BaseGetRowCommand):
|
||||
table = 'Logical_Switch'
|
||||
|
||||
|
||||
class BindLsCommand(cmd.BaseCommand):
|
||||
table_name = 'Physical_Port'
|
||||
|
||||
def __init__(self, api, pswitch, port, vlan, switch):
|
||||
super().__init__(api)
|
||||
self.pswitch = pswitch
|
||||
self.port = port
|
||||
self.vlan = vlan
|
||||
self.switch = switch
|
||||
self.conditions = [('name', '=', self.port)]
|
||||
|
||||
def run_idl(self, txn):
|
||||
pswitch = self.api.lookup('Physical_Switch', self.pswitch)
|
||||
switch = self.api.lookup('Logical_Switch', self.switch)
|
||||
port = next((p for p in pswitch.ports
|
||||
if idlutils.row_match(p, self.conditions)), None)
|
||||
if not port:
|
||||
raise idlutils.RowNotFound(table=self.table_name,
|
||||
col='name', match=self.port)
|
||||
port.setkey('vlan_bindings', self.vlan, switch.uuid)
|
||||
|
||||
|
||||
class UnbindLsCommand(cmd.BaseCommand):
|
||||
table_name = 'Physical_Port'
|
||||
|
||||
def __init__(self, api, pswitch, port, vlan):
|
||||
super().__init__(api)
|
||||
self.pswitch = pswitch
|
||||
self.port = port
|
||||
self.vlan = vlan
|
||||
self.conditions = [('name', '=', self.port)]
|
||||
|
||||
def run_idl(self, txn):
|
||||
pswitch = self.api.lookup('Physical_Switch', self.pswitch)
|
||||
port = next((p for p in pswitch.ports
|
||||
if idlutils.row_match(p, self.conditions)), None)
|
||||
if not port:
|
||||
raise idlutils.RowNotFound(table=self.table_name,
|
||||
col='name', match=self.port)
|
||||
port.delkey('vlan_bindings', self.vlan)
|
||||
|
||||
|
||||
class _ClearMacsCommand(cmd.BaseCommand):
|
||||
def __init__(self, api, switch):
|
||||
super().__init__(api)
|
||||
self.switch = switch
|
||||
|
||||
def run_idl(self, txn):
|
||||
switch = self.api.lookup('Logical_Switch', self.switch)
|
||||
macs = []
|
||||
|
||||
for table_name in self.table_names:
|
||||
macs.extend(idlutils.rows_by_value(self.api.idl,
|
||||
table_name,
|
||||
'logical_switch', switch))
|
||||
for mac in macs:
|
||||
mac.delete()
|
||||
|
||||
|
||||
class ClearLocalMacsCommand(_ClearMacsCommand):
|
||||
table_names = ['Ucast_Macs_Local', 'Mcast_Macs_Local']
|
||||
|
||||
|
||||
class ClearRemoteMacsCommand(_ClearMacsCommand):
|
||||
table_names = ['Ucast_Macs_Remote', 'Mcast_Macs_Remote']
|
||||
|
||||
|
||||
class _ListMacsCommand(cmd.ReadOnlyCommand):
|
||||
def __init__(self, api, switch):
|
||||
super().__init__(api)
|
||||
self.switch = switch
|
||||
|
||||
def run_idl(self, txn):
|
||||
switch = self.api.lookup('Logical_Switch', self.switch)
|
||||
self.result = []
|
||||
|
||||
for table_name in self.table_names:
|
||||
self.result.append([rowview.RowView(mac)
|
||||
for mac in idlutils.rows_by_value(
|
||||
self.api.idl, table_name,
|
||||
'logical_switch', switch)])
|
||||
|
||||
|
||||
class ListLocalMacsCommand(_ListMacsCommand):
|
||||
table_names = ['Ucast_Macs_Local', 'Mcast_Macs_Local']
|
||||
|
||||
|
||||
class ListRemoteMacsCommand(_ListMacsCommand):
|
||||
table_names = ['Ucast_Macs_Remote', 'Mcast_Macs_Remote']
|
86
ovsdbapp/schema/hardware_vtep/impl_idl.py
Normal file
86
ovsdbapp/schema/hardware_vtep/impl_idl.py
Normal file
@ -0,0 +1,86 @@
|
||||
# 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.
|
||||
|
||||
from ovsdbapp.backend import ovs_idl
|
||||
from ovsdbapp.backend.ovs_idl import idlutils
|
||||
from ovsdbapp.schema.hardware_vtep import api
|
||||
from ovsdbapp.schema.hardware_vtep import commands as cmd
|
||||
|
||||
|
||||
class HwVtepApiIdlImpl(ovs_idl.Backend, api.API):
|
||||
schema = 'hardware_vtep'
|
||||
lookup_table = {
|
||||
'Global': idlutils.RowLookup('Global', None, None),
|
||||
'Physical_Switch': idlutils.RowLookup('Physical_Switch', 'name', None),
|
||||
'Physical_Port': idlutils.RowLookup('Physical_Port', 'name', None),
|
||||
'Logical_Switch': idlutils.RowLookup('Logical_Switch', 'name', None),
|
||||
'Ucast_Macs_Local': idlutils.RowLookup('Ucast_Macs_Local', None, None),
|
||||
'Mcast_Macs_Local': idlutils.RowLookup('Mcast_Macs_Local', None, None),
|
||||
'Ucast_Macs_Remote': idlutils.RowLookup('Ucast_Macs_Remote',
|
||||
None, None),
|
||||
'Mcast_Macs_Remote': idlutils.RowLookup('Mcast_Macs_Remote',
|
||||
None, None),
|
||||
}
|
||||
|
||||
def add_ps(self, pswitch, may_exist=False, **columns):
|
||||
return cmd.AddPsCommand(self, pswitch, may_exist, **columns)
|
||||
|
||||
def del_ps(self, pswitch, if_exists=False):
|
||||
return cmd.DelPsCommand(self, pswitch, if_exists)
|
||||
|
||||
def list_ps(self):
|
||||
return cmd.ListPsCommand(self)
|
||||
|
||||
def get_ps(self, pswitch):
|
||||
return cmd.GetPsCommand(self, pswitch)
|
||||
|
||||
def add_port(self, pswitch, port, may_exist=False):
|
||||
return cmd.AddPortCommand(self, pswitch, port, may_exist)
|
||||
|
||||
def del_port(self, pswitch, port, if_exists=False):
|
||||
return cmd.DelPortCommand(self, pswitch, port, if_exists)
|
||||
|
||||
def list_ports(self, pswitch):
|
||||
return cmd.ListPortsCommand(self, pswitch)
|
||||
|
||||
def get_port(self, port):
|
||||
return cmd.GetPortCommand(self, port)
|
||||
|
||||
def add_ls(self, switch, may_exist=False, **columns):
|
||||
return cmd.AddLsCommand(self, switch, may_exist, **columns)
|
||||
|
||||
def del_ls(self, switch, if_exists=False):
|
||||
return cmd.DelLsCommand(self, switch, if_exists)
|
||||
|
||||
def list_ls(self):
|
||||
return cmd.ListLsCommand(self)
|
||||
|
||||
def get_ls(self, switch):
|
||||
return cmd.GetLsCommand(self, switch)
|
||||
|
||||
def bind_ls(self, pswitch, port, vlan, switch):
|
||||
return cmd.BindLsCommand(self, pswitch, port, vlan, switch)
|
||||
|
||||
def unbind_ls(self, pswitch, port, vlan):
|
||||
return cmd.UnbindLsCommand(self, pswitch, port, vlan)
|
||||
|
||||
def clear_local_macs(self, switch):
|
||||
return cmd.ClearLocalMacsCommand(self, switch)
|
||||
|
||||
def clear_remote_macs(self, switch):
|
||||
return cmd.ClearRemoteMacsCommand(self, switch)
|
||||
|
||||
def list_local_macs(self, switch):
|
||||
return cmd.ListLocalMacsCommand(self, switch)
|
||||
|
||||
def list_remote_macs(self, switch):
|
||||
return cmd.ListRemoteMacsCommand(self, switch)
|
28
ovsdbapp/tests/functional/schema/hardware_vtep/fixtures.py
Normal file
28
ovsdbapp/tests/functional/schema/hardware_vtep/fixtures.py
Normal file
@ -0,0 +1,28 @@
|
||||
# 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.
|
||||
|
||||
from ovsdbapp.schema.hardware_vtep import impl_idl
|
||||
from ovsdbapp.tests.functional.schema import fixtures
|
||||
|
||||
|
||||
class HwVtepApiFixture(fixtures.ApiImplFixture):
|
||||
api_cls = impl_idl.HwVtepApiIdlImpl
|
||||
|
||||
|
||||
class PhysicalSwitchFixture(fixtures.ImplIdlFixture):
|
||||
create = 'add_ps'
|
||||
delete = 'del_ps'
|
||||
|
||||
|
||||
class LogicalSwitchFixture(fixtures.ImplIdlFixture):
|
||||
create = 'add_ls'
|
||||
delete = 'del_ls'
|
387
ovsdbapp/tests/functional/schema/hardware_vtep/test_impl_idl.py
Normal file
387
ovsdbapp/tests/functional/schema/hardware_vtep/test_impl_idl.py
Normal file
@ -0,0 +1,387 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017 Red Hat, Inc.
|
||||
|
||||
# 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.
|
||||
|
||||
from ovsdbapp.backend.ovs_idl import idlutils
|
||||
from ovsdbapp.schema.hardware_vtep.commands import get_global_record
|
||||
from ovsdbapp.tests.functional import base
|
||||
from ovsdbapp.tests.functional.schema.hardware_vtep import fixtures
|
||||
from ovsdbapp.tests import utils
|
||||
|
||||
|
||||
class HardwareVtepTest(base.FunctionalTestCase):
|
||||
schemas = ["hardware_vtep"]
|
||||
fixture_class = base.venv.OvsVtepVenvFixture
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.schema_map = cls.schema_map.copy()
|
||||
cls.schema_map['hardware_vtep'] = cls.ovsvenv.ovs_connection
|
||||
|
||||
def setUp(self):
|
||||
if not self.ovsvenv.has_vtep:
|
||||
self.skipTest("Installed version of OVS does not support VTEP")
|
||||
super().setUp()
|
||||
self.api = self.useFixture(
|
||||
fixtures.HwVtepApiFixture(self.connection)).obj
|
||||
|
||||
|
||||
class TestPhysicalSwitchOps(HardwareVtepTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.table = self.api.tables['Physical_Switch']
|
||||
self.config = get_global_record(self.api)
|
||||
|
||||
def _add_ps(self, *args, **kwargs):
|
||||
ps = self.useFixture(fixtures.PhysicalSwitchFixture(self.api, *args,
|
||||
**kwargs)).obj
|
||||
self.assertIn(ps.uuid, self.table.rows)
|
||||
self.assertIn(ps, self.config.switches)
|
||||
return ps
|
||||
|
||||
def _test_get_ps(self, col):
|
||||
ps = self._add_ps(pswitch=utils.get_rand_device_name())
|
||||
val = getattr(ps, col)
|
||||
found = self.api.get_ps(val).execute(check_error=True)
|
||||
self.assertEqual(ps, found)
|
||||
|
||||
def test_get_ps_uuid(self):
|
||||
self._test_get_ps('uuid')
|
||||
|
||||
def test_get_ps_name(self):
|
||||
self._test_get_ps('name')
|
||||
|
||||
def test_add_ps_name(self):
|
||||
name = utils.get_rand_device_name()
|
||||
sw = self._add_ps(name)
|
||||
self.assertEqual(name, sw.name)
|
||||
|
||||
def test_add_ps_exists(self):
|
||||
name = utils.get_rand_device_name()
|
||||
self._add_ps(name)
|
||||
cmd = self.api.add_ps(name)
|
||||
self.assertRaises(RuntimeError, cmd.execute, check_error=True)
|
||||
|
||||
def test_add_ps_may_exist(self):
|
||||
name = utils.get_rand_device_name()
|
||||
sw = self._add_ps(name)
|
||||
sw2 = self.api.add_ps(name, may_exist=True).execute(check_error=True)
|
||||
self.assertEqual(sw, sw2)
|
||||
|
||||
def test_del_ps(self):
|
||||
name = utils.get_rand_device_name()
|
||||
sw = self._add_ps(name)
|
||||
self.api.del_ps(sw.uuid).execute(check_error=True)
|
||||
self.assertNotIn(sw.uuid, self.table.rows)
|
||||
self.assertNotIn(sw, self.config.switches)
|
||||
|
||||
def test_del_ps_by_name(self):
|
||||
name = utils.get_rand_device_name()
|
||||
sw = self._add_ps(name)
|
||||
self.api.del_ps(name).execute(check_error=True)
|
||||
self.assertNotIn(sw.uuid, self.table.rows)
|
||||
self.assertNotIn(sw, self.config.switches)
|
||||
|
||||
def test_del_ps_no_exist(self):
|
||||
name = utils.get_rand_device_name()
|
||||
cmd = self.api.del_ps(name)
|
||||
self.assertRaises(RuntimeError, cmd.execute, check_error=True)
|
||||
|
||||
def test_del_ps_if_exists(self):
|
||||
name = utils.get_rand_device_name()
|
||||
self.api.del_ps(name, if_exists=True).execute(check_error=True)
|
||||
|
||||
def test_list_ps(self):
|
||||
switches = {self._add_ps(str(i)) for i in range(3)}
|
||||
switch_set = set(self.api.list_ps().execute(check_error=True))
|
||||
self.assertTrue(switches.issubset(switch_set))
|
||||
|
||||
|
||||
class TestPhysicalPortOps(HardwareVtepTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.table = self.api.tables['Physical_Port']
|
||||
self.ps = self.useFixture(fixtures.PhysicalSwitchFixture(
|
||||
self.api, utils.get_rand_device_name())).obj
|
||||
|
||||
def _add_port(self, *args, name=None, **kwargs):
|
||||
port = self.api.add_port(self.ps.uuid,
|
||||
name or utils.get_rand_device_name(),
|
||||
*args, **kwargs).execute()
|
||||
self.assertIn(port.uuid, self.table.rows)
|
||||
self.assertIn(port, self.ps.ports)
|
||||
return port
|
||||
|
||||
def _test_get_port(self, col):
|
||||
port = self._add_port(name=utils.get_rand_device_name())
|
||||
val = getattr(port, col)
|
||||
found = self.api.get_port(val).execute(check_error=True)
|
||||
self.assertEqual(port, found)
|
||||
|
||||
def test_get_port_uuid(self):
|
||||
self._test_get_port('uuid')
|
||||
|
||||
def test_get_port_name(self):
|
||||
self._test_get_port('name')
|
||||
|
||||
def test_add_port_name(self):
|
||||
name = utils.get_rand_device_name()
|
||||
port = self._add_port(name=name)
|
||||
self.assertEqual(name, port.name)
|
||||
|
||||
def test_add_port_exists(self):
|
||||
name = utils.get_rand_device_name()
|
||||
self._add_port(name=name)
|
||||
cmd = self.api.add_port(self.ps.uuid, name)
|
||||
self.assertRaises(RuntimeError, cmd.execute, check_error=True)
|
||||
|
||||
def test_add_port_may_exist(self):
|
||||
name = utils.get_rand_device_name()
|
||||
port = self._add_port(name=name)
|
||||
port2 = self.api.add_port(
|
||||
self.ps.uuid, name, may_exist=True).execute(check_error=True)
|
||||
self.assertEqual(port, port2)
|
||||
|
||||
def test_del_port(self):
|
||||
port = self._add_port()
|
||||
self.api.del_port(self.ps.name, port.name).execute(check_error=True)
|
||||
self.assertNotIn(port.uuid, self.table.rows)
|
||||
self.assertNotIn(port, self.ps.ports)
|
||||
|
||||
def test_del_port_by_name(self):
|
||||
name = utils.get_rand_device_name()
|
||||
port = self._add_port(name=name)
|
||||
self.api.del_port(self.ps.uuid, name).execute(check_error=True)
|
||||
self.assertNotIn(port.uuid, self.table.rows)
|
||||
self.assertNotIn(port, self.ps.ports)
|
||||
|
||||
def test_del_port_no_exist(self):
|
||||
name = utils.get_rand_device_name()
|
||||
cmd = self.api.del_port(self.ps.uuid, name)
|
||||
self.assertRaises(RuntimeError, cmd.execute, check_error=True)
|
||||
|
||||
def test_del_ps_if_exists(self):
|
||||
name = utils.get_rand_device_name()
|
||||
self.api.del_port(self.ps.uuid, name, if_exists=True).execute(
|
||||
check_error=True)
|
||||
|
||||
def test_list_ps(self):
|
||||
ports = {self._add_port(str(i)) for i in range(3)}
|
||||
port_set = set(self.api.list_ports(
|
||||
self.ps.uuid).execute(check_error=True))
|
||||
self.assertTrue(ports.issubset(port_set))
|
||||
|
||||
|
||||
class TestLogicalSwitchOps(HardwareVtepTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.table = self.api.tables['Logical_Switch']
|
||||
self.vlan = 10
|
||||
|
||||
def _add_ls(self, *args, **kwargs):
|
||||
ls = self.useFixture(fixtures.LogicalSwitchFixture(self.api, *args,
|
||||
**kwargs)).obj
|
||||
self.assertIn(ls.uuid, self.table.rows)
|
||||
return ls
|
||||
|
||||
def _test_get_ls(self, col):
|
||||
ls = self._add_ls(switch=utils.get_rand_device_name())
|
||||
val = getattr(ls, col)
|
||||
found = self.api.get_ls(val).execute(check_error=True)
|
||||
self.assertEqual(ls, found)
|
||||
|
||||
def test_get_ls_uuid(self):
|
||||
self._test_get_ls('uuid')
|
||||
|
||||
def test_get_ls_name(self):
|
||||
self._test_get_ls('name')
|
||||
|
||||
def test_add_ls_name(self):
|
||||
name = utils.get_rand_device_name()
|
||||
sw = self._add_ls(name)
|
||||
self.assertEqual(name, sw.name)
|
||||
|
||||
def test_add_ls_exists(self):
|
||||
name = utils.get_rand_device_name()
|
||||
self._add_ls(name)
|
||||
cmd = self.api.add_ls(name)
|
||||
self.assertRaises(RuntimeError, cmd.execute, check_error=True)
|
||||
|
||||
def test_add_ls_may_exist(self):
|
||||
name = utils.get_rand_device_name()
|
||||
sw = self._add_ls(name)
|
||||
sw2 = self.api.add_ls(name, may_exist=True).execute(check_error=True)
|
||||
self.assertEqual(sw, sw2)
|
||||
|
||||
def test_del_ls(self):
|
||||
name = utils.get_rand_device_name()
|
||||
sw = self._add_ls(name)
|
||||
self.api.del_ls(sw.uuid).execute(check_error=True)
|
||||
self.assertNotIn(sw.uuid, self.table.rows)
|
||||
|
||||
def test_del_ls_by_name(self):
|
||||
name = utils.get_rand_device_name()
|
||||
self._add_ls(name)
|
||||
self.api.del_ls(name).execute(check_error=True)
|
||||
|
||||
def test_del_ls_no_exist(self):
|
||||
name = utils.get_rand_device_name()
|
||||
cmd = self.api.del_ls(name)
|
||||
self.assertRaises(RuntimeError, cmd.execute, check_error=True)
|
||||
|
||||
def test_del_ls_if_exists(self):
|
||||
name = utils.get_rand_device_name()
|
||||
self.api.del_ls(name, if_exists=True).execute(check_error=True)
|
||||
|
||||
def test_list_ls(self):
|
||||
switches = {self._add_ls(str(i)) for i in range(3)}
|
||||
switch_set = set(self.api.list_ls().execute(check_error=True))
|
||||
self.assertTrue(switches.issubset(switch_set))
|
||||
|
||||
def test_bind_unbind_ls(self):
|
||||
name = utils.get_rand_device_name()
|
||||
switch = self._add_ls(name)
|
||||
ps = self.useFixture(fixtures.PhysicalSwitchFixture(
|
||||
self.api, name)).obj
|
||||
port = self.api.add_port(ps.uuid, name,
|
||||
may_exist=True).execute(check_error=True)
|
||||
|
||||
self.api.bind_ls(ps.name, port.name,
|
||||
self.vlan, switch.name).execute(check_error=True)
|
||||
self.assertEqual(port.vlan_bindings, {self.vlan: switch})
|
||||
|
||||
self.api.unbind_ls(ps.name, port.name,
|
||||
self.vlan).execute(check_error=True)
|
||||
self.assertEqual(port.vlan_bindings, {})
|
||||
|
||||
def _test_bind_ls_no_exist(self,
|
||||
pswitch_name=None,
|
||||
port_name=None,
|
||||
switch_name=None):
|
||||
cmd = self.api.bind_ls(pswitch_name, port_name, self.vlan, switch_name)
|
||||
self.assertRaises(idlutils.RowNotFound, cmd.execute, check_error=True)
|
||||
|
||||
def test_bind_ls_pswitch_no_exist(self):
|
||||
name = utils.get_rand_device_name()
|
||||
switch = self._add_ls(utils.get_rand_device_name())
|
||||
self._test_bind_ls_no_exist(pswitch_name=name,
|
||||
port_name=name,
|
||||
switch_name=switch.name)
|
||||
|
||||
def test_bind_ls_port_no_exist(self):
|
||||
name = utils.get_rand_device_name()
|
||||
switch = self._add_ls(utils.get_rand_device_name())
|
||||
ps = self.useFixture(fixtures.PhysicalSwitchFixture(
|
||||
self.api, utils.get_rand_device_name())).obj
|
||||
self._test_bind_ls_no_exist(pswitch_name=ps.name,
|
||||
port_name=name,
|
||||
switch_name=switch.name)
|
||||
|
||||
def test_bind_ls_switch_no_exist(self):
|
||||
name = utils.get_rand_device_name()
|
||||
ps = self.useFixture(fixtures.PhysicalSwitchFixture(
|
||||
self.api, utils.get_rand_device_name())).obj
|
||||
port = self.api.add_port(ps.uuid, utils.get_rand_device_name(),
|
||||
may_exist=True).execute(check_error=True)
|
||||
self._test_bind_ls_no_exist(pswitch_name=ps.name,
|
||||
port_name=port.name,
|
||||
switch_name=name)
|
||||
|
||||
def test_unbind_ls_no_exist(self):
|
||||
name = utils.get_rand_device_name()
|
||||
switch = self._add_ls(name)
|
||||
ps = self.useFixture(fixtures.PhysicalSwitchFixture(
|
||||
self.api, name)).obj
|
||||
port = self.api.add_port(ps.uuid, name,
|
||||
may_exist=True).execute(check_error=True)
|
||||
self.api.bind_ls(ps.name, port.name,
|
||||
self.vlan, switch.name).execute(check_error=True)
|
||||
|
||||
for pswitch, port in [('pswitch', port.name), (ps.name, 'port')]:
|
||||
cmd = self.api.unbind_ls(pswitch, port, self.vlan)
|
||||
self.assertRaises(idlutils.RowNotFound, cmd.execute,
|
||||
check_error=True)
|
||||
|
||||
def test_unbind_ls_vlan_no_exists(self):
|
||||
name = utils.get_rand_device_name()
|
||||
switch = self._add_ls(name)
|
||||
ps = self.useFixture(fixtures.PhysicalSwitchFixture(
|
||||
self.api, name)).obj
|
||||
port = self.api.add_port(ps.uuid, name,
|
||||
may_exist=True).execute(check_error=True)
|
||||
self.api.bind_ls(ps.name, port.name,
|
||||
self.vlan, switch.name).execute(check_error=True)
|
||||
vlan_bindings = port.vlan_bindings.copy()
|
||||
self.api.unbind_ls(ps.name, port.name,
|
||||
self.vlan + 1).execute(check_error=True)
|
||||
self.assertEqual(port.vlan_bindings, vlan_bindings)
|
||||
|
||||
|
||||
class TestMacBindingsOps(HardwareVtepTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.ls = self.useFixture(fixtures.LogicalSwitchFixture(
|
||||
self.api, utils.get_rand_device_name())).obj
|
||||
self.mac = '0a:00:d0:af:20:c0'
|
||||
self.ip = '192.168.0.1'
|
||||
self.ovsvenv.call(['vtep-ctl', 'add-ucast-local',
|
||||
self.ls.name, self.mac, self.ip])
|
||||
self.ovsvenv.call(['vtep-ctl', 'add-mcast-local',
|
||||
self.ls.name, self.mac, self.ip])
|
||||
self.ovsvenv.call(['vtep-ctl', 'add-ucast-remote',
|
||||
self.ls.name, self.mac, self.ip])
|
||||
self.ovsvenv.call(['vtep-ctl', 'add-mcast-remote',
|
||||
self.ls.name, self.mac, self.ip])
|
||||
for args in [
|
||||
['vtep-ctl', 'del-ucast-local', self.ls.name, self.mac],
|
||||
['vtep-ctl', 'del-mcast-local', self.ls.name, self.mac, self.ip],
|
||||
['vtep-ctl', 'del-ucast-remote', self.ls.name, self.mac],
|
||||
['vtep-ctl', 'del-mcast-remote', self.ls.name, self.mac, self.ip]
|
||||
]:
|
||||
self.addCleanup(self.ovsvenv.call, args)
|
||||
|
||||
def test_list_local_macs(self):
|
||||
local_macs = self.api.list_local_macs(
|
||||
self.ls.name).execute(check_error=True)
|
||||
for macs in local_macs:
|
||||
self.assertEqual(len(macs), 1)
|
||||
self.assertEqual(macs[0].MAC, self.mac)
|
||||
|
||||
def test_list_remote_macs(self):
|
||||
remote_macs = self.api.list_remote_macs(
|
||||
self.ls.name).execute(check_error=True)
|
||||
for macs in remote_macs:
|
||||
self.assertEqual(len(macs), 1)
|
||||
self.assertEqual(macs[0].MAC, self.mac)
|
||||
|
||||
def test_clear_local_macs(self):
|
||||
ucast_table = self.api.tables['Ucast_Macs_Local']
|
||||
mcast_table = self.api.tables['Mcast_Macs_Local']
|
||||
for table in [ucast_table, mcast_table]:
|
||||
self.assertEqual(len(table.rows), 1)
|
||||
|
||||
self.api.clear_local_macs(self.ls.name).execute(check_error=True)
|
||||
for table in [ucast_table, mcast_table]:
|
||||
self.assertEqual(len(table.rows), 0)
|
||||
|
||||
def test_clear_remote_macs(self):
|
||||
ucast_table = self.api.tables['Ucast_Macs_Remote']
|
||||
mcast_table = self.api.tables['Mcast_Macs_Remote']
|
||||
for table in [ucast_table, mcast_table]:
|
||||
self.assertEqual(len(table.rows), 1)
|
||||
|
||||
self.api.clear_remote_macs(self.ls.name).execute(check_error=True)
|
||||
for table in [ucast_table, mcast_table]:
|
||||
self.assertEqual(len(table.rows), 0)
|
@ -32,6 +32,8 @@ class OvsVenvFixture(fixtures.Fixture):
|
||||
os.path.join(os.path.sep, 'usr', 'local', 'share', 'openvswitch'),
|
||||
os.path.join(os.path.sep, 'usr', 'share', 'openvswitch'))
|
||||
|
||||
OVS_SCHEMA = 'vswitch.ovsschema'
|
||||
|
||||
def __init__(self, venv, ovsdir=None, dummy=DUMMY_OVERRIDE_ALL,
|
||||
remove=False):
|
||||
"""Initialize fixture
|
||||
@ -76,10 +78,10 @@ class OvsVenvFixture(fixtures.Fixture):
|
||||
|
||||
@property
|
||||
def ovs_schema(self):
|
||||
path = os.path.join(self.ovsdir, 'vswitchd', 'vswitch.ovsschema')
|
||||
path = os.path.join(self.ovsdir, 'vswitchd', self.OVS_SCHEMA)
|
||||
if os.path.isfile(path):
|
||||
return path
|
||||
return os.path.join(self.ovsdir, 'vswitch.ovsschema')
|
||||
return os.path.join(self.ovsdir, self.OVS_SCHEMA)
|
||||
|
||||
@property
|
||||
def dummy_arg(self):
|
||||
@ -275,3 +277,37 @@ class OvsOvnIcVenvFixture(OvsOvnVenvFixture):
|
||||
def init_processes(self):
|
||||
super().init_processes()
|
||||
self.call(['ovn-ic-nbctl', 'init'])
|
||||
|
||||
|
||||
class OvsVtepVenvFixture(OvsOvnVenvFixture):
|
||||
VTEP_SCHEMA = 'vtep.ovsschema'
|
||||
|
||||
def __init__(self, venv, vtepdir=None, **kwargs):
|
||||
if vtepdir and os.path.isdir(vtepdir):
|
||||
self.PATH_VAR_TEMPLATE += ":{0}".format(vtepdir)
|
||||
self.vtepdir = self._share_path(self.OVS_PATHS, vtepdir)
|
||||
super().__init__(venv, **kwargs)
|
||||
|
||||
def _setUp(self):
|
||||
if self.has_vtep:
|
||||
super()._setUp()
|
||||
|
||||
@property
|
||||
def vtep_schema(self):
|
||||
return os.path.join(self.vtepdir, self.VTEP_SCHEMA)
|
||||
|
||||
@property
|
||||
def has_vtep(self):
|
||||
return os.path.isfile(self.vtep_schema)
|
||||
|
||||
def setup_dbs(self):
|
||||
db_filename = 'vtep.conf'
|
||||
super().setup_dbs()
|
||||
self.create_db(db_filename, self.vtep_schema)
|
||||
self.ovsdb_server_dbs.append(db_filename)
|
||||
|
||||
def init_processes(self):
|
||||
super().init_processes()
|
||||
# there are no 'init' method in vtep-ctl,
|
||||
# but record in 'Global' table is needed
|
||||
self.call(['vtep-ctl', 'show'])
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added support for the "hardware_vtep" schema. The ``HwVtepApiIdlImpl`` class provides
|
||||
interaction with "hw_vtep.db", adds support to add, delete and list registers rows of
|
||||
"Physical_Switch", "Physical_Port" and "Logical_Switch" tables. Also added support for
|
||||
listing and clearing the remote and local multicast and unicast MAC bindings.
|
Loading…
x
Reference in New Issue
Block a user