Skip to content

trestle.core.generic_oscal

trestle.core.generic_oscal ¤

Generic classes to support both SSP and DefinedComponents.

Attributes¤

IMPLEMENTED_REQUIREMENTS = 'implemented_requirements' module-attribute ¤

NcNameStr = Annotated[str, StringConstraints(pattern=_NCNAME_PATTERN)] module-attribute ¤

NonWhitespaceStr = Annotated[str, StringConstraints(pattern=_NON_WHITESPACE_PATTERN)] module-attribute ¤

UuidStr = Annotated[str, StringConstraints(pattern=_UUID_PATTERN)] module-attribute ¤

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

Classes¤

GenericByComponent ¤

Bases: TrestleBaseModel


              flowchart TD
              trestle.core.generic_oscal.GenericByComponent[GenericByComponent]
              trestle.core.trestle_base_model.TrestleBaseModel[TrestleBaseModel]

                              trestle.core.trestle_base_model.TrestleBaseModel --> trestle.core.generic_oscal.GenericByComponent
                


              click trestle.core.generic_oscal.GenericByComponent href "" "trestle.core.generic_oscal.GenericByComponent"
              click trestle.core.trestle_base_model.TrestleBaseModel href "" "trestle.core.trestle_base_model.TrestleBaseModel"
            

Generic ByComponent for SSP and DefinedComponent.

Source code in trestle/core/generic_oscal.py
 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
class GenericByComponent(TrestleBaseModel):
    """Generic ByComponent for SSP and DefinedComponent."""

    # only in SSP
    component_uuid: UuidStr = Field(
        ...,
        alias='component_uuid',
        description='A machine-oriented identifier reference to the component that is implemeting a given control.',
        title='Component Universally Unique Identifier Reference',
    )
    uuid: UuidStr = Field(
        ...,
        description='A machine-oriented, globally unique identifier with cross-instance scope that can be used to reference this by-component entry elsewhere in this or other OSCAL instances. The locally defined UUID of the by-component entry can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance). This UUID should be assigned per-subject, which means it should be consistently used to identify the same subject across revisions of the document.',
        title='By-Component Universally Unique Identifier',
    )
    description: str = Field(
        ...,
        description='An implementation statement that describes how a control or a control statement is implemented within the referenced system component.',
        title='Control Implementation Description',
    )
    props: Optional[List[common.Property]] = Field(None)
    links: Optional[List[common.Link]] = Field(None)
    set_parameters: Optional[List[GenericSetParameter]] = Field(None, alias='set-parameters')
    implementation_status: Optional[common.ImplementationStatus] = Field(None, alias='implementation-status')
    # removed export, inherited, satisfied
    responsible_roles: Optional[List[common.ResponsibleRole]] = Field(None, alias='responsible-roles')
    remarks: Optional[str] = None

    @staticmethod
    def generate() -> GenericByComponent:
        """Generate instance of generic ByComponent."""
        uuid = str(uuid4())
        return GenericByComponent(
            component_uuid=const.SAMPLE_UUID_STR,
            uuid=uuid,
            description='',
            set_parameters=None,
            implementation_status=None,
            responsible_roles=None,
        )  # type: ignore[call-arg]

    def as_ssp(self) -> ossp.ByComponent:
        """Convert to ssp format."""
        set_params = []
        for set_param in as_list(self.set_parameters):
            # SetParameter may be a Union type - check for values field
            values = set_param.values if hasattr(set_param, 'values') else None
            new_set_param = ossp.SetParameter(
                **{'param-id': set_param.param_id, 'values': values, 'remarks': set_param.remarks}
            )
            set_params.append(new_set_param)
        set_params = none_if_empty(set_params)
        return ossp.ByComponent(
            **{
                'component-uuid': self.component_uuid,
                'uuid': self.uuid,
                'description': self.description,
                'props': self.props,
                'links': self.links,
                'set-parameters': set_params,
                'implementation-status': self.implementation_status,
                'responsible-roles': self.responsible_roles,
            }
        )
Attributes¤
component_uuid = Field(..., alias='component_uuid', description='A machine-oriented identifier reference to the component that is implemeting a given control.', title='Component Universally Unique Identifier Reference') class-attribute instance-attribute ¤
description = Field(..., description='An implementation statement that describes how a control or a control statement is implemented within the referenced system component.', title='Control Implementation Description') class-attribute instance-attribute ¤
implementation_status = Field(None, alias='implementation-status') class-attribute instance-attribute ¤
props = Field(None) class-attribute instance-attribute ¤
remarks = None class-attribute instance-attribute ¤
responsible_roles = Field(None, alias='responsible-roles') class-attribute instance-attribute ¤
set_parameters = Field(None, alias='set-parameters') class-attribute instance-attribute ¤
uuid = Field(..., description='A machine-oriented, globally unique identifier with cross-instance scope that can be used to reference this by-component entry elsewhere in this or other OSCAL instances. The locally defined UUID of the by-component entry can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance). This UUID should be assigned per-subject, which means it should be consistently used to identify the same subject across revisions of the document.', title='By-Component Universally Unique Identifier') class-attribute instance-attribute ¤
Methods:¤
as_ssp() ¤

