Allow StringField to enforce max length¶
https://blueprints.launchpad.net/nova/+spec/string-field-max-length
This blueprint aims to add a max length constraint to the nova.objects.fields.StringField class.
Problem description¶
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.
Proposed change¶
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.
Alternatives¶
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¶
None
Security impact¶
None
Notifications impact¶
None
Other end user impact¶
None
Performance Impact¶
None
Other deployer impact¶
None
Developer impact¶
None
Implementation¶
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__)
to this:
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.
Work Items¶
N/A
Assignee(s)¶
- Primary assignee:
jaypipes
Dependencies¶
None
Testing¶
Would need new unit tests. No need for any integration test changes.
Documentation Impact¶
None
References¶
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.
http://git.openstack.org/cgit/openstack/nova-specs/tree/specs/juno/tag-instances.rst