Skip to content

Commit 3408092

Browse files
author
Édouard Thuleau
committedAug 4, 2016
[VNC OpenStack] Remove stale security group rules
When a security group is deleted all security group rules which reference it as 'remote_group_id' should be deleted. As the contrail data model does not permit to easy found that rules, that fix propose to clean that stale rules only when they are listed or read. [1] https://github.com/openstack/tempest/search?utf8=%E2%9C%93&q=test_security_group_rules_delete_when_peer_group_deleted&type=Code Change-Id: Ifcd39f7f7b04c07cb6d4b62aa8aa90007f8bc81d Closes-Bug: #1591976 (cherry picked from commit ad6a675)
1 parent 2038787 commit 3408092

File tree

2 files changed

+122
-21
lines changed

2 files changed

+122
-21
lines changed
 

‎src/config/vnc_openstack/vnc_openstack/neutron_plugin_db.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,16 +1088,18 @@ def _security_group_rule_vnc_to_neutron(self, sg_id, sg_rule, sg_obj=None):
10881088
addr.get_subnet().get_ip_prefix_len())
10891089
elif addr.get_security_group():
10901090
if (addr.get_security_group() != 'any' and
1091-
addr.get_security_group() != 'local'):
1091+
addr.get_security_group() != 'local'):
10921092
remote_sg = addr.get_security_group()
1093-
try:
1094-
if remote_sg != ':'.join(sg_obj.get_fq_name()):
1095-
remote_sg_obj = self._vnc_lib.security_group_read(fq_name_str=remote_sg)
1096-
else:
1097-
remote_sg_obj = sg_obj
1098-
remote_sg_uuid = remote_sg_obj.uuid
1099-
except NoIdError:
1100-
pass
1093+
if remote_sg != ':'.join(sg_obj.get_fq_name()):
1094+
try:
1095+
remote_sg_uuid = self._vnc_lib.fq_name_to_id(
1096+
'security-group', remote_sg.split(':'))
1097+
except NoIdError:
1098+
# Filter rule out as the remote security group does not
1099+
# exist anymore
1100+
return sgr_q_dict
1101+
else:
1102+
remote_sg_uuid = sg_obj.uuid
11011103

11021104
sgr_q_dict['id'] = sg_rule.get_rule_uuid()
11031105
sgr_q_dict['tenant_id'] = sg_obj.parent_uuid.replace('-', '')
@@ -4018,9 +4020,11 @@ def security_group_rule_read(self, context, sgr_id):
40184020

40194021
sg_obj, sg_rule = self._security_group_rule_find(sgr_id, project_uuid)
40204022
if sg_obj and sg_rule:
4021-
return self._security_group_rule_vnc_to_neutron(sg_obj.uuid,
4022-
sg_rule, sg_obj)
4023-
4023+
sgr_info = self._security_group_rule_vnc_to_neutron(sg_obj.uuid,
4024+
sg_rule,
4025+
sg_obj)
4026+
if sgr_info:
4027+
return sgr_info
40244028
self._raise_contrail_exception('SecurityGroupRuleNotFound', id=sgr_id)
40254029
#end security_group_rule_read
40264030

@@ -4049,10 +4053,10 @@ def security_group_rules_read(self, sg_id, sg_obj=None):
40494053
return
40504054

40514055
for sg_rule in sgr_entries.get_policy_rule():
4052-
sg_info = self._security_group_rule_vnc_to_neutron(sg_obj.uuid,
4053-
sg_rule,
4054-
sg_obj)
4055-
sg_rules.append(sg_info)
4056+
sgr_info = self._security_group_rule_vnc_to_neutron(
4057+
sg_obj.uuid, sg_rule, sg_obj)
4058+
if sgr_info:
4059+
sg_rules.append(sgr_info)
40564060
except NoIdError:
40574061
self._raise_contrail_exception('SecurityGroupNotFound', id=sg_id)
40584062

‎src/config/vnc_openstack/vnc_openstack/tests/test_basic.py