Convert to ssp format.

Source code in trestle/core/generic_oscal.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
def as_ssp(self) -> ossp.ByComponent:
    """Convert to ssp format."""
    set_params = []
    for set_param in as_list(self.set_parameters):
        # SetParameter may be a Union type - check for values field
        values = set_param.values if hasattr(set_param, 'values') else None
        new_set_param = ossp.SetParameter(
            **{'param-id': set_param.param_id, 'values': values, 'remarks': set_param.remarks}
        )
        set_params.append(new_set_param)
    set_params = none_if_empty(set_params)
    return ossp.ByComponent(
        **{
            'component-uuid': self.component_uuid,
            'uuid': self.uuid,
            'description': self.description,
            'props': self.props,
            'links': self.links,
            'set-parameters': set_params,
            'implementation-status': self.implementation_status,
            'responsible-roles': self.responsible_roles,
        }
    )
generate() staticmethod ¤

Generate instance of generic ByComponent.

Source code in trestle/core/generic_oscal.py
83
84
85
86
87
88
89
90
91
92
93
94
@staticmethod
def generate() -> GenericByComponent:
    """Generate instance of generic ByComponent."""
    uuid = str(uuid4())
    return GenericByComponent(
        component_uuid=const.SAMPLE_UUID_STR,
        uuid=uuid,
        description='',
        set_parameters=None,
        implementation_status=None,
        responsible_roles=None,
    )  # type: ignore[call-arg]

GenericComponent ¤

Bases: TrestleBaseModel


              flowchart TD
              trestle.core.generic_oscal.GenericComponent[GenericComponent]
              trestle.core.trestle_base_model.TrestleBaseModel[TrestleBaseModel]

                              trestle.core.trestle_base_model.TrestleBaseModel --> trestle.core.generic_oscal.GenericComponent
                


              click trestle.core.generic_oscal.GenericComponent href "" "trestle.core.generic_oscal.GenericComponent"
              click trestle.core.trestle_base_model.TrestleBaseModel href "" "trestle.core.trestle_base_model.TrestleBaseModel"
            

Generic component for SSP SystemComponent and DefinedComponent.

Source code in trestle/core/generic_oscal.py
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
class GenericComponent(TrestleBaseModel):
    """Generic component for SSP SystemComponent and DefinedComponent."""

    uuid: UuidStr = Field(
        ...,
        description='A machine-oriented, globally unique identifier with cross-instance scope that can be used to reference this component elsewhere in this or other OSCAL instances. The locally defined UUID of the component can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance). This UUID should be assigned per-subject, which means it should be consistently used to identify the same subject across revisions of the document.',
        title='Component Identifier',
    )
    type: NonWhitespaceStr = Field(
        ..., description='A category describing the purpose of the component.', title='Component Type'
    )
    title: str = Field(..., description='A human readable name for the component.', title='Component Title')
    description: str = Field(
        ...,
        description='A description of the component, including information about its function.',
        title='Component Description',
    )
    purpose: Optional[str] = Field(
        None, description='A summary of the technological or business purpose of the component.', title='Purpose'
    )
    props: Optional[List[common.Property]] = Field(None)
    links: Optional[List[common.Link]] = Field(None)
    responsible_roles: Optional[List[common.ResponsibleRole]] = Field(None, alias='responsible-roles')
    protocols: Optional[List[common.Protocol]] = Field(None)
    # ssp does not have a list of ci's but it does have one ci
    control_implementations: Optional[List[GenericControlImplementation]] = Field(None, alias='control-implementations')
    remarks: Optional[str] = None
    # ssp has
    status: Optional[common.ImplementationStatus] = None

    def as_defined_component(self) -> comp.DefinedComponent:
        """Convert to DefinedComponent."""
        status = self.status
        class_dict = copy.deepcopy(self.__dict__)
        class_dict.pop('status', None)
        # Clean up empty lists to avoid Pydantic v2 validation errors with min_length constraints
        # Convert empty lists to None for optional fields
        for key in class_dict.keys():
            if isinstance(class_dict[key], list) and len(class_dict[key]) == 0:
                class_dict[key] = None
        def_comp = comp.DefinedComponent(**class_dict)
        ControlInterface.insert_status_in_props(def_comp, status)  # type: ignore[type-var]
        return def_comp

    @classmethod
    def from_defined_component(cls, def_comp: comp.DefinedComponent) -> GenericComponent:
        """Convert defined component to generic."""
        status = ControlInterface.get_status_from_props(def_comp)  # type: ignore[type-var]
        class_dict = copy.deepcopy(def_comp.__dict__)
        # Ensure type is a plain string - Pydantic may store it as a constrained type
        if 'type' in class_dict:
            class_dict['type'] = str(class_dict['type'])
        if 'control_implementations' in class_dict:
            new_cis = []
            for ci in class_dict['control_implementations']:
                new_cis.append(GenericControlImplementation.from_component_ci(ci))
            class_dict['control-implementations'] = new_cis
            class_dict.pop('control_implementations', None)
        class_dict['status'] = status
        return cls(**class_dict)

    def as_system_component(self, status_override: str = '') -> common.SystemComponent:
        """Convert to SystemComponent."""
        class_dict = copy.deepcopy(self.__dict__)
        class_dict.pop('control_implementations', None)
        # Ensure type is a string - Pydantic may store it as a constrained type
        if 'type' in class_dict:
            class_dict['type'] = str(class_dict['type'])
        status_str = self.status.state if self.status else const.STATUS_OPERATIONAL
        status_str = status_override if status_override else status_str
        if status_str not in ['under-development', 'operational', 'disposition', 'other']:
            logger.warning(
                f'SystemComponent status {status_str} not recognized.  Setting to {const.STATUS_OPERATIONAL}'
            )
            status_str = const.STATUS_OPERATIONAL
        class_dict['status'] = common.Status(state=status_str, remarks=self.status.remarks)
        return common.SystemComponent(**class_dict)

    @staticmethod
    def generate() -> GenericComponent:
        """Generate instance of GenericComponent."""
        uuid = str(uuid4())
        status = common.ImplementationStatus(state=const.STATUS_OPERATIONAL)
        return GenericComponent(
            **{
                'uuid': uuid,
                'type': const.REPLACE_ME,
                'title': const.REPLACE_ME,
                'description': const.REPLACE_ME,
                'status': status,
                'purpose': None,
                'props': None,
                'links': None,
                'responsible-roles': None,
                'protocols': None,
                'control-implementations': None,
            }
        )
