def _validate_tags_dict(tags): for namespace, ns_tags in tags.items(): TAG_NAMESPACE_VALIDATION(namespace) if ns_tags is None: continue if not isinstance(ns_tags, dict): raise MarshmallowValidationError( "Tags in a namespace must be an object or null.") for key, values in ns_tags.items(): TAG_KEY_VALIDATION(key) if values is None: continue if not isinstance(values, list): raise MarshmallowValidationError( "Tag values must be an array or null.") for value in values: if value is None: continue if not isinstance(value, str): raise MarshmallowValidationError( "Tag value must be a string or null.") TAG_VALUE_VALIDATION(value) return True
def make_host(self, data: Dict[str, Any], **kwargs) -> "Host": name = data["name"] control_name = data["control_name"] # validate name and control_name if name != safe_name(name): raise MarshmallowValidationError( f"Name '{name}' does not appear to be a valid hostname") if control_name and control_name != safe_name(control_name): raise MarshmallowValidationError( f"Control name '{control_name}' does not appear to be valid") # validate pmtr variant if data["pmtr_variant"]: try: PmtrVariant(data["pmtr_variant"]) except ValueError: raise MarshmallowValidationError( f"PMTR variant '{data['pmtr_variant']}' is invalid") # validate control method if (data["control_method"] and data["control_method"] not in config.HOST_CONTROL_CLASS_NAMES): raise MarshmallowValidationError( f"Control method '{data['control_method']}' is invalid") return Host(**data)
def system_profile_is_valid(self, system_profile): try: jsonschema_validate(system_profile, self.system_profile_normalizer.schema) except JsonSchemaValidationError as error: raise MarshmallowValidationError(f"System profile does not conform to schema.\n{error}") from error for dd_i, disk_device in enumerate(system_profile.get("disk_devices", [])): if not check_empty_keys(disk_device.get("options")): raise MarshmallowValidationError(f"Empty key in /system_profile/disk_devices/{dd_i}/options.")
def validate_start_delay(self, value): msg = "start_delay must be an integer or a special argument string" if isinstance(value, str): try: parse_special_arg(value) except ValueError: raise MarshmallowValidationError(msg) elif value is not None and not isinstance(value, int): raise MarshmallowValidationError(msg)
def validate_measure_player_names(self, score: "Score", **kwargs) -> None: # no duplicate measure names measure_names = [x.name for x in score.measures] if len(set(measure_names)) != len(measure_names): raise MarshmallowValidationError("Duplicate measure name(s)") for measure in score.measures: # all players specified in measure also exist in score's list of players for player_name in measure.player_names: if player_name not in score.players: raise MarshmallowValidationError( f"Unrecognized player '{player_name}' in measure" f" '{measure.name}'")
def validate_store_params(self, measure: "Measure"): if measure.store_interim_results and not measure.store_as: raise MarshmallowValidationError( "'store_as' must be specified if 'store_interim_results' is True" ) if measure.store_singleton: if len(measure.player_names) > 1: logger.warning( "'store_singleton' with more than one player will likely cause data" " loss" ) if not measure.store_as: raise MarshmallowValidationError( "'store_as' must be specified if 'store_singleton' is True" )
def validate_tags(self, tags): if isinstance(tags, list): return self._validate_tags_list(tags) elif isinstance(tags, dict): return self._validate_tags_dict(tags) else: raise MarshmallowValidationError("Tags must be either an object or an array, and cannot be null.")
def validate_provider(self, data, **kwargs): provider_type = data.get("provider_type") provider_id = data.get("provider_id") if (provider_type and not provider_id) or (provider_id and not provider_type): raise MarshmallowValidationError("provider_type and provider_id are both required.") if provider_type and provider_type.lower() not in ProviderType.__members__.values(): raise MarshmallowValidationError( f'Unknown Provider Type: "{provider_type}". ' f'Valid provider types are: {", ".join([p.value for p in ProviderType])}.' ) # check for white spaces, tabs, and newline characters only if provider_id and provider_id.isspace(): raise MarshmallowValidationError("Provider id can not be just blank, whitespaces or tabs")
def _get_range_validator(self, vname, range_dict, param_name, param_spec, raw_data): if vname == "range": range_class = contrib_validate.Range elif vname == "date_range": range_class = contrib_validate.DateRange else: raise MarshmallowValidationError( f"{vname} is not an allowed validator.") min_value = range_dict.get("min", None) if min_value is not None: min_oth_param, min_vos = self._resolve_op_value( min_value, param_name, param_spec, raw_data) max_value = range_dict.get("max", None) if max_value is not None: max_oth_param, max_vos = self._resolve_op_value( max_value, param_name, param_spec, raw_data) min_vos = self._sort_by_label_to_extend(min_vos) max_vos = self._sort_by_label_to_extend(max_vos) error_min = f"{param_name}{{labels}} {{input}} < min {{min}} {min_oth_param}{{oth_labels}}" error_max = f"{param_name}{{labels}} {{input}} > max {{max}} {max_oth_param}{{oth_labels}}" return range_class( min_vo=min_vos, max_vo=max_vos, error_min=error_min, error_max=error_max, )
def _get_range_validator(self, vname, range_dict, param_name, dims, param_spec, raw_data): if vname == "range": range_class = contrib_validate.Range elif vname == "date_range": range_class = contrib_validate.DateRange else: raise MarshmallowValidationError( f"{vname} is not an allowed validator.") min_value = range_dict.get("min", None) if min_value is not None: min_value = self._resolve_op_value(min_value, param_name, param_spec, raw_data) max_value = range_dict.get("max", None) if max_value is not None: max_value = self._resolve_op_value(max_value, param_name, param_spec, raw_data) dim_suffix = f" for dimensions {dims}" if dims else "" min_error = ("{param_name} {input} must be greater than " "{min}{dim_suffix}.").format( param_name=param_name, dims=dims, input="{input}", min="{min}", dim_suffix=dim_suffix, ) max_error = ("{param_name} {input} must be less than " "{max}{dim_suffix}.").format( param_name=param_name, dims=dims, input="{input}", max="{max}", dim_suffix=dim_suffix, ) return range_class(min_value, max_value, min_error, max_error)
def validate_tags(self, tags): if isinstance(tags, list): return self._validate_tags_list(tags) elif isinstance(tags, dict): return self._validate_tags_dict(tags) elif tags is None: return True else: raise MarshmallowValidationError("Tags must be either an object, an array or null.")
def _get_range_validator( self, vname, range_dict, param_name, param_spec, raw_data, ndim_restriction=False, validate_schema=True, ): if vname == "range": range_class = contrib.validate.Range elif vname == "date_range": range_class = contrib.validate.DateRange else: raise MarshmallowValidationError( f"{vname} is not an allowed validator.") min_value = range_dict.get("min", None) is_related_param = min_value == "default" or min_value in self.fields if min_value is None or (is_related_param and not validate_schema): min_oth_param, min_vos = None, [] elif is_related_param and validate_schema: min_oth_param, min_vos = self._get_related_value( min_value, param_name, param_spec, raw_data) else: min_oth_param, min_vos = None, [{"value": min_value}] max_value = range_dict.get("max", None) is_related_param = max_value == "default" or max_value in self.fields if max_value is None or (is_related_param and not validate_schema): max_oth_param, max_vos = None, [] elif is_related_param and validate_schema: max_oth_param, max_vos = self._get_related_value( max_value, param_name, param_spec, raw_data) else: max_oth_param, max_vos = None, [{"value": max_value}] self._check_ndim_restriction( param_name, min_oth_param, max_oth_param, ndim_restriction=ndim_restriction, ) min_vos = self._sort_by_label_to_extend(min_vos) max_vos = self._sort_by_label_to_extend(max_vos) error_min = (f"{param_name}{{labels}} {{input}} < min {{min}} " f"{min_oth_param or ''}{{oth_labels}}").strip() error_max = (f"{param_name}{{labels}} {{input}} > max {{max}} " f"{max_oth_param or ''}{{oth_labels}}").strip() return range_class( min_vo=min_vos, max_vo=max_vos, error_min=error_min, error_max=error_max, level=range_dict.get("level"), )
def validate_measure_depends_on(self, score: "Score", **kwargs) -> None: measure_names = [x.name for x in score.measures] bad_deps = [] for measure in score.measures: for dep in measure.depends_on: if dep not in measure_names: bad_deps.append(dep) if len(bad_deps) > 0: raise MarshmallowValidationError( f"Invalid values for depends_on:\n{bad_deps}")
def validate_global(self, data, **kwargs): try: if "schema" in data: with open(config.ENCRYPTION_KEY_PATH, 'rb') as f: temp = fernet_decrypt(f.read(), data['value']) Draft4Validator(data['schema']['schema']).validate(temp) except (SchemaError, JSONSchemaValidationError): raise MarshmallowValidationError( f"Global variable did not validate with provided schema: " f"{data['schema']['schema']}")
def validate_params(self, data, **kwargs): """ Loop over all parameters defined on this class. Validate them using the `self.validate_param`. Errors are stored until all parameters have been validated. Note that all data has been type-validated. These methods only do range validation. """ errors = defaultdict(dict) errors_exist = False for name, specs in data.items(): for i, spec in enumerate(specs): iserrors = self.validate_param(name, spec, data) if iserrors: errors_exist = True errors[name][i] = {"value": iserrors} if errors_exist: raise MarshmallowValidationError(dict(errors))
def validate_params(self, data, **kwargs): """ Loop over all parameters defined on this class. Validate them using the `self.validate_param`. Errors are stored until all parameters have been validated. Note that all data has been type-validated. These methods only do range validation. """ warnings = defaultdict(dict) errors = defaultdict(dict) for name, specs in data.items(): for i, spec in enumerate(specs): _warnings, _errors = self.validate_param(name, spec, data) if _warnings: warnings[name][i] = {"value": _warnings} if _errors: errors[name][i] = {"value": _errors} if warnings and not self.ignore_warnings: errors["warnings"] = warnings if errors: ve = MarshmallowValidationError(dict(errors)) raise ve
def validate_only(self, data): """ Bypass deserialization and just run field validators. This is taken from the marshmallow _do_load function: https://github.com/marshmallow-code/marshmallow/blob/3.5.2/src/marshmallow/schema.py#L807 """ error_store = ErrorStore() # Run field-level validation self._invoke_field_validators(error_store=error_store, data=data, many=None) # Run schema-level validation if self._has_processors(decorators.VALIDATES_SCHEMA): field_errors = bool(error_store.errors) self._invoke_schema_validators( error_store=error_store, pass_many=True, data=data, original_data=data, many=None, partial=None, field_errors=field_errors, ) self._invoke_schema_validators( error_store=error_store, pass_many=False, data=data, original_data=data, many=None, partial=None, field_errors=field_errors, ) errors = error_store.errors if errors: exc = MarshmallowValidationError(errors, data=data, valid_data=data) self.handle_error(exc, data, many=None, partial=None) raise exc return data
def validate_start_params(self, measure: "Measure"): if measure.start_delay is None and measure.depends_on == []: raise MarshmallowValidationError( "Input data must specify one or both of 'start_delay' and 'depends_on'" )
def validate_global_template(self, data, **kwargs): try: Draft4Validator.check_schema(data["schema"]) except (SchemaError, JSONSchemaValidationError) as e: raise MarshmallowValidationError(str(e))
def validate_python_ver(self, value): if value is not None and value not in config.SUPPORTED_PYTHON_VERSIONS: raise MarshmallowValidationError( f"Unsupported python version '{value}'")
def validate_control_method(self, value): if value is not None and value not in config.HOST_CONTROL_CLASS_NAMES: raise MarshmallowValidationError( f"Unrecognized control method '{value}'")
def has_timezone_info(self, timestamp): if timestamp.tzinfo is None: raise MarshmallowValidationError("Timestamp must contain timezone info")
def just_one(self, data, **kwargs): if len(data.keys()) > 1: raise MarshmallowValidationError( f"Only one condition may be specified for the 'is' field. " f"You specified {len(data.keys())}.")
def _get_when_validator( self, vname, when_dict, param_name, param_spec, raw_data, ndim_restriction=False, ): when_param = when_dict["param"] if (when_param not in self.context["spec"]._data.keys() and when_param != "default"): raise MarshmallowValidationError( f"'{when_param}' is not a specified parameter.") oth_param, when_vos = self._resolve_op_value(when_param, param_name, param_spec, raw_data) then_validators = [] for vname, vdata in when_dict["then"].items(): then_validators.append( getattr(self, self.WRAPPER_MAP[vname])( vname, vdata, param_name, param_spec, raw_data, ndim_restriction=True, )) otherwise_validators = [] for vname, vdata in when_dict["otherwise"].items(): otherwise_validators.append( getattr(self, self.WRAPPER_MAP[vname])( vname, vdata, param_name, param_spec, raw_data, ndim_restriction=True, )) _type = self.context["spec"]._data[oth_param]["type"] number_dims = self.context["spec"]._data[oth_param]["number_dims"] error_then = ( f"When {oth_param}{{when_labels}}{{ix}} is {{is_val}}, " f"{param_name}{{labels}}{{ix}} value is invalid: {{submsg}}") error_otherwise = ( f"When {oth_param}{{when_labels}}{{ix}} is not {{is_val}}, " f"{param_name}{{labels}}{{ix}} value is invalid: {{submsg}}") return contrib.validate.When( when_dict["is"], when_vos, then_validators, otherwise_validators, error_then, error_otherwise, _type, number_dims, )
def _must_be_less_than_90_degrees(value: Decimal) -> None: if abs(value) > 90: raise MarshmallowValidationError("Value must be less than 90 degrees.")
def _must_be_positive(value: int) -> None: if value < 0: raise MarshmallowValidationError("User id must be greater than 0.")
def _must_not_be_empty(value: str) -> None: if not value.strip(): raise MarshmallowValidationError("Must not be empty")
def __call__(self, value): if value.strip() == '': raise MarshmallowValidationError(message='Must not be empty.')
def cant_depend_on_yourself(self, measure: "Measure"): for depname in measure.depends_on: if depname == measure.name: raise MarshmallowValidationError("You cannot depend on yourself")
def validate_task_name(self, value): attr, msg = get_attr(value) if not attr: raise MarshmallowValidationError(msg)