Lines changed: 102 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ class TestBasic(test_case.NeutronBackendTestCase):
1515
def read_resource(self, url_pfx, id):
1616
context = {'operation': 'READ',
1717
'user_id': '',
18-
'roles': ''}
18+
'roles': '',
19+
'is_admin': True}
1920
data = {'fields': None,
2021
'id': id}
2122
body = {'context': context, 'data': data}
@@ -137,7 +138,7 @@ def list_resource(url_pfx):
137138
# for collections that are objects in contrail model
138139
for (objects, res_url_pfx, res_xlate_name) in collection_types:
139140
res_dicts = list_resource(res_url_pfx)
140-
present_ids = [r['id'] for r in res_dicts]
141+
present_ids = [r['id'] for r in res_dicts]
141142
for obj in objects:
142143
self.assertIn(obj.uuid, present_ids)
143144

@@ -153,11 +154,11 @@ def err_on_object_2(orig_method, res_obj, *args, **kwargs):
153154
with test_common.patch(
154155
neutron_db_obj, res_xlate_name, err_on_object_2):
155156
res_dicts = list_resource(res_url_pfx)
156-
present_ids = [r['id'] for r in res_dicts]
157+
present_ids = [r['id'] for r in res_dicts]
157158
self.assertNotIn(objects[2].uuid, present_ids)
158159

159160
res_dicts = list_resource(res_url_pfx)
160-
present_ids = [r['id'] for r in res_dicts]
161+
present_ids = [r['id'] for r in res_dicts]
161162
for obj in objects:
162163
self.assertIn(obj.uuid, present_ids)
163164
# end for collections that are objects in contrail model
@@ -176,7 +177,7 @@ def err_on_sn2(orig_method, subnet_vnc, *args, **kwargs):
176177
with test_common.patch(
177178
neutron_db_obj, '_subnet_vnc_to_neutron', err_on_sn2):
178179
res_dicts = list_resource('subnet')
179-
present_ids = [r['id'] for r in res_dicts]
180+
present_ids = [r['id'] for r in res_dicts]
180181
self.assertNotIn(sn2_id, present_ids)
181182
# end test_list_with_inconsistent_members
182183

