Merge "V3 jsonschema validation: Group type specs"
This commit is contained in:
commit
db2ae0902a
43
cinder/api/schemas/group_specs.py
Normal file
43
cinder/api/schemas/group_specs.py
Normal 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
|
||||
})
|
@ -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())
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user