Implement query param schema for sec group APIs

sec group APIs accept query param to filter the
quota.
This commit adds json schema to validate the valid
query parameters.

There is no change in API behaviour and additionalProperties
is kept True for backward compatibility.

Partially implements blueprint json-schema-validation-for-query-param

Change-Id: If55296e0efe6676bb931aad8b2b0133efbb910a7
This commit is contained in:
ghanshyam 2017-11-19 11:36:44 +03:00 committed by Ghanshyam Mann
parent 57728836f2
commit ddf058ba16
3 changed files with 78 additions and 0 deletions

View File

@ -36,3 +36,19 @@ server_create = {
server_create_v20 = copy.deepcopy(server_create)
server_create_v20['security_groups']['items']['properties']['name'] = (
parameter_types.name_with_leading_trailing_spaces)
index_query = {
'type': 'object',
'properties': {
'limit': parameter_types.multi_params(
parameter_types.non_negative_integer),
'offset': parameter_types.multi_params(
parameter_types.non_negative_integer),
'all_tenants': parameter_types.multi_params({'type': 'string'})
},
# 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
}

View File

@ -26,6 +26,7 @@ from nova.api.openstack.compute.schemas import security_groups as \
schema_security_groups
from nova.api.openstack import extensions
from nova.api.openstack import wsgi
from nova.api import validation
from nova import compute
from nova import exception
from nova.i18n import _
@ -191,6 +192,7 @@ class SecurityGroupController(SecurityGroupControllerBase, wsgi.Controller):
raise exc.HTTPBadRequest(explanation=exp.format_message())
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@validation.query_schema(schema_security_groups.index_query)
@extensions.expected_errors(404)
def index(self, req):
"""Returns a list of security groups."""

View File

@ -658,6 +658,66 @@ class TestSecurityGroupsV21(test.TestCase):
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.delete,
self.req, '1')
def _test_list_with_invalid_filter(
self, url, expected_exception=exception.ValidationError):
prefix = '/os-security-groups'
req = fakes.HTTPRequest.blank(prefix + url)
self.assertRaises(expected_exception,
self.controller.index, req)
def test_list_with_invalid_non_int_limit(self):
self._test_list_with_invalid_filter('?limit=-9')
def test_list_with_invalid_string_limit(self):
self._test_list_with_invalid_filter('?limit=abc')
def test_list_duplicate_query_with_invalid_string_limit(self):
self._test_list_with_invalid_filter(
'?limit=1&limit=abc')
def test_list_with_invalid_non_int_offset(self):
self._test_list_with_invalid_filter('?offset=-9')
def test_list_with_invalid_string_offset(self):
self._test_list_with_invalid_filter('?offset=abc')
def test_list_duplicate_query_with_invalid_string_offset(self):
self._test_list_with_invalid_filter(
'?offset=1&offset=abc')
def test_list_duplicate_query_parameters_validation(self):
params = {
'limit': 1,
'offset': 1,
'all_tenants': 1
}
for param, value in params.items():
req = fakes.HTTPRequest.blank(
'/os-security-groups' + '?%s=%s&%s=%s' %
(param, value, param, value))
self.controller.index(req)
def test_list_with_additional_filter(self):
req = fakes.HTTPRequest.blank(
'/os-security-groups?limit=1&offset=1&additional=something')
self.controller.index(req)
def test_list_all_tenants_filter_as_string(self):
req = fakes.HTTPRequest.blank(
'/os-security-groups?all_tenants=abc')
self.controller.index(req)
def test_list_all_tenants_filter_as_positive_int(self):
req = fakes.HTTPRequest.blank(
'/os-security-groups?all_tenants=1')
self.controller.index(req)
def test_list_all_tenants_filter_as_negative_int(self):
req = fakes.HTTPRequest.blank(
'/os-security-groups?all_tenants=-1')
self.controller.index(req)
def test_associate_by_non_existing_security_group_name(self):
self.stub_out('nova.db.instance_get', return_server)
self.assertEqual(return_server(None, '1'),