Merge "[ovn]: port forwarding -- IDL changes"

This commit is contained in:
Zuul 2020-07-29 15:20:22 +00:00 committed by Gerrit Code Review
commit 8b1a837973
4 changed files with 110 additions and 1 deletions

View File

@ -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):

View File

@ -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):

View File

@ -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):

View File

@ -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):