Add QoSDelExtIdCommand
This command removes all QoS rules matching a set of keys and expected values passed in the command instantiation. No exception is thrown if no QoS is found with the required external IDs. For example, this will be used in Neutron to delete all QoS registers related to a floating IP, searching for neutron.common.ovn.constants.OVN_FIP_EXT_ID_KEY key and the floating IP register UUID. Change-Id: I0eb7151eabaf40232f79797b2775c9bb7891013f Related-Bug: #1877408
This commit is contained in:
parent
7736bac7dc
commit
08605e94a4
|
@ -249,6 +249,19 @@ class API(api.API, metaclass=abc.ABCMeta):
|
|||
:returns: :class:`Command` with RowView list result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def qos_del_ext_ids(self, lswitch_name, external_ids, if_exists=True):
|
||||
"""Delete all QoS rules related to a floating IP.
|
||||
|
||||
:param lswitch_name: The unique name of the logical switch
|
||||
:type lswitch_name: string
|
||||
:param external_ids: Pairs of key/value to find in the "external_ids"
|
||||
:type external_ids: dict
|
||||
:param if_exists: Do not fail if the Logical_Switch row does not exist
|
||||
:type if_exists: bool
|
||||
:returns: :class:`Command` with no result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def lsp_add(self, switch, port, parent_name=None, tag=None,
|
||||
may_exist=False, **columns):
|
||||
|
|
|
@ -303,6 +303,31 @@ class QoSListCommand(cmd.ReadOnlyCommand):
|
|||
self.result = [rowview.RowView(row) for row in ls.qos_rules]
|
||||
|
||||
|
||||
class QoSDelExtIdCommand(cmd.BaseCommand):
|
||||
def __init__(self, api, lswitch, external_ids, if_exists=False):
|
||||
if not external_ids:
|
||||
raise TypeError('external_ids dictionary cannot be empty')
|
||||
super(QoSDelExtIdCommand, self).__init__(api)
|
||||
self.lswitch = lswitch
|
||||
self.external_ids = external_ids
|
||||
self.if_exists = if_exists
|
||||
|
||||
def run_idl(self, txn):
|
||||
try:
|
||||
lswitch = idlutils.row_by_value(self.api.idl, 'Logical_Switch',
|
||||
'name', self.lswitch)
|
||||
except idlutils.RowNotFound:
|
||||
if self.if_exists:
|
||||
return
|
||||
msg = 'Logical Switch %s does not exist' % self.lswitch
|
||||
raise RuntimeError(msg)
|
||||
|
||||
for qos in lswitch.qos_rules:
|
||||
if self.external_ids.items() <= qos.external_ids.items():
|
||||
lswitch.delvalue('qos_rules', qos)
|
||||
qos.delete()
|
||||
|
||||
|
||||
class LspAddCommand(cmd.AddCommand):
|
||||
table_name = 'Logical_Switch_Port'
|
||||
|
||||
|
|
|
@ -89,6 +89,10 @@ class OvnNbApiIdlImpl(ovs_idl.Backend, api.API):
|
|||
def qos_list(self, switch):
|
||||
return cmd.QoSListCommand(self, switch)
|
||||
|
||||
def qos_del_ext_ids(self, lswitch_name, external_ids, if_exists=True):
|
||||
return cmd.QoSDelExtIdCommand(self, lswitch_name, external_ids,
|
||||
if_exists=if_exists)
|
||||
|
||||
def lsp_add(self, switch, port, parent_name=None, tag=None,
|
||||
may_exist=False, **columns):
|
||||
return cmd.LspAddCommand(self, switch, port, parent_name, tag,
|
||||
|
|
|
@ -318,6 +318,69 @@ class TestQoSOps(OvnNorthboundTest):
|
|||
self.assertIn(r1, qos_rules)
|
||||
self.assertIn(r2, qos_rules)
|
||||
|
||||
def _create_fip_qoses(self):
|
||||
ext_ids_1 = {'key1': 'value1', 'key2': 'value2'}
|
||||
self.qos_1 = self._qos_add('from-lport', 0, 'output == "fake_port1"',
|
||||
dscp=11, external_ids=ext_ids_1)
|
||||
ext_ids_2 = {'key3': 'value3', 'key4': 'value4'}
|
||||
self.qos_2 = self._qos_add('from-lport', 1, 'output == "fake_port2"',
|
||||
dscp=11, external_ids=ext_ids_2)
|
||||
self.qos_3 = self._qos_add('from-lport', 2, 'output == "fake_port3"',
|
||||
dscp=10)
|
||||
|
||||
def test_qos_delete_external_ids(self):
|
||||
self._create_fip_qoses()
|
||||
self.api.qos_del_ext_ids(self.switch.name,
|
||||
{'key1': 'value1'}).execute(check_error=True)
|
||||
qos_rules = self.api.qos_list(
|
||||
self.switch.uuid).execute(check_error=True)
|
||||
self.assertCountEqual([self.qos_2, self.qos_3], qos_rules)
|
||||
|
||||
self.api.qos_del_ext_ids(
|
||||
self.switch.name,
|
||||
{'key3': 'value3', 'key4': 'value4'}).execute(check_error=True)
|
||||
qos_rules = self.api.qos_list(
|
||||
self.switch.uuid).execute(check_error=True)
|
||||
self.assertCountEqual([self.qos_3], qos_rules)
|
||||
|
||||
def test_qos_delete_external_ids_wrong_keys_or_values(self):
|
||||
self._create_fip_qoses()
|
||||
self.api.qos_del_ext_ids(self.switch.name,
|
||||
{'key_z': 'value1'}).execute(check_error=True)
|
||||
qos_rules = self.api.qos_list(
|
||||
self.switch.uuid).execute(check_error=True)
|
||||
self.assertCountEqual([self.qos_1, self.qos_2, self.qos_3], qos_rules)
|
||||
|
||||
self.api.qos_del_ext_ids(self.switch.name,
|
||||
{'key1': 'value_z'}).execute(check_error=True)
|
||||
qos_rules = self.api.qos_list(
|
||||
self.switch.uuid).execute(check_error=True)
|
||||
self.assertCountEqual([self.qos_1, self.qos_2, self.qos_3], qos_rules)
|
||||
|
||||
self.api.qos_del_ext_ids(
|
||||
self.switch.name,
|
||||
{'key3': 'value3', 'key4': 'value_z'}).execute(check_error=True)
|
||||
qos_rules = self.api.qos_list(
|
||||
self.switch.uuid).execute(check_error=True)
|
||||
self.assertCountEqual([self.qos_1, self.qos_2, self.qos_3], qos_rules)
|
||||
|
||||
def test_qos_delete_external_ids_empty_dict(self):
|
||||
self.assertRaises(TypeError, self.api.qos_del_ext_ids,
|
||||
self.switch.name, {})
|
||||
|
||||
def test_qos_delete_external_ids_if_exists(self):
|
||||
self._create_fip_qoses()
|
||||
cmd = self.api.qos_del_ext_ids('wrong_ls_name',
|
||||
{'key1': 'value1'}, if_exists=False)
|
||||
self.assertRaises(RuntimeError, cmd.execute, check_error=True)
|
||||
|
||||
self.api.qos_del_ext_ids('wrong_ls_name',
|
||||
{'key1': 'value1'}).execute(check_error=True)
|
||||
# No qos rule has been deleted from the correct logical switch.
|
||||
qos_rules = self.api.qos_list(
|
||||
self.switch.uuid).execute(check_error=True)
|
||||
self.assertCountEqual([self.qos_1, self.qos_2, self.qos_3], qos_rules)
|
||||
|
||||
|
||||
class TestLspOps(OvnNorthboundTest):
|
||||
def setUp(self):
|
||||
|
|
Loading…
Reference in New Issue