deb-glare/glare/objects/validators.py

225 lines
6.9 KiB
Python

# Copyright 2016 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import six
import uuid
from oslo_log import log as logging
from oslo_utils import encodeutils
from oslo_versionedobjects import fields
from glare.i18n import _
from glare.objects import fields as glare_fields
LOG = logging.getLogger(__name__)
class Validator(object):
"""Common interface for all validators"""
def validate(self, value):
raise NotImplementedError()
def get_allowed_types(self):
raise NotImplementedError()
def check_type_allowed(self, field_type):
if not issubclass(field_type, self.get_allowed_types()):
# try to check if field_type is correct
# in case of element_type passed
allowed_field_types = tuple(type(field.AUTO_TYPE)
for field in self.get_allowed_types()
if hasattr(field, 'AUTO_TYPE'))
if not issubclass(field_type, allowed_field_types):
raise TypeError(
_("%(type)s is not allowed for validator "
"%(val)s. Allowed types are %(allowed)s.") % {
"type": str(field_type),
"val": str(self.__class__),
"allowed": str(self.get_allowed_types())})
def __call__(self, value):
try:
self.validate(value)
except ValueError:
raise
except TypeError as e:
# we are raising all expected ex Type Errors as ValueErrors
LOG.exception(e)
raise ValueError(encodeutils.exception_to_unicode(e))
class UUID(Validator):
def get_allowed_types(self):
return fields.StringField,
def validate(self, value):
uuid.UUID(value)
class SizeValidator(Validator):
def __init__(self, size):
self.size = size
class MaxStrLen(SizeValidator):
def get_allowed_types(self):
return fields.StringField,
def validate(self, value):
l = len(value)
if l > self.size:
raise ValueError(
_("String length must be less than %(size)s. "
"Current size: %(cur)s") % {'size': self.size,
'cur': l})
class MinStrLen(SizeValidator):
def get_allowed_types(self):
return fields.StringField,
def validate(self, value):
l = len(value)
if l < self.size:
raise ValueError(
_("String length must be more than %(size)s. "
"Current size: %(cur)s") % {'size': self.size,
'cur': l})
class ForbiddenChars(Validator):
def __init__(self, forbidden_chars):
self.forbidden_chars = forbidden_chars
def get_allowed_types(self):
return fields.StringField,
def validate(self, value):
for fc in self.forbidden_chars:
if fc in value:
raise ValueError(
_("Forbidden character %(char) found in string "
"%(string)s")
% {"char": fc, "string": value})
class MaxSize(SizeValidator):
def get_allowed_types(self):
return glare_fields.Dict, glare_fields.List
def validate(self, value):
l = len(value)
if l > self.size:
raise ValueError(
_("Number of items must be less than "
"%(size)s. Current size: %(cur)s") %
{'size': self.size, 'cur': l})
class Unique(Validator):
def get_allowed_types(self):
return glare_fields.List,
def validate(self, value):
if len(value) != len(set(value)):
raise ValueError(_("List items %s must be unique.") % value)
class AllowedListValues(Validator):
def __init__(self, allowed_values):
self.allowed_items = allowed_values
def get_allowed_types(self):
return glare_fields.List,
def validate(self, value):
for item in value:
if item not in self.allowed_items:
raise ValueError(
_("Value %(item)s is not allowed in list. "
"Allowed list values: %(allowed)s") %
{"item": item,
"allowed": self.allowed_items})
class AllowedDictKeys(Validator):
def __init__(self, allowed_keys):
self.allowed_items = allowed_keys
def get_allowed_types(self):
return glare_fields.Dict,
def validate(self, value):
for item in value:
if item not in self.allowed_items:
raise ValueError(_("Key %(item)s is not allowed in dict. "
"Allowed key values: %(allowed)s") %
{"item": item,
"allowed": ', '.join(self.allowed_items)})
class RequiredDictKeys(Validator):
def __init__(self, required_keys):
self.required_items = required_keys
def get_allowed_types(self):
return glare_fields.Dict,
def validate(self, value):
for item in self.required_items:
if item not in value:
raise ValueError(_("Key %(item)s is required in dict. "
"Required key values: %(required)s") %
{"item": item,
"required": ', '.join(self.required_items)})
class MaxDictKeyLen(SizeValidator):
def get_allowed_types(self):
return glare_fields.Dict,
def validate(self, value):
for key in value:
if len(str(key)) > self.size:
raise ValueError(_("Dict key length %(key)s must be less than "
"%(size)s.") % {'key': key,
'size': self.size})
class ElementValidator(Validator):
def __init__(self, validators):
self.validators = validators
class ListElementValidator(ElementValidator):
def get_allowed_types(self):
return glare_fields.List,
def validate(self, value):
for v in value:
for validator in self.validators:
validator(v)
class DictElementValidator(ElementValidator):
def get_allowed_types(self):
return glare_fields.Dict,
def validate(self, value):
for v in six.itervalues(value):
for validator in self.validators:
validator(v)