Attributes¤
control_implementations = Field(None, alias='control-implementations') class-attribute instance-attribute ¤
description = Field(..., description='A description of the component, including information about its function.', title='Component Description') class-attribute instance-attribute ¤
props = Field(None) class-attribute instance-attribute ¤
protocols = Field(None) class-attribute instance-attribute ¤
purpose = Field(None, description='A summary of the technological or business purpose of the component.', title='Purpose') class-attribute instance-attribute ¤
remarks = None class-attribute instance-attribute ¤
responsible_roles = Field(None, alias='responsible-roles') class-attribute instance-attribute ¤
status = None class-attribute instance-attribute ¤
title = Field(..., description='A human readable name for the component.', title='Component Title') class-attribute instance-attribute ¤
type = Field(..., description='A category describing the purpose of the component.', title='Component Type') class-attribute instance-attribute ¤
uuid = Field(..., description='A machine-oriented, globally unique identifier with cross-instance scope that can be used to reference this component elsewhere in this or other OSCAL instances. The locally defined UUID of the component can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance). This UUID should be assigned per-subject, which means it should be consistently used to identify the same subject across revisions of the document.', title='Component Identifier') class-attribute instance-attribute ¤
Methods:¤
as_defined_component() ¤

Convert to DefinedComponent.

Source code in trestle/core/generic_oscal.py
201
202
203
204
205
206
207
208
209
210
211
212
213
def as_defined_component(self) -> comp.DefinedComponent:
    """Convert to DefinedComponent."""
    status = self.status
    class_dict = copy.deepcopy(self.__dict__)
    class_dict.pop('status', None)
    # Clean up empty lists to avoid Pydantic v2 validation errors with min_length constraints
    # Convert empty lists to None for optional fields
    for key in class_dict.keys():
        if isinstance(class_dict[key], list) and len(class_dict[key]) == 0:
            class_dict[key] = None
    def_comp = comp.DefinedComponent(**class_dict)
    ControlInterface.insert_status_in_props(def_comp, status)  # type: ignore[type-var]
    return def_comp
as_system_component(status_override='') ¤

Convert to SystemComponent.

Source code in trestle/core/generic_oscal.py
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
def as_system_component(self, status_override: str = '') -> common.SystemComponent:
    """Convert to SystemComponent."""
    class_dict = copy.deepcopy(self.__dict__)
    class_dict.pop('control_implementations', None)
    # Ensure type is a string - Pydantic may store it as a constrained type
    if 'type' in class_dict:
        class_dict['type'] = str(class_dict['type'])
    status_str = self.status.state if self.status else const.STATUS_OPERATIONAL
    status_str = status_override if status_override else status_str
    if status_str not in ['under-development', 'operational', 'disposition', 'other']:
        logger.warning(
            f'SystemComponent status {status_str} not recognized.  Setting to {const.STATUS_OPERATIONAL}'
        )
        status_str = const.STATUS_OPERATIONAL
    class_dict['status'] = common.Status(state=status_str, remarks=self.status.remarks)
    return common.SystemComponent(**class_dict)
