[python-neutronclient/f21] Fix listing security group rules
Jakub Ruzicka
jruzicka at fedoraproject.org
Thu Aug 21 15:39:18 UTC 2014
commit 7ddca4eba148fdcf4563b337578a0b69a397e8fd
Author: Jakub Ruzicka <jruzicka at redhat.com>
Date: Thu Aug 21 17:38:56 2014 +0200
Fix listing security group rules
0002-Fix-listing-security-group-rules.patch | 180 +++++++++++++++++++++++++++
python-neutronclient.spec | 7 +-
2 files changed, 186 insertions(+), 1 deletions(-)
---
diff --git a/0002-Fix-listing-security-group-rules.patch b/0002-Fix-listing-security-group-rules.patch
new file mode 100644
index 0000000..06255dc
--- /dev/null
+++ b/0002-Fix-listing-security-group-rules.patch
@@ -0,0 +1,180 @@
+From 1bc908fdd08ae207785ab2ad572e7289acf4d246 Mon Sep 17 00:00:00 2001
+From: liuweicai <liuuweicai at gmail.com>
+Date: Wed, 28 May 2014 10:07:43 +0800
+Subject: [PATCH] Fix listing security group rules
+
+It was failing when there are too many security groups, since we're
+hitting a RequestURITooLong exception.
+
+Co-Authored-By: Vincent Untz <vuntz at suse.com>
+Co-Authored-By: Ilya Shakhat <ishakhat at mirantis.com>
+Change-Id: If94b6a2ed6878efad1224e056ecf43e65e85e821
+Closes-Bug: 1271462
+---
+ neutronclient/neutron/v2_0/securitygroup.py | 29 ++++++-
+ .../tests/unit/test_cli20_securitygroup.py | 97 ++++++++++++++++++++++
+ 2 files changed, 123 insertions(+), 3 deletions(-)
+
+diff --git a/neutronclient/neutron/v2_0/securitygroup.py b/neutronclient/neutron/v2_0/securitygroup.py
+index b59eba5..06d1c4a 100644
+--- a/neutronclient/neutron/v2_0/securitygroup.py
++++ b/neutronclient/neutron/v2_0/securitygroup.py
+@@ -17,6 +17,7 @@
+ import argparse
+ import logging
+
++from neutronclient.common import exceptions
+ from neutronclient.neutron import v2_0 as neutronV20
+ from neutronclient.openstack.common.gettextutils import _
+
+@@ -141,9 +142,31 @@ class ListSecurityGroupRule(neutronV20.ListCommand):
+ for rule in data:
+ for key in self.replace_rules:
+ sec_group_ids.add(rule[key])
+- search_opts.update({"id": sec_group_ids})
+- secgroups = neutron_client.list_security_groups(**search_opts)
+- secgroups = secgroups.get('security_groups', [])
++ sec_group_ids = list(sec_group_ids)
++
++ def _get_sec_group_list(sec_group_ids):
++ search_opts['id'] = sec_group_ids
++ return neutron_client.list_security_groups(
++ **search_opts).get('security_groups', [])
++
++ try:
++ secgroups = _get_sec_group_list(sec_group_ids)
++ except exceptions.RequestURITooLong as uri_len_exc:
++ # Length of a query filter on security group rule id
++ # id=<uuid>& (with len(uuid)=36)
++ sec_group_id_filter_len = 40
++ # The URI is too long because of too many sec_group_id filters
++ # Use the excess attribute of the exception to know how many
++ # sec_group_id filters can be inserted into a single request
++ sec_group_count = len(sec_group_ids)
++ max_size = ((sec_group_id_filter_len * sec_group_count) -
++ uri_len_exc.excess)
++ chunk_size = max_size / sec_group_id_filter_len
++ secgroups = []
++ for i in range(0, sec_group_count, chunk_size):
++ secgroups.extend(
++ _get_sec_group_list(sec_group_ids[i: i + chunk_size]))
++
+ sg_dict = dict([(sg['id'], sg['name'])
+ for sg in secgroups if sg['name']])
+ for rule in data:
+diff --git a/neutronclient/tests/unit/test_cli20_securitygroup.py b/neutronclient/tests/unit/test_cli20_securitygroup.py
+index 3ffd023..72267c7 100644
+--- a/neutronclient/tests/unit/test_cli20_securitygroup.py
++++ b/neutronclient/tests/unit/test_cli20_securitygroup.py
+@@ -17,7 +17,10 @@
+ import sys
+
+ import mox
++import six
+
++from neutronclient.common import exceptions
++from neutronclient.common import utils
+ from neutronclient.neutron.v2_0 import securitygroup
+ from neutronclient.tests.unit import test_cli20
+
+@@ -186,6 +189,100 @@ class CLITestV20SecurityGroupsJSON(test_cli20.CLITestV20Base):
+ mox.IgnoreArg())
+ self._test_list_resources(resources, cmd, True)
+
++ def _test_extend_list(self, mox_calls):
++ resources = "security_groups"
++
++ data = [{'name': 'default',
++ 'security_group_id': 'secgroupid%02d' % i,
++ 'remote_group_id': 'remgroupid%02d' % i}
++ for i in range(10)]
++
++ cmd = securitygroup.ListSecurityGroupRule(
++ test_cli20.MyApp(sys.stdout), None)
++ self.mox.StubOutWithMock(cmd, "get_client")
++ self.mox.StubOutWithMock(self.client.httpclient, "request")
++
++ cmd.get_client().MultipleTimes().AndReturn(self.client)
++ path = getattr(self.client, resources + '_path')
++ mox_calls(path, data)
++ self.mox.ReplayAll()
++ known_args, _vs = cmd.get_parser(
++ 'list' + resources).parse_known_args()
++
++ cmd.extend_list(data, known_args)
++ self.mox.VerifyAll()
++ self.mox.UnsetStubs()
++
++ def _build_test_data(self, data, excess=0):
++ # Length of a query filter on security group rule id
++ # in these testcases, id='secgroupid%02d' (with len(id)=12)
++ sec_group_id_filter_len = 12
++
++ response = []
++ replace_rules = {'security_group_id': 'security_group',
++ 'remote_group_id': 'remote_group'}
++
++ search_opts = {'fields': ['id', 'name']}
++ sec_group_ids = set()
++ for rule in data:
++ for key in replace_rules:
++ sec_group_ids.add(rule[key])
++ response.append({'id': rule[key], 'name': 'default'})
++ sec_group_ids = list(sec_group_ids)
++
++ result = []
++
++ sec_group_count = len(sec_group_ids)
++ max_size = ((sec_group_id_filter_len * sec_group_count) - excess)
++ chunk_size = max_size / sec_group_id_filter_len
++
++ for i in range(0, sec_group_count, chunk_size):
++ search_opts['id'] = sec_group_ids[i: i + chunk_size]
++ params = utils.safe_encode_dict(search_opts)
++ resp_str = self.client.serialize({'security_groups': response})
++
++ result.append({
++ 'filter': six.moves.urllib.parse.urlencode(params, doseq=1),
++ 'response': (test_cli20.MyResp(200), resp_str),
++ })
++
++ return result
++
++ def test_extend_list(self):
++ def mox_calls(path, data):
++ responses = self._build_test_data(data)
++ self.client.httpclient.request(
++ test_cli20.MyUrlComparator(test_cli20.end_url(
++ path, responses[0]['filter']), self.client),
++ 'GET',
++ body=None,
++ headers=mox.ContainsKeyValue(
++ 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(
++ responses[0]['response'])
++
++ self._test_extend_list(mox_calls)
++
++ def test_extend_list_exceed_max_uri_len(self):
++ def mox_calls(path, data):
++ # 1 char of extra URI len will cause a split in 2 requests
++ self.mox.StubOutWithMock(self.client, '_check_uri_length')
++ self.client._check_uri_length(mox.IgnoreArg()).AndRaise(
++ exceptions.RequestURITooLong(excess=1))
++ responses = self._build_test_data(data, excess=1)
++
++ for item in responses:
++ self.client._check_uri_length(
++ mox.IgnoreArg()).AndReturn(None)
++ self.client.httpclient.request(
++ test_cli20.end_url(path, item['filter']),
++ 'GET',
++ body=None,
++ headers=mox.ContainsKeyValue(
++ 'X-Auth-Token', test_cli20.TOKEN)).AndReturn(
++ item['response'])
++
++ self._test_extend_list(mox_calls)
++
+ def test_list_security_group_rules_pagination(self):
+ resources = "security_group_rules"
+ cmd = securitygroup.ListSecurityGroupRule(
diff --git a/python-neutronclient.spec b/python-neutronclient.spec
index db0c8fa..3d2e9aa 100644
--- a/python-neutronclient.spec
+++ b/python-neutronclient.spec
@@ -1,6 +1,6 @@
Name: python-neutronclient
Version: 2.3.4
-Release: 2%{?dist}
+Release: 3%{?dist}
Summary: Python API and CLI for OpenStack Neutron
Group: Development/Languages
@@ -12,6 +12,7 @@ Source0: https://pypi.python.org/packages/source/p/%{name}/%{name}-%{version}
# patches_base=2.3.4
#
Patch0001: 0001-Remove-runtime-dependency-on-python-pbr.patch
+Patch0002: 0002-Fix-listing-security-group-rules.patch
BuildArch: noarch
@@ -34,6 +35,7 @@ Neutron's API.
%setup -q -n %{name}-%{version}
%patch0001 -p1
+%patch0002 -p1
# We provide version like this in order to remove runtime dep on pbr.
sed -i s/REDHATNEUTRONCLIENTVERSION/%{version}/ neutronclient/version.py
@@ -63,6 +65,9 @@ rm -rf %{buildroot}%{python_sitelib}/neutronclient/tests
%{_sysconfdir}/bash_completion.d
%changelog
+* Thu Aug 21 2014 Jakub Ruzicka <jruzicka at redhat.com> 2.3.4-3
+- Fix listing security group rules
+
* Sat Jun 07 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.3.4-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
More information about the scm-commits
mailing list