Merge "Enable conversion for composite attribute items"
This commit is contained in:
commit
591ce97ab9
@ -320,6 +320,29 @@ def _validate_uuid_list(data, valid_values=None):
|
|||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_dict_item(key, key_validator, data):
|
||||||
|
# Find conversion function, if any, and apply it
|
||||||
|
conv_func = key_validator.get('convert_to')
|
||||||
|
if conv_func:
|
||||||
|
data[key] = conv_func(data.get(key))
|
||||||
|
# Find validator function
|
||||||
|
# TODO(salv-orlando): Structure of dict attributes should be improved
|
||||||
|
# to avoid iterating over items
|
||||||
|
val_func = val_params = None
|
||||||
|
for (k, v) in key_validator.iteritems():
|
||||||
|
if k.startswith('type:'):
|
||||||
|
# ask forgiveness, not permission
|
||||||
|
try:
|
||||||
|
val_func = validators[k]
|
||||||
|
except KeyError:
|
||||||
|
return _("Validator '%s' does not exist.") % k
|
||||||
|
val_params = v
|
||||||
|
break
|
||||||
|
# Process validation
|
||||||
|
if val_func:
|
||||||
|
return val_func(data.get(key), val_params)
|
||||||
|
|
||||||
|
|
||||||
def _validate_dict(data, key_specs=None):
|
def _validate_dict(data, key_specs=None):
|
||||||
if not isinstance(data, dict):
|
if not isinstance(data, dict):
|
||||||
msg = _("'%s' is not a dictionary") % data
|
msg = _("'%s' is not a dictionary") % data
|
||||||
@ -339,22 +362,11 @@ def _validate_dict(data, key_specs=None):
|
|||||||
LOG.debug(msg)
|
LOG.debug(msg)
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
# Perform validation of all values according to the specifications.
|
# Perform validation and conversion of all values
|
||||||
|
# according to the specifications.
|
||||||
for key, key_validator in [(k, v) for k, v in key_specs.iteritems()
|
for key, key_validator in [(k, v) for k, v in key_specs.iteritems()
|
||||||
if k in data]:
|
if k in data]:
|
||||||
|
msg = _validate_dict_item(key, key_validator, data)
|
||||||
for val_name in [n for n in key_validator.iterkeys()
|
|
||||||
if n.startswith('type:')]:
|
|
||||||
# Check whether specified validator exists.
|
|
||||||
if val_name not in validators:
|
|
||||||
msg = _("Validator '%s' does not exist.") % val_name
|
|
||||||
LOG.debug(msg)
|
|
||||||
return msg
|
|
||||||
|
|
||||||
val_func = validators[val_name]
|
|
||||||
val_params = key_validator[val_name]
|
|
||||||
|
|
||||||
msg = val_func(data.get(key), val_params)
|
|
||||||
if msg:
|
if msg:
|
||||||
LOG.debug(msg)
|
LOG.debug(msg)
|
||||||
return msg
|
return msg
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
from neutron.api import extensions
|
from neutron.api import extensions
|
||||||
|
from neutron.api.v2 import attributes as attrs
|
||||||
from neutron.common import exceptions as qexception
|
from neutron.common import exceptions as qexception
|
||||||
from neutron.extensions import l3
|
from neutron.extensions import l3
|
||||||
|
|
||||||
@ -37,7 +38,8 @@ EXTENDED_ATTRIBUTES_2_0 = {
|
|||||||
'validate':
|
'validate':
|
||||||
{'type:dict_or_nodata':
|
{'type:dict_or_nodata':
|
||||||
{'network_id': {'type:uuid': None, 'required': True},
|
{'network_id': {'type:uuid': None, 'required': True},
|
||||||
'enable_snat': {'type:boolean': None, 'required': False}}
|
'enable_snat': {'type:boolean': None, 'required': False,
|
||||||
|
'convert_to': attrs.convert_to_boolean}}
|
||||||
}}}}
|
}}}}
|
||||||
|
|
||||||
|
|
||||||
|
@ -537,6 +537,20 @@ class TestAttributes(base.BaseTestCase):
|
|||||||
msg = attributes._validate_dict(dictionary, constraints)
|
msg = attributes._validate_dict(dictionary, constraints)
|
||||||
self.assertIsNotNone(msg)
|
self.assertIsNotNone(msg)
|
||||||
|
|
||||||
|
def test_validate_dict_convert_boolean(self):
|
||||||
|
dictionary, constraints = self._construct_dict_and_constraints()
|
||||||
|
|
||||||
|
constraints['key_bool'] = {
|
||||||
|
'type:boolean': None,
|
||||||
|
'required': False,
|
||||||
|
'convert_to': attributes.convert_to_boolean}
|
||||||
|
dictionary['key_bool'] = 'true'
|
||||||
|
msg = attributes._validate_dict(dictionary, constraints)
|
||||||
|
self.assertIsNone(msg)
|
||||||
|
# Explicitly comparing with literal 'True' as assertTrue
|
||||||
|
# succeeds also for 'true'
|
||||||
|
self.assertIs(True, dictionary['key_bool'])
|
||||||
|
|
||||||
def test_subdictionary(self):
|
def test_subdictionary(self):
|
||||||
dictionary, constraints = self._construct_dict_and_constraints()
|
dictionary, constraints = self._construct_dict_and_constraints()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user