from_defined_component(def_comp) classmethod ¤

Convert defined component to generic.

Source code in trestle/core/generic_oscal.py
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
@classmethod
def from_defined_component(cls, def_comp: comp.DefinedComponent) -> GenericComponent:
    """Convert defined component to generic."""
    status = ControlInterface.get_status_from_props(def_comp)  # type: ignore[type-var]
    class_dict = copy.deepcopy(def_comp.__dict__)
    # Ensure type is a plain string - Pydantic may store it as a constrained type
    if 'type' in class_dict:
        class_dict['type'] = str(class_dict['type'])
    if 'control_implementations' in class_dict:
        new_cis = []
        for ci in class_dict['control_implementations']:
            new_cis.append(GenericControlImplementation.from_component_ci(ci))
        class_dict['control-implementations'] = new_cis
        class_dict.pop('control_implementations', None)
    class_dict['status'] = status
    return cls(**class_dict)
generate() staticmethod ¤

Generate instance of GenericComponent.

Source code in trestle/core/generic_oscal.py
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
@staticmethod
def generate() -> GenericComponent:
    """Generate instance of GenericComponent."""
    uuid = str(uuid4())
    status = common.ImplementationStatus(state=const.STATUS_OPERATIONAL)
    return GenericComponent(
        **{
            'uuid': uuid,
            'type': const.REPLACE_ME,
            'title': const.REPLACE_ME,
            'description': const.REPLACE_ME,
            'status': status,
            'purpose': None,
            'props': None,
            'links': None,
            'responsible-roles': None,
            'protocols': None,
            'control-implementations': None,
        }
    )

GenericControlImplementation ¤

Bases: TrestleBaseModel


              flowchart TD
              trestle.core.generic_oscal.GenericControlImplementation[GenericControlImplementation]
              trestle.core.trestle_base_model.TrestleBaseModel[TrestleBaseModel]

                              trestle.core.trestle_base_model.TrestleBaseModel --> trestle.core.generic_oscal.GenericControlImplementation
                


              click trestle.core.generic_oscal.GenericControlImplementation href "" "trestle.core.generic_oscal.GenericControlImplementation"
              click trestle.core.trestle_base_model.TrestleBaseModel href "" "trestle.core.trestle_base_model.TrestleBaseModel"
            

Generic control implementation for SSP and CompDef.

Source code in trestle/core/generic_oscal.py
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
class GenericControlImplementation(TrestleBaseModel):
    """Generic control implementation for SSP and CompDef."""

    # not in ssp
    uuid: UuidStr = Field(
        ...,
        description='A machine-oriented, globally unique identifier with cross-instance scope that can be used to reference a set of implemented controls elsewhere in this or other OSCAL instances. The locally defined UUID of the control implementation set can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance). This UUID should be assigned per-subject, which means it should be consistently used to identify the same subject across revisions of the document.',
        title='Control Implementation Set Identifier',
    )
    # not in ssp
    source: str = Field(
        ...,
        description='A reference to an OSCAL catalog or profile providing the referenced control or subcontrol definition.',
        title='Source Resource Reference',
    )
    description: str = Field(
        ...,
        description='A description of how the specified set of controls are implemented for the containing component or capability.',
        title='Control Implementation Description',
    )
    # not in ssp
    props: Optional[List[common.Property]] = Field(None)
    # not in ssp
    links: Optional[List[common.Link]] = Field(None)
    set_parameters: Optional[List[GenericSetParameter]] = Field(None, alias='set-parameters')
    implemented_requirements: List[GenericImplementedRequirement] = Field(..., alias='implemented-requirements')

    @staticmethod
    def generate() -> GenericControlImplementation:
        """Generate instance of this class."""
        uuid = str(uuid4())
        imp_reqs = [GenericImplementedRequirement.generate()]
        class_dict = {
            'uuid': uuid,
            'control-id': const.REPLACE_ME,
            'source': const.REPLACE_ME,
            'description': const.REPLACE_ME,
            'implemented-requirements': imp_reqs,
        }
        return GenericControlImplementation(**class_dict)

    @classmethod
    def from_component_ci(cls, control_imp: comp.ControlImplementation) -> GenericControlImplementation:
        """Convert component control imp to generic."""
        class_dict = copy.deepcopy(control_imp.__dict__)
        if IMPLEMENTED_REQUIREMENTS in class_dict:
            new_irs = []
            ir_list = class_dict.get(IMPLEMENTED_REQUIREMENTS, None)
            for ir in as_list(ir_list):
                new_ir = GenericImplementedRequirement.from_comp_def(ir)
                new_irs.append(new_ir)
            class_dict['implemented-requirements'] = none_if_empty(new_irs)
            class_dict.pop(IMPLEMENTED_REQUIREMENTS, None)
            new_sps = []
            sp_list = class_dict.get('set_parameters', None)
            for sp in as_list(sp_list):
                new_sps.append(GenericSetParameter.from_defined_component(sp))
            class_dict['set-parameters'] = none_if_empty(new_sps)
            class_dict.pop('set_parameters', None)

        return cls(**class_dict)

    def as_ssp(self) -> ossp.ControlImplementation:
        """Represent in ssp form."""
        imp_reqs = []
        for imp_req in self.implemented_requirements:
            imp_reqs.append(imp_req.as_ssp())
        class_dict = self.__dict__
        for prop in ['uuid', 'source', 'props', 'links', IMPLEMENTED_REQUIREMENTS]:
            class_dict.pop(prop, None)
        if imp_reqs:
            class_dict['implemented-requirements'] = imp_reqs
            class_dict.pop(IMPLEMENTED_REQUIREMENTS, None)
        return ossp.ControlImplementation(**class_dict)
