[ovn]: port forwarding -- IDL changes
This is a subset of the changes for implementing the floating IP port forwarding feature in neutron, using OVN as the backend. This changeset covers the additions to northbound api needed for handling load balancer entries created on behalf of port forwarding. Depends-On: https://review.opendev.org/#/c/729354/ Change-Id: I7d0aa51468dbd2c298395c3dccd8f222e87032d8 Partially-implements: ovn/port_forwarding Partial-Bug: #1877447
This commit is contained in:
parent
4e5d392a8f
commit
597bb0d187
|
@ -570,6 +570,42 @@ class API(api.API, metaclass=abc.ABCMeta):
|
|||
:returns: :class:`Command` with no result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_lb_external_ids(self, lb_name, values, if_exists=True):
|
||||
"""Set the external_ids field of a given Load Balancer.
|
||||
|
||||
:param lb_name: The name of the load_balancer
|
||||
:type lb_name: string
|
||||
:param values: Values to be set in external_ids
|
||||
:type values: dict
|
||||
:param if_exists: Do not fail if lb_name does not exist
|
||||
:type if_exists: bool
|
||||
:returns: :class:`Command` with no result
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_router_floatingip_lbs(self, lrouter_name):
|
||||
"""Get Load Balancers used as port forwarding by a Logical Router.
|
||||
|
||||
:param lrouter_name: The name of the logical router
|
||||
:type lrouter_name: string
|
||||
:returns: a list of Load_Balancer rows matched
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_floatingip_in_nat_or_lb(self, fip_id):
|
||||
"""Get a Floating IP from either NAT or Load Balancer table by its ID
|
||||
|
||||
NAT rows in OVN are mapped for floating IPs, except for port
|
||||
forwarding. In such cases, Load Balancer table is used . This function
|
||||
returns a row from NAT, if there is one. Otherwise, it will lookup
|
||||
for the FIP ID in the LB table and return the first match.
|
||||
|
||||
:param fip_id: The floating IP id
|
||||
:type fip_id: string
|
||||
:returns: The NAT rule row or Load_Balancer row or None
|
||||
"""
|
||||
|
||||
|
||||
class SbAPI(api.API, metaclass=abc.ABCMeta):
|
||||
|
||||
|
|
|
@ -569,6 +569,10 @@ class UpdatePortBindingExtIdsCommand(UpdateObjectExtIdsCommand):
|
|||
field = 'logical_port'
|
||||
|
||||
|
||||
class UpdateLbExternalIds(UpdateObjectExtIdsCommand):
|
||||
table = 'Load_Balancer'
|
||||
|
||||
|
||||
class AddDHCPOptionsCommand(command.BaseCommand):
|
||||
def __init__(self, api, subnet_id, port_id=None, may_exist=True,
|
||||
**columns):
|
||||
|
|
|
@ -33,6 +33,7 @@ from neutron.common.ovn import utils
|
|||
from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf as cfg
|
||||
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import commands as cmd
|
||||
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovsdb_monitor
|
||||
from neutron.services.portforwarding import constants as pf_const
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
@ -617,6 +618,26 @@ class OvsdbNbOvnIdl(nb_impl_idl.OvnNbApiIdlImpl, Backend):
|
|||
|
||||
return (ls, None)
|
||||
|
||||
def get_router_floatingip_lbs(self, lrouter_name):
|
||||
rc = self.db_find_rows('Load_Balancer', (
|
||||
'external_ids', '=',
|
||||
{ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY:
|
||||
pf_const.PORT_FORWARDING_PLUGIN,
|
||||
ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: lrouter_name}))
|
||||
return [ovn_obj for ovn_obj in rc.execute(check_error=True)
|
||||
if ovn_const.OVN_FIP_EXT_ID_KEY in ovn_obj.external_ids]
|
||||
|
||||
def get_floatingip_in_nat_or_lb(self, fip_id):
|
||||
fip = self.get_floatingip(fip_id)
|
||||
if fip:
|
||||
return fip
|
||||
result = self.db_find('Load_Balancer', (
|
||||
'external_ids', '=',
|
||||
{ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY:
|
||||
pf_const.PORT_FORWARDING_PLUGIN,
|
||||
ovn_const.OVN_FIP_EXT_ID_KEY: fip_id})).execute(check_error=True)
|
||||
return result[0] if result else None
|
||||
|
||||
def get_floatingip(self, fip_id):
|
||||
# TODO(dalvarez): remove this check once the minimum OVS required
|
||||
# version contains the column (when OVS 2.8.2 is released).
|
||||
|
@ -717,6 +738,9 @@ class OvsdbNbOvnIdl(nb_impl_idl.OvnNbApiIdlImpl, Backend):
|
|||
return cmd.UnsetLSwitchPortToVirtualTypeCommand(
|
||||
self, lport_name, virtual_parent, if_exists)
|
||||
|
||||
def update_lb_external_ids(self, lb_name, values, if_exists=True):
|
||||
return cmd.UpdateLbExternalIds(self, lb_name, values, if_exists)
|
||||
|
||||
|
||||
class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend):
|
||||
def __init__(self, connection):
|
||||
|
|
|
@ -22,6 +22,7 @@ from neutron.common.ovn import constants as ovn_const
|
|||
from neutron.common.ovn import utils
|
||||
from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf
|
||||
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import impl_idl_ovn
|
||||
from neutron.services.portforwarding import constants as pf_const
|
||||
from neutron.tests import base
|
||||
from neutron.tests.unit import fake_resources as fakes
|
||||
|
||||
|
@ -278,7 +279,21 @@ class TestNBImplIdlOvn(TestDBImplIdlOvn):
|
|||
{'name': '$as_ip4_id_5',
|
||||
'addresses': ['20.0.2.1', '20.0.2.2'],
|
||||
'external_ids': {ovn_const.OVN_SG_EXT_ID_KEY: 'id_5'}}],
|
||||
}
|
||||
'lbs': [
|
||||
{'name': 'lb_1',
|
||||
'external_ids': {
|
||||
ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY:
|
||||
pf_const.PORT_FORWARDING_PLUGIN,
|
||||
ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: 'rtr_name',
|
||||
ovn_const.OVN_FIP_EXT_ID_KEY: 'fip_id_1'}},
|
||||
{'name': 'lb_2',
|
||||
'external_ids': {
|
||||
ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY:
|
||||
pf_const.PORT_FORWARDING_PLUGIN,
|
||||
ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: 'rtr_name',
|
||||
ovn_const.OVN_FIP_EXT_ID_KEY: 'fip_id_2'}},
|
||||
{'name': 'lb_3', 'external_ids': {}}],
|
||||
}
|
||||
|
||||
fake_associations = {
|
||||
'lstolsp': {
|
||||
|
@ -328,6 +343,7 @@ class TestNBImplIdlOvn(TestDBImplIdlOvn):
|
|||
self.acl_table = fakes.FakeOvsdbTable.create_one_ovsdb_table()
|
||||
self.dhcp_table = fakes.FakeOvsdbTable.create_one_ovsdb_table()
|
||||
self.address_set_table = fakes.FakeOvsdbTable.create_one_ovsdb_table()
|
||||
self.lb_table = fakes.FakeOvsdbTable.create_one_ovsdb_table()
|
||||
|
||||
self._tables = {}
|
||||
self._tables['Logical_Switch'] = self.lswitch_table
|
||||
|
@ -338,6 +354,7 @@ class TestNBImplIdlOvn(TestDBImplIdlOvn):
|
|||
self._tables['ACL'] = self.acl_table
|
||||
self._tables['DHCP_Options'] = self.dhcp_table
|
||||
self._tables['Address_Set'] = self.address_set_table
|
||||
self._tables['Load_Balancer'] = self.lb_table
|
||||
|
||||
with mock.patch.object(impl_idl_ovn, 'get_connection',
|
||||
return_value=mock.Mock()):
|
||||
|
@ -399,6 +416,9 @@ class TestNBImplIdlOvn(TestDBImplIdlOvn):
|
|||
# Load address sets
|
||||
fake_address_sets = TestNBImplIdlOvn.fake_set['address_sets']
|
||||
self._load_ovsdb_fake_rows(self.address_set_table, fake_address_sets)
|
||||
# Load load balancers
|
||||
fake_lbs = TestNBImplIdlOvn.fake_set['lbs']
|
||||
self._load_ovsdb_fake_rows(self.lb_table, fake_lbs)
|
||||
|
||||
@mock.patch.object(ovs_idl.Backend, 'autocreate_indices', mock.Mock(),
|
||||
create=True)
|
||||
|
@ -782,6 +802,31 @@ class TestNBImplIdlOvn(TestDBImplIdlOvn):
|
|||
port_groups = self.nb_ovn_idl.get_sg_port_groups()
|
||||
self.assertEqual({}, port_groups)
|
||||
|
||||
def test_get_router_floatingip_lbs(self):
|
||||
lrouter_name = 'rtr_name'
|
||||
# Empty
|
||||
lbs = self.nb_ovn_idl.get_router_floatingip_lbs(lrouter_name)
|
||||
self.assertEqual([], lbs)
|
||||
self._load_nb_db()
|
||||
lbs = self.nb_ovn_idl.get_router_floatingip_lbs('not_there')
|
||||
self.assertEqual([], lbs)
|
||||
lb1_row = self._find_ovsdb_fake_row(self.lb_table, 'name', 'lb_1')
|
||||
lb2_row = self._find_ovsdb_fake_row(self.lb_table, 'name', 'lb_2')
|
||||
lbs = self.nb_ovn_idl.get_router_floatingip_lbs(lrouter_name)
|
||||
self.assertEqual(lbs, [lb1_row, lb2_row])
|
||||
|
||||
def test_get_floatingip_in_nat_or_lb(self):
|
||||
fip_id = 'fip_id_2'
|
||||
# Empty
|
||||
lb = self.nb_ovn_idl.get_floatingip_in_nat_or_lb(fip_id)
|
||||
self.assertIsNone(lb)
|
||||
self._load_nb_db()
|
||||
lb = self.nb_ovn_idl.get_floatingip_in_nat_or_lb('not_there')
|
||||
self.assertIsNone(lb)
|
||||
lb_row = self._find_ovsdb_fake_row(self.lb_table, 'name', 'lb_2')
|
||||
lb = self.nb_ovn_idl.get_floatingip_in_nat_or_lb(fip_id)
|
||||
self.assertEqual(lb['_uuid'], lb_row.uuid)
|
||||
|
||||
|
||||
class TestSBImplIdlOvn(TestDBImplIdlOvn):
|
||||
|
||||
|
|
Loading…
Reference in New Issue