Bump revision number of objects when description is changed

"Description" attribute belongs to the StandardAttribute class from
which many other classes inherits (like e.g. Network, Port or Subnet).
In case when only description of object is updated, revision number of
the object should be bumped but it wasn't the case for all of the
objects. For example updated description of the Network or Router didn't
bumped its revision_number. It was like that because StandardAttribute
object was the only one which was dirty in the session, and as it is not
member of the HasStandardAttibutes class, it was filtered out.

Now, to fix that problem revision_plugin looks in the session.dirty list
for objects which inherits from HasStandardAttibutes class (as it was
before) but also for StandardAttribute objects to bump revision numbers.

Closes-Bug: #1981817
Closes-Bug: #1865173
Change-Id: I79b40a8ae5d594ed6fc875572663469c8b701202
(cherry picked from commit 4c9cb83d6b)
This commit is contained in:
Slawek Kaplonski 2022-08-01 13:00:28 +02:00
parent 80ad263e28
commit 39f7e12993
2 changed files with 44 additions and 5 deletions

View File

@ -49,15 +49,38 @@ class RevisionPlugin(service_base.ServicePluginBase):
db_api.sqla_listen(se.Session, 'after_rollback',
self._clear_rev_bumped_flags)
def _get_objects_to_bump_revision(self, dirty_objects):
all_std_attr_objects = []
objects_to_bump_revision = []
for dirty_object in dirty_objects:
if isinstance(dirty_object, standard_attr.HasStandardAttributes):
objects_to_bump_revision.append(dirty_object)
elif isinstance(dirty_object, standard_attr.StandardAttribute):
all_std_attr_objects.append(dirty_object)
# Now as we have all objects divided into 2 groups, we need to ensure
# that we don't have revision number for the same one in both groups.
# It may happen e.g. for the Subnet object, as during update of Subnet,
# both Subnet and StandardAttribute objects of that subnet are dirty.
# But for example for Network, when only description is changed, only
# StandardAttribute object is in the dirty objects set.
std_attr_ids = [o.standard_attr_id for o in objects_to_bump_revision]
# NOTE(slaweq): StandardAttribute objects which have "description"
# field modified, should have revision bumped too
objects_to_bump_revision += [
o for o in all_std_attr_objects
if ('description' not in o._sa_instance_state.unmodified and
o.id not in std_attr_ids)]
return objects_to_bump_revision
def bump_revisions(self, session, context, instances):
self._enforce_if_match_constraints(session)
# bump revision number for any updated objects in the session
# bump revision number for updated objects in the session
self._bump_obj_revisions(
session,
[
obj for obj in session.dirty
if isinstance(obj, standard_attr.HasStandardAttributes)]
)
self._get_objects_to_bump_revision(session.dirty))
# see if any created/updated/deleted objects bump the revision
# of another object

View File

@ -178,6 +178,22 @@ class TestRevisionPlugin(test_plugin.Ml2PluginV2TestCase):
new_rev = response['port']['revision_number']
self.assertGreater(new_rev, rev)
def test_network_description_bumps_revision(self):
with self.network() as net:
rev = net['network']['revision_number']
data = {'network': {'description': 'Test Description'}}
response = self._update('networks', net['network']['id'], data)
new_rev = response['network']['revision_number']
self.assertEqual(rev + 1, new_rev)
def test_subnet_description_bumps_revision(self):
with self.subnet() as subnet:
rev = subnet['subnet']['revision_number']
data = {'subnet': {'description': 'Test Description'}}
response = self._update('subnets', subnet['subnet']['id'], data)
new_rev = response['subnet']['revision_number']
self.assertEqual(rev + 1, new_rev)
def test_security_group_rule_ops_bump_security_group(self):
s = {'security_group': {'tenant_id': 'some_tenant', 'name': '',
'description': 's'}}