Browse Source

Exclude all device_ids that belong to Neutron DHCP Agent

It looks like sometimes, the device_id for ports created
by Neutron DHCP Agent can be in the form of:

- dhcp-$hostuuid-$networkid
- 'reserved_dhcp_port' (DEVICE_ID_RESERVED_DHCP_PORT)

Current code is only taking the first form into account when
skipping Neutron DHCP Agent ports. This patch is changing it
to include both forms.

Closes-Bug: #1848521
Co-Authored-By: Lucas Alvares Gomes <lucasagomes@gmail.com>
Change-Id: Ifbfc551ac68dcc5d3d39a155f7642f2f2d9272c4
Signed-off-by: Daniel Alvarez <dalvarez@redhat.com>
(cherry picked from commit 15bf8f265b)
changes/95/703195/1
Daniel Alvarez 2 years ago
committed by Flavio Fernandes
parent
commit
d2127eb634
  1. 20
      networking_ovn/common/ovn_client.py
  2. 11
      networking_ovn/common/utils.py
  3. 9
      networking_ovn/ovn_db_sync.py
  4. 18
      networking_ovn/tests/unit/ml2/test_mech_driver.py

20
networking_ovn/common/ovn_client.py

@ -222,8 +222,15 @@ class OVNClient(object):
self._get_allowed_addresses_from_port(port)
addresses = [address]
addresses.extend(new_macs)
port_type = ovn_const.OVN_NEUTRON_OWNER_TO_PORT_TYPE.get(
port['device_owner'], '')
# Only adjust the OVN type if the port is not owned by Neutron
# DHCP agents.
if (port['device_owner'] == const.DEVICE_OWNER_DHCP and
not utils.is_neutron_dhcp_agent_port(port)):
port_type = 'localport'
else:
port_type = ovn_const.OVN_NEUTRON_OWNER_TO_PORT_TYPE.get(
port['device_owner'], '')
# The "unknown" address should only be set for the normal LSP
# ports (the ones which type is empty)
@ -1773,9 +1780,12 @@ class OVNClient(object):
ports = self._plugin.get_ports(context, filters=dict(
network_id=[network_id], device_owner=[const.DEVICE_OWNER_DHCP]))
# There should be only one metadata port per network
if len(ports) == 1:
return ports[0]
# Metadata ports are DHCP ports not belonging to the Neutron
# DHCP agents
for port in ports:
if not utils.is_neutron_dhcp_agent_port(port):
return port
def _find_metadata_port_ip(self, context, subnet):
metadata_port = self._find_metadata_port(context, subnet['network_id'])

11
networking_ovn/common/utils.py

@ -391,3 +391,14 @@ def is_gateway_chassis_invalid(chassis_name, gw_chassis,
elif gw_chassis and chassis_name not in gw_chassis:
return True
return False
def is_neutron_dhcp_agent_port(port):
"""Check if the given DHCP port belongs to Neutron DHCP agents
The DHCP ports with the device_id equals to 'reserved_dhcp_port'
or starting with the word 'dhcp' belongs to the Neutron DHCP agents.
"""
return (port['device_owner'] == const.DEVICE_OWNER_DHCP and
(port['device_id'] == const.DEVICE_ID_RESERVED_DHCP_PORT or
port['device_id'].startswith('dhcp')))

9
networking_ovn/ovn_db_sync.py

@ -899,9 +899,16 @@ class OvnNbSynchronizer(OvnDbSynchronizer):
return
LOG.debug('OVN sync metadata ports started')
for net in self.core_plugin.get_networks(ctx):
dhcp_ports = self.core_plugin.get_ports(ctx, filters=dict(
all_dhcp_ports = self.core_plugin.get_ports(ctx, filters=dict(
network_id=[net['id']],
device_owner=[constants.DEVICE_OWNER_DHCP]))
dhcp_ports = []
for port in all_dhcp_ports:
# Do not touch the Neutron DHCP agents ports
if not utils.is_neutron_dhcp_agent_port(port):
dhcp_ports.append(port)
if not dhcp_ports:
LOG.warning('Missing metadata port found in Neutron for '
'network %s', net['id'])

18
networking_ovn/tests/unit/ml2/test_mech_driver.py

@ -2476,6 +2476,7 @@ class TestOVNMechanismDriverMetadataPort(test_plugin.Ml2PluginV2TestCase):
self.mech_driver._sb_ovn = fakes.FakeOvsdbSbOvnIdl()
self.nb_ovn = self.mech_driver._nb_ovn
self.sb_ovn = self.mech_driver._sb_ovn
self.ctx = context.get_admin_context()
ovn_config.cfg.CONF.set_override('ovn_metadata_enabled',
True,
group='ovn')
@ -2483,6 +2484,23 @@ class TestOVNMechanismDriverMetadataPort(test_plugin.Ml2PluginV2TestCase):
p.start()
self.addCleanup(p.stop)
def _create_fake_dhcp_port(self, device_id):
return {'network_id': 'fake', 'device_owner': const.DEVICE_OWNER_DHCP,
'device_id': device_id}
@mock.patch('neutron.db.db_base_plugin_v2.NeutronDbPluginV2.get_ports')
def test__find_metadata_port(self, mock_get_ports):
ports = [
self._create_fake_dhcp_port('dhcp-0'),
self._create_fake_dhcp_port('dhcp-1'),
self._create_fake_dhcp_port(const.DEVICE_ID_RESERVED_DHCP_PORT),
self._create_fake_dhcp_port('ovnmeta-0')]
mock_get_ports.return_value = ports
md_port = self.mech_driver._ovn_client._find_metadata_port(
self.ctx, 'fake-net-id')
self.assertEqual('ovnmeta-0', md_port['device_id'])
def test_metadata_port_on_network_create(self):
"""Check metadata port create.

Loading…
Cancel
Save