api: allow any scheduler hints

To help with v2.1 compat mode, we need to allow users to pass in any
scheduler hints, to allow for out of tree extensions.

This includes ensuring the soft additional properties validator does not
strip out extra properties when they are allowed by the schema.

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. This
patch relax the validation of scheduler hints for v2.1 also.

Co-Authored-By: Ed Leafe <ed@leafe.com>
Co-Authored-By: Alex Xu <hejie.xu@intel.com>
Change-Id: I4c066075165f69d355a74979808fa0ad8d6546ab
This commit is contained in:
John Garbutt 2015-08-27 15:14:30 +01:00 committed by He Jie Xu
parent bd3b5a62b4
commit 4a29486f4c
3 changed files with 53 additions and 3 deletions

View File

@ -52,7 +52,11 @@ _hints = {
'pattern': '^\/[0-9a-f.:]+$'
},
},
'additionalProperties': False
# 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
}

View File

@ -75,13 +75,29 @@ def _validate_uri(instance):
require_authority=True)
def _soft_validate_additional_properties(validator, aP, instance, schema):
def _soft_validate_additional_properties(validator,
additional_properties_value,
instance,
schema):
"""This validator function is used for legacy v2 compatible mode in v2.1.
This will skip all the addtional properties checking but keep check the
'patternProperties'. 'patternProperties' is used for metadata API.
If there are not any properties on the instance that are not specified in
the schema, this will return without any effect. If there are any such
extra properties, they will be handled as follows:
- if the schema has an additionalProperties value of True, the extra
properties on the instance will not be touched.
- if the schema has an additionalProperties value of False and there
aren't patternProperties specified, the extra properties will be stripped
from the instance.
- if the schema has an additionalProperties value of False and there
are patternProperties specified, the extra properties will not be
touched and raise validation error if pattern doesn't match.
"""
if not validator.is_type(instance, "object"):
if (not validator.is_type(instance, "object") or
additional_properties_value):
return
properties = schema.get("properties", {})

View File

@ -121,12 +121,25 @@ class TestSoftAddtionalPropertiesValidation(test.NoDBTestCase):
'bar': {'type': 'string'}
},
'additionalProperties': False}
self.schema_allow = {
'type': 'object',
'properties': {
'foo': {'type': 'string'},
'bar': {'type': 'string'}
},
'additionalProperties': True}
self.schema_with_pattern = {
'type': 'object',
'patternProperties': {
'^[a-zA-Z0-9-_:. ]{1,255}$': {'type': 'string'}
},
'additionalProperties': False}
self.schema_allow_with_pattern = {
'type': 'object',
'patternProperties': {
'^[a-zA-Z0-9-_:. ]{1,255}$': {'type': 'string'}
},
'additionalProperties': True}
def test_strip_extra_properties_out_without_extra_props(self):
validator = validators._SchemaValidator(self.schema).validator
@ -144,6 +157,23 @@ class TestSoftAddtionalPropertiesValidation(test.NoDBTestCase):
self.assertRaises(StopIteration, gen.next)
self.assertEqual({'foo': '1'}, instance)
def test_not_strip_extra_properties_out_with_allow_extra_props(self):
validator = validators._SchemaValidator(self.schema_allow).validator
instance = {'foo': '1', 'extra_foo': 'extra'}
gen = validators._soft_validate_additional_properties(
validator, True, instance, self.schema_allow)
self.assertRaises(StopIteration, gen.next)
self.assertEqual({'foo': '1', 'extra_foo': 'extra'}, instance)
def test_pattern_properties_with_invalid_property_and_allow_extra_props(
self):
validator = validators._SchemaValidator(
self.schema_with_pattern).validator
instance = {'foo': '1', 'b' * 300: 'extra'}
gen = validators._soft_validate_additional_properties(
validator, True, instance, self.schema_with_pattern)
self.assertRaises(StopIteration, gen.next)
def test_pattern_properties(self):
validator = validators._SchemaValidator(
self.schema_with_pattern).validator