Attributes¤
description = Field(..., description='A description of how the specified set of controls are implemented for the containing component or capability.', title='Control Implementation Description') class-attribute instance-attribute ¤
implemented_requirements = Field(..., alias='implemented-requirements') class-attribute instance-attribute ¤
props = Field(None) class-attribute instance-attribute ¤
set_parameters = Field(None, alias='set-parameters') class-attribute instance-attribute ¤
source = Field(..., description='A reference to an OSCAL catalog or profile providing the referenced control or subcontrol definition.', title='Source Resource Reference') class-attribute instance-attribute ¤
uuid = Field(..., description='A machine-oriented, globally unique identifier with cross-instance scope that can be used to reference a set of implemented controls elsewhere in this or other OSCAL instances. The locally defined UUID of the control implementation set can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance). This UUID should be assigned per-subject, which means it should be consistently used to identify the same subject across revisions of the document.', title='Control Implementation Set Identifier') class-attribute instance-attribute ¤
Methods:¤
as_ssp() ¤

Represent in ssp form.

Source code in trestle/core/generic_oscal.py
424
425
426
427
428
429
430
431
432
433
434
435
def as_ssp(self) -> ossp.ControlImplementation:
    """Represent in ssp form."""
    imp_reqs = []
    for imp_req in self.implemented_requirements:
        imp_reqs.append(imp_req.as_ssp())
    class_dict = self.__dict__
    for prop in ['uuid', 'source', 'props', 'links', IMPLEMENTED_REQUIREMENTS]:
        class_dict.pop(prop, None)
    if imp_reqs:
        class_dict['implemented-requirements'] = imp_reqs
        class_dict.pop(IMPLEMENTED_REQUIREMENTS, None)
    return ossp.ControlImplementation(**class_dict)
from_component_ci(control_imp) classmethod ¤

Convert component control imp to generic.

Source code in trestle/core/generic_oscal.py
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
@classmethod
def from_component_ci(cls, control_imp: comp.ControlImplementation) -> GenericControlImplementation:
    """Convert component control imp to generic."""
    class_dict = copy.deepcopy(control_imp.__dict__)
    if IMPLEMENTED_REQUIREMENTS in class_dict:
        new_irs = []
        ir_list = class_dict.get(IMPLEMENTED_REQUIREMENTS, None)
        for ir in as_list(ir_list):
            new_ir = GenericImplementedRequirement.from_comp_def(ir)
            new_irs.append(new_ir)
        class_dict['implemented-requirements'] = none_if_empty(new_irs)
        class_dict.pop(IMPLEMENTED_REQUIREMENTS, None)
        new_sps = []
        sp_list = class_dict.get('set_parameters', None)
        for sp in as_list(sp_list):
            new_sps.append(GenericSetParameter.from_defined_component(sp))
        class_dict['set-parameters'] = none_if_empty(new_sps)
        class_dict.pop('set_parameters', None)

    return cls(**class_dict)
generate() staticmethod ¤

Generate instance of this class.

Source code in trestle/core/generic_oscal.py
389
390
391
392
393
394
395
396
397
398
399
400
401
@staticmethod
def generate() -> GenericControlImplementation:
    """Generate instance of this class."""
    uuid = str(uuid4())
    imp_reqs = [GenericImplementedRequirement.generate()]
    class_dict = {
        'uuid': uuid,
        'control-id': const.REPLACE_ME,
        'source': const.REPLACE_ME,
        'description': const.REPLACE_ME,
        'implemented-requirements': imp_reqs,
    }
    return GenericControlImplementation(**class_dict)

GenericImplementedRequirement ¤

