def create_transport_udp(generic_options, compression_options, crypto_options): """ Validate creating udp/udpu transport options dict generic_options -- generic transport options dict compression_options -- compression options dict crypto_options -- crypto options """ # No need to support force: # * values are either an enum or numbers with no range set - nothing to # force # * names are strictly set as we cannot risk the user overwrites some # setting they should not to # * changes to names and values in corosync are very rare allowed_options = [ "ip_version", "netmtu", ] validators = [ validate.value_in("ip_version", constants.IP_VERSION_VALUES), validate.value_positive_integer("netmtu"), ] report_items = (validate.run_collection_of_option_validators( generic_options, validators) + validate.names_in( allowed_options, generic_options.keys(), "udp/udpu transport")) if compression_options: report_items.append( reports.corosync_transport_unsupported_options( "compression", "udp/udpu", ("knet", ))) if crypto_options: report_items.append( reports.corosync_transport_unsupported_options( "crypto", "udp/udpu", ("knet", ))) return report_items
def initialize_block_devices(lib_env, device_list, option_dict): """ Initialize SBD devices in device_list with options_dict. lib_env -- LibraryEnvironment device_list -- list of strings option_dict -- dictionary """ report_item_list = [] if not device_list: report_item_list.append(reports.required_option_is_missing(["device"])) supported_options = sbd.DEVICE_INITIALIZATION_OPTIONS_MAPPING.keys() report_item_list += names_in(supported_options, option_dict.keys()) validator_list = [ value_nonnegative_integer(key) for key in supported_options ] report_item_list += run_collection_of_option_validators( option_dict, validator_list ) lib_env.report_processor.process_list(report_item_list) sbd.initialize_block_devices( lib_env.report_processor, lib_env.cmd_runner(), device_list, option_dict )
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_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.value_nonnegative_integer("SBD_WATCHDOG_TIMEOUT"), validate.value_in( "SBD_TIMEOUT_ACTION", TIMEOUT_ACTION_ALLOWED_VALUE_LIST, code_to_allow_extra_values=report_codes.FORCE_OPTIONS, extra_values_allowed=allow_invalid_option_values, ), ] return (validate.names_in( ALLOWED_SBD_OPTION_LIST, sbd_config.keys(), option_type=None, banned_name_list=UNSUPPORTED_SBD_OPTION_LIST, code_to_allow_extra_names=report_codes.FORCE_OPTIONS, extra_names_allowed=allow_unknown_opts, ) + validate.run_collection_of_option_validators(sbd_config, validators))
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 test_return_error_on_not_allowed_and_banned_names_forced(self): code = "force_code" assert_report_item_list_equal( validate.names_in( ["a", "b"], ["x", "a", "z", "c", "d"], banned_name_list=["x", "y", "z"], code_to_allow_extra_names=code, extra_names_allowed=True, ), [ fixture.warn( report_codes.INVALID_OPTIONS, option_names=["c", "d"], allowed=["a", "b"], option_type="option", allowed_patterns=[], ), fixture.error( report_codes.INVALID_OPTIONS, option_names=["x", "z"], allowed=["a", "b"], option_type="option", allowed_patterns=[], ), ] )
def _qdevice_update_model_net_options(options, node_ids, force_options=False): """ Validate quorum device model options when updating a quorum device dict options -- model options list node_ids -- list of existing node ids bool force_options -- turn forceable errors into warnings """ allowed_options = ( _QDEVICE_NET_REQUIRED_OPTIONS + _QDEVICE_NET_OPTIONAL_OPTIONS ) option_type = "quorum device model" validators = _get_qdevice_model_net_options_validators( node_ids, allow_empty_values=True, force_options=force_options ) return ( validate.run_collection_of_option_validators(options, validators) + validate.names_in( allowed_options, options.keys(), option_type, **validate.allow_extra_names( 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 _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 validate_parameters_create(self, parameters, force=False): # This is just a basic validation checking that required parameters are # set and all set parameters are known to an agent. Missing checks are: # 1. values checks - if a param is an integer, then "abc" is not valid # 2. warnings should be emitted when a deprecated param is set # 3. errors should be emitted when a deprecated parameter and a # parameter obsoleting it are set at the same time # 4. possibly some other checks # All of these have been missing in pcs since ever (ad 1. agents have # never provided enough info for us to do such validations, ad 2. and # 3. there were no deprecated parameters before). The checks should be # implemented in agents themselves, so I'm not adding them now either. report_items = [] # report unknown parameters report_items.extend( validate.names_in( {param["name"] for param in self.get_parameters()}, parameters.keys(), self._agent_type_label, report_codes.FORCE_OPTIONS, force)) # report missing required parameters missing_parameters = self._find_missing_required_parameters(parameters) if missing_parameters: forcible, severity = self._validate_report_forcible_severity(force) report_items.append( reports.required_option_is_missing( sorted(missing_parameters), self._agent_type_label, severity=severity, forceable=forcible, )) return report_items
def _validate_storage_map_list(options_list, id_provider, force_options): allowed_options = [ "id", "options", "source-dir", "source-dir-root", "target-dir", ] source_dir_options = ["source-dir", "source-dir-root"] validators = [ validate.value_id("id", "storage-map id", id_provider), validate.is_required_some_of(source_dir_options, "storage-map"), validate.mutually_exclusive(source_dir_options, "storage-map"), validate.is_required("target-dir", "storage-map"), ] 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(), "storage-map", report_codes.FORCE_OPTIONS, force_options ) ) return report_list
def _validate_container_docker_options_update( docker_el, options, force_options ): validators = [ # image is a mandatory attribute and cannot be removed validate.value_not_empty("image", "image name"), validate.value_empty_or_valid( "masters", validate.value_nonnegative_integer("masters") ), validate.value_empty_or_valid( "replicas", validate.value_positive_integer("replicas") ), validate.value_empty_or_valid( "replicas-per-host", validate.value_positive_integer("replicas-per-host") ), ] return ( validate.run_collection_of_option_validators(options, validators) + validate.names_in( # allow to remove options even if they are not allowed _docker_options | _options_to_remove(options), options.keys(), "container", report_codes.FORCE_OPTIONS, force_options ) )
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.value_nonnegative_integer("SBD_WATCHDOG_TIMEOUT"), validate.value_in( "SBD_TIMEOUT_ACTION", TIMEOUT_ACTION_ALLOWED_VALUE_LIST, code_to_allow_extra_values=report_codes.FORCE_OPTIONS, extra_values_allowed=allow_invalid_option_values, ), ] return ( validate.names_in( ALLOWED_SBD_OPTION_LIST, sbd_config.keys(), option_type=None, banned_name_list=UNSUPPORTED_SBD_OPTION_LIST, code_to_allow_extra_names=report_codes.FORCE_OPTIONS, extra_names_allowed=allow_unknown_opts, ) + validate.run_collection_of_option_validators(sbd_config, validators) )
def test_return_error_on_not_allowed_and_banned_names_forced(self): code = "force_code" assert_report_item_list_equal( validate.names_in( ["a", "b"], ["x", "a", "z", "c", "d"], banned_name_list=["x", "y", "z"], code_to_allow_extra_names=code, extra_names_allowed=True, ), [ fixture.warn( report_codes.INVALID_OPTIONS, option_names=["c", "d"], allowed=["a", "b"], option_type="option", allowed_patterns=[], ), fixture.error( report_codes.INVALID_OPTIONS, option_names=["x", "z"], allowed=["a", "b"], option_type="option", allowed_patterns=[], ), ])
def test_return_empty_report_on_allowed_names(self): assert_report_item_list_equal( validate.names_in( ["a", "b", "c"], ["a", "b"], ), [], )
def create_totem(options): """ Validate creating the "totem" section dict options -- totem options """ # No need to support force: # * values are either bool or numbers with no range set - nothing to force # * names are strictly set as we cannot risk the user overwrites some # setting they should not to # * changes to names and values in corosync are very rare allowed_options = [ "consensus", "downcheck", "fail_recv_const", "heartbeat_failures_allowed", "hold", "join", "max_messages", "max_network_delay", "merge", "miss_count_const", "send_join", "seqno_unchanged_const", "token", "token_coefficient", "token_retransmit", "token_retransmits_before_loss_const", "window_size", ] validators = [ validate.value_nonnegative_integer("consensus"), validate.value_nonnegative_integer("downcheck"), validate.value_nonnegative_integer("fail_recv_const"), validate.value_nonnegative_integer("heartbeat_failures_allowed"), validate.value_nonnegative_integer("hold"), validate.value_nonnegative_integer("join"), validate.value_nonnegative_integer("max_messages"), validate.value_nonnegative_integer("max_network_delay"), validate.value_nonnegative_integer("merge"), validate.value_nonnegative_integer("miss_count_const"), validate.value_nonnegative_integer("send_join"), validate.value_nonnegative_integer("seqno_unchanged_const"), validate.value_nonnegative_integer("token"), validate.value_nonnegative_integer("token_coefficient"), validate.value_nonnegative_integer("token_retransmit"), validate.value_nonnegative_integer( "token_retransmits_before_loss_const" ), validate.value_nonnegative_integer("window_size"), ] report_items = ( validate.run_collection_of_option_validators(options, validators) + validate.names_in(allowed_options, options.keys(), "totem") ) return report_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 _validate_generic_container_options_update(docker_el, options, force_options): validators = [ # image is a mandatory attribute and cannot be removed validate.value_not_empty("image", "image name"), validate.value_empty_or_valid( "masters", validate.value_nonnegative_integer("masters")), validate.value_empty_or_valid( "promoted-max", validate.value_nonnegative_integer("promoted-max")), validate.value_empty_or_valid( "replicas", validate.value_positive_integer("replicas")), validate.value_empty_or_valid( "replicas-per-host", validate.value_positive_integer("replicas-per-host")), ] # CIB does not allow both to be set. Deleting both is not a problem, # though. Deleting one while setting another also works and is further # checked bellow. if not (options.get("masters", "") == "" or options.get("promoted-max", "") == ""): validators.append( validate.mutually_exclusive(["masters", "promoted-max"], "container")) deprecation_reports = [] if options.get("masters"): # If the user wants to delete the masters option, do not report it is # deprecated. They may be removing it because they just found out it is # deprecated. deprecation_reports.append( reports.deprecated_option("masters", ["promoted-max"], "container", severity=ReportItemSeverity.WARNING)) # Do not allow to set masters if promoted-max is set unless promoted-max is # going to be removed now. Do the same check also the other way around. CIB # only allows one of them to be set. if (options.get("masters") and docker_el.get("promoted-max") and options.get("promoted-max") != ""): deprecation_reports.append( reports.prerequisite_option_must_not_be_set( "masters", "promoted-max", "container", "container")) if (options.get("promoted-max") and docker_el.get("masters") and options.get("masters") != ""): deprecation_reports.append( reports.prerequisite_option_must_not_be_set( "promoted-max", "masters", "container", "container")) return (validate.run_collection_of_option_validators(options, validators) + deprecation_reports + validate.names_in( # allow to remove options even if they are not allowed _generic_container_options | _options_to_remove(options), options.keys(), "container", report_codes.FORCE_OPTIONS, force_options))
def test_return_error_with_allowed_patterns(self): assert_report_item_list_equal( validate.names_in(["a", "b", "c"], ["x", "y"], allowed_option_patterns=["pattern"]), [(severities.ERROR, report_codes.INVALID_OPTIONS, { "option_names": ["x", "y"], "allowed": ["a", "b", "c"], "option_type": "option", "allowed_patterns": ["pattern"], }, None)])
def test_return_error_on_not_allowed_names(self): assert_report_item_list_equal( validate.names_in( ["a", "b", "c"], ["x", "y"], ), [(severities.ERROR, report_codes.INVALID_OPTION, { "option_names": ["x", "y"], "allowed": ["a", "b", "c"], "option_type": "option", }, None)])
def validate_parameters_update( self, current_parameters, new_parameters, force=False ): # This is just a basic validation checking that required parameters are # set and all set parameters are known to an agent. Missing checks are: # 1. values checks - if a param is an integer, then "abc" is not valid # 2. warnings should be emitted when a deprecated param is set # 3. errors should be emitted when a deprecated parameter and a # parameter obsoleting it are set at the same time # 4. possibly some other checks # All of these have been missing in pcs since ever (ad 1. agents have # never provided enough info for us to do such validations, ad 2. and # 3. there were no deprecated parameters before). The checks should be # implemented in agents themselves, so I'm not adding them now either. report_items = [] # get resulting set of agent's parameters final_parameters = dict(current_parameters) for name, value in new_parameters.items(): if value: final_parameters[name] = value else: if name in final_parameters: del final_parameters[name] # report unknown parameters report_items.extend( validate.names_in( {param["name"] for param in self.get_parameters()}, # Do not report unknown parameters already set in the CIB. They # have been reported already when the were added to the CIB. set(new_parameters.keys()) - set(current_parameters.keys()), self._agent_type_label, report_codes.FORCE_OPTIONS, force ) ) # report missing or removed required parameters missing_parameters = self._find_missing_required_parameters( final_parameters ) if missing_parameters: forcible, severity = self._validate_report_forcible_severity(force) report_items.append(reports.required_option_is_missing( sorted(missing_parameters), self._agent_type_label, severity=severity, forceable=forcible, )) return report_items
def _validate_container_docker_options_new(options, force_options): validators = [ validate.is_required("image", "container"), validate.value_not_empty("image", "image name"), validate.value_nonnegative_integer("masters"), validate.value_positive_integer("replicas"), validate.value_positive_integer("replicas-per-host"), ] return (validate.run_collection_of_option_validators(options, validators) + validate.names_in(_docker_options, options.keys(), "container", report_codes.FORCE_OPTIONS, force_options))
def __validate_heuristics_noexec_option_names( self, options_nonexec, force_options=False ): return validate.names_in( ("mode", "interval", "sync_timeout", "timeout"), options_nonexec.keys(), "heuristics", report_codes.FORCE_OPTIONS, allow_extra_names=force_options, allowed_option_patterns=["exec_NAME"] )
def test_return_forceable_error_on_not_allowed_names(self): assert_report_item_list_equal( validate.names_in( ["a", "b", "c"], ["x", "y"], option_type="some option", code_to_allow_extra_names="FORCE_CODE", ), [(severities.ERROR, report_codes.INVALID_OPTION, { "option_names": ["x", "y"], "allowed": ["a", "b", "c"], "option_type": "some option", }, "FORCE_CODE")])
def validate_parameters_update(self, current_parameters, new_parameters, force=False): # This is just a basic validation checking that required parameters are # set and all set parameters are known to an agent. Missing checks are: # 1. values checks - if a param is an integer, then "abc" is not valid # 2. warnings should be emitted when a deprecated param is set # 3. errors should be emitted when a deprecated parameter and a # parameter obsoleting it are set at the same time # 4. possibly some other checks # All of these have been missing in pcs since ever (ad 1. agents have # never provided enough info for us to do such validations, ad 2. and # 3. there were no deprecated parameters before). The checks should be # implemented in agents themselves, so I'm not adding them now either. report_items = [] # get resulting set of agent's parameters final_parameters = dict(current_parameters) for name, value in new_parameters.items(): if len(value) < 1: if name in final_parameters: del final_parameters[name] else: final_parameters[name] = value # report unknown parameters report_items.extend( validate.names_in( {param["name"] for param in self.get_parameters()}, # Do not report unknown parameters already set in the CIB. They # have been reported already when the were added to the CIB. set(new_parameters.keys()) - set(current_parameters.keys()), self._agent_type_label, report_codes.FORCE_OPTIONS, force)) # report missing or removed required parameters missing_parameters = self._find_missing_required_parameters( final_parameters) if missing_parameters: forcible, severity = self._validate_report_forcible_severity(force) report_items.append( reports.required_option_is_missing( sorted(missing_parameters), self._agent_type_label, severity=severity, forceable=forcible, )) return report_items
def test_return_error_on_not_allowed_names_without_force_code(self): assert_report_item_list_equal( validate.names_in( ["a", "b", "c"], ["x", "y"], #does now work without code_to_allow_extra_names allow_extra_names=True, ), [(severities.ERROR, report_codes.INVALID_OPTION, { "option_names": ["x", "y"], "allowed": ["a", "b", "c"], "option_type": "option", }, None)])
def test_return_warning_on_not_allowed_names(self): assert_report_item_list_equal( validate.names_in( ["a", "b", "c"], ["x", "y"], option_type="some option", code_to_allow_extra_names="FORCE_CODE", allow_extra_names=True, ), [(severities.WARNING, report_codes.INVALID_OPTION, { "option_names": ["x", "y"], "allowed": ["a", "b", "c"], "option_type": "some option", }, 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_return_error_on_not_allowed_and_banned_names(self): assert_report_item_list_equal( validate.names_in( ["a", "b"], ["x", "a", "z", "c"], banned_name_list=["x", "y", "z"], ), [ fixture.error( report_codes.INVALID_OPTIONS, option_names=["c", "x", "z"], allowed=["a", "b"], option_type="option", allowed_patterns=[], ) ])
def _validate_quorum_options(options, has_qdevice, allow_empty_values): validators = _get_quorum_options_validators(allow_empty_values) report_items = ( validate.run_collection_of_option_validators(options, validators) + validate.names_in(constants.QUORUM_OPTIONS, options.keys(), "quorum")) if has_qdevice: qdevice_incompatible_options = [ name for name in options if name in constants.QUORUM_OPTIONS_INCOMPATIBLE_WITH_QDEVICE ] if qdevice_incompatible_options: report_items.append( reports.corosync_options_incompatible_with_qdevice( qdevice_incompatible_options)) return report_items
def test_return_error_on_not_allowed_and_banned_names(self): assert_report_item_list_equal( validate.names_in( ["a", "b"], ["x", "a", "z", "c"], banned_name_list=["x", "y", "z"], ), [ fixture.error( report_codes.INVALID_OPTIONS, option_names=["c", "x", "z"], allowed=["a", "b"], option_type="option", allowed_patterns=[], ) ] )
def validate_operation(operation, options_validator_list): """ Return a list with reports (ReportItems) about problems inside operation. dict operation contains attributes of operation """ report_list = validate.names_in( ATTRIBUTES, operation.keys(), "resource operation", ) report_list.extend( validate.run_collection_of_option_validators(operation, options_validator_list)) return report_list
def validate_operation(operation, options_validator_list): """ Return a list with reports (ReportItems) about problems inside operation. dict operation contains attributes of operation """ report_list = validate.names_in( ATTRIBUTES, operation.keys(), "resource operation", ) report_list.extend(validate.run_collection_of_option_validators( operation, options_validator_list )) return report_list
def test_return_error_on_not_allowed_names(self): assert_report_item_list_equal( validate.names_in( ["a", "b", "c"], ["x", "y"], ), [ ( severities.ERROR, report_codes.INVALID_OPTION, { "option_names": ["x", "y"], "allowed": ["a", "b", "c"], "option_type": "option", }, 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 _validate_generic_container_options_new(options, force_options): 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 options: deprecation_reports.append( reports.deprecated_option("masters", ["promoted-max"], "container", severity=ReportItemSeverity.WARNING)) return (validate.run_collection_of_option_validators(options, validators) + deprecation_reports + validate.names_in( _generic_container_options, options.keys(), "container", report_codes.FORCE_OPTIONS, force_options))
def test_return_error_with_allowed_patterns(self): assert_report_item_list_equal( validate.names_in( ["a", "b", "c"], ["x", "y"], allowed_option_patterns=["pattern"] ), [ ( severities.ERROR, report_codes.INVALID_OPTIONS, { "option_names": ["x", "y"], "allowed": ["a", "b", "c"], "option_type": "option", "allowed_patterns": ["pattern"], }, None ) ] )
def test_return_forceable_error_on_not_allowed_names(self): assert_report_item_list_equal( validate.names_in( ["a", "b", "c"], ["x", "y"], option_type="some option", code_to_allow_extra_names="FORCE_CODE", ), [ ( severities.ERROR, report_codes.INVALID_OPTION, { "option_names": ["x", "y"], "allowed": ["a", "b", "c"], "option_type": "some option", }, "FORCE_CODE" ) ] )
def test_return_error_on_not_allowed_names_without_force_code(self): assert_report_item_list_equal( validate.names_in( ["a", "b", "c"], ["x", "y"], #does now work without code_to_allow_extra_names allow_extra_names=True, ), [ ( severities.ERROR, report_codes.INVALID_OPTION, { "option_names": ["x", "y"], "allowed": ["a", "b", "c"], "option_type": "option", }, None ) ] )
def test_return_warning_on_not_allowed_names(self): assert_report_item_list_equal( validate.names_in( ["a", "b", "c"], ["x", "y"], option_type="some option", code_to_allow_extra_names="FORCE_CODE", allow_extra_names=True, ), [ ( severities.WARNING, report_codes.INVALID_OPTION, { "option_names": ["x", "y"], "allowed": ["a", "b", "c"], "option_type": "some option", }, None ) ] )