@@ -287,6 +288,102 @@ def test_port_bindings(self):
287288
self.assertTrue(isinstance(port_dict['binding:profile'], dict))
288289
self.assertTrue(isinstance(port_dict['binding:host_id'], basestring))
289290
# end test_port_bindings
291+
292+
def test_sg_rules_delete_when_peer_group_deleted_on_read_sg(self):
293+
sg1_obj = vnc_api.SecurityGroup('sg1-%s' %(self.id()))
294+
self._vnc_lib.security_group_create(sg1_obj)
295+
sg1_obj = self._vnc_lib.security_group_read(sg1_obj.fq_name)
296+
sg2_obj = vnc_api.SecurityGroup('sg2-%s' %(self.id()))
297+
self._vnc_lib.security_group_create(sg2_obj)
298+
sg2_obj = self._vnc_lib.security_group_read(sg2_obj.fq_name)
299+
sgr_uuid = str(uuid.uuid4())
300+
local = [vnc_api.AddressType(security_group='local')]
301+
remote = [vnc_api.AddressType(security_group=sg2_obj.get_fq_name_str())]
302+
sgr_obj = vnc_api.PolicyRuleType(rule_uuid=sgr_uuid,
303+
direction='>',
304+
protocol='any',
305+
src_addresses=remote,
306+
src_ports=[vnc_api.PortType(0, 255)],
307+
dst_addresses=local,
308+
dst_ports=[vnc_api.PortType(0, 255)],
309+
ethertype='IPv4')
310+
rules = vnc_api.PolicyEntriesType([sgr_obj])
311+
sg1_obj.set_security_group_entries(rules)
312+
self._vnc_lib.security_group_update(sg1_obj)
313+
314+
self._vnc_lib.security_group_delete(fq_name=sg2_obj.fq_name)
315+
316+
sg_dict = self.read_resource('security_group', sg1_obj.uuid)
317+
sgr = [rule['id'] for rule in sg_dict.get('security_group_rules', [])]
318+
self.assertNotIn(sgr_uuid, sgr)
319+
sg1_obj = self._vnc_lib.security_group_read(sg1_obj.fq_name)
320+
sgr = [rule.rule_uuid for rule in
321+
sg1_obj.get_security_group_entries().get_policy_rule() or []]
322+
self.assertIn(sgr_uuid, sgr)
323+
324+
def test_sg_rules_delete_when_peer_group_deleted_on_read_rule(self):
325+
sg1_obj = vnc_api.SecurityGroup('sg1-%s' %(self.id()))
326+
self._vnc_lib.security_group_create(sg1_obj)
327+
sg1_obj = self._vnc_lib.security_group_read(sg1_obj.fq_name)
328+
sg2_obj = vnc_api.SecurityGroup('sg2-%s' %(self.id()))
329+
self._vnc_lib.security_group_create(sg2_obj)
330+
sg2_obj = self._vnc_lib.security_group_read(sg2_obj.fq_name)
331+
sgr_uuid = str(uuid.uuid4())
332+
local = [vnc_api.AddressType(security_group='local')]
333+
remote = [vnc_api.AddressType(
334+
security_group=sg2_obj.get_fq_name_str())]
335+
sgr_obj = vnc_api.PolicyRuleType(rule_uuid=sgr_uuid,
336+
direction='>',
337+
protocol='any',
338+
src_addresses=remote,
339+
src_ports=[vnc_api.PortType(0, 255)],
340+
dst_addresses=local,
341+
dst_ports=[vnc_api.PortType(0, 255)],
342+
ethertype='IPv4')
343+
rules = vnc_api.PolicyEntriesType([sgr_obj])
344+
sg1_obj.set_security_group_entries(rules)
345+
self._vnc_lib.security_group_update(sg1_obj)
346+
347+
self._vnc_lib.security_group_delete(fq_name=sg2_obj.fq_name)
348+
349+
with ExpectedException(webtest.app.AppError):
350+
self.read_resource('security_group_rule', sgr_uuid)
351+
sg1_obj = self._vnc_lib.security_group_read(sg1_obj.fq_name)
352+
sgr = [rule.rule_uuid for rule in
353+
sg1_obj.get_security_group_entries().get_policy_rule() or []]
354+
self.assertIn(sgr_uuid, sgr)
355+
356+
def test_sg_rules_delete_when_peer_group_deleted_on_list_rules(self):
357+
sg1_obj = vnc_api.SecurityGroup('sg1-%s' %(self.id()))
358+
self._vnc_lib.security_group_create(sg1_obj)
359+
sg1_obj = self._vnc_lib.security_group_read(sg1_obj.fq_name)
360+
sg2_obj = vnc_api.SecurityGroup('sg2-%s' %(self.id()))
361+
self._vnc_lib.security_group_create(sg2_obj)
362+
sg2_obj = self._vnc_lib.security_group_read(sg2_obj.fq_name)
363+
sgr_uuid = str(uuid.uuid4())
364+
local = [vnc_api.AddressType(security_group='local')]
365+
remote = [vnc_api.AddressType(
366+
security_group=sg2_obj.get_fq_name_str())]
367+
sgr_obj = vnc_api.PolicyRuleType(rule_uuid=sgr_uuid,
368+
direction='>',
369+
protocol='any',
370+
src_addresses=remote,
371+
src_ports=[vnc_api.PortType(0, 255)],
372+
dst_addresses=local,
373+
dst_ports=[vnc_api.PortType(0, 255)],
374+
ethertype='IPv4')
375+
rules = vnc_api.PolicyEntriesType([sgr_obj])
376+
sg1_obj.set_security_group_entries(rules)
377+
self._vnc_lib.security_group_update(sg1_obj)
378+
379+
self._vnc_lib.security_group_delete(fq_name=sg2_obj.fq_name)
380+
381+
sgr_dict = self.list_resource('security_group_rule')
382+
self.assertNotIn(sgr_uuid, [rule['id'] for rule in sgr_dict])
383+
sg1_obj = self._vnc_lib.security_group_read(sg1_obj.fq_name)
384+
sgr = [rule.rule_uuid for rule in
385+
sg1_obj.get_security_group_entries().get_policy_rule() or []]
386+
self.assertIn(sgr_uuid, sgr)
290387
# end class TestBasic
291388

292389
class TestExtraFieldsPresenceByKnob(test_case.NeutronBackendTestCase):

0 commit comments

Comments
 (0)