validator
trestle.core.validator
¤
Base class for all validators.
logger
¤
Classes¤
Validator (ABC)
¤
Validator base class.
Source code in trestle/core/validator.py
class Validator(ABC):
"""Validator base class."""
def error_msg(self) -> Optional[str]:
"""Error message used to describe this validator."""
# subclasses can override as needed
return self.__doc__
@abstractmethod
def model_is_valid(
self, model: TopLevelOscalModel, quiet: bool, trestle_root: Optional[pathlib.Path] = None
) -> bool:
"""
Validate the model.
args:
model: An Oscal model that can be passed to the validator.
quiet: Don't report msgs unless invalid.
returns:
Whether or not the model passed this validation test.
"""
def validate(self, args: argparse.Namespace) -> int:
"""Perform the validation according to user options."""
trestle_root = args.trestle_root # trestle root is set via command line in args. Default is cwd.
# validate by type - all of type or just specified by name
if args.type:
models = []
if args.name:
models = [args.name]
else:
models = ModelUtils.get_models_of_type(args.type, trestle_root)
models_path = trestle_root / ModelUtils.model_type_to_model_dir(args.type)
for m in models:
model_path = models_path / m
try:
_, _, model = ModelUtils.load_distributed(model_path, trestle_root)
except TrestleError as e:
logger.warning(f'File load error {e}')
return CmdReturnCodes.OSCAL_VALIDATION_ERROR.value
if not self.model_is_valid(model, args.quiet, trestle_root): # type: ignore
logger.info(f'INVALID: Model {model_path} did not pass the {self.error_msg()}')
return CmdReturnCodes.OSCAL_VALIDATION_ERROR.value
if not args.quiet:
logger.info(f'VALID: Model {model_path} passed the {self.error_msg()}')
return CmdReturnCodes.SUCCESS.value
# validate all
if args.all:
model_tups = ModelUtils.get_all_models(trestle_root)
for mt in model_tups:
model_dir = trestle_root / ModelUtils.model_type_to_model_dir(mt[0]) / mt[1]
extension_type = trestle.common.file_utils.get_contextual_file_type(model_dir)
model_path = model_dir / f'{mt[0]}{FileContentType.to_file_extension(extension_type)}'
_, _, model = ModelUtils.load_distributed(model_path, trestle_root)
if not self.model_is_valid(model, args.quiet, trestle_root): # type: ignore
logger.info(f'INVALID: Model {model_path} did not pass the {self.error_msg()}')
return CmdReturnCodes.OSCAL_VALIDATION_ERROR.value
if not args.quiet:
logger.info(f'VALID: Model {model_path} passed the {self.error_msg()}')
return CmdReturnCodes.SUCCESS.value
# validate file
if args.file:
file_path = trestle_root / args.file
_, _, model = ModelUtils.load_distributed(file_path, trestle_root)
if not self.model_is_valid(model, args.quiet, trestle_root): # type: ignore
logger.info(f'INVALID: Model {file_path} did not pass the {self.error_msg()}')
return CmdReturnCodes.OSCAL_VALIDATION_ERROR.value
if not args.quiet:
logger.info(f'VALID: Model {file_path} passed the {self.error_msg()}')
return CmdReturnCodes.SUCCESS.value
Methods¤
error_msg(self)
¤
Error message used to describe this validator.
Source code in trestle/core/validator.py
def error_msg(self) -> Optional[str]:
"""Error message used to describe this validator."""
# subclasses can override as needed
return self.__doc__
model_is_valid(self, model, quiet, trestle_root=None)
¤
Validate the model.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
model |
~TopLevelOscalModel |
An Oscal model that can be passed to the validator. |
required |
quiet |
bool |
Don't report msgs unless invalid. |
required |
Returns:
Type | Description |
---|---|
bool |
Whether or not the model passed this validation test. |
Source code in trestle/core/validator.py
@abstractmethod
def model_is_valid(
self, model: TopLevelOscalModel, quiet: bool, trestle_root: Optional[pathlib.Path] = None
) -> bool:
"""
Validate the model.
args:
model: An Oscal model that can be passed to the validator.
quiet: Don't report msgs unless invalid.
returns:
Whether or not the model passed this validation test.
"""
validate(self, args)
¤
Perform the validation according to user options.
Source code in trestle/core/validator.py
def validate(self, args: argparse.Namespace) -> int:
"""Perform the validation according to user options."""
trestle_root = args.trestle_root # trestle root is set via command line in args. Default is cwd.
# validate by type - all of type or just specified by name
if args.type:
models = []
if args.name:
models = [args.name]
else:
models = ModelUtils.get_models_of_type(args.type, trestle_root)
models_path = trestle_root / ModelUtils.model_type_to_model_dir(args.type)
for m in models:
model_path = models_path / m
try:
_, _, model = ModelUtils.load_distributed(model_path, trestle_root)
except TrestleError as e:
logger.warning(f'File load error {e}')
return CmdReturnCodes.OSCAL_VALIDATION_ERROR.value
if not self.model_is_valid(model, args.quiet, trestle_root): # type: ignore
logger.info(f'INVALID: Model {model_path} did not pass the {self.error_msg()}')
return CmdReturnCodes.OSCAL_VALIDATION_ERROR.value
if not args.quiet:
logger.info(f'VALID: Model {model_path} passed the {self.error_msg()}')
return CmdReturnCodes.SUCCESS.value
# validate all
if args.all:
model_tups = ModelUtils.get_all_models(trestle_root)
for mt in model_tups:
model_dir = trestle_root / ModelUtils.model_type_to_model_dir(mt[0]) / mt[1]
extension_type = trestle.common.file_utils.get_contextual_file_type(model_dir)
model_path = model_dir / f'{mt[0]}{FileContentType.to_file_extension(extension_type)}'
_, _, model = ModelUtils.load_distributed(model_path, trestle_root)
if not self.model_is_valid(model, args.quiet, trestle_root): # type: ignore
logger.info(f'INVALID: Model {model_path} did not pass the {self.error_msg()}')
return CmdReturnCodes.OSCAL_VALIDATION_ERROR.value
if not args.quiet:
logger.info(f'VALID: Model {model_path} passed the {self.error_msg()}')
return CmdReturnCodes.SUCCESS.value
# validate file
if args.file:
file_path = trestle_root / args.file
_, _, model = ModelUtils.load_distributed(file_path, trestle_root)
if not self.model_is_valid(model, args.quiet, trestle_root): # type: ignore
logger.info(f'INVALID: Model {file_path} did not pass the {self.error_msg()}')
return CmdReturnCodes.OSCAL_VALIDATION_ERROR.value
if not args.quiet:
logger.info(f'VALID: Model {file_path} passed the {self.error_msg()}')
return CmdReturnCodes.SUCCESS.value
handler: python