Allow StringField to enforce max length¶
This blueprint aims to add a max length constraint to the nova.objects.fields.StringField class.
Currently, the nova object framework revolves around the use of field type classes that describe the schema of an object. Each object model is simply a collection of fields, each of which have a particular type, such as IntegerField or StringField.
In much the same way that a SQL database schema describes the constraints that a given column in a table must adhere to – e.g. the length of characters possible in a CHAR field, or a valid DATETIME string – the nova objects should be self-validating.
This specification proposes to change the coerce method of the String class to validate on the number of characters in the field’s string value.
The StringField concrete field class shall have a new max_length kwarg added to its constructor that will control the validation. The default value will be None, and no StringField objects defined in the schemas of any of the nova object models shall be changed in this spec.
None (keep things the way they are now)
Data model impact¶
None (the existing models themselves won’t be changed in this specification at all)
REST API impact¶
Other end user impact¶
Other deployer impact¶
Roughly, the code the String field type class would change from this:
class String(FieldType): @staticmethod def coerce(obj, attr, value): # FIXME(danms): We should really try to avoid the need to do this if isinstance(value, (six.string_types, int, long, float, datetime.datetime)): return unicode(value) else: raise ValueError(_('A string is required here, not %s') % value.__class__.__name__)
class String(FieldType): def __init__(self, max_length=None): """ :param max_length: Optional constraint on the number of Unicode characters the string value can be. """ self._max_length = max_length @staticmethod def coerce(self, obj, attr, value): # FIXME(danms): We should really try to avoid the need to do this if isinstance(value, (six.string_types, int, long, float, datetime.datetime)): result = unicode(value) else: raise ValueError(_('A string is required here, not %s') % value.__class__.__name__) if self._max_length is not None: if len(value) > self._max_length): msg = _("String %(result)s is longer than maximum allowed " "length of %(max_length)d.") msg = msg % dict(result=result, max_length=self._max_length) raise ValueError(msg) return result
The StringField class would then need to be modified to allow passing the max_length parameter along to its type class.
- Primary assignee:
Would need new unit tests. No need for any integration test changes.
The server-instance-tagging work will likely be the first work to use this functionality, as the tag string has a max length associated with it and we need to be very careful about changing existing model fields’ string length validation code, so a new field like the tag field is an ideal place to begin with this implementation.