Skip to content

Commit c91c82f

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Delete sg rule which remote is the deleted sg" into stable/zed
2 parents 10598f0 + e4cf8cc commit c91c82f

File tree

3 files changed

+78
-11
lines changed

3 files changed

+78
-11
lines changed

neutron/db/securitygroups_db.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,12 @@ def delete_security_group(self, context, id):
253253
if sg['name'] == 'default' and not context.is_admin:
254254
raise ext_sg.SecurityGroupCannotRemoveDefault()
255255

256+
# Check if there are rules with remote_group_id ponting to
257+
# the security_group to be deleted
258+
rules_ids_as_remote = self._get_security_group_rules_by_remote(
259+
context=context, remote_id=id,
260+
)
261+
256262
self._registry_publish(resources.SECURITY_GROUP,
257263
events.BEFORE_DELETE,
258264
exc_cls=ext_sg.SecurityGroupInUse, id=id,
@@ -281,6 +287,20 @@ def delete_security_group(self, context, id):
281287
context, resource_id=id, states=(sec_group,),
282288
metadata={'security_group_rule_ids': sgr_ids,
283289
'name': sg['name']}))
290+
for rule in rules_ids_as_remote:
291+
registry.publish(
292+
resources.SECURITY_GROUP_RULE,
293+
events.AFTER_DELETE,
294+
self,
295+
payload=events.DBEventPayload(
296+
context,
297+
resource_id=rule['id'],
298+
metadata={'security_group_id': rule['security_group_id'],
299+
'remote_group_id': rule['remote_group_id'],
300+
'rule': rule
301+
}
302+
)
303+
)
284304

285305
@db_api.retry_if_session_inactive()
286306
def update_security_group(self, context, id, security_group):
@@ -367,6 +387,23 @@ def _get_port_security_group_bindings(self, context,
367387
self._make_security_group_binding_dict,
368388
filters=filters, fields=fields)
369389

390+
def _get_security_group_rules_by_remote(self, context, remote_id):
391+
return model_query.get_collection(
392+
context, sg_models.SecurityGroupRule,
393+
self._make_security_group_rule_dict,
394+
filters={'remote_group_id': [remote_id]},
395+
fields=['id',
396+
'remote_group_id',
397+
'security_group_id',
398+
'direction',
399+
'ethertype',
400+
'protocol',
401+
'port_range_min',
402+
'port_range_max',
403+
'normalized_cidr'
404+
]
405+
)
406+
370407
@db_api.retry_if_session_inactive()
371408
def _delete_port_security_group_bindings(self, context, port_id):
372409
with db_api.CONTEXT_WRITER.using(context):

neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,6 @@ def subscribe(self):
261261
registry.subscribe(self._create_security_group,
262262
resources.SECURITY_GROUP,
263263
events.AFTER_CREATE)
264-
registry.subscribe(self._delete_security_group_precommit,
265-
resources.SECURITY_GROUP,
266-
events.PRECOMMIT_DELETE)
267264
registry.subscribe(self._delete_security_group,
268265
resources.SECURITY_GROUP,
269266
events.AFTER_DELETE)
@@ -276,6 +273,9 @@ def subscribe(self):
276273
registry.subscribe(self._process_sg_rule_notification,
277274
resources.SECURITY_GROUP_RULE,
278275
events.BEFORE_DELETE)
276+
registry.subscribe(self._process_sg_rule_after_del_notification,
277+
resources.SECURITY_GROUP_RULE,
278+
events.AFTER_DELETE)
279279

280280
def _clean_hash_ring(self, *args, **kwargs):
281281
admin_context = n_context.get_admin_context()
@@ -392,14 +392,6 @@ def _create_security_group(self, resource, event, trigger, payload):
392392
self._ovn_client.create_security_group(context,
393393
security_group)
394394

395-
def _delete_security_group_precommit(self, resource, event, trigger,
396-
payload):
397-
context = n_context.get_admin_context()
398-
security_group_id = payload.resource_id
399-
for sg_rule in self._plugin.get_security_group_rules(
400-
context, filters={'remote_group_id': [security_group_id]}):
401-
self._ovn_client.delete_security_group_rule(context, sg_rule)
402-
403395
def _delete_security_group(self, resource, event, trigger, payload):
404396
context = payload.context
405397
security_group_id = payload.resource_id
@@ -457,6 +449,12 @@ def _process_sg_rule_notification(
457449
context,
458450
sg_rule)
459451

452+
def _process_sg_rule_after_del_notification(
453+
self, resource, event, trigger, payload):
454+
context = payload.context
455+
sg_rule = payload.metadata['rule']
456+
self._ovn_client.delete_security_group_rule(context, sg_rule)
457+
460458
def _sg_has_rules_with_same_normalized_cidr(self, sg_rule):
461459
compare_keys = [
462460
'ethertype', 'direction', 'protocol',

neutron/tests/unit/db/test_securitygroups_db.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,38 @@ def test_security_group_precommit_and_after_delete_event(self):
404404
self.assertEqual([mock.ANY, mock.ANY],
405405
payload.metadata.get('security_group_rule_ids'))
406406

407+
def test_security_group_rule_after_delete_event_for_remot_group(self):
408+
sg1_dict = self.mixin.create_security_group(self.ctx, FAKE_SECGROUP)
409+
sg2_dict = self.mixin.create_security_group(self.ctx, FAKE_SECGROUP)
410+
411+
fake_rule = copy.deepcopy(FAKE_SECGROUP_RULE)
412+
fake_rule['security_group_rule']['security_group_id'] = sg1_dict['id']
413+
fake_rule['security_group_rule']['remote_group_id'] = sg2_dict['id']
414+
fake_rule['security_group_rule']['remote_ip_prefix'] = None
415+
remote_rule = self.mixin.create_security_group_rule(
416+
self.ctx, fake_rule)
417+
418+
with mock.patch.object(registry, "publish") as mock_publish:
419+
self.mixin.delete_security_group(self.ctx, sg2_dict['id'])
420+
mock_publish.assert_has_calls(
421+
[mock.call('security_group', 'before_delete',
422+
mock.ANY, payload=mock.ANY),
423+
mock.call('security_group', 'precommit_delete',
424+
mock.ANY,
425+
payload=mock.ANY),
426+
mock.call('security_group', 'after_delete',
427+
mock.ANY,
428+
payload=mock.ANY),
429+
mock.call('security_group_rule', 'after_delete',
430+
mock.ANY,
431+
payload=mock.ANY)])
432+
rule_payload = mock_publish.mock_calls[3][2]['payload']
433+
self.assertEqual(remote_rule['id'], rule_payload.resource_id)
434+
self.assertEqual(sg1_dict['id'],
435+
rule_payload.metadata['security_group_id'])
436+
self.assertEqual(sg2_dict['id'],
437+
rule_payload.metadata['remote_group_id'])
438+
407439
def test_security_group_rule_precommit_create_event_fail(self):
408440
registry.subscribe(fake_callback, resources.SECURITY_GROUP_RULE,
409441
events.PRECOMMIT_CREATE)

0 commit comments

Comments
 (0)