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.

Change-Id: Ia63a375e360fb7b1ee31e4d9f96b38d9f31f4096
Signed-off-by: Numan Siddique <nusiddiq@redhat.com>
Co-Authored-By: Maciej Józefczyk <mjozefcz@redhat.com>
changes/27/667027/14
Numan Siddique 2 years ago
committed by Maciej Józefczyk
parent
commit
c8e8cdbb4b
  1. 1
      networking_ovn/common/constants.py
  2. 32
      networking_ovn/common/ovn_client.py
  3. 3
      networking_ovn/tests/unit/fakes.py
  4. 42
      networking_ovn/tests/unit/l3/test_l3_ovn.py

1
networking_ovn/common/constants.py

@ -22,6 +22,7 @@ OVN_ML2_MECH_DRIVER_NAME = 'ovn'
OVN_NETWORK_NAME_EXT_ID_KEY = 'neutron:network_name'
OVN_NETWORK_MTU_EXT_ID_KEY = 'neutron:mtu'
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'

32
networking_ovn/common/ovn_client.py

@ -680,6 +680,24 @@ class OVNClient(object):
columns['external_ids'] = ext_ids
commands.append(func(*nat_rule_args, **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):
@ -687,6 +705,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):

3
networking_ovn/tests/unit/fakes.py

@ -100,6 +100,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()
@ -138,6 +140,7 @@ class FakeOvsdbNbOvnIdl(object):
self.db_find = mock.Mock()
self.db_set = mock.Mock()
self.db_clear = mock.Mock()
self.db_remove = mock.Mock()
class FakeOvsdbSbOvnIdl(object):

42
networking_ovn/tests/unit/l3/test_l3_ovn.py

@ -941,6 +941,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 = (
@ -952,6 +965,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