Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Trestle release #1399

Merged
merged 11 commits into from
Jun 26, 2023
20 changes: 6 additions & 14 deletions MAINTAINERS.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
Trestle was designed and open sourced by a team based at [IBM Research](https://www.research.ibm.com/) and others around the world. The list includes:

Christopher Butler - [butler54](https://github.com/butler54)

Bruno Marques - [brunomarq](https://github.com/brunomarq)
Alejandro Jose Leiva Palomo [AleJo2995](https://github.com/AleJo2995)

Lenin Mehedy - [leninmehedy](https://github.com/leninmehedy)
Christopher Butler [butler54](https://github.com/butler54)

Simon Metson - [drsm79](https://github.com/drsm79)
Lou Degenaro [degenaro](https://github.com/degenaro)

Frank Suits - [fsuits](https://github.com/fsuits)
Frank Suits [fsuits](https://github.com/fsuits)

Jeff Tan - [jeffdmgit](https://github.com/jeffdmgit)
Jennifer Power [jpower432](https://github.com/jpower432)

Nebula Alam - [aNebula](https://github.com/aNebula)
Manjiree Gadgil [mrgadgil](https://github.com/mrgadgil)

Vikas Agarwal [vikas-agarwal76](https://github.com/vikas-agarwal76)

Lou Degenaro [degenaro](https://github.com/degenaro)

Ekaterina Nikonova [enikonovad](https://github.com/enikonovad)

Alejandro Jose Leiva Palomo [AleJo2995](https://github.com/AleJo2995)
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,16 @@ Compliance trestle is currently stable and is based on NIST OSCAL version 1.0.4,
## Community call

We would like to share development in progress for compliance trestle, coming soon and get feedback from community on what features would they like to see in compliance trestle.\
The community call will happen every 2 week(s) on Tuesday at 10am EST.\
The community call will happen every 2 week(s) on Tuesday at 10.00am EST.\
Meeting information:

```
Compliance Trestle Community Call
Hosted by MANJIREE GADGIL

https://ibm.webex.com/ibm/j.php?MTID=m46740e85f87f290d0848c6941c489b0a
Tuesday, May 16, 2023 10:30 AM | 30 minutes | (UTC-04:00) Eastern Time (US & Canada)
Occurs every 2 week(s) on Tuesday effective 5/16/2023 from 10:30 AM to 11:00 AM, (UTC-04:00) Eastern Time (US & Canada)
https://ibm.webex.com/ibm/j.php?MTID=mcf86d5904761ea884ec248c006fc3b81
Tuesday, May 16, 2023 10:00 AM | 30 minutes | (UTC-04:00) Eastern Time (US & Canada)
Occurs every 2 week(s) on Tuesday effective 5/16/2023 from 10:00 AM to 10:30 AM, (UTC-04:00) Eastern Time (US & Canada)

Join by phone
1-844-531-0958 United States Toll Free
Expand Down
2 changes: 2 additions & 0 deletions docs/api_reference/trestle.tasks.oscal_catalog_to_csv.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
::: trestle.tasks.oscal_catalog_to_csv
handler: python
10 changes: 6 additions & 4 deletions docs/trestle_author.md
Original file line number Diff line number Diff line change
Expand Up @@ -613,15 +613,17 @@ CLI evocation:

> trestle author ssp-filter

The `ssp-filter` sub-command takes a given SSP and filters its contents based on a given profile, list of components, and/or control implementation status.
The `ssp-filter` sub-command takes a given SSP and filters its contents based on a given profile, list of components, control implementation status and/or control origination.

If filtering by profile, the SSP is assumed to contain a superset of controls needed by the profile, and the filter operation generates a new SSP with just the controls needed by that profile. If the profile references a control not in the SSP, the routine fails with an error.

If filtering by components, a colon-delimited list of components should be provided, with `This system` as the default name for the overall required component for the entire system. Case and spaces are ignored in the component names, so the names could be specified as `--components "this system: my component"`. The resulting, filtered ssp will have updated implementated requirements with filtered by_components on each requirement, and filtered by_components on each statement.
If filtering by components, a colon-delimited list of components should be provided, with `This system` as the default name for the overall required component for the entire system. Case and spaces are ignored in the component names, so the names could be specified as `--components "this system: my component"`. The resulting, filtered ssp will have updated implemented requirements with filtered by_components on each requirement, and filtered by_components on each statement.

If filtering by control implementation status, a comma-demilited list of implementation status values should be provided. These values must comply with the OSCAL SSP format references's allowed values, which are as follows: implemented, partial, planned, alternative, and not-applicable.
If filtering by control implementation status, a comma-delimited list of implementation status values should be provided. These values must comply with the OSCAL SSP format references's allowed values, which are as follows: implemented, partial, planned, alternative, and not-applicable.

You may filter by a combination of a profile, list of component names, and implementation statuses.
If filtering by control origination, a comma-delimited list of control origination values should be provided. These values must comply with the OSCAL SSP format references's allowed values for the control origination property, which are as follows: system-specific, inherited, organization, customer-configured, and customer-provided.

You may filter by a combination of a profile, list of component names, implementation statuses, and control origination values.

As with the other related author commands, if an existing destination file already exists, it is not updated if no changes would be made.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1010,13 +1010,13 @@ If you do not specify component-defintions during assembly, the markdown should

<summary>trestle author ssp-filter</summary>

Once you have an SSP in the trestle directory you can filter its contents with a profile, list of components, or list of implementation status values by using the command `trestle author ssp-filter`. The SSP is assumed to contain a superset of the controls needed by the profile if a profile is specified, and the filter operation will generate a new SSP with only those controls needed by the profile. If a list of component names is provided, only the specified components will appear in the system implementation of the ssp. If a list of implementation statuses is provided, controls with implementations including those statuses will appear in the control implementation of the ssp.
Once you have an SSP in the trestle directory you can filter its contents with a profile, list of components, list of implementation statuses, or list control origination values by using the command `trestle author ssp-filter`. The SSP is assumed to contain a superset of the controls needed by the profile if a profile is specified, and the filter operation will generate a new SSP with only those controls needed by the profile. If a list of component names is provided, only the specified components will appear in the system implementation of the ssp. If a list of implementation statuses is provided, controls with implementations including those statuses will appear in the control implementation of the ssp. Similarly, if a list of control origination values is provided, implemented requirements with a control origination property value included in the provided values will appear in the control implementation of the ssp.

The filter command is invoked as:

`trestle author ssp-filter --name my_ssp --profile my_profile --components comp_a:comp_b --implementation-status "planned,partial" --output my_culled_ssp`
`trestle author ssp-filter --name my_ssp --profile my_profile --components comp_a:comp_b --implementation-status "planned,partial" --control-origination "customer-configured" --output my_culled_ssp`

The SSP must be present in the trestle workspace and, if filtering by profile, that profile must also be in the trestle workspace. This command will generate a new SSP in the workspace. If the profile makes reference to a control not in the SSP then the routine will fail with an error message. Similarly, if one of the components is not present in the ssp the routine will also fail. The implementation statuses must be one of the allowed values as defined in the OSCAL SSP JSON format reference. Those include the following: implemented, partial, planned, alternative, and not-applicable. If an invalid value is provided, an error is returned.
The SSP must be present in the trestle workspace and, if filtering by profile, that profile must also be in the trestle workspace. This command will generate a new SSP in the workspace. If the profile makes reference to a control not in the SSP then the routine will fail with an error message. Similarly, if one of the components is not present in the ssp the routine will also fail. The implementation statuses must be one of the allowed values as defined in the OSCAL SSP JSON format reference. Those include the following: implemented, partial, planned, alternative, and not-applicable. If an invalid value is provided, an error is returned. The control origination values also must be one of the allowed values as defined in the OSCAL SSP JSON format reference. Those include the following: system-specific, inherited, customer-configured, customer-provided, and organization. If an invalid value is provided, an error is returned.

</details>

Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ nav:
- csv_to_oscal_cd: api_reference/trestle.tasks.csv_to_oscal_cd.md
- ocp4_cis_profile_to_oscal_catalog: api_reference/trestle.tasks.ocp4_cis_profile_to_oscal_catalog.md
- ocp4_cis_profile_to_oscal_cd: api_reference/trestle.tasks.ocp4_cis_profile_to_oscal_cd.md
- oscal_catalog_to_csv: api_reference/trestle.tasks.oscal_catalog_to_csv.md
- oscal_profile_to_osco_profile: api_reference/trestle.tasks.oscal_profile_to_osco_profile.md
- osco_result_to_oscal_ar: api_reference/trestle.tasks.osco_result_to_oscal_ar.md
- tanium_result_to_oscal_ar: api_reference/trestle.tasks.tanium_result_to_oscal_ar.md
Expand Down
17 changes: 17 additions & 0 deletions tests/data/jinja/profile_to_docs_no_part_prose.md.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Control Page

{{
control_writer.write_control_with_sections(control, profile, group_title,
['statement', 'objective', 'ExpectedEvidence', 'guidance', 'table_of_parameters', 'instructions', 'additional_instructions'],
{'statement':'Statement Header',
'objective':'Control Objective Header',
'guidance':'Implementation Guidance',
'instructions': 'Instructions With Prose',
'additional_instructions': 'Additional Instructions (No Prose)',
'table_of_parameters':'Table of Control Parameters'
},
label_column=True,
add_group_to_title=False
)
| safe
}}
12 changes: 12 additions & 0 deletions tests/data/json/comp_def_b.json
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,14 @@
{
"name": "implementation-status",
"value": "implemented"
},
{
"name": "control-origination",
"value": "system-specific"
},
{
"name": "control-origination",
"value": "customer-configured"
}
],
"responsible-roles": [
Expand Down Expand Up @@ -300,6 +308,10 @@
{
"name": "implementation-status",
"value": "implemented"
},
{
"name": "control-origination",
"value": "system-specific"
}
],
"responsible-roles": [
Expand Down
89 changes: 89 additions & 0 deletions tests/data/json/comp_prof_part_none.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
{
"profile": {
"uuid": "A0000000-0000-4000-8000-000000000014",
"metadata": {
"title": "comp prof aa",
"last-modified": "2021-01-01T00:00:00.000+00:00",
"version": "2021-01-01",
"oscal-version": "1.0.0"
},
"imports": [
{
"href": "trestle://catalogs/simplified_nist_catalog/catalog.json",
"include-controls": [
{
"with-ids": [
"ac-1",
"ac-2",
"ac-2.1",
"ac-3",
"at-1",
"ac-6.7",
"ac-4",
"at-2"
]
}
]
}
],
"merge": {
"as-is": true
},
"modify": {
"alters": [
{
"control-id": "ac-1",
"adds": [
{
"position": "ending",
"parts": [
{
"id": "ac-1_instructions",
"name": "instructions",
"prose": "A set of instructions for executors to follow 1."
},
{
"id": "ac-1_additional_instructions",
"name": "additional_instructions",
"parts": [
{
"id": "ac-1_additional_instructions.a",
"name": "a",
"parts": [
{
"id": "ac-1_additional_instructions.a.some_detail_add_instr_1",
"name": "some_detail_add_instr_1"
},
{
"id": "ac-1_additional_instructions.a.some_detail_add_instr_2",
"name": "some_detail_add_instr_2",
"prose": "More text on how to follow instructions - a2."
}
]
},
{
"id": "ac-1_additional_instructions.b",
"name": "b",
"parts": [
{
"id": "ac-1_additional_instructions.b.some_detail_add_instr_1",
"name": "some_detail_add_instr_1",
"prose": "More text on how to follow instructions - b1"
},
{
"id": "ac-1_additional_instructions.b.some_detail_add_instr_1",
"name": "some_detail_add_instr_2",
"prose": "More text on how to follow instructions - b2"
}
]
}
]
}
]
}
]
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[task.oscal-catalog-to-csv]

input-file = nist-content/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json
output-dir = /tmp
output-name = NIST_SP-800-53_rev5_catalog.by_control.csv
level = control
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[task.oscal-catalog-to-csv]

input-file = nist-content/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json
output-dir = /tmp
output-name = NIST_SP-800-53_rev5_catalog.by_statement.csv
2 changes: 1 addition & 1 deletion tests/trestle/core/commands/author/catalog_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ def test_catalog_duplicate_parts_statement(tmp_trestle_dir: pathlib.Path, monkey
file_utils.insert_text_in_file(md_path, '## Control Statement', control_statement_prose_with_parts)

catalog_assemble = 'trestle author catalog-assemble -o my_catalog -m md_catalog'
test_utils.execute_command_and_assert(catalog_assemble, 1, monkeypatch)
test_utils.execute_command_and_assert(catalog_assemble, 0, monkeypatch)

_, error = capsys.readouterr()
assert 'Duplicate part id ac-2_smt.a' in error
Expand Down
8 changes: 5 additions & 3 deletions tests/trestle/core/commands/author/command_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import pytest

import trestle.cli
from trestle.core.commands.common.return_codes import CmdReturnCodes


def test_governed_docs_cli(tmp_trestle_dir: pathlib.Path, monkeypatch: MonkeyPatch) -> None:
Expand All @@ -32,7 +33,7 @@ def test_governed_docs_cli(tmp_trestle_dir: pathlib.Path, monkeypatch: MonkeyPat
trestle.cli.run()
# FIXME: Needs to be changed once implemented.
assert wrapped_error.type == SystemExit
assert wrapped_error.value.code == 2
assert wrapped_error.value.code == CmdReturnCodes.INCORRECT_ARGS.value


def test_governed_folders_cli(tmp_trestle_dir: pathlib.Path, monkeypatch: MonkeyPatch) -> None:
Expand All @@ -43,7 +44,7 @@ def test_governed_folders_cli(tmp_trestle_dir: pathlib.Path, monkeypatch: Monkey
trestle.cli.run()
# FIXME: Needs to be changed once implemented.
assert wrapped_error.type == SystemExit
assert wrapped_error.value.code == 2
assert wrapped_error.value.code == CmdReturnCodes.INCORRECT_ARGS.value


@pytest.mark.parametrize(
Expand All @@ -52,8 +53,9 @@ def test_governed_folders_cli(tmp_trestle_dir: pathlib.Path, monkeypatch: Monkey
def test_failure_not_trestle(command_string, tmp_path: pathlib.Path, monkeypatch: MonkeyPatch) -> None:
"""Test for failure based on not in trestle directory."""
monkeypatch.setattr(sys, 'argv', command_string.split())
monkeypatch.chdir(tmp_path)
with pytest.raises(SystemExit) as wrapped_error:
trestle.cli.run()
# FIXME: Needs to be changed once implemented.
assert wrapped_error.type == SystemExit
assert wrapped_error.value.code == 5
assert wrapped_error.value.code == CmdReturnCodes.TRESTLE_ROOT_ERROR.value
22 changes: 20 additions & 2 deletions tests/trestle/core/commands/author/jinja_cmd_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@
from trestle.core.markdown.docs_markdown_node import DocsMarkdownNode


def setup_ssp(testdata_dir: pathlib.Path, tmp_trestle_dir: pathlib.Path, monkeypatch: MonkeyPatch):
def setup_ssp(
testdata_dir: pathlib.Path,
tmp_trestle_dir: pathlib.Path,
monkeypatch: MonkeyPatch,
profile_name: str = 'comp_prof'
):
"""Prepare repository for docs generation."""
args, _ = setup_for_ssp(tmp_trestle_dir, 'comp_prof', 'my_ssp')
args, _ = setup_for_ssp(tmp_trestle_dir, profile_name, 'my_ssp')
ssp_cmd = SSPGenerate()
assert ssp_cmd._run(args) == 0

Expand Down Expand Up @@ -151,6 +156,19 @@ def test_jinja_profile_docs(
assert node4.get_node_for_key('## Implementation Guidance')


def test_jinja_profile_docs_no_part_prose(
testdata_dir: pathlib.Path, tmp_trestle_dir: pathlib.Path, monkeypatch: MonkeyPatch
) -> None:
"""Test Jinja Profile to multiple md files output. Test for if part to add does not have prose at all."""
input_template = 'profile_to_docs_no_part_prose.md.jinja'
profile_name = 'comp_prof_part_none'

setup_ssp(testdata_dir, tmp_trestle_dir, monkeypatch, profile_name)

command_import = f'trestle author jinja -i {input_template} -o controls -p {profile_name} --docs-profile'
execute_command_and_assert(command_import, 0, monkeypatch)


def test_jinja_profile_docs_with_group_title(
testdata_dir: pathlib.Path, tmp_trestle_dir: pathlib.Path, monkeypatch: MonkeyPatch
) -> None:
Expand Down
Loading