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):
if not isinstance(data, dict):
msg = _("'%s' is not a dictionary") % data
LOG.debug(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()
if k in 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:
- LOG.debug(msg)
- return msg
+ msg = _validate_dict_item(key, key_validator, data)
+ if msg:
+ LOG.debug(msg)
+ return msg
def _validate_dict_or_none(data, key_specs=None):
#
from neutron.api import extensions
+from neutron.api.v2 import attributes as attrs
from neutron.common import exceptions as qexception
from neutron.extensions import l3
'validate':
{'type:dict_or_nodata':
{'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}}
}}}}
msg = attributes._validate_dict(dictionary, constraints)
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):
dictionary, constraints = self._construct_dict_and_constraints()