Files
deb-nova/nova/api/validation/__init__.py
Ken'ichi Ohmichi 6ae6845c63 Separate API schemas for v2.0 compatible API
We are facing v2 compatibility problems for v2.0 compatible API which
became the default API on /v2 endpoint in Liberty. For fixing these
problems, we need to change some API schemas but we cannot change them
directly because these schemas are used for v2.1 API also and we need
to bump a new microversion for changing them as microversions contract.

To fix these problem without v2.1 API schema changes, this patch
separates the API schemas of v2.0 compatible API from v2.1 API ones.

If we need to separate v2.0 schemas from v2.1, we can specify the
separated schema with '2.0' to the decorator @validation.schema like:

    @validation.schema(schema_v20, '2.0', '2.0')
    @validation.schema(schema, '2.1')
    def update(self, req, id, body):
        ...

Change-Id: If35306b6a9dfc0da355b9edbf4451bf72516da24
2015-09-09 13:37:56 +08:00

77 lines
3.0 KiB
Python

# Copyright 2013 NEC Corporation. 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.
"""
Request Body validating middleware.
"""
import functools
from nova.api.openstack import api_version_request as api_version
from nova.api.validation import validators
def schema(request_body_schema, min_version=None, max_version=None):
"""Register a schema to validate request body.
Registered schema will be used for validating request body just before
API method executing.
:argument dict request_body_schema: a schema to validate request body
"""
def add_validator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
min_ver = api_version.APIVersionRequest(min_version)
max_ver = api_version.APIVersionRequest(max_version)
# The request object is always the second argument.
# However numerous unittests pass in the request object
# via kwargs instead so we handle that as well.
# TODO(cyeoh): cleanup unittests so we don't have to
# to do this
if 'req' in kwargs:
ver = kwargs['req'].api_version_request
legacy_v2 = kwargs['req'].is_legacy_v2()
else:
ver = args[1].api_version_request
legacy_v2 = args[1].is_legacy_v2()
if legacy_v2:
# NOTE: For v2.0 compatible API, here should work like
# client | schema min_version | schema
# -----------+--------------------+--------
# legacy_v2 | None | work
# legacy_v2 | 2.0 | work
# legacy_v2 | 2.1+ | don't
if min_version is None or min_version == '2.0':
schema_validator = validators._SchemaValidator(
request_body_schema, legacy_v2)
schema_validator.validate(kwargs['body'])
elif ver.matches(min_ver, max_ver):
# Only validate against the schema if it lies within
# the version range specified. Note that if both min
# and max are not specified the validator will always
# be run.
schema_validator = validators._SchemaValidator(
request_body_schema, legacy_v2)
schema_validator.validate(kwargs['body'])
return func(*args, **kwargs)
return wrapper
return add_validator