def validate_operation_list(operation_list, allowed_operation_name_list, allow_invalid=False): kwargs = validate.set_warning(report_codes.FORCE_OPTIONS, allow_invalid) option_type = "resource operation" validators = [ validate.NamesIn(ATTRIBUTES, option_type=option_type), validate.IsRequiredAll(["name"], option_type=option_type), validate.ValueIn( "name", allowed_operation_name_list, option_name_for_report="operation name", **kwargs, ), validate.ValueIn("role", RESOURCE_ROLES), validate.ValueIn("on-fail", ON_FAIL_VALUES), validate.ValueIn("record-pending", BOOLEAN_VALUES), validate.ValueIn("enabled", BOOLEAN_VALUES), validate.MutuallyExclusive(["interval-origin", "start-delay"], option_type=option_type), validate.ValueId("id", option_name_for_report="operation id"), ] validator_all = validate.ValidatorAll(validators) report_list = [] for operation in operation_list: report_list.extend(validator_all.validate(operation)) return report_list
def test_returns_empty_report_on_valid_normalized_option(self): assert_report_item_list_equal( validate.ValueIn("a", ["b"]).validate( {"a": validate.ValuePair(original="C", normalized="b")} ), [], )
def _validate_sbd_options(sbd_config, allow_unknown_opts=False, allow_invalid_option_values=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. """ validators = [ validate.NamesIn( ALLOWED_SBD_OPTION_LIST, banned_name_list=UNSUPPORTED_SBD_OPTION_LIST, **validate.set_warning(report_codes.FORCE_OPTIONS, allow_unknown_opts), ), validate.ValueNonnegativeInteger("SBD_WATCHDOG_TIMEOUT"), validate.ValueIn( "SBD_TIMEOUT_ACTION", TIMEOUT_ACTION_ALLOWED_VALUE_LIST, **validate.set_warning(report_codes.FORCE_OPTIONS, allow_invalid_option_values), ), ] return validate.ValidatorAll(validators).validate(sbd_config)
def _validate_options(options) -> reports.ReportItemList: # Pacemaker does not care currently about meaningfulness for concrete # constraint, so we use all attribs. validators = [ validate.NamesIn(_ATTRIBUTES, option_type="set"), validate.ValueIn("action", const.PCMK_ACTIONS), validate.ValueIn("require-all", _BOOLEAN_VALUES), validate.ValueIn("role", const.PCMK_ROLES), validate.ValueIn("sequential", _BOOLEAN_VALUES), validate.ValueDeprecated( "role", { const.PCMK_ROLE_PROMOTED_LEGACY: const.PCMK_ROLE_PROMOTED, const.PCMK_ROLE_UNPROMOTED_LEGACY: const.PCMK_ROLE_UNPROMOTED, }, reports.ReportItemSeverity.deprecation(), ), ] return validate.ValidatorAll(validators).validate(options)
def test_returns_report_about_invalid_option(self): assert_report_item_list_equal( validate.ValueIn("a", ["b"]).validate({"a": "c"}), [ fixture.error( report_codes.INVALID_OPTION_VALUE, option_name="a", option_value="c", allowed_values=["b"], cannot_be_empty=False, forbidden_characters=None, ), ])
def test_support_option_value_pair(self): assert_report_item_list_equal( validate.ValueIn("a", ["b"]).validate( {"a": validate.ValuePair(original="C", normalized="c")}), [ fixture.error( report_codes.INVALID_OPTION_VALUE, option_name="a", option_value="C", allowed_values=["b"], cannot_be_empty=False, forbidden_characters=None, ), ])
def _validate_operation_list( operation_list, allowed_operation_name_list, allow_invalid=False ): severity = reports.item.get_severity(reports.codes.FORCE, allow_invalid) option_type = "resource operation" validators = [ validate.NamesIn(ATTRIBUTES, option_type=option_type), validate.IsRequiredAll(["name"], option_type=option_type), validate.ValueIn( "name", allowed_operation_name_list, option_name_for_report="operation name", severity=severity, ), validate.ValueIn("role", const.PCMK_ROLES), validate.ValueDeprecated( "role", { const.PCMK_ROLE_PROMOTED_LEGACY: const.PCMK_ROLE_PROMOTED, const.PCMK_ROLE_UNPROMOTED_LEGACY: const.PCMK_ROLE_UNPROMOTED, }, reports.ReportItemSeverity.deprecation(), ), validate.ValueIn("on-fail", ON_FAIL_VALUES), validate.ValueIn("record-pending", _BOOLEAN_VALUES), validate.ValueIn("enabled", _BOOLEAN_VALUES), validate.MutuallyExclusive( ["interval-origin", "start-delay"], option_type=option_type ), validate.ValueId("id", option_name_for_report="operation id"), ] validator_all = validate.ValidatorAll(validators) report_list = [] for operation in operation_list: report_list.extend(validator_all.validate(operation)) return report_list
def test_supports_warning(self): assert_report_item_list_equal( validate.ValueIn("a", ["b"], code_for_warning="FORCE", produce_warning=True).validate({"a": "c"}), [ fixture.warn( report_codes.INVALID_OPTION_VALUE, option_name="a", option_value="c", allowed_values=["b"], cannot_be_empty=False, forbidden_characters=None, ), ])
def test_supports_another_report_option_name(self): assert_report_item_list_equal( validate.ValueIn("a", ["b"], option_name_for_report="option a").validate( {"a": "c"}), [ fixture.error( report_codes.INVALID_OPTION_VALUE, option_name="option a", option_value="c", allowed_values=["b"], cannot_be_empty=False, forbidden_characters=None, ), ])
def _validate_ticket_options(options, allow_unknown_options): severity = reports.item.get_severity(reports.codes.FORCE, allow_unknown_options) validator_list = ([ validate.NamesIn( constants.TICKET_KEYS, option_type="booth ticket", banned_name_list=constants.GLOBAL_KEYS, severity=severity, ), ] + [ validate.ValueNotEmpty(option, None) for option in options if option != "mode" ] + [validate.ValueIn("mode", ["auto", "manual"], severity=severity)]) normalized_options = validate.values_to_pairs( options, lambda key, value: value.strip()) return validate.ValidatorAll(validator_list).validate(normalized_options)
def test_supports_warning(self): assert_report_item_list_equal( validate.ValueIn( "a", ["b"], severity=reports.item.ReportItemSeverity.warning(), ).validate({"a": "c"}), [ fixture.warn( reports.codes.INVALID_OPTION_VALUE, option_name="a", option_value="c", allowed_values=["b"], cannot_be_empty=False, forbidden_characters=None, ), ], )
def test_collect_all_errors_from_specifications(self): assert_report_item_list_equal( validate.ValidatorAll([ validate.NamesIn(["x", "y"]), validate.MutuallyExclusive(["x", "y"]), validate.ValuePositiveInteger("x"), validate.ValueIn("y", ["a", "b"]), ]).validate({ "x": "abcd", "y": "defg", "z": "hijk", }), [ fixture.error( reports.codes.INVALID_OPTIONS, option_names=["z"], option_type=None, allowed=["x", "y"], allowed_patterns=[], ), fixture.error( reports.codes.MUTUALLY_EXCLUSIVE_OPTIONS, option_names=["x", "y"], option_type=None, ), fixture.error( reports.codes.INVALID_OPTION_VALUE, option_value="abcd", option_name="x", allowed_values="a positive integer", cannot_be_empty=False, forbidden_characters=None, ), fixture.error( reports.codes.INVALID_OPTION_VALUE, option_value="defg", option_name="y", allowed_values=["a", "b"], cannot_be_empty=False, forbidden_characters=None, ), ], )
def test_returns_empty_report_on_valid_option(self): assert_report_item_list_equal( validate.ValueIn("a", ["b"]).validate({"a": "b"}), [])
def prepare_options_plain( cib: _Element, report_processor: reports.ReportProcessor, options, ticket: str, resource_id, ): options = options.copy() report_processor.report_list(_validate_options_common(options)) if not ticket: report_processor.report( ReportItem.error( reports.messages.RequiredOptionsAreMissing(["ticket"]))) else: report_processor.report_list(validate_ticket_name(ticket)) options["ticket"] = ticket if not resource_id: report_processor.report( ReportItem.error( reports.messages.RequiredOptionsAreMissing(["rsc"]))) options["rsc"] = resource_id role_value_validator = validate.ValueIn("rsc-role", const.PCMK_ROLES, option_name_for_report="role") role_value_validator.empty_string_valid = True validators = [ role_value_validator, validate.ValueDeprecated( "rsc-role", { const.PCMK_ROLE_PROMOTED_LEGACY: const.PCMK_ROLE_PROMOTED, const.PCMK_ROLE_UNPROMOTED_LEGACY: const.PCMK_ROLE_UNPROMOTED, }, reports.ReportItemSeverity.deprecation(), option_name_for_report="role", ), ] report_processor.report_list( validate.ValidatorAll(validators).validate( validate.values_to_pairs( options, validate.option_value_normalization( {"rsc-role": lambda value: value.capitalize()}), ))) if report_processor.has_errors: raise LibraryError() if "rsc-role" in options: if options["rsc-role"]: options["rsc-role"] = pacemaker.role.get_value_for_cib( options["rsc-role"].capitalize(), tools.are_new_role_names_supported(cib), ) else: del options["rsc-role"] 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), )