Browse Source

Store the FIP associated to a port in the OVN Northbound db.

If a floating ip is associated to a port, it will be stored as
Logical_Switch_Port.external_ids:neutron:port_fip=FIP

OVN octavia driver will use this information to associate the floating ip
to the load balancer vip if the port is a virtual ip port created by
OVN octavia driver.

Signed-off-by: Numan Siddique <nusiddiq@redhat.com>
Co-Authored-By: Maciej Józefczyk <mjozefcz@redhat.com>
(cherry picked from commit c8e8cdbb4b)

Conflicts:
    networking_ovn/tests/unit/fakes.py

Change-Id: Ia63a375e360fb7b1ee31e4d9f96b38d9f31f4096
changes/98/706798/2
Numan Siddique 1 year ago
committed by Maciej Józefczyk
parent
commit
31fa432d9d
4 changed files with 80 additions and 0 deletions
  1. +1
    -0
      networking_ovn/common/constants.py
  2. +31
    -0
      networking_ovn/common/ovn_client.py
  3. +6
    -0
      networking_ovn/tests/unit/fakes.py
  4. +42
    -0
      networking_ovn/tests/unit/l3/test_l3_ovn.py

+ 1
- 0
networking_ovn/common/constants.py View File

@@ -21,6 +21,7 @@ OVN_SG_RULE_EXT_ID_KEY = 'neutron:security_group_rule_id'
OVN_ML2_MECH_DRIVER_NAME = 'ovn'
OVN_NETWORK_NAME_EXT_ID_KEY = 'neutron:network_name'
OVN_PORT_NAME_EXT_ID_KEY = 'neutron:port_name'
OVN_PORT_FIP_EXT_ID_KEY = 'neutron:port_fip'
OVN_ROUTER_NAME_EXT_ID_KEY = 'neutron:router_name'
OVN_ROUTER_IS_EXT_GW = 'neutron:is_ext_gw'
OVN_GW_PORT_EXT_ID_KEY = 'neutron:gw_port_id'


+ 31
- 0
networking_ovn/common/ovn_client.py View File

@@ -665,6 +665,23 @@ class OVNClient(object):
commands.append(self._nb_idl.add_nat_rule_in_lrouter(gw_lrouter_name,
**columns))

# Get the logical port (of the private network) and set the field
# external_ids:fip=<FIP>. This will be used by the ovn octavia driver
# to add the floating ip as vip in the Load_Balancer.vips column.
private_lsp = self._nb_idl.get_lswitch_port(floatingip['port_id'])

if private_lsp:
port_fip = {
ovn_const.OVN_PORT_FIP_EXT_ID_KEY:
floatingip['floating_ip_address']}
commands.append(
self._nb_idl.db_set('Logical_Switch_Port', private_lsp.uuid,
('external_ids', port_fip))
)
else:
LOG.warning("LSP for floatingip %s, has not been found! "
"Cannot set FIP on VIP.",
floatingip['id'])
self._transaction(commands, txn=txn)

def _delete_floatingip(self, fip, lrouter, txn=None):
@@ -672,6 +689,20 @@ class OVNClient(object):
lrouter, type='dnat_and_snat',
logical_ip=fip['logical_ip'],
external_ip=fip['external_ip'])]
try:
port_id = (
fip['external_ids'].get(ovn_const.OVN_FIP_PORT_EXT_ID_KEY))
if port_id:
private_lsp = self._nb_idl.get_lswitch_port(port_id)
if private_lsp:
commands.append(
self._nb_idl.db_remove(
'Logical_Switch_Port', private_lsp.uuid,
'external_ids',
(ovn_const.OVN_PORT_FIP_EXT_ID_KEY))
)
except KeyError:
LOG.debug("FIP %s doesn't have external_ids.", fip)
self._transaction(commands, txn=txn)

def update_floatingip_status(self, floatingip):


+ 6
- 0
networking_ovn/tests/unit/fakes.py View File

