Create a list of default filter ops for each field type
Change-Id: I76b2e80c97670b4ae49ba7f8b293519369c4ca9a
This commit is contained in:
parent
a1ccdd5bac
commit
acf175d335
@ -87,20 +87,14 @@ class BaseArtifact(base.VersionedObject):
|
||||
nullable=False, sortable=True,
|
||||
description="Artifact status."),
|
||||
'created_at': Field(fields.DateTimeField, system=True,
|
||||
filter_ops=[attribute.FILTER_GT,
|
||||
attribute.FILTER_LT],
|
||||
nullable=False, sortable=True,
|
||||
description="Datetime when artifact has "
|
||||
"been created."),
|
||||
'updated_at': Field(fields.DateTimeField, system=True,
|
||||
filter_ops=[attribute.FILTER_GT,
|
||||
attribute.FILTER_LT],
|
||||
nullable=False, sortable=True,
|
||||
description="Datetime when artifact has "
|
||||
"been updated last time."),
|
||||
'activated_at': Field(fields.DateTimeField, system=True,
|
||||
filter_ops=[attribute.FILTER_GT,
|
||||
attribute.FILTER_LT],
|
||||
required_on_activate=False, sortable=True,
|
||||
description="Datetime when artifact has became "
|
||||
"active."),
|
||||
@ -121,20 +115,15 @@ class BaseArtifact(base.VersionedObject):
|
||||
description="List of tags added to Artifact."),
|
||||
'metadata': DictField(fields.String, required_on_activate=False,
|
||||
element_validators=[validators.MinStrLen(1)],
|
||||
filter_ops=(attribute.FILTER_EQ,
|
||||
attribute.FILTER_IN,
|
||||
attribute.FILTER_NEQ),
|
||||
description="Key-value dict with useful "
|
||||
"information about an artifact."),
|
||||
'visibility': Field(fields.StringField, default='private',
|
||||
nullable=False, filter_ops=(attribute.FILTER_EQ,),
|
||||
sortable=True,
|
||||
nullable=False, sortable=True,
|
||||
description="Artifact visibility that defines "
|
||||
"if artifact can be available to "
|
||||
"other users."),
|
||||
'version': Field(glare_fields.VersionField, required_on_activate=False,
|
||||
default=DEFAULT_ARTIFACT_VERSION,
|
||||
filter_ops=attribute.FILTERS, nullable=False,
|
||||
default=DEFAULT_ARTIFACT_VERSION, nullable=False,
|
||||
sortable=True, validators=[validators.Version()],
|
||||
description="Artifact version(semver).")
|
||||
}
|
||||
@ -769,8 +758,7 @@ class BaseArtifact(base.VersionedObject):
|
||||
:param field_name: blob or blob dict field name
|
||||
:return: maximum blob size in bytes
|
||||
"""
|
||||
return getattr(cls.fields[field_name], 'max_blob_size',
|
||||
attribute.BlobAttribute.DEFAULT_MAX_BLOB_SIZE)
|
||||
return getattr(cls.fields[field_name], 'max_blob_size')
|
||||
|
||||
@classmethod
|
||||
def validate_upload_allowed(cls, af, field_name, blob_key=None):
|
||||
|
@ -24,6 +24,8 @@ FILTERS = (
|
||||
FILTER_EQ, FILTER_NEQ, FILTER_IN, FILTER_GT, FILTER_GTE, FILTER_LT,
|
||||
FILTER_LTE) = ('eq', 'neq', 'in', 'gt', 'gte', 'lt', 'lte')
|
||||
|
||||
DEFAULT_MAX_BLOB_SIZE = 10485760
|
||||
|
||||
|
||||
class Attribute(object):
|
||||
def __init__(self, field_class, mutable=False, required_on_activate=True,
|
||||
@ -56,19 +58,41 @@ class Attribute(object):
|
||||
self.system = system
|
||||
self.sortable = sortable
|
||||
|
||||
if field_class is glare_fields.BlobField:
|
||||
if filter_ops:
|
||||
raise exc.IncorrectArtifactType(
|
||||
"Cannot specify filters for blobs")
|
||||
self.filter_ops = []
|
||||
try:
|
||||
default_ops = self.get_allowed_filter_ops(self.element_type)
|
||||
except AttributeError:
|
||||
default_ops = self.get_allowed_filter_ops(field_class)
|
||||
|
||||
if filter_ops is None:
|
||||
self.filter_ops = default_ops
|
||||
else:
|
||||
self.filter_ops = [FILTER_EQ, FILTER_NEQ, FILTER_IN] \
|
||||
if filter_ops is None else filter_ops
|
||||
for op in filter_ops:
|
||||
if op not in default_ops:
|
||||
raise exc.IncorrectArtifactType(
|
||||
"Incorrect filter operator '%s'. "
|
||||
"Only %s are allowed" % (op, ', '.join(default_ops)))
|
||||
self.filter_ops = filter_ops
|
||||
|
||||
self.field_attrs = ['mutable', 'required_on_activate', 'system',
|
||||
'sortable', 'filter_ops', 'description']
|
||||
self.description = description
|
||||
|
||||
@staticmethod
|
||||
def get_allowed_filter_ops(field):
|
||||
if field in (fields.StringField, fields.String,
|
||||
glare_fields.ArtifactStatusField):
|
||||
return [FILTER_EQ, FILTER_NEQ, FILTER_IN]
|
||||
elif field in (fields.IntegerField, fields.Integer, fields.FloatField,
|
||||
fields.Float, glare_fields.VersionField):
|
||||
return FILTERS
|
||||
elif field in (fields.FlexibleBooleanField, fields.FlexibleBoolean,
|
||||
glare_fields.Link, glare_fields.LinkFieldType):
|
||||
return [FILTER_EQ, FILTER_NEQ]
|
||||
elif field in (glare_fields.BlobField, glare_fields.BlobFieldType):
|
||||
return []
|
||||
elif field is fields.DateTimeField:
|
||||
return [FILTER_LT, FILTER_GT]
|
||||
|
||||
def get_default_validators(self):
|
||||
default = []
|
||||
if issubclass(self.field_class, fields.StringField):
|
||||
@ -125,19 +149,20 @@ class Attribute(object):
|
||||
class CompoundAttribute(Attribute):
|
||||
def __init__(self, field_class, element_type, element_validators=None,
|
||||
**kwargs):
|
||||
super(CompoundAttribute, self).__init__(field_class, **kwargs)
|
||||
if self.sortable:
|
||||
raise exc.IncorrectArtifactType("'sortable' must be False for "
|
||||
"compound type.")
|
||||
|
||||
if element_type is None:
|
||||
raise exc.IncorrectArtifactType("'element_type' must be set for "
|
||||
"compound type.")
|
||||
self.element_type = element_type
|
||||
|
||||
super(CompoundAttribute, self).__init__(field_class, **kwargs)
|
||||
|
||||
self.vo_attrs.append('element_type')
|
||||
self.field_attrs.append('element_type')
|
||||
|
||||
self.element_validators = element_validators or []
|
||||
if self.sortable:
|
||||
raise exc.IncorrectArtifactType("'sortable' must be False for "
|
||||
"compound type.")
|
||||
|
||||
def get_element_validators(self):
|
||||
default_vals = []
|
||||
@ -178,8 +203,6 @@ class DictAttribute(CompoundAttribute):
|
||||
super(DictAttribute, self).__init__(glare_fields.Dict, element_type,
|
||||
**kwargs)
|
||||
self.validators.append(val_lib.MaxDictSize(max_size))
|
||||
if element_type is glare_fields.BlobFieldType:
|
||||
self.filter_ops = []
|
||||
|
||||
def get_default_validators(self):
|
||||
default_vals = []
|
||||
@ -192,8 +215,6 @@ class DictAttribute(CompoundAttribute):
|
||||
|
||||
|
||||
class BlobAttribute(Attribute):
|
||||
DEFAULT_MAX_BLOB_SIZE = 10485760
|
||||
|
||||
def __init__(self, max_blob_size=DEFAULT_MAX_BLOB_SIZE, **kwargs):
|
||||
super(BlobAttribute, self).__init__(
|
||||
field_class=glare_fields.BlobField, **kwargs)
|
||||
@ -202,8 +223,7 @@ class BlobAttribute(Attribute):
|
||||
|
||||
|
||||
class BlobDictAttribute(DictAttribute):
|
||||
def __init__(self, max_blob_size=BlobAttribute.DEFAULT_MAX_BLOB_SIZE,
|
||||
**kwargs):
|
||||
def __init__(self, max_blob_size=DEFAULT_MAX_BLOB_SIZE, **kwargs):
|
||||
super(BlobDictAttribute, self).__init__(
|
||||
element_type=glare_fields.BlobFieldType, **kwargs)
|
||||
self.max_blob_size = int(max_blob_size)
|
||||
|
@ -210,18 +210,21 @@ class TestList(base.TestArtifact):
|
||||
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||
self.assertEqual(art_list[5:], result)
|
||||
|
||||
# visibility=neq:private
|
||||
url = '/sample_artifact?visibility=neq:private'
|
||||
self.get(url=url, status=400)
|
||||
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||
self.assertEqual(art_list[5:], result)
|
||||
|
||||
url = '/sample_artifact?visibility=neq:public'
|
||||
self.get(url=url, status=400)
|
||||
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||
self.assertEqual(art_list[:5], result)
|
||||
|
||||
url = '/sample_artifact?visibility=blabla'
|
||||
self.get(url=url, status=200)
|
||||
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||
self.assertEqual([], result)
|
||||
|
||||
url = '/sample_artifact?visibility=neq:blabla'
|
||||
self.get(url=url, status=400)
|
||||
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||
self.assertEqual(art_list, result)
|
||||
|
||||
url = '/sample_artifact?name=eq:name0&name=name1&tags=tag1'
|
||||
result = self.get(url=url)['sample_artifact']
|
||||
@ -367,7 +370,7 @@ class TestList(base.TestArtifact):
|
||||
result = sort_results(self.get(url=url)['sample_artifact'])
|
||||
self.assertEqual([], result)
|
||||
|
||||
for op in ['gt', 'gte', 'lt', 'lte', 'neq']:
|
||||
for op in ['gt', 'gte', 'lt', 'lte']:
|
||||
url = '/sample_artifact?dict_of_str.pr3=%s:val3' % op
|
||||
self.get(url=url, status=400)
|
||||
|
||||
|
@ -21,8 +21,7 @@ from glare.tests.functional import base
|
||||
fixture_base_props = {
|
||||
u'activated_at': {
|
||||
u'description': u'Datetime when artifact has became active.',
|
||||
u'filter_ops': [u'gt',
|
||||
u'lt'],
|
||||
u'filter_ops': [u'lt', u'gt'],
|
||||
u'format': u'date-time',
|
||||
u'glareType': u'DateTime',
|
||||
u'readOnly': True,
|
||||
@ -32,8 +31,7 @@ fixture_base_props = {
|
||||
u'null']},
|
||||
u'created_at': {
|
||||
u'description': u'Datetime when artifact has been created.',
|
||||
u'filter_ops': [u'gt',
|
||||
u'lt'],
|
||||
u'filter_ops': [u'lt', u'gt'],
|
||||
u'format': u'date-time',
|
||||
u'glareType': u'DateTime',
|
||||
u'readOnly': True,
|
||||
@ -63,9 +61,7 @@ fixture_base_props = {
|
||||
u'default': {},
|
||||
u'description': u'Key-value dict with useful information '
|
||||
u'about an artifact.',
|
||||
u'filter_ops': [u'eq',
|
||||
u'in',
|
||||
u'neq'],
|
||||
u'filter_ops': [u'eq', u'neq', u'in'],
|
||||
u'glareType': u'StringDict',
|
||||
u'maxProperties': 255,
|
||||
u'required_on_activate': False,
|
||||
@ -114,8 +110,7 @@ fixture_base_props = {
|
||||
u'unique': True},
|
||||
u'updated_at': {
|
||||
u'description': u'Datetime when artifact has been updated last time.',
|
||||
u'filter_ops': [u'gt',
|
||||
u'lt'],
|
||||
u'filter_ops': [u'lt', u'gt'],
|
||||
u'format': u'date-time',
|
||||
u'glareType': u'DateTime',
|
||||
u'readOnly': True,
|
||||
@ -141,7 +136,7 @@ fixture_base_props = {
|
||||
u'description': u'Artifact visibility that defines if '
|
||||
u'artifact can be available to other '
|
||||
u'users.',
|
||||
u'filter_ops': [u'eq'],
|
||||
u'filter_ops': [u'eq', u'neq', u'in'],
|
||||
u'glareType': u'String',
|
||||
u'maxLength': 255,
|
||||
u'sortable': True,
|
||||
@ -201,15 +196,13 @@ fixtures = {
|
||||
u'type': [u'string',
|
||||
u'null']},
|
||||
u'link1': {u'filter_ops': [u'eq',
|
||||
u'neq',
|
||||
u'in'],
|
||||
u'neq'],
|
||||
u'glareType': u'Link',
|
||||
u'required_on_activate': False,
|
||||
u'type': [u'string',
|
||||
u'null']},
|
||||
u'link2': {u'filter_ops': [u'eq',
|
||||
u'neq',
|
||||
u'in'],
|
||||
u'neq'],
|
||||
u'glareType': u'Link',
|
||||
u'required_on_activate': False,
|
||||
u'type': [u'string',
|
||||
@ -423,11 +416,7 @@ fixtures = {
|
||||
u'null']},
|
||||
u'str1': {u'filter_ops': [u'eq',
|
||||
u'neq',
|
||||
u'in',
|
||||
u'gt',
|
||||
u'gte',
|
||||
u'lt',
|
||||
u'lte'],
|
||||
u'in'],
|
||||
u'glareType': u'String',
|
||||
u'maxLength': 255,
|
||||
u'required_on_activate': False,
|
||||
@ -436,11 +425,7 @@ fixtures = {
|
||||
u'null']},
|
||||
u'string_mutable': {u'filter_ops': [u'eq',
|
||||
u'neq',
|
||||
u'in',
|
||||
u'gt',
|
||||
u'gte',
|
||||
u'lt',
|
||||
u'lte'],
|
||||
u'in'],
|
||||
u'glareType': u'String',
|
||||
u'maxLength': 255,
|
||||
u'mutable': True,
|
||||
@ -450,11 +435,7 @@ fixtures = {
|
||||
u'string_required': {
|
||||
u'filter_ops': [u'eq',
|
||||
u'neq',
|
||||
u'in',
|
||||
u'gt',
|
||||
u'gte',
|
||||
u'lt',
|
||||
u'lte'],
|
||||
u'in'],
|
||||
u'glareType': u'String',
|
||||
u'maxLength': 255,
|
||||
u'type': [u'string',
|
||||
@ -466,11 +447,7 @@ fixtures = {
|
||||
None],
|
||||
u'filter_ops': [u'eq',
|
||||
u'neq',
|
||||
u'in',
|
||||
u'gt',
|
||||
u'gte',
|
||||
u'lt',
|
||||
u'lte'],
|
||||
u'in'],
|
||||
u'glareType': u'String',
|
||||
u'maxLength': 10,
|
||||
u'required_on_activate': False,
|
||||
@ -566,8 +543,7 @@ fixtures = {
|
||||
u'description': u'List of package dependencies for '
|
||||
u'this package.',
|
||||
u'filter_ops': [u'eq',
|
||||
u'neq',
|
||||
u'in'],
|
||||
u'neq'],
|
||||
u'glareType': u'LinkList',
|
||||
u'items': {u'type': u'string'},
|
||||
u'maxItems': 255,
|
||||
@ -751,7 +727,11 @@ fixtures = {
|
||||
u'description': u'Minimal disk space required to boot image.',
|
||||
u'filter_ops': [u'eq',
|
||||
u'neq',
|
||||
u'in'],
|
||||
u'in',
|
||||
u'gt',
|
||||
u'gte',
|
||||
u'lt',
|
||||
u'lte'],
|
||||
u'glareType': u'Integer',
|
||||
u'minimum': 0,
|
||||
u'required_on_activate': False,
|
||||
@ -760,7 +740,11 @@ fixtures = {
|
||||
u'description': u'Minimal RAM required to boot image.',
|
||||
u'filter_ops': [u'eq',
|
||||
u'neq',
|
||||
u'in'],
|
||||
u'in',
|
||||
u'gt',
|
||||
u'gte',
|
||||
u'lt',
|
||||
u'lte'],
|
||||
u'glareType': u'Integer',
|
||||
u'minimum': 0,
|
||||
u'required_on_activate': False,
|
||||
@ -828,8 +812,7 @@ fixtures = {
|
||||
u'that can be used with current '
|
||||
u'template.',
|
||||
u'filter_ops': [u'eq',
|
||||
u'neq',
|
||||
u'in'],
|
||||
u'neq'],
|
||||
u'glareType': u'LinkDict',
|
||||
u'maxProperties': 255,
|
||||
u'mutable': True,
|
||||
|
@ -32,10 +32,10 @@ class SampleArtifact(base_artifact.BaseArtifact):
|
||||
VERSION = '1.0'
|
||||
|
||||
fields = {
|
||||
'blob': Blob(required_on_activate=False, mutable=True, filter_ops=[],
|
||||
'blob': Blob(required_on_activate=False, mutable=True,
|
||||
description="I am Blob"),
|
||||
'small_blob': Blob(max_blob_size=10, required_on_activate=False,
|
||||
mutable=True, filter_ops=[]),
|
||||
mutable=True),
|
||||
'link1': Field(glare_fields.Link,
|
||||
required_on_activate=False),
|
||||
'link2': Field(glare_fields.Link,
|
||||
@ -50,24 +50,19 @@ class SampleArtifact(base_artifact.BaseArtifact):
|
||||
default=False),
|
||||
'int1': Field(fields.IntegerField,
|
||||
required_on_activate=False,
|
||||
sortable=True,
|
||||
filter_ops=attribute.FILTERS),
|
||||
sortable=True),
|
||||
'int2': Field(fields.IntegerField,
|
||||
sortable=True,
|
||||
required_on_activate=False,
|
||||
filter_ops=attribute.FILTERS),
|
||||
required_on_activate=False),
|
||||
'float1': Field(fields.FloatField,
|
||||
sortable=True,
|
||||
required_on_activate=False,
|
||||
filter_ops=attribute.FILTERS),
|
||||
required_on_activate=False),
|
||||
'float2': Field(fields.FloatField,
|
||||
sortable=True,
|
||||
required_on_activate=False,
|
||||
filter_ops=attribute.FILTERS),
|
||||
required_on_activate=False),
|
||||
'str1': Field(fields.StringField,
|
||||
sortable=True,
|
||||
required_on_activate=False,
|
||||
filter_ops=attribute.FILTERS),
|
||||
required_on_activate=False),
|
||||
'list_of_str': List(fields.String,
|
||||
required_on_activate=False,
|
||||
filter_ops=(attribute.FILTER_EQ,
|
||||
@ -97,14 +92,11 @@ class SampleArtifact(base_artifact.BaseArtifact):
|
||||
validators.MaxDictKeyLen(1000)]),
|
||||
'string_mutable': Field(fields.StringField,
|
||||
required_on_activate=False,
|
||||
mutable=True,
|
||||
filter_ops=attribute.FILTERS),
|
||||
mutable=True),
|
||||
'string_required': Field(fields.StringField,
|
||||
required_on_activate=True,
|
||||
filter_ops=attribute.FILTERS),
|
||||
required_on_activate=True),
|
||||
'string_validators': Field(fields.StringField,
|
||||
required_on_activate=False,
|
||||
filter_ops=attribute.FILTERS,
|
||||
validators=[
|
||||
validators.AllowedValues(
|
||||
['aa', 'bb', 'c' * 11]),
|
||||
@ -112,7 +104,6 @@ class SampleArtifact(base_artifact.BaseArtifact):
|
||||
]),
|
||||
'int_validators': Field(fields.IntegerField,
|
||||
required_on_activate=False,
|
||||
filter_ops=attribute.FILTERS,
|
||||
validators=[
|
||||
validators.MinNumberSize(10),
|
||||
validators.MaxNumberSize(20)
|
||||
|
Loading…
Reference in New Issue
Block a user