Skip to content

rule_parameters_validator

trestle.core.rule_parameters_validator ¤

Validate by confirming rule parameter values are consistent.

Attributes¤

logger = logging.getLogger(__name__) module-attribute ¤

Classes¤

RuleParametersValidator ¤

Bases: Validator

Validator to confirm all rule parameter values are consistent.

Source code in trestle/core/rule_parameters_validator.py
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
class RuleParametersValidator(Validator):
    """Validator to confirm all rule parameter values are consistent."""

    def __init__(self) -> None:
        """Initialize rule param values dictionary."""
        self._rule_param_values_dict: Dict[str, Any] = {}

    def _add_imp_req_rule_params_to_dict(
        self,
        imp_requirement: ImplementedRequirement,
        cat_int: CatalogInterface,
    ) -> None:
        """
        Iterate all by components in an object and add the rule shared parameter values to list.

        args:
            imp_requirement: Current implemented requirement.
            cat_int: Instance of catalog interface with controls catalog loaded.
        """
        for by_component in as_list(imp_requirement.by_components):
            # adds rule param values present in set parameters for current imp req
            self._add_rule_params(imp_requirement, imp_requirement.control_id, cat_int, by_component.component_uuid)
            # adds rule param values present in set parameters for current by_component in by_components list
            # in the current implemented requirement
            self._add_rule_params(by_component, imp_requirement.control_id, cat_int, by_component.component_uuid)
            for statement in as_list(imp_requirement.statements):
                # iterates by each by component inclded at each statemtent set for current imp req
                for by_comp in as_list(statement.by_components):
                    # adds rule param values present in set parameters for current by_component in by_components list
                    # of current statement in current implemented requirement
                    self._add_rule_params(by_comp, imp_requirement.control_id, cat_int, by_comp.component_uuid)

    def _add_rule_params(
        self, item: TypeWithSetParams, control_id: str, cat_int: CatalogInterface, comp_uuid: str = ''
    ) -> None:
        """
        Add a rule shared parameter to the rule shared parameters list.

        args:
            item: Generic item to iterate over parameters.
            control_id: Current control id.
            cat_int: Instance of catalog interface with controls catalog loaded.
            comp_uuid: Component uuid to save.
        """
        for set_param in as_list(item.set_parameters):
            # validates if current param_id is or not associated with a control so we can assume it´s a rule param
            control = cat_int.get_control_by_param_id(set_param.param_id)
            if not control:
                deep_set(self._rule_param_values_dict, [set_param.param_id, comp_uuid, control_id], set_param.values)

    def model_is_valid(
        self, model: TopLevelOscalModel, quiet: bool, trestle_root: Optional[pathlib.Path] = None
    ) -> bool:
        """
        Test if the model is valid.

        args:
            model: A top level OSCAL model.
            quiet: Don't report msgs unless invalid.
            trestle_root: Trestle root path.

        returns:
            True (valid) if the model's rule parameter values are the same across controls.
        """
        # verify if model type is either an SSP of a Component Definition
        if not isinstance(model, SystemSecurityPlan):
            return True

        if not model.import_profile.href:
            logger.info(f'INVALID: Model {model.metadata.title} has no referenced profile')
            return False
        profile_catalog = ProfileResolver().get_resolved_profile_catalog(trestle_root, model.import_profile.href)
        catalog_interface = CatalogInterface(profile_catalog)
        # iterate by each implemented requirement defined
        for imp_req in model.control_implementation.implemented_requirements:
            # adds rule param values to dict by implemented requirement basis
            self._add_imp_req_rule_params_to_dict(imp_req, catalog_interface)
        if self._rule_param_values_dict:
            # compare all values in shared paramerets by component basis
            for shared_param, values_dict in self._rule_param_values_dict.items():
                for comp_name, value_dict in values_dict.items():
                    expected_value = next(iter(value_dict.values()))
                    if not all(value == expected_value for value in value_dict.values()):
                        logger.error(
                            f'Rule parameter values for param: {shared_param} in '
                            f' {comp_name} are not consistent with '
                            'other values provided across controls. Invalid model'
                        )
                        return False
        return True
Functions¤
__init__() ¤

Initialize rule param values dictionary.

Source code in trestle/core/rule_parameters_validator.py
35
36
37
def __init__(self) -> None:
    """Initialize rule param values dictionary."""
    self._rule_param_values_dict: Dict[str, Any] = {}
model_is_valid(model, quiet, trestle_root=None) ¤

Test if the model is valid.

Parameters:

Name Type Description Default
model TopLevelOscalModel

A top level OSCAL model.

required
quiet bool

Don't report msgs unless invalid.

required
trestle_root Optional[Path]

Trestle root path.

None

Returns:

Type Description
bool

True (valid) if the model's rule parameter values are the same across controls.

Source code in trestle/core/rule_parameters_validator.py
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
def model_is_valid(
    self, model: TopLevelOscalModel, quiet: bool, trestle_root: Optional[pathlib.Path] = None
) -> bool:
    """
    Test if the model is valid.

    args:
        model: A top level OSCAL model.
        quiet: Don't report msgs unless invalid.
        trestle_root: Trestle root path.

    returns:
        True (valid) if the model's rule parameter values are the same across controls.
    """
    # verify if model type is either an SSP of a Component Definition
    if not isinstance(model, SystemSecurityPlan):
        return True

    if not model.import_profile.href:
        logger.info(f'INVALID: Model {model.metadata.title} has no referenced profile')
        return False
    profile_catalog = ProfileResolver().get_resolved_profile_catalog(trestle_root, model.import_profile.href)
    catalog_interface = CatalogInterface(profile_catalog)
    # iterate by each implemented requirement defined
    for imp_req in model.control_implementation.implemented_requirements:
        # adds rule param values to dict by implemented requirement basis
        self._add_imp_req_rule_params_to_dict(imp_req, catalog_interface)
    if self._rule_param_values_dict:
        # compare all values in shared paramerets by component basis
        for shared_param, values_dict in self._rule_param_values_dict.items():
            for comp_name, value_dict in values_dict.items():
                expected_value = next(iter(value_dict.values()))
                if not all(value == expected_value for value in value_dict.values()):
                    logger.error(
                        f'Rule parameter values for param: {shared_param} in '
                        f' {comp_name} are not consistent with '
                        'other values provided across controls. Invalid model'
                    )
                    return False
    return True

Functions¤

handler: python