Delete sg rule which remote is the deleted sg
Based on bug #2008712 if we have a security-group which is the remote group of a 2nd security-group, the backend never deletes the rule of the 2nd group which remote_group_id is the original security-group. By AFTER_DELETE event for each rule that has the security_group_id as remote_group_id, we can make the mech drivers do their work and delete these rules in the backend. One version of this fix was merged: https://review.opendev.org/q/I207ecf7954b06507e03cb16b502ceb6e2807e0e7 and reverted due to #2019449: https://review.opendev.org/q/I077fe87435f61bd29d5c1efc979c2adebca26181 This patch is based on https://review.opendev.org/c/openstack/neutron/+/876716/1 Closes-Bug: #2008712 Related-Bug: #2019449 Change-Id: I9e8ddfa26c5402fefd573b0e2ea5f3a57983ca35
This commit is contained in:
parent
126d54badc
commit
67a0b07287
|
@ -306,6 +306,13 @@ class SecurityGroupServerAPIShim(sg_rpc_base.SecurityGroupInfoAPIMixin):
|
|||
for rule in self.rcache.get_resources('SecurityGroupRule', filters):
|
||||
self.rcache.record_resource_delete(context, 'SecurityGroupRule',
|
||||
rule.id)
|
||||
# If there's a rule which remote is the deleted sg, remove that also.
|
||||
rules = self.rcache.match_resources_with_func(
|
||||
'SecurityGroupRule',
|
||||
lambda sg_rule: sg_rule.remote_group_id == existing.id)
|
||||
for rule in rules:
|
||||
self.rcache.record_resource_delete(context, 'SecurityGroupRule',
|
||||
rule.id)
|
||||
|
||||
def _handle_sg_rule_delete(self, rtype, event, trigger, payload):
|
||||
existing = payload.states[0]
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
from unittest import mock
|
||||
|
||||
import netaddr
|
||||
from neutron_lib.callbacks import events
|
||||
from neutron_lib import context
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
|
@ -120,13 +121,14 @@ class SecurityGroupServerAPIShimTestCase(base.BaseTestCase):
|
|||
return_value=False)
|
||||
def _make_security_group_ovo(self, *args, **kwargs):
|
||||
attrs = {'id': uuidutils.generate_uuid(), 'revision_number': 1}
|
||||
r_group = kwargs.get('remote_group_id') or attrs['id']
|
||||
sg_rule = securitygroup.SecurityGroupRule(
|
||||
id=uuidutils.generate_uuid(),
|
||||
security_group_id=attrs['id'],
|
||||
direction='ingress',
|
||||
ethertype='IPv4', protocol='tcp',
|
||||
port_range_min=400,
|
||||
remote_group_id=attrs['id'],
|
||||
remote_group_id=r_group,
|
||||
revision_number=1,
|
||||
remote_address_group_id=kwargs.get('remote_address_group_id',
|
||||
None),
|
||||
|
@ -198,6 +200,52 @@ class SecurityGroupServerAPIShimTestCase(base.BaseTestCase):
|
|||
self.sg_agent.security_groups_member_updated.assert_called_with(
|
||||
{s1.id})
|
||||
|
||||
def test_sg_delete_events_with_remote(self):
|
||||
s1 = self._make_security_group_ovo(remote_group_id='')
|
||||
s2 = self._make_security_group_ovo(remote_group_id=s1.id)
|
||||
rules = self.rcache.get_resources(
|
||||
'SecurityGroupRule',
|
||||
filters={'security_group_id': (s1.id, s2.id)})
|
||||
self.assertEqual(2, len(rules))
|
||||
self.assertEqual(s1.id, rules[0].remote_group_id)
|
||||
|
||||
self.shim._clear_child_sg_rules(
|
||||
'SecurityGroup', 'after_delete', '',
|
||||
events.DBEventPayload(
|
||||
context=self.ctx,
|
||||
states=[s1]
|
||||
)
|
||||
)
|
||||
rules = self.rcache.get_resources(
|
||||
'SecurityGroupRule',
|
||||
filters={'security_group_id': (s1.id, s2.id)})
|
||||
self.assertEqual(0, len(rules))
|
||||
|
||||
def test_sg_delete_events_without_remote(self):
|
||||
s1 = self._make_security_group_ovo()
|
||||
s2 = self._make_security_group_ovo()
|
||||
rules = self.rcache.get_resources(
|
||||
'SecurityGroupRule',
|
||||
filters={'security_group_id': (s1.id, s2.id)})
|
||||
self.assertEqual(2, len(rules))
|
||||
self.assertEqual(s1.id, rules[0].remote_group_id)
|
||||
|
||||
self.shim._clear_child_sg_rules(
|
||||
'SecurityGroup', 'after_delete', '',
|
||||
events.DBEventPayload(
|
||||
context=self.ctx,
|
||||
states=[s1]
|
||||
)
|
||||
)
|
||||
s1_rules = self.rcache.get_resources(
|
||||
'SecurityGroupRule',
|
||||
filters={'security_group_id': (s1.id, )})
|
||||
self.assertEqual(0, len(s1_rules))
|
||||
s2_rules = self.rcache.get_resources(
|
||||
'SecurityGroupRule',
|
||||
filters={'security_group_id': (s2.id, )})
|
||||
self.assertEqual(1, len(s2_rules))
|
||||
|
||||
def test_get_secgroup_ids_for_address_group(self):
|
||||
ag = self._make_address_group_ovo()
|
||||
sg1 = self._make_security_group_ovo(remote_address_group_id=ag.id)
|
||||
|
|
Loading…
Reference in New Issue