Merge "V3 jsonschema validation: scheduler_hints"
This commit is contained in:
commit
5dcf4f52ad
@ -12,32 +12,28 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import webob.exc
|
||||
|
||||
from cinder.api import extensions
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.i18n import _
|
||||
from cinder.api.schemas import scheduler_hints
|
||||
from cinder.api import validation
|
||||
|
||||
|
||||
class SchedulerHintsController(wsgi.Controller):
|
||||
|
||||
@staticmethod
|
||||
def _extract_scheduler_hints(body):
|
||||
@validation.schema(scheduler_hints.create)
|
||||
def _extract_scheduler_hints(self, req, body):
|
||||
hints = {}
|
||||
|
||||
attr = '%s:scheduler_hints' % Scheduler_hints.alias
|
||||
try:
|
||||
if attr in body:
|
||||
hints.update(body[attr])
|
||||
except ValueError:
|
||||
msg = _("Malformed scheduler_hints attribute")
|
||||
raise webob.exc.HTTPBadRequest(explanation=msg)
|
||||
if body.get(attr) is not None:
|
||||
hints.update(body.get(attr))
|
||||
|
||||
return hints
|
||||
|
||||
@wsgi.extends
|
||||
def create(self, req, body):
|
||||
hints = self._extract_scheduler_hints(body)
|
||||
attr = '%s:scheduler_hints' % Scheduler_hints.alias
|
||||
scheduler_hints_body = dict.fromkeys((attr,), body.get(attr))
|
||||
hints = self._extract_scheduler_hints(req, body=scheduler_hints_body)
|
||||
|
||||
if 'volume' in body:
|
||||
body['volume']['scheduler_hints'] = hints
|
||||
|
79
cinder/api/schemas/scheduler_hints.py
Normal file
79
cinder/api/schemas/scheduler_hints.py
Normal file
@ -0,0 +1,79 @@
|
||||
# Copyright (C) 2018 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.
|
||||
|
||||
"""
|
||||
Schema for V3 scheduler_hints API.
|
||||
|
||||
"""
|
||||
|
||||
from cinder.api.validation import parameter_types
|
||||
|
||||
create = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'OS-SCH-HNT:scheduler_hints': {
|
||||
'type': ['object', 'null'],
|
||||
'properties': {
|
||||
'local_to_instance': parameter_types.optional_uuid,
|
||||
'different_host': {
|
||||
# NOTE: The value of 'different_host' is the set of volume
|
||||
# uuids where a new volume is scheduled on a different
|
||||
# host. A user can specify one volume as string parameter
|
||||
# and should specify multiple volumes as array parameter
|
||||
# instead.
|
||||
'oneOf': [
|
||||
{
|
||||
'type': 'string',
|
||||
'format': 'uuid'
|
||||
},
|
||||
{
|
||||
'type': 'array',
|
||||
'items': parameter_types.uuid,
|
||||
'uniqueItems': True,
|
||||
}
|
||||
]
|
||||
},
|
||||
'same_host': {
|
||||
# NOTE: The value of 'same_host' is the set of volume
|
||||
# uuids where a new volume is scheduled on the same host.
|
||||
# A user can specify one volume as string parameter and
|
||||
# should specify multiple volumes as array parameter
|
||||
# instead.
|
||||
'oneOf': [
|
||||
{
|
||||
'type': 'string',
|
||||
'format': 'uuid'
|
||||
},
|
||||
{
|
||||
'type': 'array',
|
||||
'items': parameter_types.uuid,
|
||||
'uniqueItems': True,
|
||||
}
|
||||
]
|
||||
},
|
||||
'query': {
|
||||
# NOTE: The value of 'query' is converted to dict data with
|
||||
# jsonutils.loads() and used for filtering hosts.
|
||||
'type': ['string', 'object'],
|
||||
},
|
||||
},
|
||||
# NOTE: As this Mail:
|
||||
# http://lists.openstack.org/pipermail/openstack-dev/2015-June/067996.html
|
||||
# pointed out the limit the scheduler-hints in the API is
|
||||
# problematic. So relax it.
|
||||
'additionalProperties': True
|
||||
},
|
||||
},
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
|
||||
import datetime
|
||||
|
||||
import ddt
|
||||
from oslo_serialization import jsonutils
|
||||
from six.moves import http_client
|
||||
|
||||
@ -30,6 +31,7 @@ from cinder.tests.unit import fake_constants as fake
|
||||
UUID = fakes.FAKE_UUID
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class SchedulerHintsTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
@ -104,3 +106,44 @@ class SchedulerHintsTestCase(test.TestCase):
|
||||
req.body = jsonutils.dump_as_bytes(body)
|
||||
res = req.get_response(self.app)
|
||||
self.assertEqual(http_client.BAD_REQUEST, res.status_int)
|
||||
|
||||
@ddt.data({'local_to_instance': UUID},
|
||||
{'local_to_instance': None},
|
||||
{'different_host': [fake.UUID1, fake.UUID2]},
|
||||
{'same_host': UUID},
|
||||
{'same_host': [fake.UUID1, fake.UUID2]},
|
||||
{'fake_key': 'fake_value'},
|
||||
{'query': 'query_testing'},
|
||||
{'query': {}},
|
||||
None)
|
||||
def test_scheduler_hints_with_valid_body(self, value):
|
||||
req = fakes.HTTPRequest.blank('/v2/%s/volumes' % fake.PROJECT_ID)
|
||||
req.method = 'POST'
|
||||
req.content_type = 'application/json'
|
||||
body = {'volume': {'size': 1},
|
||||
'OS-SCH-HNT:scheduler_hints': value}
|
||||
|
||||
req.body = jsonutils.dump_as_bytes(body)
|
||||
res = req.get_response(self.app)
|
||||
self.assertEqual(http_client.ACCEPTED, res.status_int)
|
||||
|
||||
@ddt.data({'local_to_instance': 'local_to_instance'},
|
||||
{'different_host': 'different_host'},
|
||||
{'different_host': ['different_host']},
|
||||
{'different_host': [UUID, UUID]},
|
||||
{'same_host': 'same_host'},
|
||||
{'same_host': ['same_host']},
|
||||
{'same_host': [UUID, UUID]},
|
||||
{'query': None},
|
||||
{'scheduler_hints'})
|
||||
def test_scheduler_hints_with_invalid_body(self, value):
|
||||
req = fakes.HTTPRequest.blank('/v2/%s/volumes' % fake.PROJECT_ID)
|
||||
req.method = 'POST'
|
||||
req.content_type = 'application/json'
|
||||
body = {'volume': {'size': 1},
|
||||
'OS-SCH-HNT:scheduler_hints': value}
|
||||
|
||||
req.body = jsonutils.dump_as_bytes(body)
|
||||
res = req.get_response(self.app)
|
||||
|
||||
self.assertEqual(http_client.BAD_REQUEST, res.status_int)
|
||||
|
Loading…
x
Reference in New Issue
Block a user