Bases: TrestleBaseModel


              flowchart TD
              trestle.core.generic_oscal.GenericImplementedRequirement[GenericImplementedRequirement]
              trestle.core.trestle_base_model.TrestleBaseModel[TrestleBaseModel]

                              trestle.core.trestle_base_model.TrestleBaseModel --> trestle.core.generic_oscal.GenericImplementedRequirement
                


              click trestle.core.generic_oscal.GenericImplementedRequirement href "" "trestle.core.generic_oscal.GenericImplementedRequirement"
              click trestle.core.trestle_base_model.TrestleBaseModel href "" "trestle.core.trestle_base_model.TrestleBaseModel"
            

Generic ImplementedRequirement for SSP and DefinedComponent.

Source code in trestle/core/generic_oscal.py
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
class GenericImplementedRequirement(TrestleBaseModel):
    """Generic ImplementedRequirement for SSP and DefinedComponent."""

    uuid: UuidStr = Field(
        ...,
        description='A machine-oriented, globally unique identifier with cross-instance scope that can be used to reference a specific control implementation elsewhere in this or other OSCAL instances. The locally defined UUID of the control implementation can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance).This UUID should be assigned per-subject, which means it should be consistently used to identify the same subject across revisions of the document.',
        title='Control Implementation Identifier',
    )
    control_id: NcNameStr = Field(
        ...,
        alias='control-id',
        description='A human-oriented identifier reference to a control with a corresponding id value. When referencing an externally defined control, the Control Identifier Reference must be used in the context of the external / imported OSCAL instance (e.g., uri-reference).',
        title='Control Identifier Reference',
    )
    # only compdef has description
    description: str = Field(
        ...,
        description='A description of how the specified control is implemented for the containing component or capability.',
        title='Control Implementation Description',
    )
    props: Optional[List[common.Property]] = Field(None)
    links: Optional[List[common.Link]] = Field(None)
    set_parameters: Optional[List[GenericSetParameter]] = Field(None, alias='set-parameters')
    responsible_roles: Optional[List[common.ResponsibleRole]] = Field(None, alias='responsible-roles')
    statements: Optional[List[GenericStatement]] = Field(None)
    remarks: Optional[str] = None
    # ssp has following
    by_components: Optional[List[GenericByComponent]] = Field(None, alias='by-components')

    @staticmethod
    def generate() -> GenericImplementedRequirement:
        """Generate instance of this class."""
        uuid = str(uuid4())
        class_dict = {'uuid': uuid, 'control-id': const.REPLACE_ME, 'description': ''}
        return GenericImplementedRequirement(**class_dict)

    @classmethod
    def from_comp_def(cls, imp_req: comp.ImplementedRequirement) -> GenericImplementedRequirement:
        """Convert component form of imp req to generic."""
        class_dict = copy.deepcopy(imp_req.__dict__)
        class_dict['control-id'] = class_dict.pop('control_id', None)
        # Convert comp.Statement objects to GenericStatement objects
        if 'statements' in class_dict and class_dict['statements']:
            generic_statements = []
            for stmt in class_dict['statements']:
                # comp.Statement and GenericStatement have the same fields, so we can convert directly
                generic_stmt = GenericStatement(**stmt.__dict__)
                generic_statements.append(generic_stmt)
            class_dict['statements'] = generic_statements
        return cls(**class_dict)

    def as_ssp(self) -> ossp.ImplementedRequirement:
        """Convert to ssp form."""
        class_dict = copy.deepcopy(self.__dict__)
        del class_dict['description']
        new_stat_list = []
        for statement in as_list(self.statements):
            new_stat_list.append(statement.as_ssp())
        if new_stat_list:
            class_dict['statements'] = new_stat_list
        # Clean up empty lists to avoid Pydantic v2 validation errors with min_length constraints
        # Convert empty lists to None for optional fields
        for key in class_dict.keys():
            if isinstance(class_dict[key], list) and len(class_dict[key]) == 0:
                class_dict[key] = None
        return ossp.ImplementedRequirement(**class_dict)
Attributes¤
by_components = Field(None, alias='by-components') class-attribute instance-attribute ¤
control_id = Field(..., alias='control-id', description='A human-oriented identifier reference to a control with a corresponding id value. When referencing an externally defined control, the Control Identifier Reference must be used in the context of the external / imported OSCAL instance (e.g., uri-reference).', title='Control Identifier Reference') class-attribute instance-attribute ¤
description = Field(..., description='A description of how the specified control is implemented for the containing component or capability.', title='Control Implementation Description') class-attribute instance-attribute ¤
props = Field(None) class-attribute instance-attribute ¤
remarks = None class-attribute instance-attribute ¤
responsible_roles = Field(None, alias='responsible-roles') class-attribute instance-attribute ¤
set_parameters = Field(None, alias='set-parameters') class-attribute instance-attribute ¤
statements = Field(None) class-attribute instance-attribute ¤
uuid = Field(..., description='A machine-oriented, globally unique identifier with cross-instance scope that can be used to reference a specific control implementation elsewhere in this or other OSCAL instances. The locally defined UUID of the control implementation can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance).This UUID should be assigned per-subject, which means it should be consistently used to identify the same subject across revisions of the document.', title='Control Implementation Identifier') class-attribute instance-attribute ¤
Methods:¤
as_ssp() ¤

