From 056d321c5cdff1607b1f1fc76c4331fb3ce9577c Mon Sep 17 00:00:00 2001 From: ghanshyam Date: Sun, 24 Sep 2017 14:40:46 +0000 Subject: [PATCH] Implement query param schema for agent index GET agent API accept query param to filter the agent list. This commit adds json schema to validating the valid query parameters. There is no change in API behaviour and additionalProperty is kept True for backward compatibility. Partially implements blueprint json-schema-validation-for-query-param Change-Id: Ief3a7cb5b4147ff292194d6ec559031d3c7ea0ad --- nova/api/openstack/compute/agents.py | 1 + nova/api/openstack/compute/schemas/agents.py | 13 ++++ .../unit/api/openstack/compute/test_agents.py | 65 ++++++++++++++++++- 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/nova/api/openstack/compute/agents.py b/nova/api/openstack/compute/agents.py index 489c85a920..6763f132f0 100644 --- a/nova/api/openstack/compute/agents.py +++ b/nova/api/openstack/compute/agents.py @@ -47,6 +47,7 @@ class AgentController(wsgi.Controller): http://wiki.openstack.org/GuestAgent http://wiki.openstack.org/GuestAgentXenStoreCommunication """ + @validation.query_schema(schema.index_query) @extensions.expected_errors(()) def index(self, req): """Return a list of all agent builds. Filter by hypervisor.""" diff --git a/nova/api/openstack/compute/schemas/agents.py b/nova/api/openstack/compute/schemas/agents.py index 0d30efcf07..3ef66c84eb 100644 --- a/nova/api/openstack/compute/schemas/agents.py +++ b/nova/api/openstack/compute/schemas/agents.py @@ -11,6 +11,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +from nova.api.validation import parameter_types create = { 'type': 'object', @@ -79,3 +80,15 @@ update = { 'required': ['para'], 'additionalProperties': False, } + +index_query = { + 'type': 'object', + 'properties': { + 'hypervisor': parameter_types.common_query_param + }, + # NOTE(gmann): This is kept True to keep backward compatibility. + # As of now Schema validation stripped out the additional parameters and + # does not raise 400. In the future, we may block the additional parameters + # by bump in Microversion. + 'additionalProperties': True +} diff --git a/nova/tests/unit/api/openstack/compute/test_agents.py b/nova/tests/unit/api/openstack/compute/test_agents.py index c47f52823c..0b51ccf8bd 100644 --- a/nova/tests/unit/api/openstack/compute/test_agents.py +++ b/nova/tests/unit/api/openstack/compute/test_agents.py @@ -204,8 +204,10 @@ class AgentsTestV21(test.NoDBTestCase): self.assertRaises(webob.exc.HTTPBadRequest, self.controller.delete, self.req, 'string_id') - def test_agents_list(self): - res_dict = self.controller.index(self.req) + def _test_agents_list(self, query_string=None): + req = fakes.HTTPRequest.blank('', use_admin_context=True, + query_string=query_string) + res_dict = self.controller.index(req) agents_list = [{'hypervisor': 'kvm', 'os': 'win', 'architecture': 'x86', 'version': '7.0', @@ -233,6 +235,9 @@ class AgentsTestV21(test.NoDBTestCase): ] self.assertEqual(res_dict, {'agents': agents_list}) + def test_agents_list(self): + self._test_agents_list() + def test_agents_list_with_hypervisor(self): req = fakes.HTTPRequest.blank('', use_admin_context=True, query_string='hypervisor=kvm') @@ -252,6 +257,62 @@ class AgentsTestV21(test.NoDBTestCase): ] self.assertEqual(res_dict, {'agents': response}) + def test_agents_list_with_multi_hypervisor_filter(self): + query_string = 'hypervisor=xen&hypervisor=kvm' + req = fakes.HTTPRequest.blank('', use_admin_context=True, + query_string=query_string) + res_dict = self.controller.index(req) + response = [{'hypervisor': 'kvm', 'os': 'win', + 'architecture': 'x86', + 'version': '7.0', + 'url': 'http://example.com/path/to/resource', + 'md5hash': 'add6bb58e139be103324d04d82d8f545', + 'agent_id': 1}, + {'hypervisor': 'kvm', 'os': 'linux', + 'architecture': 'x86', + 'version': '16.0', + 'url': 'http://example.com/path/to/resource1', + 'md5hash': 'add6bb58e139be103324d04d82d8f546', + 'agent_id': 2}, + ] + self.assertEqual(res_dict, {'agents': response}) + + def test_agents_list_query_allow_negative_int_as_string(self): + req = fakes.HTTPRequest.blank('', use_admin_context=True, + query_string='hypervisor=-1') + res_dict = self.controller.index(req) + self.assertEqual(res_dict, {'agents': []}) + + def test_agents_list_query_allow_int_as_string(self): + req = fakes.HTTPRequest.blank('', use_admin_context=True, + query_string='hypervisor=1') + res_dict = self.controller.index(req) + self.assertEqual(res_dict, {'agents': []}) + + def test_agents_list_with_unknown_filter(self): + query_string = 'unknown_filter=abc' + self._test_agents_list(query_string=query_string) + + def test_agents_list_with_hypervisor_and_additional_filter(self): + req = fakes.HTTPRequest.blank( + '', use_admin_context=True, + query_string='hypervisor=kvm&additional_filter=abc') + res_dict = self.controller.index(req) + response = [{'hypervisor': 'kvm', 'os': 'win', + 'architecture': 'x86', + 'version': '7.0', + 'url': 'http://example.com/path/to/resource', + 'md5hash': 'add6bb58e139be103324d04d82d8f545', + 'agent_id': 1}, + {'hypervisor': 'kvm', 'os': 'linux', + 'architecture': 'x86', + 'version': '16.0', + 'url': 'http://example.com/path/to/resource1', + 'md5hash': 'add6bb58e139be103324d04d82d8f546', + 'agent_id': 2}, + ] + self.assertEqual(res_dict, {'agents': response}) + def test_agents_update(self): body = {'para': {'version': '7.0', 'url': 'http://example.com/path/to/resource',