check query param for used_limits function

Add additional schema check for used_limit query function,
as we need backward compatible those changes, here we don't do real
check and later a microversion need to be done to do the real check.

Part of blueprint json-schema-validation-for-query-param

Change-Id: I32ea7481aad3988f816e4d6511b6ffb2ca68586c
This commit is contained in:
jichenjc 2017-08-30 02:31:55 +08:00
parent 232458ae4e
commit cd132060f1
3 changed files with 66 additions and 5 deletions

View File

@ -21,9 +21,11 @@ from nova.api.openstack.api_version_request \
import MIN_WITHOUT_IMAGE_META_PROXY_API_VERSION
from nova.api.openstack.api_version_request \
import MIN_WITHOUT_PROXY_API_SUPPORT_VERSION
from nova.api.openstack.compute.schemas import limits
from nova.api.openstack.compute.views import limits as limits_views
from nova.api.openstack import extensions
from nova.api.openstack import wsgi
from nova.api import validation
from nova.policies import limits as limits_policies
from nova import quota
@ -36,18 +38,21 @@ class LimitsController(wsgi.Controller):
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@extensions.expected_errors(())
@validation.query_schema(limits.limits_query_schema)
def index(self, req):
return self._index(req)
@wsgi.Controller.api_version(MIN_WITHOUT_PROXY_API_SUPPORT_VERSION, # noqa
MAX_IMAGE_META_PROXY_API_VERSION) # noqa
@extensions.expected_errors(())
@validation.query_schema(limits.limits_query_schema)
def index(self, req):
return self._index(req, filter_result=True)
@wsgi.Controller.api_version( # noqa
MIN_WITHOUT_IMAGE_META_PROXY_API_VERSION) # noqa
@extensions.expected_errors(())
@validation.query_schema(limits.limits_query_schema)
def index(self, req):
return self._index(req, filter_result=True, max_image_meta=False)

View File

@ -0,0 +1,24 @@
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# 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
limits_query_schema = {
'type': 'object',
'properties': {
'tenant_id': parameter_types.common_query_param,
},
# For backward compatible changes
'additionalProperties': True
}

View File

@ -14,6 +14,7 @@
# under the License.
import mock
import webob
from nova.api.openstack import api_version_request
from nova.api.openstack.compute import used_limits \
@ -32,7 +33,13 @@ class FakeRequest(object):
self.reserved = reserved
self.api_version_request = api_version_request.min_api_version()
self.GET = {'reserved': 1} if reserved else {}
if reserved:
self.GET = webob.request.MultiDict({'reserved': 1})
else:
self.GET = webob.request.MultiDict({})
def is_legacy_v2(self):
return False
class UsedLimitsTestCaseV21(test.NoDBTestCase):
@ -114,7 +121,7 @@ class UsedLimitsTestCaseV21(test.NoDBTestCase):
"user_id": user_id
}
fake_req = FakeRequest(self.fake_context)
fake_req.GET = {'tenant_id': tenant_id}
fake_req.GET = webob.request.MultiDict({'tenant_id': tenant_id})
with mock.patch.object(quota.QUOTAS, 'get_project_quotas',
return_value={}) as mock_get_quotas:
@ -125,8 +132,11 @@ class UsedLimitsTestCaseV21(test.NoDBTestCase):
mock_get_quotas.assert_called_once_with(self.fake_context,
tenant_id, usages=True)
def test_admin_can_fetch_used_limits_for_own_project(self):
def _test_admin_can_fetch_used_limits_for_own_project(self, req_get):
project_id = "123456"
if 'tenant_id' in req_get:
project_id = req_get['tenant_id']
user_id = "A1234"
self.fake_context.project_id = project_id
self.fake_context.user_id = user_id
@ -137,7 +147,7 @@ class UsedLimitsTestCaseV21(test.NoDBTestCase):
},
}
fake_req = FakeRequest(self.fake_context)
fake_req.GET = {}
fake_req.GET = webob.request.MultiDict(req_get)
with mock.patch.object(quota.QUOTAS, 'get_project_quotas',
return_value={}) as mock_get_quotas:
@ -147,6 +157,28 @@ class UsedLimitsTestCaseV21(test.NoDBTestCase):
mock_get_quotas.assert_called_once_with(self.fake_context,
project_id, usages=True)
def test_admin_can_fetch_used_limits_for_own_project(self):
req_get = {}
self._test_admin_can_fetch_used_limits_for_own_project(req_get)
def test_admin_can_fetch_used_limits_for_dummy_only(self):
# for back compatible we allow additional param to be send to req.GET
# it can be removed when we add restrictions to query param later
req_get = {'dummy': 'dummy'}
self._test_admin_can_fetch_used_limits_for_own_project(req_get)
def test_admin_can_fetch_used_limits_with_positive_int(self):
req_get = {'tenant_id': 123}
self._test_admin_can_fetch_used_limits_for_own_project(req_get)
def test_admin_can_fetch_used_limits_with_negative_int(self):
req_get = {'tenant_id': -1}
self._test_admin_can_fetch_used_limits_for_own_project(req_get)
def test_admin_can_fetch_used_limits_with_unkown_param(self):
req_get = {'tenant_id': '123', 'unknown': 'unknown'}
self._test_admin_can_fetch_used_limits_for_own_project(req_get)
def test_non_admin_cannot_fetch_used_limits_for_any_other_project(self):
project_id = "123456"
user_id = "A1234"
@ -164,7 +196,7 @@ class UsedLimitsTestCaseV21(test.NoDBTestCase):
"user_id": user_id
}
fake_req = FakeRequest(self.fake_context)
fake_req.GET = {'tenant_id': tenant_id}
fake_req.GET = webob.request.MultiDict({'tenant_id': tenant_id})
self.mock_can.side_effect = exception.PolicyNotAuthorized(
action=self.used_limit_extension)