def check_input_data(self, data): if type(data) != types.ListType: raise InvalidArgument('Provided data is not a list: %s.' % str(data)) for d in data: if type(d) != types.DictType: raise InvalidArgument('List member is not a dictionary: %s.' % str(d))
def __check_and_prepare_input(self, input_value, input_arg_name): if type(input_value) == types.StringType: if input_value.find(' ') >= 0: raise InvalidArgument('Value for argument %s must be provided either as a comma-separated string list, or as a python list of strings.' % input_arg_name) return input_value elif type(input_value) == types.ListType: input_value = ','.join(input_value) return input_value else: raise InvalidArgument('Input value must be provided either as a comma-separated string list, or as a python list of strings (%s input: %s).' % (input_arg_name, input_value))
def unpack_input_json(self, json_string): if not json_string: return None try: json_dict = json.loads(json_string) except Exception as ex: raise InvalidArgument('Input is not a valid json string: %s (error: %s).' % (str(json_string), ex)) if type(json_dict) != dict: raise InvalidArgument('Input json string does not contain dictionary: %s.' % str(json_string)) return json_dict
def check_attribute_data(self, name, data): if not name: raise InvalidArgument('Invalid complex attribute name.') if type(data) != dict: raise InvalidArgument( 'Complex attribute data must be a dictionary.') for key in [ 'shortcut', 'type', 'relop', 'requestable', 'consumable', 'default', 'urgency', 'aapre', 'affinity' ]: if key not in data: raise InvalidArgument( 'Complex attribute data is missing the "%s" key.' % key)
def __prepare_object(self, pycl_object=None, name=None, data=None, metadata=None, json_string=None, add_required_data=True): uge_version = self.qconf_executor.get_uge_version() data2 = copy.copy(data) metadata2 = copy.copy(metadata) name2 = name # If pycl_object is provided, combine its data/metadata # with provided data/metadata if pycl_object is not None: generated_object = self.GENERATE_OBJECT_FACTORY_METHOD(uge_version, add_required_data=False) if not str(type(pycl_object)) == str(type(generated_object)): raise InvalidArgument( 'The pycl_object argument must be an instance of %s.' % generated_object.__class__.__name__) data2 = copy.copy(pycl_object.data) if data: data2.update(data) metadata2 = copy.copy(pycl_object.metadata) if metadata: metadata2.update(metadata) if not name2: name2 = pycl_object.name result_object = self.GENERATE_OBJECT_FACTORY_METHOD( uge_version, name=name2, data=data2, metadata=metadata2, json_string=json_string, add_required_data=add_required_data) result_object.check_user_provided_keys() return result_object
def add_stnode(self, path, shares): try: share_value = int(shares) except ValueError as ex: raise InvalidArgument(exception=ex) self.qconf_executor.execute_qconf('-astnode %s=%s' % (path, shares), self.QCONF_ERROR_REGEX_LIST) return self.get_object()
def convert_dict_keys(self): for key in list(self.DICT_KEY_MAP.keys()): value = self.data.get(key) if value is not None: if type(value) == bytes: self.data[key] = self.parse_value_as_dict(key, value) elif type(value) != dict: raise InvalidArgument( 'Value for key %s must be provided either as a string, or as a python dictionary.' % key)
def unpack_input_json(self, json_string): if not json_string: return None try: json_dict = json.loads(json_string) except Exception, ex: raise InvalidArgument( 'Input is not a valid json string: %s (error: %s).' % (str(json_string), ex))
def convert_list_keys(self): for key in list(self.LIST_KEY_MAP.keys()): value = self.data.get(key) if value is not None: if type(value) == bytes or type(value) == str: delimiter = self.LIST_KEY_MAP.get(key, self.DEFAULT_LIST_DELIMITER) self.data[key] = value.split(delimiter) elif type(value) != list: raise InvalidArgument( 'Value for key %s must be provided either as a string, or as a python list of strings.' % key)
def parse_value_as_dict(self, key, value): delimiter = self.DICT_KEY_MAP.get(key, self.DEFAULT_LIST_DELIMITER) items = value.split(delimiter) value_dict = {} for item in items: if item.find(self.DICT_VALUE_DELIMITER) < 0: raise InvalidArgument( 'Cannot parse dictionary value: Unexpected format of item %s for key %s.' % (item, key)) item_tokens = item.split(self.DICT_VALUE_DELIMITER) item_key = item_tokens[0] item_value = self.DICT_VALUE_DELIMITER.join(item_tokens[1:]) value_dict[item_key] = self.uge_to_py(item_key, item_value) return value_dict
def update_with_required_data_defaults(self): """ Updates list objects with default values for required data keys. :raises: **InvalidArgument** - in case object's data is not a list, or one of the list members is not a dictionary. """ if type(self.data) != list: raise InvalidRequest('Data object is not a list: %s.' % str(self.data)) for d in self.data: if type(d) != dict: raise InvalidArgument('List member is not a dictionary: %s.' % str(d)) for (key, value) in list(self.get_required_data_defaults().items()): if key not in d: d[key] = value
def __prepare_names(self, names): if type(names) == types.StringType: if names.find(','): name_list = names.split(',') else: name_list = names.split() elif type(names) == types.ListType: name_list = names else: raise InvalidArgument('Names must be provided either as a list, or as a string containing names separated by space or comma.') name_list2 = [] for name in name_list: trimmed_name = name.strip() if len(trimmed_name): name_list2.append(trimmed_name) return ','.join(name_list2)
def parse_args(self, usage=None): """ Parse command arguments. :param usage: Command usage. :type usage: str """ if usage: self.parser.usage = usage try: (self.options, self.args) = self.parser.parse_args() except SystemExit as rc: sys.stdout.flush() sys.stderr.flush() os._exit(int(str(rc))) if self.valid_arg_count < len(self.args): # Postitional args are not enabled and we have some msg = "Invalid Argument(s):" for arg in self.args[self.valid_arg_count:]: msg += " " + arg raise InvalidArgument(msg) opt_dict = self.options.__dict__ if opt_dict.get('cmd_version'): print('%s version: %s' % (os.path.basename( sys.argv[0]), ConfigManager.get_instance().get_version())) os._exit(0) # Log level. console_log_level = opt_dict.get('console_log_level', None) if console_log_level: LogManager.get_instance().set_console_log_level(console_log_level) # Check input arguments. self.check_input_args() return (self.options, self.args)
def __prepare_names(self, names): if sys.version_info < (3, ): text_type = unicode binary_type = str else: text_type = str binary_type = bytes if type(names) == text_type or type(names) == binary_type: if names.find(','): name_list = names.split(',') else: name_list = names.split() elif type(names) == list: name_list = names else: raise InvalidArgument( 'Names must be provided either as a list, or as a string containing names separated by space or comma.' ) name_list2 = [] for name in name_list: trimmed_name = name.strip() if len(trimmed_name): name_list2.append(trimmed_name) return ','.join(name_list2)
def add_stnode(self, path, shares): try: share_value = int(shares) except ValueError, ex: raise InvalidArgument(exception=ex)
class QconfCli(object): """ Base qconf command line interface class. """ __metaclass__ = abc.ABCMeta def __init__(self, valid_arg_count=0): """ Class constructor. :param valid_arg_count: Number of allowed positional arguments (default: 0). :type valid_arg_count: int """ self.logger = LogManager.get_instance().get_logger( self.__class__.__name__) self.parser = OptionParser(add_help_option=False) self.options = {} self.args = [] self.valid_arg_count = valid_arg_count self.option_group_dict = {} common_group = 'Common Options' self.add_option_group(common_group, None) self.add_option_to_group(common_group, '-h', '--help', action='help', help='Show this help message and exit.') self.add_option_to_group(common_group, '-?', '', action='help', help='Show this help message and exit.') self.add_option_to_group(common_group, '-v', '', action='store_true', dest='cmd_version', default=False, help='Print version and exit.') self.add_option_to_group( common_group, '-d', '--debug', dest='console_log_level', help= 'Set debug level; valid values are: critical, error, warning, info, debug' ) def add_option(self, *args, **kwargs): """ Add CLI option. """ self.parser.add_option(*args, **kwargs) def add_option_to_group(self, group_name, *args, **kwargs): """ Add option to the given group. Group should be created using add_option_group(). :param group_name: Group name. :type group_name: str """ group = self.option_group_dict.get(group_name) group.add_option(*args, **kwargs) def add_option_group(self, group_name, desc): """ Add option group. :param group_name: Group name. :type group_name: str """ group = OptionGroup(self.parser, group_name, desc) self.parser.add_option_group(group) self.option_group_dict[group_name] = group def parse_args(self, usage=None): """ Parse command arguments. :param usage: Command usage. :type usage: str """ if usage: self.parser.usage = usage try: (self.options, self.args) = self.parser.parse_args() except SystemExit, rc: sys.stdout.flush() sys.stderr.flush() os._exit(int(str(rc))) if self.valid_arg_count < len(self.args): # Postitional args are not enabled and we have some msg = "Invalid Argument(s):" for arg in self.args[self.valid_arg_count:]: msg += " " + arg raise InvalidArgument(msg) opt_dict = self.options.__dict__ if opt_dict.get('cmd_version'): print '%s version: %s' % (os.path.basename( sys.argv[0]), ConfigManager.get_instance().get_version()) os._exit(0) # Log level. console_log_level = opt_dict.get('console_log_level', None) if console_log_level: LogManager.get_instance().set_console_log_level(console_log_level) # Check input arguments. self.check_input_args() return (self.options, self.args)
def check_input_data(self, data): if type(data) != types.ListType: raise InvalidArgument('Provided data is not a list: %s.' % str(data))
class QconfObject(object): """ This class encapsulates data and functionality common to all Qconf API objects. """ VERSION = '1.0' NAME_KEY = None UGE_PYTHON_OBJECT_MAP = { 'NONE': None, 'INFINITY': float('inf'), 'TRUE': True, 'FALSE': False, } UGE_CASE_SENSITIVE_KEYS = {} USER_PROVIDED_KEYS = [] REQUIRED_DATA_DEFAULTS = {} BOOL_KEY_MAP = {} INT_KEY_MAP = {} FLOAT_KEY_MAP = {} LIST_KEY_MAP = {} DEFAULT_LIST_DELIMITER = ',' DICT_KEY_MAP = {} DEFAULT_DICT_DELIMITER = ',' DICT_VALUE_DELIMITER = '=' OPTIONAL_KEYS_ALLOWED = False def __init__(self, name=None, data=None, metadata=None, json_string=None): """ Class constructor. :param name: Object name. If provided, it will override object's name from data or JSON string parameters. :type name: str :param data: Object data. If provided, it will override corresponding data from object's JSON string representation. :type data: varies :param metadata: Object metadata. If provided, it will override corresponding metadata from object's JSON string representation. :type metadata: dict :param json_string: Object's JSON string representation. :type json_string: str :raises: **InvalidArgument** - in case metadata is not a dictionary, JSON string is not valid, or it does not contain dictionary representing a Qconf object. """ self.name = name self.metadata = {} if not hasattr(self, 'data'): self.data = {} # Unpack and check json json_dict = self.unpack_input_json(json_string) if json_dict: if json_dict.has_key('data'): self.data = json_dict.get('data') del json_dict['data'] self.metadata = json_dict # Merge json entries with provided metadata if metadata: self.check_input_metadata(metadata) self.metadata.update(metadata) # Merge json entries with provided data if data: self.check_input_data(data) if type(data) == types.DictType: self.data.update(data) else: self.data = data if name and self.NAME_KEY: self.data[self.NAME_KEY] = name # Convert list and dict keys self.convert_list_keys() self.convert_dict_keys() # Add standard metadata self.metadata['object_version'] = self.VERSION self.metadata['object_class'] = self.__class__.__name__ def unpack_input_json(self, json_string): if not json_string: return None try: json_dict = json.loads(json_string) except Exception, ex: raise InvalidArgument( 'Input is not a valid json string: %s (error: %s).' % (str(json_string), ex)) if type(json_dict) != types.DictType: raise InvalidArgument( 'Input json string does not contain dictionary: %s.' % str(json_string)) return json_dict
def check_input_metadata(self, metadata): if metadata: if type(metadata) != dict: raise InvalidArgument( 'Provided metadata is not a dictionary: %s.' % str(metadata))