def _validate_storage_map_list(options_list, id_provider, force_options): kwargs = validate.set_warning(report_codes.FORCE_OPTIONS, force_options) option_type = "storage-map" validators = [ validate.NamesIn(STORAGE_MAP_OPTIONS, option_type=option_type, **kwargs), validate.ValueId( "id", option_name_for_report="storage-map id", id_provider=id_provider, ), validate.IsRequiredSome( ["source-dir", "source-dir-root"], option_type=option_type, ), validate.MutuallyExclusive( ["source-dir", "source-dir-root"], option_type=option_type, ), validate.IsRequiredAll(["target-dir"], option_type=option_type), ] validator_all = validate.ValidatorAll(validators) report_list = [] for options in options_list: report_list.extend(validator_all.validate(options)) return report_list
def test_pair_success(self): id_provider = IdProvider(etree.fromstring("<a><test id='used' /></a>")) assert_report_item_list_equal( validate.ValueId("id", id_provider=id_provider).validate( {"id": validate.ValuePair("correct", "correct")}), [], )
def validate_new( id_provider, bundle_id, container_type, container_options, network_options, port_map, storage_map, force_options=False, ): """ Validate new bundle parameters, return list of report items IdProvider id_provider -- elements' ids generator and uniqueness checker string bundle_id -- id of the bundle string container_type -- bundle container type dict container_options -- container options dict network_options -- network options list of dict port_map -- list of port mapping options list of dict storage_map -- list of storage mapping options bool force_options -- return warnings instead of forceable errors """ return ( validate.ValueId( "id", option_name_for_report="bundle name", # with id_provider it validates that the id is available as well id_provider=id_provider, ).validate({"id": bundle_id}) + _validate_container(container_type, container_options, force_options) + _validate_network_options_new(network_options, force_options) + _validate_port_map_list(port_map, id_provider, force_options) + _validate_storage_map_list(storage_map, id_provider, force_options))
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 _validate_port_map_list(options_list, id_provider, force_options): kwargs = validate.set_warning(report_codes.FORCE_OPTIONS, force_options) option_type = "port-map" validators = [ validate.NamesIn(PORT_MAP_OPTIONS, option_type=option_type, **kwargs), validate.ValueId("id", option_name_for_report="port-map id", id_provider=id_provider), validate.DependsOnOption( ["internal-port"], "port", option_type=option_type, prerequisite_type=option_type, ), validate.IsRequiredSome(["port", "range"], option_type=option_type), validate.MutuallyExclusive(["port", "range"], option_type=option_type), validate.ValuePortNumber("port"), validate.ValuePortNumber("internal-port"), validate.ValuePortRange("range", **kwargs), ] validator_all = validate.ValidatorAll(validators) report_list = [] for options in options_list: report_list.extend(validator_all.validate(options)) return report_list
def test_used_id(self): id_provider = IdProvider(etree.fromstring("<a><test id='used' /></a>")) assert_report_item_list_equal( validate.ValueId("id", id_provider=id_provider).validate( {"id": "used"} ), [fixture.error(report_codes.ID_ALREADY_EXISTS, id="used",),], )
def test_empty_id(self): assert_report_item_list_equal( validate.ValueId("id").validate({"id": ""}), [ fixture.error( report_codes.INVALID_ID_IS_EMPTY, id_description=None, ), ], )
def test_invalid_char(self): assert_report_item_list_equal( validate.ValueId("id").validate({"id": "te#st"}), [ fixture.error( report_codes.INVALID_ID, id="te#st", id_description=None, invalid_character="#", is_first_char=False, ), ])
def validate(self, force_options: bool = False) -> reports.ReportItemList: report_list: reports.ReportItemList = [] # Nvpair dict is intentionally not validated: it may contain any keys # and values. This can change in the future and then we add a # validation. Until then there is really nothing to validate there. # validate nvset options validators = [ validate.NamesIn( ("id", "score"), severity=reports.item.get_severity(reports.codes.FORCE_OPTIONS, force_options), ), # with id_provider it validates that the id is available as well validate.ValueId("id", option_name_for_report="id", id_provider=self._id_provider), validate.ValueScore("score"), ] report_list.extend( validate.ValidatorAll(validators).validate(self._nvset_options)) # parse and validate rule # TODO write and call parsed rule validation and cleanup and tests if self._nvset_rule: try: # Allow flags are set to True always, the parsed rule tree is # checked in the validator instead. That gives us better error # messages, such as "op expression cannot be used in this # context" instead of a universal "parse error". self._nvset_rule_parsed = parse_rule(self._nvset_rule, allow_rsc_expr=True, allow_op_expr=True) report_list.extend( RuleValidator( self._nvset_rule_parsed, allow_rsc_expr=self._allow_rsc_expr, allow_op_expr=self._allow_op_expr, ).get_reports()) except RuleParseError as e: report_list.append( reports.ReportItem.error( reports.messages.RuleExpressionParseError( e.rule_string, e.msg, e.rule_line, e.lineno, e.colno, e.pos, ))) return report_list
def test_invalid_first_char(self): assert_report_item_list_equal( validate.ValueId("id", option_name_for_report="test id").validate( {"id": "0-test"}), [ fixture.error( report_codes.INVALID_ID, id="0-test", id_description="test id", invalid_character="0", is_first_char=True, ), ])
def test_pair_used_id(self): id_provider = IdProvider(etree.fromstring("<a><test id='used' /></a>")) assert_report_item_list_equal( validate.ValueId("id", id_provider=id_provider).validate( {"id": validate.ValuePair("not-used", "used")}), [ fixture.error( report_codes.ID_ALREADY_EXISTS, # TODO: This should be "not-used". However an old # validator is used and it doesn't work with pairs. id="used", ), ])
def test_pair_invalid(self): assert_report_item_list_equal( validate.ValueId("id").validate( {"id": validate.ValuePair("@&#", "")}), [ fixture.error( report_codes.EMPTY_ID, # TODO: This should be "@&#". However an old validator # is used and it doesn't work with pairs. id="", id_description=None, ), ])
def test_pair_invalid(self): assert_report_item_list_equal( validate.ValueId("id").validate( {"id": validate.ValuePair("@&#", "")}), [ fixture.error( reports.codes.INVALID_ID_IS_EMPTY, # TODO: This should be INVALID_ID_BAD_CHAR with value # "@&#". However an old validator is used and it doesn't # work with pairs and therefore the empty string is used. id_description="id", ), ], )
def validate(self, force_options: bool = False) -> reports.ReportItemList: report_list: reports.ReportItemList = [] # Nvpair dict is intentionally not validated: it may contain any keys # and values. This can change in the future and then we add a # validation. Until then there is really nothing to validate there. # validate nvset options validators = [ validate.NamesIn( ("id", "score"), severity=reports.item.get_severity(reports.codes.FORCE, force_options), ), # with id_provider it validates that the id is available as well validate.ValueId("id", option_name_for_report="id", id_provider=self._id_provider), validate.ValueScore("score"), ] report_list.extend( validate.ValidatorAll(validators).validate(self._nvset_options)) # parse and validate rule if self._nvset_rule: try: self._nvset_rule_parsed = parse_rule(self._nvset_rule) report_list.extend( RuleValidator( self._nvset_rule_parsed, allow_rsc_expr=self._allow_rsc_expr, allow_op_expr=self._allow_op_expr, allow_node_attr_expr=self._allow_node_attr_expr, ).get_reports()) except RuleParseError as e: report_list.append( reports.ReportItem.error( reports.messages.RuleExpressionParseError( e.rule_string, e.msg, e.rule_line, e.lineno, e.colno, e.pos, ))) return report_list
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