Convert to ssp form.

Source code in trestle/core/generic_oscal.py
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
def as_ssp(self) -> ossp.ImplementedRequirement:
    """Convert to ssp form."""
    class_dict = copy.deepcopy(self.__dict__)
    del class_dict['description']
    new_stat_list = []
    for statement in as_list(self.statements):
        new_stat_list.append(statement.as_ssp())
    if new_stat_list:
        class_dict['statements'] = new_stat_list
    # Clean up empty lists to avoid Pydantic v2 validation errors with min_length constraints
    # Convert empty lists to None for optional fields
    for key in class_dict.keys():
        if isinstance(class_dict[key], list) and len(class_dict[key]) == 0:
            class_dict[key] = None
    return ossp.ImplementedRequirement(**class_dict)
from_comp_def(imp_req) classmethod ¤

Convert component form of imp req to generic.

Source code in trestle/core/generic_oscal.py
330
331
332
333
334
335
336
337
338
339
340
341
342
343
@classmethod
def from_comp_def(cls, imp_req: comp.ImplementedRequirement) -> GenericImplementedRequirement:
    """Convert component form of imp req to generic."""
    class_dict = copy.deepcopy(imp_req.__dict__)
    class_dict['control-id'] = class_dict.pop('control_id', None)
    # Convert comp.Statement objects to GenericStatement objects
    if 'statements' in class_dict and class_dict['statements']:
        generic_statements = []
        for stmt in class_dict['statements']:
            # comp.Statement and GenericStatement have the same fields, so we can convert directly
            generic_stmt = GenericStatement(**stmt.__dict__)
            generic_statements.append(generic_stmt)
        class_dict['statements'] = generic_statements
    return cls(**class_dict)
generate() staticmethod ¤

Generate instance of this class.

Source code in trestle/core/generic_oscal.py
323
324
325
326
327
328
@staticmethod
def generate() -> GenericImplementedRequirement:
    """Generate instance of this class."""
    uuid = str(uuid4())
    class_dict = {'uuid': uuid, 'control-id': const.REPLACE_ME, 'description': ''}
    return GenericImplementedRequirement(**class_dict)

GenericSetParameter ¤

Bases: TrestleBaseModel


              flowchart TD
              trestle.core.generic_oscal.GenericSetParameter[GenericSetParameter]
              trestle.core.trestle_base_model.TrestleBaseModel[TrestleBaseModel]

                              trestle.core.trestle_base_model.TrestleBaseModel --> trestle.core.generic_oscal.GenericSetParameter
                


              click trestle.core.generic_oscal.GenericSetParameter href "" "trestle.core.generic_oscal.GenericSetParameter"
              click trestle.core.trestle_base_model.TrestleBaseModel href "" "trestle.core.trestle_base_model.TrestleBaseModel"
            

Generic SetParameter for SSP and DefinedComponent.

Source code in trestle/core/generic_oscal.py
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
class GenericSetParameter(TrestleBaseModel):
    """Generic SetParameter for SSP and DefinedComponent."""

    param_id: NcNameStr = Field(
        ...,
        alias='param-id',
        description="A human-oriented reference to a parameter within a control, who's catalog has been imported into the current implementation context.",
        title='Parameter ID',
    )
    values: List[str] = Field(...)
    remarks: Optional[str] = None

    @staticmethod
    def from_defined_component(sp: comp.SetParameter) -> GenericSetParameter:
        """Generate generic set parameter from comp_def version."""
        class_dict = {'param-id': sp.param_id, 'values': sp.values, 'remarks': sp.remarks}
        return GenericSetParameter(**class_dict)

    def to_ssp(self) -> ossp.SetParameter:
        """Convert to ssp format."""
        return ossp.SetParameter(**{'param-id': self.param_id, 'values': self.values, 'remarks': self.remarks})
Attributes¤
param_id = Field(..., alias='param-id', description="A human-oriented reference to a parameter within a control, who's catalog has been imported into the current implementation context.", title='Parameter ID') class-attribute instance-attribute ¤
remarks = None class-attribute instance-attribute ¤
values = Field(...) class-attribute instance-attribute ¤
Methods:¤
from_defined_component(sp) staticmethod ¤

Generate generic set parameter from comp_def version.

Source code in trestle/core/generic_oscal.py
283
284
285
286
287
@staticmethod
def from_defined_component(sp: comp.SetParameter) -> GenericSetParameter:
    """Generate generic set parameter from comp_def version."""
    class_dict = {'param-id': sp.param_id, 'values': sp.values, 'remarks': sp.remarks}
    return GenericSetParameter(**class_dict)
