nb: add support for set of addresses API
This change adds functions and commands to add, delete, list, get and update sets of addresses. Closes-Bug: #1951110 Change-Id: I9390bf5e3586a3dd28c3743d06578c2a8f262e77
This commit is contained in:
parent
0e4c7a056c
commit
641b6b857e
@ -206,6 +206,68 @@ class API(api.API, metaclass=abc.ABCMeta):
|
||||
:returns: :class:`Command` with RowView list result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def address_set_add(self, name, addresses=None, may_exist=False):
|
||||
"""Create a set of addresses named 'name'
|
||||
|
||||
:param name: The name of the address set
|
||||
:type name: string
|
||||
:param addresses: One or more IP addresses to add to the address set
|
||||
:type addresses: list of strings
|
||||
:param may_exist: If True, don't fail if the address set already exists
|
||||
:type may_exist: boolean
|
||||
:returns: :class:`Command` with RowView result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def address_set_del(self, address_set, if_exists=False):
|
||||
"""Delete a set of addresses 'address_set'
|
||||
|
||||
:param address_set: The name of the address set
|
||||
:type address_set: string or uuid.UUID
|
||||
:param if_exists: Do not fail if the Address_set row does not exist
|
||||
:type if_exists: bool
|
||||
:returns: :class:`Command` with no result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def address_set_get(self, address_set):
|
||||
"""Get a set of addresses for 'address_set'
|
||||
|
||||
:param address_set: The name of the address set
|
||||
:type address_set: string or uuid.UUID
|
||||
:returns: :class:`Command` with RowView result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def address_set_list(self):
|
||||
"""Get all sets of addresses
|
||||
|
||||
:returns: :class:`Command` with RowView list result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def address_set_add_addresses(self, address_set, addresses):
|
||||
"""Add a list of addresses to 'address_set'
|
||||
|
||||
:param address_set: The name of the address set
|
||||
:type address_set: string or uuid.UUID
|
||||
:param addresses: One or more IP addresses to add to the address set
|
||||
:type addresses: string or list of strings
|
||||
:returns: :class:`Command` with no result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def address_set_remove_addresses(self, address_set, addresses):
|
||||
"""Remove a list of addresses from 'address_set'
|
||||
|
||||
:param address_set: The name of the address set
|
||||
:type address_set: string or uuid.UUID
|
||||
:param addresses: One or more IP addresses to remove from address set
|
||||
:type addresses: string of list of strings
|
||||
:returns: :class:`Command` with no result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def qos_add(self, switch, direction, priority, match, rate=None,
|
||||
burst=None, dscp=None, may_exist=False, **columns):
|
||||
|
@ -214,6 +214,88 @@ class PgAclListCommand(_AclListHelper):
|
||||
lookup_table = 'Port_Group'
|
||||
|
||||
|
||||
class AddressSetAddCommand(cmd.AddCommand):
|
||||
table_name = 'Address_Set'
|
||||
|
||||
def __init__(self, api, name, addresses=None, may_exist=False):
|
||||
super().__init__(api)
|
||||
self.name = name
|
||||
self.addresses = [str(netaddr.IPAddress(address))
|
||||
for address in addresses or []]
|
||||
self.may_exist = may_exist
|
||||
|
||||
def run_idl(self, txn):
|
||||
address_set = self.api.lookup(self.table_name, self.name, None)
|
||||
if address_set:
|
||||
if self.may_exist:
|
||||
self.result = rowview.RowView(address_set)
|
||||
return
|
||||
raise RuntimeError("Address set %s exists" % self.name)
|
||||
|
||||
address_set = txn.insert(self.api.tables[self.table_name])
|
||||
address_set.name = self.name
|
||||
if self.addresses:
|
||||
address_set.addresses = self.addresses
|
||||
self.result = address_set.uuid
|
||||
|
||||
|
||||
class AddressSetDelCommand(cmd.BaseCommand):
|
||||
table_name = 'Address_Set'
|
||||
|
||||
def __init__(self, api, address_set, if_exists=False):
|
||||
super().__init__(api)
|
||||
self.address_set = address_set
|
||||
self.if_exists = if_exists
|
||||
|
||||
def run_idl(self, txn):
|
||||
try:
|
||||
address_set = self.api.lookup(self.table_name, self.address_set)
|
||||
address_set.delete()
|
||||
except idlutils.RowNotFound as e:
|
||||
if self.if_exists:
|
||||
return
|
||||
msg = "Address set %s does not exist" % self.address_set
|
||||
raise RuntimeError(msg) from e
|
||||
|
||||
|
||||
class AddressSetGetCommand(cmd.BaseGetRowCommand):
|
||||
table = 'Address_Set'
|
||||
|
||||
|
||||
class AddressSetListCommand(cmd.ReadOnlyCommand):
|
||||
table = 'Address_Set'
|
||||
|
||||
def run_idl(self, txn):
|
||||
self.result = [rowview.RowView(r) for
|
||||
r in self.api.tables[self.table].rows.values()]
|
||||
|
||||
|
||||
class AddressSetUpdateAddressesCommand(cmd.BaseCommand):
|
||||
table_name = 'Address_Set'
|
||||
|
||||
def __init__(self, api, address_set, addresses):
|
||||
super().__init__(api)
|
||||
self.address_set = address_set
|
||||
if isinstance(addresses, (str, bytes)):
|
||||
addresses = [addresses]
|
||||
self.addresses = [str(netaddr.IPAddress(address))
|
||||
for address in addresses]
|
||||
|
||||
|
||||
class AddressSetAddAddressesCommand(AddressSetUpdateAddressesCommand):
|
||||
def run_idl(self, txn):
|
||||
address_set = self.api.lookup(self.table_name, self.address_set)
|
||||
for address in self.addresses:
|
||||
address_set.addvalue('addresses', address)
|
||||
|
||||
|
||||
class AddressSetRemoveAddressCommand(AddressSetUpdateAddressesCommand):
|
||||
def run_idl(self, txn):
|
||||
address_set = self.api.lookup(self.table_name, self.address_set)
|
||||
for address in self.addresses:
|
||||
address_set.delvalue('addresses', address)
|
||||
|
||||
|
||||
class QoSAddCommand(cmd.AddCommand):
|
||||
table_name = 'QoS'
|
||||
|
||||
|
@ -80,6 +80,24 @@ class OvnNbApiIdlImpl(ovs_idl.Backend, api.API):
|
||||
def pg_acl_list(self, port_group):
|
||||
return cmd.PgAclListCommand(self, port_group)
|
||||
|
||||
def address_set_add(self, name, addresses=None, may_exist=False):
|
||||
return cmd.AddressSetAddCommand(self, name, addresses, may_exist)
|
||||
|
||||
def address_set_del(self, address_set, if_exists=False):
|
||||
return cmd.AddressSetDelCommand(self, address_set, if_exists)
|
||||
|
||||
def address_set_get(self, address_set):
|
||||
return cmd.AddressSetGetCommand(self, address_set)
|
||||
|
||||
def address_set_list(self):
|
||||
return cmd.AddressSetListCommand(self)
|
||||
|
||||
def address_set_add_addresses(self, address_set, addresses):
|
||||
return cmd.AddressSetAddAddressesCommand(self, address_set, addresses)
|
||||
|
||||
def address_set_remove_addresses(self, address_set, addresses):
|
||||
return cmd.AddressSetRemoveAddressCommand(self, address_set, addresses)
|
||||
|
||||
def qos_add(self, switch, direction, priority, match, rate=None,
|
||||
burst=None, dscp=None, may_exist=False, **columns):
|
||||
return cmd.QoSAddCommand(self, switch, direction, priority, match,
|
||||
|
@ -45,6 +45,11 @@ class PortGroupFixture(fixtures.ImplIdlFixture):
|
||||
delete = 'pg_del'
|
||||
|
||||
|
||||
class AddressSetFixture(fixtures.ImplIdlFixture):
|
||||
create = 'address_set_add'
|
||||
delete = 'address_set_del'
|
||||
|
||||
|
||||
class MeterFixture(fixtures.ImplIdlFixture):
|
||||
create = 'meter_add'
|
||||
delete = 'meter_del'
|
||||
|
@ -236,6 +236,116 @@ class TestAclOps(OvnNorthboundTest):
|
||||
self.assertIn(r2, acls)
|
||||
|
||||
|
||||
class TestAddressSetOps(OvnNorthboundTest):
|
||||
def setUp(self):
|
||||
super(TestAddressSetOps, self).setUp()
|
||||
self.table = self.api.tables['Address_Set']
|
||||
|
||||
def _addr_set_add(self, name=None, *args, **kwargs):
|
||||
if name is None:
|
||||
name = utils.get_rand_name()
|
||||
fix = self.useFixture(fixtures.AddressSetFixture(self.api, name,
|
||||
*args, **kwargs))
|
||||
self.assertIn(fix.obj.uuid, self.table.rows)
|
||||
return fix.obj
|
||||
|
||||
def _test_addr_set_get(self, col):
|
||||
addr_set = self._addr_set_add()
|
||||
val = getattr(addr_set, col)
|
||||
found = self.api.address_set_get(val).execute(check_error=True)
|
||||
self.assertEqual(addr_set, found)
|
||||
|
||||
def test_addr_set_get_uuid(self):
|
||||
self._test_addr_set_get('uuid')
|
||||
|
||||
def test_addr_set_get_name(self):
|
||||
self._test_addr_set_get('name')
|
||||
|
||||
def test_addr_set_add_name(self):
|
||||
name = utils.get_rand_device_name()
|
||||
addr_set = self._addr_set_add(name)
|
||||
self.assertEqual(name, addr_set.name)
|
||||
|
||||
def test_addr_set_add_exists(self):
|
||||
name = utils.get_rand_device_name()
|
||||
self._addr_set_add(name)
|
||||
cmd = self.api.address_set_add(name)
|
||||
self.assertRaises(RuntimeError, cmd.execute, check_error=True)
|
||||
|
||||
def test_addr_set_add_may_exist(self):
|
||||
name = utils.get_rand_device_name()
|
||||
addr_set = self._addr_set_add(name)
|
||||
addr_set2 = self.api.address_set_add(
|
||||
name, may_exist=True).execute(check_error=True)
|
||||
self.assertEqual(addr_set, addr_set2)
|
||||
|
||||
def test_addr_set_add_with_addresses(self):
|
||||
addresses = ['192.168.0.1', '192.168.0.2']
|
||||
addr_set = self._addr_set_add(addresses=addresses)
|
||||
self.assertEqual(addresses, addr_set.addresses)
|
||||
|
||||
def test_addr_set_del(self):
|
||||
addr_set = self._addr_set_add()
|
||||
self.api.address_set_del(addr_set.uuid).execute(check_error=True)
|
||||
self.assertNotIn(addr_set.uuid, self.table.rows)
|
||||
|
||||
def test_addr_set_del_by_name(self):
|
||||
name = utils.get_rand_device_name()
|
||||
self._addr_set_add(name)
|
||||
self.api.address_set_del(name).execute(check_error=True)
|
||||
|
||||
def test_addr_set_del_no_exist(self):
|
||||
name = utils.get_rand_device_name()
|
||||
cmd = self.api.address_set_del(name)
|
||||
self.assertRaises(RuntimeError, cmd.execute, check_error=True)
|
||||
|
||||
def test_addr_set_del_if_exists(self):
|
||||
name = utils.get_rand_device_name()
|
||||
self.api.address_set_del(
|
||||
name, if_exists=True).execute(check_error=True)
|
||||
|
||||
def test_addr_set_list(self):
|
||||
addr_sets = {self._addr_set_add() for _ in range(3)}
|
||||
found_sets = set(self.api.address_set_list().execute(check_error=True))
|
||||
self.assertTrue(addr_sets.issubset(found_sets))
|
||||
|
||||
def test_addr_set_add_addresses(self):
|
||||
addresses = ['192.168.0.1', '192.168.0.2']
|
||||
addr_set = self._addr_set_add()
|
||||
|
||||
self.api.address_set_add_addresses(
|
||||
addr_set.uuid, addresses).execute(check_error=True)
|
||||
self.assertEqual(addresses, addr_set.addresses)
|
||||
|
||||
self.api.address_set_add_addresses(
|
||||
addr_set.uuid, addresses).execute(check_error=True)
|
||||
self.assertEqual(addresses, addr_set.addresses)
|
||||
|
||||
def test_addr_set_remove_addresses(self):
|
||||
addresses = ['192.168.0.1', '192.168.0.2']
|
||||
addr_set = self._addr_set_add(addresses=addresses)
|
||||
|
||||
self.api.address_set_remove_addresses(
|
||||
addr_set.uuid, addresses).execute(check_error=True)
|
||||
self.assertEqual(addr_set.addresses, [])
|
||||
|
||||
self.api.address_set_remove_addresses(
|
||||
addr_set.uuid, addresses).execute(check_error=True)
|
||||
self.assertEqual(addr_set.addresses, [])
|
||||
|
||||
def test_addr_set_add_remove_addresses_by_str(self):
|
||||
address = "192.168.0.1"
|
||||
addr_set = self._addr_set_add()
|
||||
|
||||
self.api.address_set_add_addresses(
|
||||
addr_set.uuid, address).execute(check_error=True)
|
||||
self.assertEqual([address], addr_set.addresses)
|
||||
|
||||
self.api.address_set_remove_addresses(
|
||||
addr_set.uuid, address).execute(check_error=True)
|
||||
self.assertEqual([], addr_set.addresses)
|
||||
|
||||
|
||||
class TestQoSOps(OvnNorthboundTest):
|
||||
def setUp(self):
|
||||
super(TestQoSOps, self).setUp()
|
||||
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added functions and commands to add, delete, list and update records of 'Address_Set' table.
|
Loading…
Reference in New Issue
Block a user