Merge "V3 jsonschema validation: Group type specs"

This commit is contained in:
Zuul 2017-12-14 17:17:23 +00:00 committed by Gerrit Code Review
commit db2ae0902a
3 changed files with 64 additions and 34 deletions

View File

@ -0,0 +1,43 @@
# Copyright (C) 2017 NTT DATA
# All Rights Reserved.
#
# 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.
import copy
group_specs_with_no_spaces_key_and_value_null = {
'type': 'object',
'patternProperties': {
'^[a-zA-Z0-9-_:.]{1,255}$': {
'type': ['string', 'null'], 'maxLength': 255
}
},
'additionalProperties': False
}
create = {
'type': 'object',
'properties': {
'type': 'object',
'group_specs': group_specs_with_no_spaces_key_and_value_null,
},
'required': ['group_specs'],
'additionalProperties': False,
}
update = copy.deepcopy(group_specs_with_no_spaces_key_and_value_null)
update.update({
'minProperties': 1,
'maxProperties': 1
})

View File

@ -17,15 +17,15 @@
from six.moves import http_client
import webob
from cinder.api import common
from cinder.api import microversions as mv
from cinder.api.openstack import wsgi
from cinder.api.schemas import group_specs
from cinder.api import validation
from cinder import db
from cinder import exception
from cinder.i18n import _
from cinder.policies import group_types as policy
from cinder import rpc
from cinder import utils
from cinder.volume import group_types
@ -55,16 +55,13 @@ class GroupTypeSpecsController(wsgi.Controller):
@wsgi.Controller.api_version(mv.GROUP_TYPE)
@wsgi.response(http_client.ACCEPTED)
def create(self, req, group_type_id, body=None):
@validation.schema(group_specs.create)
def create(self, req, group_type_id, body):
context = req.environ['cinder.context']
context.authorize(policy.SPEC_POLICY)
self.assert_valid_body(body, 'group_specs')
self._check_type(context, group_type_id)
specs = body['group_specs']
self._check_key_names(specs.keys())
utils.validate_dictionary_string_length(specs)
db.group_type_specs_update_or_create(context,
group_type_id,
specs)
@ -75,22 +72,15 @@ class GroupTypeSpecsController(wsgi.Controller):
return body
@wsgi.Controller.api_version(mv.GROUP_TYPE)
def update(self, req, group_type_id, id, body=None):
@validation.schema(group_specs.update)
def update(self, req, group_type_id, id, body):
context = req.environ['cinder.context']
context.authorize(policy.SPEC_POLICY)
if not body:
expl = _('Request body empty')
raise webob.exc.HTTPBadRequest(explanation=expl)
self._check_type(context, group_type_id)
if id not in body:
expl = _('Request body and URI mismatch')
raise webob.exc.HTTPBadRequest(explanation=expl)
if len(body) > 1:
expl = _('Request body contains too many items')
raise webob.exc.HTTPBadRequest(explanation=expl)
self._check_key_names(body.keys())
utils.validate_dictionary_string_length(body)
db.group_type_specs_update_or_create(context,
group_type_id,
@ -137,13 +127,6 @@ class GroupTypeSpecsController(wsgi.Controller):
notifier_info)
return webob.Response(status_int=http_client.ACCEPTED)
def _check_key_names(self, keys):
if not common.validate_key_names(keys):
expl = _('Key names can only contain alphanumeric characters, '
'underscores, periods, colons and hyphens.')
raise webob.exc.HTTPBadRequest(explanation=expl)
def create_resource():
return wsgi.Resource(GroupTypeSpecsController())

View File

@ -18,6 +18,7 @@ import webob
from cinder import context
from cinder import db
from cinder import exception
from cinder import rpc
from cinder import test
@ -90,7 +91,8 @@ class GroupSpecsTestCase(test.TestCase):
fake.PROJECT_ID,
use_admin_context=True,
version=mv.GROUP_TYPE)
self.controller.create(req, fake.GROUP_ID, create_fake_group_specs)
self.controller.create(req, fake.GROUP_ID,
body=create_fake_group_specs)
self.assertTrue(mock_rpc_notifier.called)
@mock.patch.object(rpc, 'get_notifier')
@ -111,7 +113,7 @@ class GroupSpecsTestCase(test.TestCase):
self.controller.update(req,
fake.GROUP_TYPE_ID,
'id',
update_fake_group_specs)
body=update_fake_group_specs)
self.assertTrue(mock_rpc_notifier.called)
@mock.patch.object(db, 'group_type_specs_get',
@ -155,7 +157,7 @@ class GroupSpecsTestCase(test.TestCase):
self.controller.create,
req,
fake.GROUP_ID,
create_fake_group_specs)
body=create_fake_group_specs)
@mock.patch.object(rpc, 'get_notifier')
@mock.patch.object(db, 'group_type_get', return_value={})
@ -178,15 +180,17 @@ class GroupSpecsTestCase(test.TestCase):
fake.PROJECT_ID,
use_admin_context=True,
version=mv.GROUP_TYPE)
self.assertRaises(webob.exc.HTTPBadRequest,
self.assertRaises(exception.ValidationError,
self.controller.update,
req,
fake.GROUP_TYPE_ID,
'id')
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
req, fake.GROUP_TYPE_ID, 'id', fake_group_specs)
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
req, fake.GROUP_TYPE_ID, 'key1', fake_group_specs)
'id', body=None)
self.assertRaises(exception.ValidationError, self.controller.update,
req, fake.GROUP_TYPE_ID, 'id',
body=fake_group_specs)
self.assertRaises(exception.ValidationError, self.controller.update,
req, fake.GROUP_TYPE_ID, 'key1',
body=fake_group_specs)
@mock.patch.object(db, 'group_type_specs_get',
return_value=fake_group_specs)
@ -216,5 +220,5 @@ class GroupSpecsTestCase(test.TestCase):
fake.PROJECT_ID,
use_admin_context=True,
version=mv.GROUP_TYPE)
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
req, fake.GROUP_ID, incorrect_fake_group_specs)
self.assertRaises(exception.ValidationError, self.controller.create,
req, fake.GROUP_ID, body=incorrect_fake_group_specs)