to_ssp() ¤

Convert to ssp format.

Source code in trestle/core/generic_oscal.py
289
290
291
def to_ssp(self) -> ossp.SetParameter:
    """Convert to ssp format."""
    return ossp.SetParameter(**{'param-id': self.param_id, 'values': self.values, 'remarks': self.remarks})

GenericStatement ¤

Bases: TrestleBaseModel


              flowchart TD
              trestle.core.generic_oscal.GenericStatement[GenericStatement]
              trestle.core.trestle_base_model.TrestleBaseModel[TrestleBaseModel]

                              trestle.core.trestle_base_model.TrestleBaseModel --> trestle.core.generic_oscal.GenericStatement
                


              click trestle.core.generic_oscal.GenericStatement href "" "trestle.core.generic_oscal.GenericStatement"
              click trestle.core.trestle_base_model.TrestleBaseModel href "" "trestle.core.trestle_base_model.TrestleBaseModel"
            

Generic statement for SSP and DefinedComp.

Source code in trestle/core/generic_oscal.py
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
class GenericStatement(TrestleBaseModel):
    """Generic statement for SSP and DefinedComp."""

    statement_id: NcNameStr = Field(
        ...,
        alias='statement_id',
        description='A human-oriented identifier reference to a control statement.',
        title='Control Statement Reference',
    )
    uuid: UuidStr = Field(
        ...,
        description='A machine-oriented, globally unique identifier with cross-instance scope that can be used to reference this control statement elsewhere in this or other OSCAL instances. The UUID of the control statement in the source OSCAL instance is sufficient to reference the data item locally or globally (e.g., in an imported OSCAL instance).',
        title='Control Statement Reference Universally Unique Identifier',
    )
    # this is not in ssp statement
    description: str = Field(
        ...,
        description='A summary of how the containing control statement is implemented by the component or capability.',
        title='Statement Implementation Description',
    )
    props: Optional[List[common.Property]] = Field(None)
    links: Optional[List[common.Link]] = Field(None)
    responsible_roles: Optional[List[common.ResponsibleRole]] = Field(None, alias='responsible-roles')
    remarks: Optional[str] = None
    # ssp has following
    by_components: Optional[List[GenericByComponent]] = Field(None, alias='by-components')

    def as_ssp(self) -> ossp.Statement:
        """Represent in ssp form."""
        class_dict = copy.deepcopy(self.__dict__)
        class_dict.pop('description', None)
        by_comps = []
        for by_comp in as_list(self.by_components):
            new_by_comp = by_comp.as_ssp()
            by_comps.append(new_by_comp)
        # Convert empty list to None to satisfy Pydantic v2 min_length constraints
        by_comps = none_if_empty(by_comps)
        return ossp.Statement(
            **{
                'statement-id': self.statement_id,
                'uuid': self.uuid,
                'props': self.props,
                'links': self.links,
                'responsible-roles': self.responsible_roles,
                'by-components': by_comps,
                'remarks': self.remarks,
            }
        )
Attributes¤
by_components = Field(None, alias='by-components') class-attribute instance-attribute ¤
description = Field(..., description='A summary of how the containing control statement is implemented by the component or capability.', title='Statement Implementation Description') class-attribute instance-attribute ¤
props = Field(None) class-attribute instance-attribute ¤
remarks = None class-attribute instance-attribute ¤
responsible_roles = Field(None, alias='responsible-roles') class-attribute instance-attribute ¤
statement_id = Field(..., alias='statement_id', description='A human-oriented identifier reference to a control statement.', title='Control Statement Reference') class-attribute instance-attribute ¤
uuid = Field(..., description='A machine-oriented, globally unique identifier with cross-instance scope that can be used to reference this control statement elsewhere in this or other OSCAL instances. The UUID of the control statement in the source OSCAL instance is sufficient to reference the data item locally or globally (e.g., in an imported OSCAL instance).', title='Control Statement Reference Universally Unique Identifier') class-attribute instance-attribute ¤
Methods:¤
as_ssp() ¤

Represent in ssp form.

Source code in trestle/core/generic_oscal.py
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
def as_ssp(self) -> ossp.Statement:
    """Represent in ssp form."""
    class_dict = copy.deepcopy(self.__dict__)
    class_dict.pop('description', None)
    by_comps = []
    for by_comp in as_list(self.by_components):
        new_by_comp = by_comp.as_ssp()
        by_comps.append(new_by_comp)
    # Convert empty list to None to satisfy Pydantic v2 min_length constraints
    by_comps = none_if_empty(by_comps)
    return ossp.Statement(
        **{
            'statement-id': self.statement_id,
            'uuid': self.uuid,
            'props': self.props,
            'links': self.links,
            'responsible-roles': self.responsible_roles,
            'by-components': by_comps,
            'remarks': self.remarks,
        }
    )

Functions:¤

handler: python