API Validators

For the REST API, attributes may have custom validators defined. Each validator will have a method to perform the validation, and a type definition string, so that the validator can be referenced.

Defining A Validator Method

The validation method will have a positional argument for the data to be validated, and may have additional (optional) keyword arguments that can be used during validation. The method must handle any exceptions and either return None (success) or a i18n string indicating the validation failure message. By convention, the method name is prefixed with validate_ and then includes the data type. For example:

def validate_uuid(data, valid_values=None):
   if not uuidutils.is_uuid_like(data):
       msg = _("'%s' is not a valid UUID") % data
       LOG.debug(msg)
       return msg

There is a validation dictionary that maps the method to a validation type that can be referred to in REST API definitions. An entry in the dictionary would look like the following:

'type:uuid': validate_uuid,

Using Validators

In client code, the validator can be used in a REST API by using the dictionary key for the validator. For example:

NETWORKS: {
    'id': {'allow_post': False, 'allow_put': False,
           'validate': {'type:uuid': None},
           'is_visible': True,
           'primary_key': True},
    'name': {'allow_post': True, 'allow_put': True,
             'validate': {'type:string': NAME_MAX_LEN},
             'default': '', 'is_visible': True}}

Here, the networks resource has an ‘id’ attribute with a UUID validator, as seen by the ‘validate’ key containing a dictionary with a key of ‘type:uuid’.

Any addition arguments for the validator can be specified as values for the dictionary entry (None in this case, NAME_MAX_LEN in the ‘name’ attribute that uses a string validator). In a IP version attribute, one could have a validator defined as follows:

'ip_version': {'allow_post': True, 'allow_put': False,
               'convert_to': conversions.convert_to_int,
               'validate': {'type:values': [4, 6]},
               'is_visible': True}}

Here, the validate_values() method will take the list of values as the allowable values that can be specified for this attribute.

Test The Validator

Do the right thing, and make sure you’ve created a unit test for any validator that you add to verify that it works as expected, even for simple validators.