From 94bc403078b1e5d2cddc697fc59b7f1d2d8a6045 Mon Sep 17 00:00:00 2001 From: Gabriele Cerami Date: Mon, 13 May 2019 10:38:50 +0100 Subject: [PATCH] ML2 plugin: extract and postpone limit in port query as with https://review.opendev.org/#/c/656066/ if limit is applied in any place other than at the end of the filters, sql alchemy will return an error, and possibily we could return less result than intended. Change-Id: I9a54ae99d2d5dfda63cb0061bcf3d727ed7cc992 Closes-Bug: #1827363 --- neutron/plugins/ml2/plugin.py | 3 +++ neutron/tests/unit/plugins/ml2/test_plugin.py | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index 6e10c87915c..40e9696db4c 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -2185,6 +2185,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, def _get_ports_query(self, context, filters=None, *args, **kwargs): filters = filters or {} security_groups = filters.pop("security_groups", None) + limit = kwargs.pop('limit', None) if security_groups: port_bindings = self._get_port_security_group_bindings( context, filters={'security_group_id': @@ -2204,6 +2205,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, models_v2.IPAllocation.ip_address.like('%%%s%%' % ip)) for ip in ip_addresses_s]) query = query.filter(substr_filter) + if limit: + query = query.limit(limit) return query def filter_hosts_with_network_access( diff --git a/neutron/tests/unit/plugins/ml2/test_plugin.py b/neutron/tests/unit/plugins/ml2/test_plugin.py index cca4ea48037..b723b897f18 100644 --- a/neutron/tests/unit/plugins/ml2/test_plugin.py +++ b/neutron/tests/unit/plugins/ml2/test_plugin.py @@ -1555,6 +1555,12 @@ fixed_ips=ip_address_substr%%3D%s&fixed_ips=subnet_id%%3D%s query_params=query_params) query_params = """ fixed_ips=ip_address_substr%%3D%s&fixed_ips=subnet_id%%3D%s +""".strip() % ('192.168.', + fixed_ips['subnet_id']) + self._test_list_resources('port', [], + query_params=query_params) + query_params = """ +fixed_ips=ip_address_substr%%3D%s&fixed_ips=subnet_id%%3D%s&limit=1 """.strip() % ('192.168.', fixed_ips['subnet_id']) self._test_list_resources('port', [], @@ -1608,6 +1614,12 @@ fixed_ips=ip_address_substr%%3D%s&fixed_ips=ip_address%%3D%s self.assertEqual(set([port1['port']['id'], port2['port']['id']]), set([port['id'] for port in ports_data['ports']])) self.assertEqual(2, len(ports_data['ports'])) + query_params = "security_groups=%s&limit=1" % ( + port1['port']['security_groups'][0]) + ports_data = self._list('ports', query_params=query_params) + self.assertIn(ports_data['ports'][0]['id'], + [port1['port']['id'], port2['port']['id']]) + self.assertEqual(1, len(ports_data['ports'])) query_params = "security_groups=%s&id=%s" % ( port1['port']['security_groups'][0], port1['port']['id'])