| #Licensed to the Apache Software Foundation (ASF) under one |
| #or more contributor license agreements. See the NOTICE file |
| #distributed with this work for additional information |
| #regarding copyright ownership. The ASF licenses this file |
| #to you 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. |
| # $Id:types.py 6172 2007-05-22 20:26:54Z zim $ |
| # |
| #------------------------------------------------------------------------------ |
| |
| """ Higher level data types and type related classes. |
| |
| Supported Types (Verification and Display): |
| |
| address - validates ip:port and host:port tcp addresses |
| ip_address - validates and IP address |
| net_address - validates an IP like address, ie netmask |
| hostname - validates a hostname with DNS |
| eaddress - validates a single email address or a comma |
| seperated list of email addresses |
| http_version - validates a value is a http version (1.0/1.1) |
| tcp_port - validates a value to be a valid tcp port (2-65535) |
| bool - validates value is (0, 1, true, false) / converts |
| true -> 1 and false -> 0 |
| directory - validates a values is a directory / resolves path to |
| absolute path |
| file - validates a value is a file / resolves path to absolute |
| path |
| float - validates a value is a float, converts string to float |
| pos_float - validates a value is a float and >= 0, converts string |
| to float |
| pos_num - same as pos_float |
| neg_float - validates a value is a float and < 0, converts string to |
| float |
| int - validates a value is an integer, converts string to |
| integer |
| pos_int - validates a value is an integer and >= 0, converts |
| string to integer |
| neg_int - validates a values is an integer and < 0, converts |
| striing to integer |
| freq - frequency, positive integer |
| size - validates a size in bytes, kb, mb, kb, and tb |
| (int > 0 post fixed with K, M, G, or T) also converts |
| value to integer bytes |
| range - numeric range, x-y normalized to a tuple, if a single |
| number is supplie a single element tuple is returned |
| timestamp - utc timestamp of the form YYYYMMDDHHMMSS |
| user_account - UNIX user account name |
| user_group - UNIX group name |
| string - arbitrarily long string |
| list - comma seperated list of strings of arbitrary length, |
| keyval - comma seperated list of key=value pairs, key does not |
| need to be unique. |
| uri - a uri """ |
| |
| import sys, os, socket, pwd, grp, stat, re, re, string, pprint, urlparse |
| |
| from tcp import tcpSocket, check_net_address, check_ip_address |
| from util import check_timestamp |
| |
| types = { 'directory' : { 'db' : 'string', |
| 'units' : None }, |
| |
| 'address' : { 'db' : 'string', |
| 'units' : None }, |
| |
| 'ip_address' : { 'db' : 'string', |
| 'units' : None }, |
| |
| 'net_address' : { 'db' : 'string', |
| 'units' : None }, |
| |
| 'bool' : { 'db' : 'bool', |
| 'units' : None }, |
| |
| 'int' : { 'db' : 'integer', |
| 'units' : None }, |
| |
| 'float' : { 'db' : 'float', |
| 'units' : None }, |
| |
| 'pos_int' : { 'db' : 'integer', |
| 'units' : None }, |
| |
| 'neg_int' : { 'db' : 'integer', |
| 'units' : None }, |
| |
| 'pos_num' : { 'db' : 'float', |
| 'units' : None }, |
| |
| 'pos_float' : { 'db' : 'float', |
| 'units' : None }, |
| |
| 'neg_float' : { 'db' : 'float', |
| 'units' : None }, |
| |
| 'string' : { 'db' : 'string', |
| 'units' : None }, |
| |
| 'list' : { 'db' : 'string', |
| 'units' : None }, |
| |
| 'file' : { 'db' : 'string', |
| 'units' : None }, |
| |
| 'size' : { 'db' : 'integer', |
| 'units' : 'bytes' }, |
| |
| 'freq' : { 'db' : 'integer', |
| 'units' : 'hz' }, |
| |
| 'eaddress' : { 'db' : 'string', |
| 'units' : None }, |
| |
| 'tcp_port' : { 'db' : 'integer', |
| 'units' : None }, |
| |
| 'http_version' : { 'db' : 'float', |
| 'units' : None }, |
| |
| 'range' : { 'db' : 'string', |
| 'units' : None }, |
| |
| 'hostname' : { 'db' : 'string', |
| 'units' : None }, |
| |
| 'user_account' : { 'db' : 'string', |
| 'units' : None }, |
| |
| 'user_group' : { 'db' : 'string', |
| 'units' : None }, |
| |
| 'timestamp' : { 'db' : 'timestamp', |
| 'units' : None }, |
| |
| 'keyval' : { 'db' : 'string', |
| 'units' : None }, |
| |
| 'uri' : { 'db' : 'string', |
| 'units' : None }, |
| |
| '' : { 'db' : 'string', |
| 'units' : None }} |
| |
| dbTypes = { 'string' : { 'type' : 'varchar', |
| 'store' : 'type_strings_0', |
| 'table' : True }, |
| |
| 'integer' : { 'type' : 'bigint', |
| 'store' : 'integers', |
| 'table' : False }, |
| |
| 'float' : { 'type' : 'real', |
| 'store' : 'floats', |
| 'table' : False }, |
| |
| 'bool' : { 'type' : 'boolean', |
| 'store' : 'bools', |
| 'table' : False }, |
| |
| 'timestamp' : { 'type' : 'timestamp(0)', |
| 'store' : 'timestamps', |
| 'table' : False }} |
| |
| reSizeFormat = re.compile("^(\d+)(k|m|g|t|p|kb|mb|gb|tb|pb)$", flags=2) |
| reDash = re.compile("\s*-\s*") |
| |
| sizeFactors = { 'b' : 1, |
| 'bytes' : 1, |
| 'k' : 1024, |
| 'kb' : 1024, |
| 'm' : 1048576, |
| 'mb' : 1048576, |
| 'g' : 1073741824, |
| 'gb' : 1073741824, |
| 't' : 1099511627776, |
| 'tb' : 1099511627776, |
| 'p' : 1125899906842624, |
| 'pb' : 1125899906842624 } |
| |
| freqFactors = { 'hz' : 1, |
| 'khz' : 1000, |
| 'mhz' : 1000000, |
| 'ghz' : 1000000000, |
| 'thz' : 1000000000000, |
| 'phz' : 1000000000000000 } |
| |
| sizeMap = [ { 'factor' : sizeFactors['b'], |
| 'long' : 'byte', |
| 'short' : 'byte' }, |
| |
| { 'factor' : sizeFactors['k'], |
| 'long' : 'Kilobyte', |
| 'short' : 'KB' }, |
| |
| { 'factor' : sizeFactors['m'], |
| 'long' : 'Megabyte', |
| 'short' : 'MB' }, |
| |
| { 'factor' : sizeFactors['g'], |
| 'long' : 'Gigabyte', |
| 'short' : 'GB' }, |
| |
| { 'factor' : sizeFactors['t'], |
| 'long' : 'Terabyte', |
| 'short' : 'TB' }, |
| |
| { 'factor' : sizeFactors['p'], |
| 'long' : 'Petabyte', |
| 'short' : 'PB' } ] |
| |
| freqMap = [ { 'factor' : freqFactors['hz'], |
| 'long' : 'Hertz', |
| 'short' : 'Hz' }, |
| |
| { 'factor' : freqFactors['khz'], |
| 'long' : 'Kilohertz', |
| 'short' : 'KHz' }, |
| |
| { 'factor' : freqFactors['mhz'], |
| 'long' : 'Megahertz', |
| 'short' : 'MHz' }, |
| |
| { 'factor' : freqFactors['ghz'], |
| 'long' : 'Gigahertz', |
| 'short' : 'GHz' }, |
| |
| { 'factor' : freqFactors['thz'], |
| 'long' : 'Terahertz', |
| 'short' : 'THz' }, |
| |
| { 'factor' : freqFactors['phz'], |
| 'long' : 'Petahertz', |
| 'short' : 'PHz' } ] |
| |
| reListString = r"(?<!\\)," |
| reList = re.compile(reListString) |
| |
| reKeyVal = r"(?<!\\)=" |
| reKeyVal = re.compile(reKeyVal) |
| |
| class typeToString: |
| """Provides method for converting normalized types to strings.""" |
| def __init__(self): |
| self.toStringFunctions = {} |
| self.__build_to_string_functions() |
| |
| def __call__(self, type, value): |
| return self.toStringFunctions[type](value) |
| |
| def __build_to_string_functions(self): |
| functions = {} |
| for function in dir(self): |
| functions[function] = 1 |
| |
| for type in types.keys(): |
| # kinda bad, need to find out how to know the name of the class |
| # I'm in. But it works. |
| functionName = "_typeToString__tostring_%s" % type |
| if functions.has_key(functionName): |
| self.toStringFunctions[type] = getattr(self, functionName) |
| else: |
| if type == '': |
| self.toStringFunctions[type] = self.__tostring_nothing |
| else: |
| error = "To string function %s for type %s does not exist." \ |
| % (functionName, type) |
| raise Exception(error) |
| sys.exit(1) |
| |
| def __tostring(self, value): |
| return str(value) |
| |
| def __tostring_directory(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_address(self, value): |
| return "%s:%s" % (value[0], value[1]) |
| |
| def __tostring_ip_address(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_net_address(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_bool(self, value): |
| if value == False: |
| return 'false' |
| elif value == True: |
| return 'true' |
| else: |
| return str(value) |
| |
| def __tostring_int(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_float(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_pos_int(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_neg_int(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_freq(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_pos_float(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_pos_num(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_neg_float(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_string(self, value): |
| return value |
| |
| def __tostring_keyval(self, value): |
| string = '"' # to protect from shell escapes |
| for key in value: |
| # for item in value[key]: |
| # string = "%s%s=%s," % (string, key, item) |
| # Quotes still cannot protect Double-slashes. |
| # Dealing with them separately |
| val = re.sub(r"\\\\",r"\\\\\\\\",value[key]) |
| |
| string = "%s%s=%s," % (string, key, val) |
| |
| return string[:-1] + '"' |
| |
| def __tostring_list(self, value): |
| string = '' |
| for item in value: |
| string = "%s%s," % (string, item) |
| |
| return string[:-1] |
| |
| def __tostring_file(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_size(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_eaddress(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_tcp_port(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_http_version(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_range(self, value): |
| if len(value) < 2: |
| return value[0] |
| else: |
| return "%s-%s" % (value[0], value[1]) |
| |
| def __tostring_timestamp(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_hostname(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_user_account(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_user_group(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_uri(self, value): |
| return self.__tostring(value) |
| |
| def __tostring_nothing(self, value): |
| return value |
| |
| class typeValidator: |
| """Type validation class used to normalize values or validated |
| single/large sets of values by type.""" |
| |
| def __init__(self, originalDir=None): |
| self.verifyFunctions = {} |
| self.__build_verify_functions() |
| |
| self.validateList = [] |
| self.validatedInfo = [] |
| self.__originalDir = originalDir |
| |
| def __getattr__(self, attrname): |
| """validateList = [ { 'func' : <bound method configValidator>, |
| 'name' : 'SA_COMMON.old_xml_dir', |
| 'value': 'var/data/old' }, |
| |
| { 'func' : <bound method configValidator>, |
| 'name' : 'SA_COMMON.log_level', |
| 'value': '4' } ] |
| |
| validatedInfo = [ { # name supplied to add() |
| 'name' : 'SA_COMMON.tmp_xml_dir', |
| |
| # is valid or not |
| 'isValid' : 1 |
| |
| # normalized value |
| 'normalized' : /var/data/tmp, |
| |
| # error string ? |
| 'errorData' : 0 }, |
| |
| { 'name' : 'SA_COMMON.new_xml_dir', |
| 'isValid' : 1 |
| 'normalized' : /var/data/new, |
| 'errorData' : 0 } ]""" |
| |
| if attrname == "validateList": |
| return self.validateList # list of items to be validated |
| elif attrname == "validatedInfo": |
| return self.validatedInfo # list of validation results |
| else: raise AttributeError, attrname |
| |
| def __build_verify_functions(self): |
| functions = {} |
| for function in dir(self): |
| functions[function] = 1 |
| |
| for type in types.keys(): |
| # kinda bad, need to find out how to know the name of the class |
| # I'm in. But it works. |
| functionName = "_typeValidator__verify_%s" % type |
| if functions.has_key(functionName): |
| self.verifyFunctions[type] = getattr(self, functionName) |
| else: |
| if type == '': |
| self.verifyFunctions[type] = self.__verify_nothing |
| else: |
| error = "Verify function %s for type %s does not exist." \ |
| % (functionName, type) |
| raise Exception(error) |
| sys.exit(1) |
| |
| def __get_value_info(self): |
| valueInfo = { 'isValid' : 0, 'normalized' : 0, 'errorData' : 0 } |
| |
| return valueInfo |
| |
| def __set_value_info(self, valueInfo, **valueData): |
| try: |
| valueInfo['normalized'] = valueData['normalized'] |
| valueInfo['isValid'] = 1 |
| except KeyError: |
| valueInfo['isValid'] = 0 |
| try: |
| valueInfo['errorData'] = valueData['errorData'] |
| except: |
| pass |
| |
| # start of 'private' verification methods, each one should correspond to a |
| # type string (see self.verify_config()) |
| def __verify_directory(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| if os.path.isdir(value): |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| else: |
| self.__set_value_info(valueInfo) |
| |
| return valueInfo |
| |
| def __norm_directory(self, value): |
| return self.__normalizedPath(value) |
| |
| def __verify_address(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| try: |
| socket = tcpSocket(value) |
| if socket.verify(): |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| else: |
| self.__set_value_info(valueInfo) |
| except: |
| self.__set_value_info(valueInfo) |
| |
| return valueInfo |
| |
| def __norm_address(self, value): |
| return value.split(':') |
| |
| def __verify_ip_address(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| if check_ip_address(value): |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| else: |
| self.__set_value_info(valueInfo) |
| |
| return valueInfo |
| |
| def __verify_net_address(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| if check_net_address(value): |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| else: |
| self.__set_value_info(valueInfo) |
| |
| return valueInfo |
| |
| def __verify_bool(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| value = str(value) |
| if re.match("^false|0|f|no$", value, 2): |
| self.__set_value_info(valueInfo, normalized=False) |
| elif re.match("^true|1|t|yes$", value, 2): |
| self.__set_value_info(valueInfo, normalized=True) |
| else: |
| self.__set_value_info(valueInfo) |
| |
| return valueInfo |
| |
| def __norm_bool(self, value): |
| value = str(value) |
| norm = "" |
| if re.match("^false|0|f|no$", value, 2): |
| norm = False |
| elif re.match("^true|1|t|yes$", value, 2): |
| norm = True |
| else: |
| raise Exception("invalid bool specified: %s" % value) |
| |
| return norm |
| |
| def __verify_int(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| try: |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| except: |
| self.__set_value_info(valueInfo) |
| |
| return valueInfo |
| |
| def __norm_int(self, value): |
| return int(value) |
| |
| def __verify_float(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| try: |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| except: |
| self.__set_value_info(valueInfo) |
| |
| return valueInfo |
| |
| def __norm_float(self, value): |
| return float(value) |
| |
| def __verify_pos_int(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| try: |
| value = self.normalize(type, value) |
| except: |
| self.__set_value_info(valueInfo) |
| else: |
| self.__set_value_info(valueInfo, normalized=value) |
| |
| return valueInfo |
| |
| def __norm_pos_int(self, value): |
| value = int(value) |
| if value < 0: |
| raise Exception("value is not positive: %s" % value) |
| |
| return value |
| |
| def __verify_neg_int(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| try: |
| value = self.normalize(type, value) |
| except: |
| self.__set_value_info(valueInfo) |
| else: |
| self.__set_value_info(valueInfo, normalized=value) |
| |
| return valueInfo |
| |
| def __norm_neg_int(self, type, value): |
| value = int(value) |
| if value > 0: |
| raise Exception("value is not negative: %s" % value) |
| |
| return value |
| |
| def __verify_freq(self, type, value): |
| return self.__verify_pos_int(type, value) |
| |
| def __norm_freq(self, value): |
| return self.__norm_pos_int(value) |
| |
| def __verify_pos_float(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| try: |
| value = self.normalize(type, value) |
| except: |
| self.__set_value_info(valueInfo) |
| else: |
| self.__set_value_info(valueInfo, normalized=value) |
| |
| return valueInfo |
| |
| def __norm_pos_float(self, value): |
| value = float(value) |
| if value < 0: |
| raise Exception("value is not positive: %s" % value) |
| |
| return value |
| |
| def __verify_pos_num(self, type, value): |
| return self.__verify_pos_float(value) |
| |
| def __norm_pos_num(self, value): |
| return self.__norm_pos_float(value) |
| |
| def __verify_neg_float(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| try: |
| value = self.normalize(type, value) |
| except: |
| self.__set_value_info(valueInfo) |
| else: |
| self.__set_value_info(valueInfo, normalized=value) |
| |
| return valueInfo |
| |
| def __norm_neg_float(self, value): |
| value = float(value) |
| if value >= 0: |
| raise Exception("value is not negative: %s" % value) |
| |
| return value |
| |
| def __verify_string(self, type, value): |
| valueInfo = self.__get_value_info() |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| |
| return valueInfo |
| |
| def __norm_string(self, value): |
| return str(value) |
| |
| def __verify_keyval(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| if reKeyVal.search(value): |
| try: |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| except: |
| self.__set_value_info(valueInfo, errorData = \ |
| "invalid list of key-value pairs : [ %s ]" % value) |
| else: |
| msg = "No key value pairs found?" |
| self.__set_value_info(valueInfo, errorData=msg) |
| |
| return valueInfo |
| |
| def __norm_keyval(self, value): |
| list = self.__norm_list(value) |
| keyValue = {} |
| for item in list: |
| (key, value) = reKeyVal.split(item) |
| #if not keyValue.has_key(key): |
| # keyValue[key] = [] |
| #keyValue[key].append(value) |
| keyValue[key] = value |
| return keyValue |
| |
| def __verify_list(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| self.__set_value_info(valueInfo, normalized=self.normalize(type,value)) |
| |
| return valueInfo |
| |
| def __norm_list(self, value): |
| norm = [] |
| if reList.search(value): |
| norm = reList.split(value) |
| else: |
| norm = [value,] |
| |
| return norm |
| |
| def __verify_file(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| if os.path.isfile(value): |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| else: |
| self.__set_value_info(valueInfo) |
| |
| return valueInfo |
| |
| def __norm_file(self, value): |
| return self.__normalizedPath(value) |
| |
| def __verify_size(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| value = str(value) |
| if reSizeFormat.match(value): |
| numberPart = int(reSizeFormat.sub("\g<1>", value)) |
| factorPart = reSizeFormat.sub("\g<2>", value) |
| try: |
| normalized = normalize_size(numberPart, factorPart) |
| self.__set_value_info(valueInfo, |
| normalized=normalized) |
| except: |
| self.__set_value_info(valueInfo) |
| else: |
| try: |
| value = int(value) |
| except: |
| self.__set_value_info(valueInfo) |
| else: |
| if value >= 0: |
| self.__set_value_info(valueInfo, normalized=value) |
| else: |
| self.__set_value_info(valueInfo) |
| |
| return valueInfo |
| |
| def __norm_size(self, file): |
| norm = None |
| if reSizeFormat.match(value): |
| numberPart = int(reSizeFormat.sub("\g<1>", value)) |
| factorPart = reSizeFormat.sub("\g<2>", value) |
| norm = normalize_size(numberPart, factorPart) |
| else: |
| norm = int(value) |
| |
| return norm |
| |
| |
| def __verify_eaddress(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| emailList = reComma.split(value) |
| |
| for emailAddress in emailList: |
| if reEmailAddress.match(emailAddress): |
| emailParts = reEmailDelimit.split(emailAddress) |
| try: |
| socket.gethostbyname(emailParts[1]) |
| self.__set_value_info(valueInfo, normalized=self.normalize( |
| type, value)) |
| except: |
| errorString = "%s is invalid (domain lookup failed)" % \ |
| emailAddress |
| self.__set_value_info(valueInfo, errorData=errorString) |
| else: |
| errorString = "%s is invalid" % emailAddress |
| self.__set_value_info(valueInfo, errorData=errorString) |
| |
| return valueInfo |
| |
| def __verify_tcp_port(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| try: |
| value = self.__norm_tcp_port(value) |
| except: |
| self.__set_value_info(valueInfo) |
| else: |
| if value in range(2, 65536): |
| self.__set_value_info(valueInfo, normalized=value) |
| else: |
| self.__set_value_info(valueInfo) |
| |
| return valueInfo |
| |
| def __norm_tcp_port(self, value): |
| return int(value) |
| |
| def __verify_http_version(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| if value in ('1.0', '1.1'): |
| self.__set_value_info(valueInfo, normalized=float(value)) |
| else: |
| self.__set_value_info(valueInfo) |
| |
| return valueInfo |
| |
| def __verify_range(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| range = reDash.split(value) |
| |
| try: |
| if len(range) > 1: |
| start = int(range[0]) |
| end = int(range[1]) |
| else: |
| start = int(range[0]) |
| end = None |
| except: |
| self.__set_value_info(valueInfo) |
| else: |
| if end: |
| if end - start != 0: |
| self.__set_value_info(valueInfo, normalized=(start, end)) |
| else: |
| self.__set_value_info(valueInfo) |
| else: |
| self.__set_value_info(valueInfo, normalized=(start,)) |
| |
| return valueInfo |
| |
| def __norm_range(self, value): |
| range = reDash.split(value) |
| if len(range) > 1: |
| start = int(range[0]) |
| end = int(range[1]) |
| else: |
| start = int(range[0]) |
| end = None |
| |
| return (start, end) |
| |
| def __verify_uri(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| _norm = None |
| try: |
| uriComponents = urlparse.urlparse(value) |
| if uriComponents[0] == '' or uriComponents[0] == 'file': |
| # if scheme is '' or 'file' |
| if not os.path.isfile(uriComponents[2]) and \ |
| not os.path.isdir(uriComponents[2]): |
| raise Exception("Invalid local URI") |
| else: |
| self.__set_value_info(valueInfo, normalized=self.normalize( |
| type,value)) |
| else: |
| # other schemes |
| # currently not checking anything. TODO |
| self.__set_value_info(valueInfo, normalized=self.normalize( |
| type,value)) |
| except: |
| errorString = "%s is an invalid uri" % value |
| self.__set_value_info(valueInfo, errorData=errorString) |
| |
| return valueInfo |
| |
| def __norm_uri(self, value): |
| uriComponents = list(urlparse.urlparse(value)) |
| if uriComponents[0] == '': |
| # if scheme is ''' |
| return self.__normalizedPath(uriComponents[2]) |
| elif uriComponents[0] == 'file': |
| # if scheme is 'file' |
| normalizedPath = self.__normalizedPath(uriComponents[2]) |
| return urlparse.urlunsplit(uriComponents[0:1] + [normalizedPath] + uriComponents[3:]) |
| |
| # Not dealing with any other case right now |
| return value |
| |
| def __verify_timestamp(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| if check_timestamp(value): |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| else: |
| self.__set_value_info(valueInfo) |
| |
| return valueInfo |
| |
| def __verify_hostname(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| try: |
| socket.gethostbyname(value) |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| except: |
| errorString = "%s is invalid (domain lookup failed)" % value |
| self.__set_value_info(valueInfo, errorData=errorString) |
| |
| return valueInfo |
| |
| def __verify_user_account(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| try: |
| pwd.getpwnam(value) |
| except: |
| errorString = "'%s' user account does not exist" % value |
| self.__set_value_info(valueInfo, errorData=errorString) |
| else: |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| |
| return valueInfo |
| |
| def __verify_user_group(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| try: |
| grp.getgrnam(value) |
| except: |
| errorString = "'%s' group does not exist" % value |
| self.__set_value_info(valueInfo, errorData=errorString) |
| else: |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| |
| return valueInfo |
| |
| def __verify_nothing(self, type, value): |
| valueInfo = self.__get_value_info() |
| |
| self.__set_value_info(valueInfo, normalized=self.normalize(type, |
| value)) |
| |
| return valueInfo |
| |
| #-------------------------------------------------------------------------- |
| |
| def normalize(self, type, value): |
| try: |
| normFunc = getattr(self, "_typeValidator__norm_%s" % type) |
| return normFunc(value) |
| except AttributeError, A: |
| # this exception should occur only when we don't have corresponding normalize function |
| return value |
| |
| def verify(self, type, value, allowNone=False): |
| """Verifies a value based on its type. |
| |
| type - supported configValidator type |
| value - data to be validated |
| allowNone - don't freak out if None or '' is supplied |
| |
| returns a valueInfo dictionary: |
| |
| valueInfo = { 'isValid' : 1, 'normalized' : 5, 'errorData' : 0 } |
| |
| where: |
| |
| isValid - true or false (0/1) |
| normalized - the normalized value |
| errorData - if invalid an error string |
| |
| supported types: |
| |
| see top level""" |
| |
| result = None |
| if allowNone: |
| if value == '' or value == None: |
| result = self.__verify_nothing(None, None) |
| result['normalized'] = None |
| else: |
| result = self.verifyFunctions[type](type, value) |
| else: |
| result = self.verifyFunctions[type](type, value) |
| |
| return result |
| |
| def is_valid_type(self, type): |
| """Returns true if type is valid.""" |
| |
| return types.has_key(type) |
| |
| def type_info(self, type): |
| """Returns type info dictionary.""" |
| |
| dbInfo = dbTypes[types[type]['db']] |
| typeInfo = types[type].copy() |
| typeInfo['db'] = dbInfo |
| |
| return typeInfo |
| |
| def add(self, name, type, value): |
| """Adds a value and type by name to the configValidate object to be |
| verified using validate(). |
| |
| name - name used to key values and access the results of the |
| validation |
| type - configValidator type |
| value - data to be verified""" |
| |
| self.validateList.append({ 'name' : name, |
| 'type' : type, |
| 'value': value }) |
| |
| def validate(self, allowNone=False): |
| """Validates configValidate object populating validatedInfo with |
| valueInfo dictionaries for each value added to the object.""" |
| |
| for valItem in self.validateList: |
| valueInfo = self.verify(valItem['type'], valItem['value'], |
| allowNone) |
| if valueInfo: |
| valueInfo['name'] = valItem['name'] |
| self.validatedInfo.append(valueInfo) |
| else: |
| raise Exception("\nMissing a return value: valueInfo\n%s" % \ |
| self.verifyFunctions[valItem['type']](valItem['value'])) |
| |
| def __normalizedPath(self, value): |
| oldWd = os.getcwd() |
| if self.__originalDir: |
| os.chdir(self.__originalDir) |
| normPath = os.path.realpath(value) |
| os.chdir(oldWd) |
| return normPath |
| |
| |
| class display: |
| def __init__(self): |
| self.displayFunctions = {} |
| self.__build_dispaly_functions() |
| |
| def __build_dispaly_functions(self): |
| functions = {} |
| for function in dir(self): |
| functions[function] = 1 |
| |
| for type in types.keys(): |
| # kinda bad, need to find out how to know the name of the class |
| # I'm in. But it works. |
| functionName = "_cisplay__display_%s" % type |
| if functions.has_key(functionName): |
| self.displayFunctions[type] = getattr(self, functionName) |
| else: |
| if type == '': |
| self.displayFunctions[type] = self.__display_default |
| else: |
| error = "Display function %s for type %s does not exist." \ |
| % (functionName, type) |
| raise Exception(error) |
| sys.exit(1) |
| |
| def __display_default(self, value, style): |
| return value |
| |
| def __display_generic_number(self, value): |
| displayNumber = '' |
| splitNum = string.split(str(value), sep='.') |
| numList = list(str(splitNum[0])) |
| numList.reverse() |
| length = len(numList) |
| counter = 0 |
| for char in numList: |
| counter = counter + 1 |
| if counter % 3 or counter == length: |
| displayNumber = "%s%s" % (char, displayNumber) |
| else: |
| displayNumber = ",%s%s" % (char, displayNumber) |
| |
| if len(splitNum) > 1: |
| displayNumber = "%s.%s" % (displayNumber, splitNum[1]) |
| |
| return displayNumber |
| |
| def __display_generic_mappable(self, map, value, style, plural=True): |
| displayValue = '' |
| length = len(str(value)) |
| if length > 3: |
| for factorSet in map: |
| displayValue = float(value) / factorSet['factor'] |
| if len(str(int(displayValue))) <= 3 or \ |
| factorSet['factor'] == map[-1]['factor']: |
| displayValue = "%10.2f" % displayValue |
| if displayValue[-1] == '0': |
| if displayValue > 1 and style != 'short' and plural: |
| displayValue = "%s %ss" % (displayValue[:-1], |
| factorSet[style]) |
| else: |
| displayValue = "%s %s" % (displayValue[:-1], |
| factorSet[style]) |
| else: |
| if displayValue > 1 and style != 'short' and plural: |
| displayValue = "%s %ss" % (displayValue, |
| factorSet[style]) |
| else: |
| displayValue = "%s %s" % (displayValue, |
| factorSet[style]) |
| break |
| |
| return displayValue |
| |
| def __display_directory(self, value, style): |
| return self.__display_default(value, style) |
| |
| def __display_address(self, value, style): |
| return self.__display_default(value, style) |
| |
| def __display_ip_address(self, value, style): |
| return self.__display_default(value, style) |
| |
| def __display_net_address(self, value, style): |
| return self.__display_default(value, style) |
| |
| def __display_bool(self, value, style): |
| displayValue = value |
| |
| if not isinstance(displayValue, bool): |
| if re.match("^false|0|f|no$", value, 2): |
| displayValue=False |
| elif re.match("^true|1|t|yes$", value, 2): |
| displayValue=True |
| |
| return displayValue |
| |
| def __display_int(self, value, style): |
| return self.__display_generic_number(value) |
| |
| def __display_float(self, value, style): |
| return self.__display_generic_number(value) |
| |
| def __display_pos_int(self, value, style): |
| return self.__display_generic_number(value) |
| |
| def __display_neg_int(self, value, style): |
| return self.__display_generic_number(value) |
| |
| def __display_pos_num(self, value, style): |
| return self.__display_generic_number(value) |
| |
| def __display_pos_float(self, value, style): |
| return self.__display_generic_number(value) |
| |
| def __display_neg_float(self, value, style): |
| return self.__display_generic_number(value) |
| |
| def __display_string(self, value, style): |
| return self.__display_default(value, style) |
| |
| def __display_list(self, value, style): |
| value = value.rstrip() |
| return value.rstrip(',') |
| |
| def __display_keyval(self, value, style): |
| value = value.rstrip() |
| return value.rstrip(',') |
| |
| def __display_file(self, value, style): |
| return self.__display_default(value, style) |
| |
| def __display_size(self, value, style): |
| return self.__display_generic_mappable(sizeMap, value, style) |
| |
| def __display_freq(self, value, style): |
| return self.__display_generic_mappable(freqMap, value, style, False) |
| |
| def __display_eaddress(self, value, style): |
| return self.__display_default(value, style) |
| |
| def __display_tcp_port(self, value, style): |
| return self.__display_default(value, style) |
| |
| def __display_http_version(self, value, style): |
| return self.__display_default(value, style) |
| |
| def __display_range(self, value, style): |
| return self.__display_default(value, style) |
| |
| def __display_hostname(self, value, style): |
| return self.__display_default(value, style) |
| |
| def __display_user_account(self, value, style): |
| return self.__display_default(value, style) |
| |
| def __display_user_group(self, value, style): |
| return self.__display_default(value, style) |
| |
| def __display_timestamp(self, value, style): |
| return self.__display_default(value, style) |
| |
| def display(self, type, value, style='short'): |
| displayValue = value |
| if value != None: |
| displayValue = self.displayFunctions[type](value, style) |
| |
| return displayValue |
| |
| typeValidatorInstance = typeValidator() |
| |
| def is_valid_type(type): |
| """Returns true if type is valid.""" |
| |
| return typeValidatorInstance.is_valid_type(type) |
| |
| def type_info(type): |
| """Returns type info dictionary.""" |
| |
| return typeValidatorInstance.type_info(type) |
| |
| def verify(type, value, allowNone=False): |
| """Returns a normalized valueInfo dictionary.""" |
| |
| return typeValidatorInstance.verify(type, value, allowNone) |
| |
| def __normalize(map, val, factor): |
| normFactor = string.lower(factor) |
| normVal = float(val) |
| return int(normVal * map[normFactor]) |
| |
| def normalize_size(size, factor): |
| """ Normalize a size to bytes. |
| |
| size - number of B, KB, MB, GB, TB, or PB |
| factor - size factor (case insensitive): |
| b | bytes - bytes |
| k | kb - kilobytes |
| m | mb - megabytes |
| g | gb - gigabytes |
| t | tb - terabytes |
| p | pb - petabytes |
| """ |
| |
| return __normalize(sizeFactors, size, factor) |
| |
| def normalize_freq(freq, factor): |
| """ Normalize a frequency to hertz. |
| |
| freq - number of Hz, Khz, Mhz, Ghz, Thz, or Phz |
| factor - size factor (case insensitive): |
| Hz - Hertz |
| Mhz - Megahertz |
| Ghz - Gigahertz |
| Thz - Terahertz |
| Phz - Petahertz |
| """ |
| |
| return __normalize(freqFactors, freq, factor) |