From 55f6a8ac5d234f004ef06add87d16284e9f048d3 Mon Sep 17 00:00:00 2001 From: shihanzhang Date: Mon, 22 Sep 2014 17:28:06 +0800 Subject: [PATCH] Fix KeyError when getting secgroup info for ports The patch fixes a regression introduced with secgroup rpc refactor by handling the case when security group contains rules for only IPv4 or IPv6. Change-Id: I02b174757bfc796a81cdb482c55ba7f9e954131d Closes-bug: #1372337 --- neutron/db/securitygroups_rpc_base.py | 3 +- .../tests/unit/test_security_groups_rpc.py | 46 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/neutron/db/securitygroups_rpc_base.py b/neutron/db/securitygroups_rpc_base.py index 8f87a8c80..1dda6bb46 100644 --- a/neutron/db/securitygroups_rpc_base.py +++ b/neutron/db/securitygroups_rpc_base.py @@ -206,7 +206,8 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin): for sg_id, member_ips in ips.items(): for ip in member_ips: ethertype = 'IPv%d' % netaddr.IPAddress(ip).version - if ip not in sg_info['sg_member_ips'][sg_id][ethertype]: + if (ethertype in sg_info['sg_member_ips'][sg_id] + and ip not in sg_info['sg_member_ips'][sg_id][ethertype]): sg_info['sg_member_ips'][sg_id][ethertype].append(ip) return sg_info diff --git a/neutron/tests/unit/test_security_groups_rpc.py b/neutron/tests/unit/test_security_groups_rpc.py index 5a1d5dc97..7f20c7d9e 100644 --- a/neutron/tests/unit/test_security_groups_rpc.py +++ b/neutron/tests/unit/test_security_groups_rpc.py @@ -544,6 +544,52 @@ class SGServerRpcCallBackTestCase(test_sg.SecurityGroupDBTestCase): expected) self._delete('ports', port_id1) + def test_security_group_info_for_devices_only_ipv6_rule(self): + with self.network() as n: + with contextlib.nested(self.subnet(n), + self.security_group()) as (subnet_v4, + sg1): + sg1_id = sg1['security_group']['id'] + rule1 = self._build_security_group_rule( + sg1_id, + 'ingress', const.PROTO_NAME_TCP, '22', + '22', remote_group_id=sg1_id, + ethertype=const.IPv6) + rules = { + 'security_group_rules': [rule1['security_group_rule']]} + self._make_security_group_rule(self.fmt, rules) + + res1 = self._create_port( + self.fmt, n['network']['id'], + security_groups=[sg1_id]) + ports_rest1 = self.deserialize(self.fmt, res1) + port_id1 = ports_rest1['port']['id'] + self.rpc.devices = {port_id1: ports_rest1['port']} + devices = [port_id1, 'no_exist_device'] + + ctx = context.get_admin_context() + ports_rpc = self.rpc.security_group_info_for_devices( + ctx, devices=devices) + expected = { + 'security_groups': {sg1_id: [ + {'direction': 'egress', 'ethertype': const.IPv4}, + {'direction': 'egress', 'ethertype': const.IPv6}, + {'direction': u'ingress', + 'protocol': const.PROTO_NAME_TCP, + 'ethertype': const.IPv6, + 'port_range_max': 22, 'port_range_min': 22, + 'remote_group_id': sg1_id} + ]}, + 'sg_member_ips': {sg1_id: { + 'IPv6': [], + }} + } + self.assertEqual(expected['security_groups'], + ports_rpc['security_groups']) + self.assertEqual(expected['sg_member_ips'][sg1_id]['IPv6'], + ports_rpc['sg_member_ips'][sg1_id]['IPv6']) + self._delete('ports', port_id1) + def test_security_group_ra_rules_for_devices_ipv6_gateway_global(self): fake_prefix = FAKE_PREFIX[const.IPv6] fake_gateway = FAKE_IP['IPv6_GLOBAL'] -- 2.45.2