[OVN] Add ``ProviderResourceAssociation`` to any ML2/OVN router

Since [1], any Neutron router created with ML2/OVN will have an
associated ``ProviderResourceAssociation`` register. The routers
created before this feature won't have any and it won't be possible
to delete them. This patch adds a temporary maintenance task to
create the needed register for these Neutron routers.

[1]https://review.opendev.org/c/openstack/neutron/+/883988

Closes-Bug: #2053122
Related-Bug: #2020823
Change-Id: Iecd5c7a66b16e25e9888dbd1e305586b2be2011e
This commit is contained in:
Rodolfo Alonso Hernandez 2024-02-13 22:28:25 +00:00
parent 2d74a93d68
commit d755c2551f
2 changed files with 48 additions and 0 deletions

View File

@ -41,6 +41,7 @@ from neutron.db import ovn_hash_ring_db as hash_ring_db
from neutron.db import ovn_revision_numbers_db as revision_numbers_db
from neutron.objects import ports as ports_obj
from neutron.objects import router as router_obj
from neutron.objects import servicetype as servicetype_obj
from neutron import service
from neutron.services.logapi.drivers.ovn import driver as log_driver
@ -1184,6 +1185,25 @@ class DBInconsistenciesPeriodics(SchemaAwarePeriodicsBase):
txn.add(cmd)
raise periodics.NeverAgain()
# TODO(ralonsoh): Remove this method in the C+2 cycle (next SLURP release)
@has_lock_periodic(spacing=600, run_immediately=True)
def add_provider_resource_association_to_routers(self):
"""Add the ``ProviderResourceAssociation`` register to all routers"""
provider_name = 'ovn'
context = n_context.get_admin_context()
pra_list = servicetype_obj.ProviderResourceAssociation.get_objects(
context, provider_name=provider_name)
pra_res_ids = set(pra.resource_id for pra in pra_list)
with db_api.CONTEXT_WRITER.using(context):
for lr in self._nb_idl.lr_list().execute(check_error=True):
router_id = lr.name.replace('neutron-', '')
if router_id not in pra_res_ids:
servicetype_obj.ProviderResourceAssociation(
context, provider_name=provider_name,
resource_id=router_id).create()
raise periodics.NeverAgain()
class HashRingHealthCheckPeriodics(object):

View File

@ -26,11 +26,13 @@ from neutron_lib.callbacks import registry
from neutron_lib import constants as n_const
from neutron_lib import context as n_context
from neutron_lib.exceptions import l3 as lib_l3_exc
from oslo_utils import uuidutils
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 as ovn_config
from neutron.db import ovn_revision_numbers_db as db_rev
from neutron.objects import servicetype as servicetype_obj
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import maintenance
from neutron.services.portforwarding import constants as pf_consts
from neutron.tests.functional import base
@ -1162,6 +1164,32 @@ class TestMaintenance(_TestMaintenanceHelper):
else:
self.assertNotIn('gateway_port', fip_rule)
def test_add_provider_resource_association_to_routers(self):
provider_name = 'ovn'
router1 = self._create_router(uuidutils.generate_uuid())
router2 = self._create_router(uuidutils.generate_uuid())
# NOTE(ralonsoh): now each Neutron router will create a
# ``ProviderResourceAssociation`` register. In order to be able to test
# the maintenance method, the router2 ``ProviderResourceAssociation``
# register is deleted.
servicetype_obj.ProviderResourceAssociation.delete_objects(
self.context, resource_id=router2['id'])
pra_list = servicetype_obj.ProviderResourceAssociation.get_objects(
self.context, provider_name=provider_name)
pra_res_ids = set(pra.resource_id for pra in pra_list)
self.assertIn(router1['id'], pra_res_ids)
self.assertNotIn(router2['id'], pra_res_ids)
self.assertRaises(
periodics.NeverAgain,
self.maint.add_provider_resource_association_to_routers)
pra_list = servicetype_obj.ProviderResourceAssociation.get_objects(
self.context, provider_name=provider_name)
pra_res_ids = set(pra.resource_id for pra in pra_list)
self.assertIn(router1['id'], pra_res_ids)
self.assertIn(router2['id'], pra_res_ids)
class TestLogMaintenance(_TestMaintenanceHelper,
test_log_driver.LogApiTestCaseBase):