def _validate_port_map_list(options_list, id_provider, force_options): allowed_options = [ "id", "port", "internal-port", "range", ] validators = [ validate.value_id("id", "port-map id", id_provider), validate.depends_on_option("internal-port", "port", "port-map", "port-map"), validate.is_required_some_of(["port", "range"], "port-map"), validate.mutually_exclusive(["port", "range"], "port-map"), validate.value_port_number("port"), validate.value_port_number("internal-port"), validate.value_port_range( "range", code_to_allow_extra_values=report_codes.FORCE_OPTIONS, allow_extra_values=force_options), ] report_list = [] for options in options_list: report_list.extend( validate.run_collection_of_option_validators(options, validators) + validate.names_in(allowed_options, options.keys(), "port-map", report_codes.FORCE_OPTIONS, force_options)) return report_list
def test_no_wrap(self): validators = validate.wrap_with_empty_or_valid(self.validators, wrap=False) validators.append(validate.value_port_number("c")) assert_report_item_list_equal( validate.run_collection_of_option_validators( { "a": "", "b": "", "c": "" }, validators), [ fixture.error( report_codes.INVALID_OPTION_VALUE, option_name="a", option_value="", allowed_values=["x", "y", "z"], ), fixture.error( report_codes.INVALID_OPTION_VALUE, option_name="b", option_value="", allowed_values="0..9", ), fixture.error( report_codes.INVALID_OPTION_VALUE, option_name="c", option_value="", allowed_values="a port number (1-65535)", ), ])
def _validate_network_options_update(bundle_el, network_el, options, force_options): report_list = [] inner_primitive = get_inner_resource(bundle_el) if (inner_primitive is not None and not _is_pcmk_remote_acccessible_after_update(network_el, options)): report_list.append( reports.get_problem_creator( report_codes.FORCE_OPTIONS, force_options)(reports.resource_in_bundle_not_accessible, bundle_el.get("id"), inner_primitive.get("id"))) validators = [ # TODO add validators for other keys (ip-range-start - IPv4) validate.value_empty_or_valid( "control-port", validate.value_port_number("control-port"), ), validate.value_empty_or_valid( "host-netmask", _value_host_netmask("host-netmask", force_options), ), ] return (report_list + validate.run_collection_of_option_validators(options, validators) + validate.names_in( # allow to remove options even if they are not allowed _network_options | _options_to_remove(options), options.keys(), "network", report_codes.FORCE_OPTIONS, force_options))
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 test_no_wrap(self): validators = validate.wrap_with_empty_or_valid( self.validators, wrap=False ) validators.append(validate.value_port_number("c")) assert_report_item_list_equal( validate.run_collection_of_option_validators( {"a": "", "b": "", "c": ""}, validators ), [ fixture.error( report_codes.INVALID_OPTION_VALUE, option_name="a", option_value="", allowed_values=["x", "y", "z"], ), fixture.error( report_codes.INVALID_OPTION_VALUE, option_name="b", option_value="", allowed_values="0..9", ), fixture.error( report_codes.INVALID_OPTION_VALUE, option_name="c", option_value="", allowed_values="a port number (1-65535)", ), ] )
def _get_qdevice_model_net_options_validators(node_ids, allow_empty_values=False, force_options=False): allow_extra_values = validate.allow_extra_values( report_codes.FORCE_OPTIONS, force_options) validators = { "connect_timeout": validate.value_integer_in_range("connect_timeout", 1000, 2 * 60 * 1000, **allow_extra_values), "force_ip_version": validate.value_in("force_ip_version", ("0", "4", "6"), **allow_extra_values), "port": validate.value_port_number("port", **allow_extra_values), "tie_breaker": validate.value_in("tie_breaker", ["lowest", "highest"] + node_ids, **allow_extra_values), } if not allow_empty_values: return ([ validate.value_not_empty("host", "a qdevice host address"), _validate_qdevice_net_algorithm(**allow_extra_values) ] + # explicitely convert to a list for python 3 list(validators.values())) return ([ validate.value_not_empty("host", "a qdevice host address"), _validate_qdevice_net_algorithm(**allow_extra_values) ] + [ validate.value_empty_or_valid(option_name, validator) for option_name, validator in validators.items() ])
def _validate_network_options_new(options, force_options): validators = [ # TODO add validators for other keys (ip-range-start - IPv4) validate.value_port_number("control-port"), _value_host_netmask("host-netmask", force_options), ] return (validate.run_collection_of_option_validators(options, validators) + validate.names_in(_network_options, options.keys(), "network", report_codes.FORCE_OPTIONS, force_options))
def test_report_invalid_value(self): assert_report_item_list_equal( validate.value_port_number("key")({ "key": "65536" }), [ (severities.ERROR, report_codes.INVALID_OPTION_VALUE, { "option_name": "key", "option_value": "65536", "allowed_values": "a port number (1-65535)", }, None), ])
def create_link_list_udp(link_list): """ Validate creating udp/udpu link (interface) list options iterable link_list -- list of link options """ if not link_list: # It is not mandatory to set link options. If an empty link list is # provided, everything is fine and we have nothing to validate. return [] allowed_options = [ "bindnetaddr", "broadcast", "mcastaddr", "mcastport", "ttl", ] validators = [ validate.value_ip_address("bindnetaddr"), validate.value_in("broadcast", ("0", "1")), validate.value_ip_address("mcastaddr"), validate.value_port_number("mcastport"), validate.value_integer_in_range("ttl", 0, 255), ] options = link_list[0] report_items = ( validate.run_collection_of_option_validators(options, validators) + validate.names_in(allowed_options, options.keys(), "link") ) # default values taken from `man corosync.conf` if options.get("broadcast", "0") == "1" and "mcastaddr" in options: report_items.append( reports.prerequisite_option_must_be_disabled( "mcastaddr", "broadcast", option_type="link", prerequisite_type="link" ) ) link_count = len(link_list) if link_count > constants.LINKS_UDP_MAX: report_items.append( reports.corosync_too_many_links( link_count, constants.LINKS_UDP_MAX, "udp/udpu" ) ) return report_items
def test_report_invalid_value(self): assert_report_item_list_equal( validate.value_port_number("key")({"key": "65536"}), [ ( severities.ERROR, report_codes.INVALID_OPTION_VALUE, { "option_name": "key", "option_value": "65536", "allowed_values": "a port number (1-65535)", }, None ), ] )
def _validate_network_options_update(network_el, options, force_options): validators = [ # TODO add validators for other keys (ip-range-start - IPv4) validate.value_empty_or_valid( "control-port", validate.value_port_number("control-port"), ), validate.value_empty_or_valid( "host-netmask", _value_host_netmask("host-netmask", force_options), ), ] return (validate.run_collection_of_option_validators(options, validators) + validate.names_in( # allow to remove options even if they are not allowed _network_options | _options_to_remove(options), options.keys(), "network", report_codes.FORCE_OPTIONS, force_options))
def test_empty_report_on_valid_option(self): assert_report_item_list_equal( validate.value_port_number("key")({ "key": "54321" }), [])
def create_link_list_knet(link_list, max_link_number): """ Validate creating knet link (interface) list options iterable link_list -- list of link options integer max_link_number -- highest allowed linknumber """ if not link_list: # It is not mandatory to set link options. If an empty link list is # provided, everything is fine and we have nothing to validate. It is # also possible to set link options for only some of the links. return [] max_link_number = max(0, min(constants.LINKS_KNET_MAX - 1, max_link_number)) max_link_count = max_link_number + 1 allowed_options = [ "ip_version", # It tells knet which IP to prefer. "linknumber", "link_priority", "mcastport", "ping_interval", "ping_precision", "ping_timeout", "pong_count", "transport", ] validators = [ validate.value_in("ip_version", ("ipv4", "ipv6")), validate.value_integer_in_range("linknumber", 0, max_link_number), validate.value_integer_in_range("link_priority", 0, 255), validate.value_port_number("mcastport"), validate.value_nonnegative_integer("ping_interval"), validate.value_nonnegative_integer("ping_precision"), validate.value_nonnegative_integer("ping_timeout"), validate.depends_on_option( "ping_interval", "ping_timeout", option_type="link", prerequisite_type="link" ), validate.depends_on_option( "ping_timeout", "ping_interval", option_type="link", prerequisite_type="link" ), validate.value_nonnegative_integer("pong_count"), validate.value_in("transport", ("sctp", "udp")), ] report_items = [] used_link_number = defaultdict(int) for options in link_list: if "linknumber" in options: used_link_number[options["linknumber"]] += 1 report_items += ( validate.run_collection_of_option_validators(options, validators) + validate.names_in(allowed_options, options.keys(), "link") ) non_unique_linknumbers = [ number for number, count in used_link_number.items() if count > 1 ] if non_unique_linknumbers: report_items.append( reports.corosync_link_number_duplication(non_unique_linknumbers) ) link_count = len(link_list) if link_count > max_link_count: report_items.append( reports.corosync_too_many_links(link_count, max_link_count, "knet") ) return report_items
def test_empty_report_on_valid_option(self): assert_report_item_list_equal( validate.value_port_number("key")({"key": "54321"}), [] )
def create_link_list_knet(link_list, max_allowed_link_count): """ Validate creating knet link (interface) list options iterable link_list -- list of link options integer max_allowed_link_count -- how many links is defined by addresses """ if not link_list: # It is not mandatory to set link options. If an empty link list is # provided, everything is fine and we have nothing to validate. It is # also possible to set link options for only some of the links. return [] allowed_options = [ "linknumber", "link_priority", "mcastport", "ping_interval", "ping_precision", "ping_timeout", "pong_count", "transport", ] validators = [ validate.value_integer_in_range("link_priority", 0, 255), validate.value_port_number("mcastport"), validate.value_nonnegative_integer("ping_interval"), validate.value_nonnegative_integer("ping_precision"), validate.value_nonnegative_integer("ping_timeout"), validate.depends_on_option("ping_interval", "ping_timeout", option_type="link", prerequisite_type="link"), validate.depends_on_option("ping_timeout", "ping_interval", option_type="link", prerequisite_type="link"), validate.value_nonnegative_integer("pong_count"), validate.value_in("transport", ("sctp", "udp")), ] report_items = [] used_link_number = defaultdict(int) for options in link_list: if "linknumber" in options: used_link_number[options["linknumber"]] += 1 if validate.is_integer(options["linknumber"], 0, constants.LINKS_KNET_MAX - 1): if int(options["linknumber"]) >= max_allowed_link_count: # first link is link0, hence >= report_items.append( reports.corosync_link_does_not_exist_cannot_update( options["linknumber"], link_count=max_allowed_link_count)) else: report_items.append( reports.invalid_option_value( "linknumber", options["linknumber"], f"0..{constants.LINKS_KNET_MAX - 1}")) report_items += ( validate.run_collection_of_option_validators(options, validators) + validate.names_in(allowed_options, options.keys(), "link")) non_unique_linknumbers = [ number for number, count in used_link_number.items() if count > 1 ] if non_unique_linknumbers: report_items.append( reports.corosync_link_number_duplication(non_unique_linknumbers)) report_items.extend( _check_link_options_count(len(link_list), max_allowed_link_count)) return report_items