@@ -102,6 +102,8 @@ class FakeOvsdbNbOvnIdl(object):
self.get_lswitch = mock.Mock()
fake_ovs_row = FakeOvsdbRow.create_one_ovsdb_row()
self.get_lswitch.return_value = fake_ovs_row
self.get_lswitch_port = mock.Mock()
self.get_lswitch_port.return_value = fake_ovs_row
self.get_ls_and_dns_record = mock.Mock()
self.get_ls_and_dns_record.return_value = (fake_ovs_row, None)
self.ls_set_dns_records = mock.Mock()
@@ -141,6 +143,10 @@ class FakeOvsdbNbOvnIdl(object):
self.nb_global = mock.Mock()
self.db_list_rows = mock.Mock()
self.lsp_list = mock.MagicMock()
self.db_find = mock.Mock()
self.db_set = mock.Mock()
self.db_clear = mock.Mock()
self.db_remove = mock.Mock()


class FakeOvsdbSbOvnIdl(object):


+ 42
- 0
networking_ovn/tests/unit/l3/test_l3_ovn.py View File

@@ -898,6 +898,19 @@ class OVNL3RouterPlugin(test_mech_driver.OVNMechanismDriverTestCase):
self.l3_inst._ovn.delete_lswitch_port.assert_called_once_with(
'fip-port-id', 'neutron-fip-net-id')

@mock.patch('neutron.db.l3_db.L3_NAT_dbonly_mixin._get_floatingip')
def test_create_floatingip_lsp_external_id(self, gf):
foo_lport = fakes.FakeOvsdbRow.create_one_ovsdb_row()
foo_lport.uuid = 'foo-port'
self.l3_inst._ovn.get_lswitch_port.return_value = foo_lport
self.l3_inst.create_floatingip(self.context, 'floatingip')
calls = [mock.call(
'Logical_Switch_Port',
'foo-port',
('external_ids', {ovn_const.OVN_PORT_FIP_EXT_ID_KEY:
'192.168.0.10'}))]
self.l3_inst._ovn.db_set.assert_has_calls(calls)

@mock.patch('neutron.db.l3_db.L3_NAT_dbonly_mixin.delete_floatingip')
def test_delete_floatingip(self, df):
self.l3_inst._ovn.get_floatingip.return_value = (
@@ -909,6 +922,35 @@ class OVNL3RouterPlugin(test_mech_driver.OVNMechanismDriverTestCase):
logical_ip='10.0.0.10',
external_ip='192.168.0.10')

@mock.patch('neutron.db.l3_db.L3_NAT_dbonly_mixin._get_floatingip')
@mock.patch('neutron.db.l3_db.L3_NAT_dbonly_mixin.delete_floatingip')
def test_delete_floatingip_lsp_external_id(self, df, gf):
gf.return_value = self.fake_floating_ip
self.l3_inst._ovn.get_floatingip.return_value = (
self.fake_ovn_nat_rule)

foo_lport = fakes.FakeOvsdbRow.create_one_ovsdb_row()
foo_lport.uuid = 'foo-port'
foo_lport.external_ids = {
ovn_const.OVN_PORT_FIP_EXT_ID_KEY: 'foo-port'}
self.l3_inst._ovn.get_lswitch_port.return_value = foo_lport

self.l3_inst.delete_floatingip(self.context, 'floatingip-id')
calls = [mock.call(
'Logical_Switch_Port', 'foo-port',
'external_ids', ovn_const.OVN_PORT_FIP_EXT_ID_KEY)]
self.l3_inst._ovn.db_remove.assert_has_calls(calls)

@mock.patch('neutron.db.l3_db.L3_NAT_dbonly_mixin._get_floatingip')
@mock.patch('neutron.db.l3_db.L3_NAT_dbonly_mixin.delete_floatingip')
def test_delete_floatingip_no_lsp_external_id(self, df, gf):
gf.return_value = self.fake_floating_ip
self.l3_inst._ovn.get_floatingip.return_value = (
self.fake_ovn_nat_rule)
self.l3_inst._ovn.get_lswitch_port.return_value = None
self.l3_inst.delete_floatingip(self.context, 'floatingip-id')
self.l3_inst._ovn.db_remove.assert_not_called()

@mock.patch('neutron.db.l3_db.L3_NAT_dbonly_mixin._get_floatingip')
@mock.patch('neutron.db.extraroute_db.ExtraRoute_dbonly_mixin.'
'update_floatingip')


Loading…
Cancel
Save