def validate_permissions(tree, permission_info_list): """ Validate given permission list. Raise LibraryError if any of permission is not valid. tree -- cib tree permission_info_list -- list of tuples like this: ("read|write|deny", "xpath|id", <id-or-xpath-string>) """ report_items = [] allowed_permissions = ["read", "write", "deny"] allowed_scopes = ["xpath", "id"] for permission, scope_type, scope in permission_info_list: if not permission in allowed_permissions: report_items.append(reports.invalid_option_value( "permission", permission, allowed_permissions )) if not scope_type in allowed_scopes: report_items.append(reports.invalid_option_value( "scope type", scope_type, allowed_scopes )) if scope_type == 'id' and not does_id_exist(tree, scope): report_items.append(reports.id_not_found(scope, "id")) if report_items: raise LibraryError(*report_items)
def __validate_quorum_options(self, options): report_items = [] for name, value in sorted(options.items()): allowed_names = self.__class__.QUORUM_OPTIONS if name not in allowed_names: report_items.append( reports.invalid_option(name, allowed_names, "quorum") ) continue if value == "": continue 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 )) return report_items
def prepare_options_with_set(cib, options, resource_set_list): options = constraint.prepare_options( tuple(ATTRIB.keys()), options, create_id=partial( constraint.create_id, cib, TAG_NAME, resource_set_list ), validate_id=partial(check_new_id_applicable, cib, DESCRIPTION), ) report_items = [] if "kind" in options: kind = options["kind"].lower().capitalize() if kind not in ATTRIB["kind"]: report_items.append(reports.invalid_option_value( "kind", options["kind"], ATTRIB["kind"] )) options["kind"] = kind if "symmetrical" in options: symmetrical = options["symmetrical"].lower() if symmetrical not in ATTRIB["symmetrical"]: report_items.append(reports.invalid_option_value( "symmetrical", options["symmetrical"], ATTRIB["symmetrical"] )) options["symmetrical"] = symmetrical if report_items: raise LibraryError(*report_items) return options
def validate_permissions(tree, permission_info_list): """ Validate given permission list. Raise LibraryError if any of permission is not valid. tree -- cib tree permission_info_list -- list of tuples like this: ("read|write|deny", "xpath|id", <id-or-xpath-string>) """ report_items = [] allowed_permissions = ["read", "write", "deny"] allowed_scopes = ["xpath", "id"] for permission, scope_type, scope in permission_info_list: if not permission in allowed_permissions: report_items.append( reports.invalid_option_value("permission", permission, allowed_permissions)) if not scope_type in allowed_scopes: report_items.append( reports.invalid_option_value("scope type", scope_type, allowed_scopes)) if scope_type == 'id' and not does_id_exist(tree, scope): report_items.append(reports.id_not_found(scope, ["id"])) if report_items: raise LibraryError(*report_items)
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_option( [key], TICKET_KEYS, "booth ticket", )) elif key not in TICKET_KEYS: reports.append( common_reports.invalid_option( [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_set_as_guest(tree, nodes, node_name, options): report_list = validate.names_in( GUEST_OPTIONS, options.keys(), "guest", ) validator_list = [ validate.value_time_interval("remote-connect-timeout"), validate.value_port_number("remote-port"), ] report_list.extend( validate.run_collection_of_option_validators(options, validator_list)) report_list.extend(validate_conflicts(tree, nodes, node_name, options)) if not node_name.strip(): report_list.append( reports.invalid_option_value( "node name", node_name, "no empty value", )) return report_list
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_option( [key], TICKET_KEYS, "booth ticket", )) elif key not in TICKET_KEYS: reports.append( common_reports.invalid_option( [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 prepare_options_plain(cib, options, ticket, resource_id): options = options.copy() report = _validate_options_common(options) if not ticket: report.append(reports.required_options_are_missing(['ticket'])) options["ticket"] = ticket if not resource_id: report.append(reports.required_options_are_missing(['rsc'])) options["rsc"] = resource_id if "rsc-role" in options: if options["rsc-role"]: resource_role = options["rsc-role"].lower().capitalize() if resource_role not in ATTRIB_PLAIN["rsc-role"]: report.append( reports.invalid_option_value("rsc-role", options["rsc-role"], ATTRIB_PLAIN["rsc-role"])) options["rsc-role"] = resource_role else: del options["rsc-role"] if report: raise LibraryError(*report) return constraint.prepare_options( tuple(list(ATTRIB) + list(ATTRIB_PLAIN)), options, partial(_create_id, cib, options["ticket"], resource_id, options.get("rsc-role", "")), partial(tools.check_new_id_applicable, cib, DESCRIPTION))
def set_message(lib_env, device, node_name, message): """ Set message on device for node_name. lib_env -- LibrayEnvironment device -- string, absolute path to device node_name -- string message -- string, mesage type, should be one of settings.sbd_message_types """ report_item_list = [] missing_options = [] if not device: missing_options.append("device") if not node_name: missing_options.append("node") if missing_options: report_item_list.append( reports.required_option_is_missing(missing_options) ) supported_messages = settings.sbd_message_types if message not in supported_messages: report_item_list.append( reports.invalid_option_value("message", message, supported_messages) ) lib_env.report_processor.process_list(report_item_list) sbd.set_message(lib_env.cmd_runner(), device, node_name, message)
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_option( [name], allowed_options, "quorum device", severity if name != "model" else ReportItemSeverity.ERROR, 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, forceable)) return report_items
def _validate_container(container_type, container_options, force_options=False): if not container_type in GENERIC_CONTAINER_TYPES: return [ reports.invalid_option_value( "container type", container_type, GENERIC_CONTAINER_TYPES, ) ] validators = [ validate.is_required("image", "container"), validate.value_not_empty("image", "image name"), validate.value_nonnegative_integer("masters"), validate.value_nonnegative_integer("promoted-max"), validate.mutually_exclusive(["masters", "promoted-max"], "container"), validate.value_positive_integer("replicas"), validate.value_positive_integer("replicas-per-host"), ] deprecation_reports = [] if "masters" in container_options: deprecation_reports.append( reports.deprecated_option("masters", ["promoted-max"], "container", severity=ReportItemSeverity.WARNING)) return (validate.run_collection_of_option_validators( container_options, validators) + deprecation_reports + validate.names_in(GENERIC_CONTAINER_OPTIONS, container_options.keys(), "container", report_codes.FORCE_OPTIONS, force_options))
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_option(name, list(ATTRIB.keys()), None)) if value not in ATTRIB[name]: raise LibraryError(reports.invalid_option_value(name, value, ATTRIB[name]))
def _validate_value(self, value): return [ reports.invalid_option_value( self._option_name, value.original, "test report", ) ]
def _validate_level(reporter, level): try: candidate = int(level) if candidate > 0: return candidate except ValueError: pass reporter.append( reports.invalid_option_value("level", level, "a positive integer"))
def test_invalid_level(self, mock_val_level, mock_val_target, mock_val_devices, mock_val_dupl, mock_append): mock_val_level.side_effect = lambda reporter, level: reporter.append( reports.invalid_option_value("level", level, "a positive integer")) self.assert_called_invalid(mock_val_level, mock_val_target, mock_val_devices, mock_val_dupl, mock_append, dupl_called=False)
def _validate_options_common(options): report = [] if "loss-policy" in options: loss_policy = options["loss-policy"].lower() if options["loss-policy"] not in ATTRIB["loss-policy"]: report.append(reports.invalid_option_value( "loss-policy", options["loss-policy"], ATTRIB["loss-policy"] )) options["loss-policy"] = loss_policy return report
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_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_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_option([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_level(reporter, level): try: candidate = int(level) if candidate > 0: return candidate except ValueError: pass reporter.add( reports.invalid_option_value("level", level, "a positive integer") )
def _validate_container(container_type, container_options, force_options=False): if container_type not in GENERIC_CONTAINER_TYPES: return [ reports.invalid_option_value( "container type", container_type, GENERIC_CONTAINER_TYPES, ) ] return _validate_generic_container_options(container_options, force_options)
def _validate_level(level) -> Tuple[ReportItemList, Optional[int]]: report_list: ReportItemList = [] try: candidate = int(level) if candidate > 0: return report_list, candidate except ValueError: pass report_list.append( reports.invalid_option_value("level", level, "a positive integer")) return report_list, None
def test_invalid_level( self, mock_val_level, mock_val_target, mock_val_devices, mock_val_dupl, mock_append ): mock_val_level.side_effect = lambda reporter, level: reporter.add( reports.invalid_option_value("level", level, "a positive integer") ) self.assert_called_invalid( mock_val_level, mock_val_target, mock_val_devices, mock_val_dupl, mock_append, dupl_called=False )
def _validate_level(reporter, level): # TODO this should not rely on the report to be sent and the execution # ended in a caller try: candidate = int(level) if candidate > 0: return candidate except ValueError: pass reporter.append( reports.invalid_option_value("level", level, "a positive integer")) return None
def __validate_quorum_device_model(self, model, force_model=False): report_items = [] allowed_values = ("net", ) if model not in allowed_values: report_items.append( reports.invalid_option_value( "model", model, allowed_values, ReportItemSeverity.WARNING if force_model else ReportItemSeverity.ERROR, None if force_model else report_codes.FORCE_QDEVICE_MODEL)) return report_items
def client_net_setup(lib_env, ca_certificate): """ Intialize qdevice net client on local host ca_certificate base64 encoded qnetd CA certificate """ try: ca_certificate_data = base64.b64decode(ca_certificate) except (TypeError, binascii.Error): raise LibraryError( reports.invalid_option_value("qnetd CA certificate", ca_certificate, ["base64 encoded certificate"])) qdevice_net.client_setup(lib_env.cmd_runner(), ca_certificate_data)
def client_net_import_certificate(lib_env, certificate): """ Import qnetd client certificate to local node certificate storage certificate base64 encoded qnetd client certificate """ try: certificate_data = base64.b64decode(certificate) except (TypeError, binascii.Error): raise LibraryError( reports.invalid_option_value("qnetd client certificate", certificate, ["base64 encoded certificate"])) qdevice_net.client_import_certificate_and_key(lib_env.cmd_runner(), certificate_data)
def client_net_setup(lib_env, ca_certificate): """ Intialize qdevice net client on local host ca_certificate base64 encoded qnetd CA certificate """ try: ca_certificate_data = base64.b64decode(ca_certificate) except (TypeError, binascii.Error): raise LibraryError(reports.invalid_option_value( "qnetd CA certificate", ca_certificate, ["base64 encoded certificate"] )) qdevice_net.client_setup(lib_env.cmd_runner(), ca_certificate_data)
def __validate_permissions(tree, permission_info_list): report_items = [] allowed_permissions = ["read", "write", "deny"] allowed_scopes = ["xpath", "id"] for permission, scope_type, scope in permission_info_list: if not permission in allowed_permissions: report_items.append(reports.invalid_option_value( "permission", permission, allowed_permissions )) if not scope_type in allowed_scopes: report_items.append(reports.invalid_option_value( "scope type", scope_type, allowed_scopes )) if scope_type == 'id' and not does_id_exist(tree, scope): report_items.append(reports.id_not_found(scope, "id")) if report_items: raise LibraryError(*report_items)
def set_expected_votes_live(lib_env, expected_votes): """ set expected votes in live cluster to specified value numeric expected_votes desired value of expected votes """ try: votes_int = int(expected_votes) if votes_int < 1: raise ValueError() except ValueError: raise LibraryError( reports.invalid_option_value("expected votes", expected_votes, "positive integer")) corosync_live.set_expected_votes(lib_env.cmd_runner(), votes_int)
def validate_func(option_dict): allowed_algorithms = ( "ffsplit", "lms", ) value = validate.ValuePair.get(option_dict["algorithm"]) if validate.is_empty_string(value.normalized): return [ reports.invalid_option_value("algorithm", value.original, allowed_algorithms) ] return validate.value_in( "algorithm", allowed_algorithms, code_to_allow_extra_values=code_to_allow_extra_values, extra_values_allowed=extra_values_allowed)(option_dict)
def set_expected_votes_live(lib_env, expected_votes): """ set expected votes in live cluster to specified value numeric expected_votes desired value of expected votes """ try: votes_int = int(expected_votes) if votes_int < 1: raise ValueError() except ValueError: raise LibraryError(reports.invalid_option_value( "expected votes", expected_votes, "positive integer" )) corosync_live.set_expected_votes(lib_env.cmd_runner(), votes_int)
def __validate_quorum_device_model(self, model, force_model=False): report_items = [] allowed_values = ( "net", ) if model not in allowed_values: report_items.append(reports.invalid_option_value( "model", model, allowed_values, ReportItemSeverity.WARNING if force_model else ReportItemSeverity.ERROR, None if force_model else report_codes.FORCE_QDEVICE_MODEL )) return report_items
def client_net_import_certificate(lib_env, certificate): """ Import qnetd client certificate to local node certificate storage certificate base64 encoded qnetd client certificate """ try: certificate_data = base64.b64decode(certificate) except (TypeError, binascii.Error): raise LibraryError(reports.invalid_option_value( "qnetd client certificate", certificate, ["base64 encoded certificate"] )) qdevice_net.client_import_certificate_and_key( lib_env.cmd_runner(), certificate_data )
def qdevice_net_sign_certificate_request(lib_env, certificate_request, cluster_name): """ Sign node certificate request by qnetd CA string certificate_request base64 encoded certificate request string cluster_name name of the cluster to which qdevice is being added """ try: certificate_request_data = base64.b64decode(certificate_request) except (TypeError, binascii.Error): raise LibraryError( reports.invalid_option_value("qnetd certificate request", certificate_request, ["base64 encoded certificate"])) return base64.b64encode( qdevice_net.qdevice_sign_certificate_request(lib_env.cmd_runner(), certificate_request_data, cluster_name))
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 = [] unsupported_sbd_option_list = [ "SBD_WATCHDOG_DEV", "SBD_OPTS", "SBD_PACEMAKER" ] allowed_sbd_options = [ "SBD_DELAY_START", "SBD_STARTMODE", "SBD_WATCHDOG_TIMEOUT" ] for sbd_opt in sbd_config: if sbd_opt in unsupported_sbd_option_list: report_item_list.append(reports.invalid_option( [sbd_opt], allowed_sbd_options, None )) elif sbd_opt not in allowed_sbd_options: report_item_list.append(reports.invalid_option( [sbd_opt], allowed_sbd_options, None, Severities.WARNING if allow_unknown_opts else Severities.ERROR, 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"], "nonnegative 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_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_container(container_type, container_options, force_options=False): if not container_type in GENERIC_CONTAINER_TYPES: return [ reports.invalid_option_value( "container type", container_type, GENERIC_CONTAINER_TYPES, ) ] validators = [ validate.NamesIn( GENERIC_CONTAINER_OPTIONS, option_type="container", **validate.set_warning(report_codes.FORCE_OPTIONS, force_options) ), validate.IsRequiredAll(["image"], option_type="container"), validate.ValueNotEmpty("image", "image name"), validate.ValueNonnegativeInteger("masters"), validate.ValueNonnegativeInteger("promoted-max"), validate.MutuallyExclusive( ["masters", "promoted-max"], option_type="container", ), validate.ValuePositiveInteger("replicas"), validate.ValuePositiveInteger("replicas-per-host"), ] deprecation_reports = [] if "masters" in container_options: deprecation_reports.append( reports.deprecated_option( "masters", ["promoted-max"], "container", severity=ReportItemSeverity.WARNING ) ) return ( validate.ValidatorAll(validators).validate(container_options) + deprecation_reports )
def _validate_value(self, value): if not isinstance(value.normalized, str): return [] forbidden_characters = "{}\n\r" if set(value.normalized) & set(forbidden_characters): # We must be strict and do not allow to override this validation, # otherwise setting a cratfed option value could be misused for # setting arbitrary corosync.conf settings. return [ reports.invalid_option_value( self._get_option_name_for_report(), value.original, None, # Make it actually print "\n" and "\r" strings instead of # going to the next line. # Let the user know all forbidden characters right away. Do # not let them try them one by one by only reporting those # actually used in the value. forbidden_characters="{}\\n\\r") ] return []
def prepare_options_plain(cib, options, ticket, resource_id): options = options.copy() report = _validate_options_common(options) if not ticket: report.append(reports.required_option_is_missing(['ticket'])) options["ticket"] = ticket if not resource_id: report.append(reports.required_option_is_missing(['rsc'])) options["rsc"] = resource_id if "rsc-role" in options: if options["rsc-role"]: resource_role = options["rsc-role"].lower().capitalize() if resource_role not in ATTRIB_PLAIN["rsc-role"]: report.append(reports.invalid_option_value( "rsc-role", options["rsc-role"], ATTRIB_PLAIN["rsc-role"] )) options["rsc-role"] = resource_role else: del options["rsc-role"] if report: raise LibraryError(*report) return constraint.prepare_options( tuple(list(ATTRIB) + list(ATTRIB_PLAIN)), options, partial( _create_id, cib, options["ticket"], resource_id, options.get("rsc-role", "") ), partial(tools.check_new_id_applicable, cib, DESCRIPTION) )
def qdevice_net_sign_certificate_request( lib_env, certificate_request, cluster_name ): """ Sign node certificate request by qnetd CA string certificate_request base64 encoded certificate request string cluster_name name of the cluster to which qdevice is being added """ try: certificate_request_data = base64.b64decode(certificate_request) except (TypeError, binascii.Error): raise LibraryError(reports.invalid_option_value( "qnetd certificate request", certificate_request, ["base64 encoded certificate"] )) return base64.b64encode( qdevice_net.qdevice_sign_certificate_request( lib_env.cmd_runner(), certificate_request_data, cluster_name ) )
def test_invalid_level(self, mock_val_level, mock_val_target, mock_val_devices, mock_val_dupl, mock_append): mock_val_level.return_value = ([ reports.invalid_option_value("level", self.level, "a positive integer") ], None) report_list = [ fixture.error( report_codes.INVALID_OPTION_VALUE, option_value=self.level, option_name="level", allowed_values="a positive integer", cannot_be_empty=False, forbidden_characters=None, ), ] self.assert_called_invalid(mock_val_level, mock_val_target, mock_val_devices, mock_val_dupl, mock_append, dupl_called=False, report_list=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_option( [name], allowed_options, "quorum device", severity if name != "model" else ReportItemSeverity.ERROR, 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, forceable )) 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
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_option( [name], allowed_options, "quorum device model", severity, 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, 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, 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, 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, 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, forceable )) if missing_options: report_items.append( reports.required_option_is_missing(sorted(missing_options)) ) return report_items
def _check_model(model): if model != "net": raise LibraryError( reports.invalid_option_value("model", model, ["net"]) )
def _check_model(model): if model != "net": raise LibraryError( reports.invalid_option_value("model", model, ["net"]))