def validate_ticket_options(report_processor, options, allow_unknown_options): reports = [] for key in sorted(options): if key in GLOBAL_KEYS: reports.append( common_reports.invalid_options( [key], TICKET_KEYS, "booth ticket", )) elif key not in TICKET_KEYS: reports.append( common_reports.invalid_options( [key], TICKET_KEYS, "booth ticket", severity=(severities.WARNING if allow_unknown_options else severities.ERROR), forceable=(None if allow_unknown_options else report_codes.FORCE_OPTIONS), )) if not options[key].strip(): reports.append( common_reports.invalid_option_value( key, options[key], "no-empty", )) report_processor.process_list(reports)
def validate_ticket_options(report_processor, options, allow_unknown_options): report_list = [] for key in sorted(options): if key in GLOBAL_KEYS: report_list.append(common_reports.invalid_options( [key], TICKET_KEYS, "booth ticket", )) elif key not in TICKET_KEYS: report_list.append( common_reports.invalid_options( [key], TICKET_KEYS, "booth ticket", severity=( severities.WARNING if allow_unknown_options else severities.ERROR ), forceable=( None if allow_unknown_options else report_codes.FORCE_OPTIONS ), ) ) if not options[key].strip(): report_list.append(common_reports.invalid_option_value( key, options[key], "no-empty", )) report_processor.process_list(report_list)
def validate(self, option_dict): name_set = set(option_dict.keys()) banned_names = set() if not (self._code_for_warning is None and not self._produce_warning): banned_names = name_set & self._banned_name_set invalid_names = name_set - set(self._option_name_list) - banned_names report_list = [] create_report = reports.get_problem_creator(self._code_for_warning, self._produce_warning) if invalid_names: report_list.append( create_report( reports.invalid_options, invalid_names, self._option_name_list, self._option_type, allowed_option_patterns=self._allowed_option_patterns, )) if banned_names: report_list.append( reports.invalid_options( banned_names, self._option_name_list, self._option_type, )) return report_list
def validate_parameters( self, parameters, parameters_type="resource", allow_invalid=False, update=False ): forceable = report_codes.FORCE_OPTIONS if not allow_invalid else None severity = ( ReportItemSeverity.ERROR if not allow_invalid else ReportItemSeverity.WARNING ) report_list = [] bad_opts, missing_req_opts = self.validate_parameters_values( parameters ) if bad_opts: report_list.append(reports.invalid_options( bad_opts, sorted([attr["name"] for attr in self.get_parameters()]), parameters_type, severity=severity, forceable=forceable, )) if not update and missing_req_opts: report_list.append(reports.required_option_is_missing( missing_req_opts, parameters_type, severity=severity, forceable=forceable, )) return report_list
def _validate_attrib_names(attrib_names, options): invalid_names = [ name for name in options.keys() if name not in attrib_names ] if invalid_names: raise LibraryError( reports.invalid_options(invalid_names, attrib_names, None))
def _validate_attrib_names(attrib_names, options): invalid_names = [ name for name in options.keys() if name not in attrib_names ] if invalid_names: raise LibraryError( reports.invalid_options(invalid_names, attrib_names, None) )
def validate_options(options): #Pacemaker does not care currently about meaningfulness for concrete #constraint, so we use all attribs. for name, value in options.items(): if name not in ATTRIB: raise LibraryError( reports.invalid_options([name], list(ATTRIB.keys()), None)) if value not in ATTRIB[name]: raise LibraryError( reports.invalid_option_value(name, value, ATTRIB[name]))
def _validate_qdevice_generic_options_names(options, force_options=False): option_type = "quorum device" allowed_options = [ "sync_timeout", "timeout", ] report_items = [] # In corosync.conf, generic options contain the "model" option. We treat # that option separately in pcs so we must not allow it to be passed in # generic options. That's why a standard validate.names_in cannot be used # in here. model_found = False invalid_options = [] for name in options: if name not in allowed_options: if name == "model": model_found = True else: invalid_options.append(name) if model_found: report_items.append( reports.invalid_options( ["model"], allowed_options, option_type, ) ) if invalid_options: report_items.append( reports.invalid_options( invalid_options, allowed_options, option_type, severity=( ReportItemSeverity.WARNING if force_options else ReportItemSeverity.ERROR ), forceable=( None if force_options else report_codes.FORCE_OPTIONS ) ) ) return report_items
def _validate_sbd_options(sbd_config, allow_unknown_opts=False): """ Validate user SBD configuration. Options 'SBD_WATCHDOG_DEV' and 'SBD_OPTS' are restricted. Returns list of ReportItem sbd_config -- dictionary in format: <SBD config option>: <value> allow_unknown_opts -- if True, accept also unknown options. """ report_item_list = [] for sbd_opt in sbd_config: if sbd_opt in UNSUPPORTED_SBD_OPTION_LIST: report_item_list.append(reports.invalid_options( [sbd_opt], ALLOWED_SBD_OPTION_LIST, None )) elif sbd_opt not in ALLOWED_SBD_OPTION_LIST: report_item_list.append(reports.invalid_options( [sbd_opt], ALLOWED_SBD_OPTION_LIST, None, severity=( Severities.WARNING if allow_unknown_opts else Severities.ERROR ), forceable=( None if allow_unknown_opts else report_codes.FORCE_OPTIONS ) )) if "SBD_WATCHDOG_TIMEOUT" in sbd_config: report_item = reports.invalid_option_value( "SBD_WATCHDOG_TIMEOUT", sbd_config["SBD_WATCHDOG_TIMEOUT"], "a non-negative integer" ) try: if int(sbd_config["SBD_WATCHDOG_TIMEOUT"]) < 0: report_item_list.append(report_item) except (ValueError, TypeError): report_item_list.append(report_item) return report_item_list
def _validate_server_not_used(agent, option_dict): if "server" in option_dict: return [reports.invalid_options( ["server"], sorted([ attr["name"] for attr in agent.get_parameters() if attr["name"] != "server" ]), "resource", )] return []
def validate_options(options): #Pacemaker does not care currently about meaningfulness for concrete #constraint, so we use all attribs. for name, value in options.items(): if name not in ATTRIB: raise LibraryError( reports.invalid_options([name], list(ATTRIB.keys()), None) ) if value not in ATTRIB[name]: raise LibraryError( reports.invalid_option_value(name, value, ATTRIB[name]) )
def names_in( allowed_name_list, name_list, option_type="option", code_to_allow_extra_names=None, extra_names_allowed=False, allowed_option_patterns=None, banned_name_list=None, ): """ Return a list with report INVALID_OPTIONS when in name_list is a name that is not in allowed_name_list. list allowed_name_list contains names which are valid list name_list contains names for validation string option_type describes type of option for reporting purposes string code_to_allow_extra_names is code for forcing invalid names. If it is empty report INVALID_OPTIONS is non-forceable error. If it is not empty report INVALID_OPTIONS is forceable error or warning. bool extra_names_allowed is flag that complements code_to_allow_extra_names and determines wheter is report INVALID_OPTIONS forceable error or warning. mixed allowed_option_patterns -- option patterns to be added to a report list banned_name_list -- list of options which cannot be forced """ name_set = set(name_list) banned_set = set(banned_name_list or []) banned_names = set() if not (code_to_allow_extra_names is None and not extra_names_allowed): banned_names = name_set & banned_set invalid_names = name_set - set(allowed_name_list) - banned_names report_list = [] create_report = reports.get_problem_creator(code_to_allow_extra_names, extra_names_allowed) if invalid_names: report_list.append( create_report(reports.invalid_options, sorted(invalid_names), sorted(allowed_name_list), option_type, allowed_option_patterns=sorted( allowed_option_patterns or []))) if banned_names: report_list.append( reports.invalid_options( sorted(banned_names), sorted(allowed_name_list), option_type, )) return report_list
def names_in( allowed_name_list, name_list, option_type="option", code_to_allow_extra_names=None, extra_names_allowed=False, allowed_option_patterns=None, banned_name_list=None, ): """ Return a list with report INVALID_OPTIONS when in name_list is a name that is not in allowed_name_list. list allowed_name_list contains names which are valid list name_list contains names for validation string option_type describes type of option for reporting purposes string code_to_allow_extra_names is code for forcing invalid names. If it is empty report INVALID_OPTIONS is non-forceable error. If it is not empty report INVALID_OPTIONS is forceable error or warning. bool extra_names_allowed is flag that complements code_to_allow_extra_names and determines wheter is report INVALID_OPTIONS forceable error or warning. mixed allowed_option_patterns -- option patterns to be added to a report list banned_name_list -- list of options which cannot be forced """ name_set = set(name_list) banned_set = set(banned_name_list or []) banned_names = set() if not (code_to_allow_extra_names is None and not extra_names_allowed): banned_names = name_set & banned_set invalid_names = name_set - set(allowed_name_list) - banned_names report_list = [] create_report = reports.get_problem_creator( code_to_allow_extra_names, extra_names_allowed ) if invalid_names: report_list.append(create_report( reports.invalid_options, sorted(invalid_names), sorted(allowed_name_list), option_type, allowed_option_patterns=sorted(allowed_option_patterns or []) )) if banned_names: report_list.append(reports.invalid_options( sorted(banned_names), sorted(allowed_name_list), option_type, )) return report_list
def __validate_quorum_device_generic_options( self, generic_options, force=False ): optional_options = frozenset([ "sync_timeout", "timeout", ]) allowed_options = optional_options report_items = [] severity = ( ReportItemSeverity.WARNING if force else ReportItemSeverity.ERROR ) forceable = None if force else report_codes.FORCE_OPTIONS for name, value in sorted(generic_options.items()): if name not in allowed_options: # model is never allowed in generic options, it is passed # in its own argument report_items.append(reports.invalid_options( [name], allowed_options, "quorum device", severity=( severity if name != "model" else ReportItemSeverity.ERROR ), forceable=(forceable if name != "model" else None) )) continue if value == "": continue if not value.isdigit(): report_items.append(reports.invalid_option_value( name, value, "positive integer", severity=severity, forceable=forceable )) return report_items
def __validate_quorum_options(self, options): report_items = [] has_qdevice = self.has_quorum_device() qdevice_incompatible_options = [] for name, value in sorted(options.items()): allowed_names = self.__class__.QUORUM_OPTIONS if name not in allowed_names: report_items.append( reports.invalid_options([name], allowed_names, "quorum") ) continue if value == "": continue if ( has_qdevice and name in self.__class__.QUORUM_OPTIONS_INCOMPATIBLE_WITH_QDEVICE ): qdevice_incompatible_options.append(name) if name == "last_man_standing_window": if not value.isdigit(): report_items.append(reports.invalid_option_value( name, value, "positive integer" )) else: allowed_values = ("0", "1") if value not in allowed_values: report_items.append(reports.invalid_option_value( name, value, allowed_values )) if qdevice_incompatible_options: report_items.append( reports.corosync_options_incompatible_with_qdevice( qdevice_incompatible_options ) ) return report_items
def __validate_quorum_device_model_net_options( self, model_options, need_required, force=False ): required_options = frozenset(["host", "algorithm"]) optional_options = frozenset([ "connect_timeout", "force_ip_version", "port", "tie_breaker", ]) allowed_options = required_options | optional_options model_options_names = frozenset(model_options.keys()) missing_options = [] report_items = [] severity = ( ReportItemSeverity.WARNING if force else ReportItemSeverity.ERROR ) forceable = None if force else report_codes.FORCE_OPTIONS if need_required: missing_options += required_options - model_options_names for name, value in sorted(model_options.items()): if name not in allowed_options: report_items.append(reports.invalid_options( [name], allowed_options, "quorum device model", severity=severity, forceable=forceable )) continue if value == "": # do not allow to remove required options if name in required_options: missing_options.append(name) else: continue if name == "algorithm": allowed_values = ("ffsplit", "lms") if value not in allowed_values: report_items.append(reports.invalid_option_value( name, value, allowed_values, severity=severity, forceable=forceable )) if name == "connect_timeout": minimum, maximum = 1000, 2*60*1000 if not (value.isdigit() and minimum <= int(value) <= maximum): min_max = "{min}-{max}".format(min=minimum, max=maximum) report_items.append(reports.invalid_option_value( name, value, min_max, severity=severity, forceable=forceable )) if name == "force_ip_version": allowed_values = ("0", "4", "6") if value not in allowed_values: report_items.append(reports.invalid_option_value( name, value, allowed_values, severity=severity, forceable=forceable )) if name == "port": minimum, maximum = 1, 65535 if not (value.isdigit() and minimum <= int(value) <= maximum): min_max = "{min}-{max}".format(min=minimum, max=maximum) report_items.append(reports.invalid_option_value( name, value, min_max, severity=severity, forceable=forceable )) if name == "tie_breaker": node_ids = [node.id for node in self.get_nodes()] allowed_nonid = ["lowest", "highest"] if value not in allowed_nonid + node_ids: allowed_values = allowed_nonid + ["valid node id"] report_items.append(reports.invalid_option_value( name, value, allowed_values, severity=severity, forceable=forceable )) if missing_options: report_items.append( reports.required_option_is_missing(sorted(missing_options)) ) return report_items