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

feat: add parameter value origin field to parameters #1470

Merged
merged 27 commits into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f9aca20
feat: add parameter value origin field to parameters
AleJo2995 Oct 19, 2023
2fccfbe
Merge branch 'develop' into fix/record-aditional-info
AleJo2995 Oct 19, 2023
8014121
Merge branch 'develop' into fix/record-aditional-info
AleJo2995 Oct 25, 2023
94ea07f
fix: remove wrong added field from oscal model
AleJo2995 Oct 31, 2023
2d51ba9
Merge branch 'develop' into fix/record-aditional-info
AleJo2995 Nov 10, 2023
015f2a6
fix: add param_value_origin to props and add validations
AleJo2995 Nov 10, 2023
338ad07
Merge branch 'fix/record-aditional-info' of https://github.com/IBM/co…
AleJo2995 Nov 10, 2023
4d3e5b1
Merge branch 'develop' into fix/record-aditional-info
AleJo2995 Nov 14, 2023
2e9d8ba
fix: correct ci
AleJo2995 Nov 14, 2023
6a6bc7c
Merge branch 'develop' into fix/record-aditional-info
AleJo2995 Nov 16, 2023
81bf9da
fix: correct param value origin cycle
AleJo2995 Nov 30, 2023
4fa3f9b
Merge branch 'fix/record-aditional-info' of https://github.com/IBM/co…
AleJo2995 Nov 30, 2023
284bd7c
fix: correct profile-param-value-origin flow
AleJo2995 Dec 5, 2023
a2cffce
fix: adding final corrections and test for inherited param-value-origin
AleJo2995 Dec 5, 2023
52c8920
fix: correct formating
AleJo2995 Dec 5, 2023
de1c86c
Merge branch 'develop' into fix/record-aditional-info
AleJo2995 Dec 5, 2023
1c984a2
fix: add step to ignore param-value-origin if no replacement was done…
AleJo2995 Dec 7, 2023
4adce20
Merge branch 'fix/record-aditional-info' of https://github.com/IBM/co…
AleJo2995 Dec 7, 2023
c2d9574
fix: correct code format
AleJo2995 Dec 7, 2023
fa0c238
Merge branch 'develop' into fix/record-aditional-info
AleJo2995 Dec 11, 2023
f628c69
fix: correct tests
AleJo2995 Dec 18, 2023
0e62504
Merge branch 'fix/record-aditional-info' of https://github.com/IBM/co…
AleJo2995 Dec 18, 2023
ef8ce5c
fix: use replace me placeholder instead of literal text
AleJo2995 Dec 18, 2023
56bbd8a
Merge branch 'develop' into fix/record-aditional-info
AleJo2995 Dec 19, 2023
928c7ba
Merge branch 'develop' into fix/record-aditional-info
AleJo2995 Dec 20, 2023
8cfc8de
fix: use replace me tag in default value for param-value-origin
AleJo2995 Dec 21, 2023
adde885
fix: correct code format
AleJo2995 Dec 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions tests/trestle/core/commands/author/profile_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1300,3 +1300,63 @@ def test_profile_generate_assesment_objectives(tmp_trestle_dir: pathlib.Path, mo
monkeypatch.setattr(sys, 'argv', test_args)

assert Trestle().run() == 0


def test_profile_generate_assemble_param_value_origin(tmp_trestle_dir: pathlib.Path, monkeypatch: MonkeyPatch) -> None:
"""Test the profile markdown generator."""
_, assembled_prof_dir, _, markdown_path = setup_profile_generate(tmp_trestle_dir, 'simple_test_profile.json')
yaml_header_path = test_utils.YAML_TEST_DATA_PATH / 'good_simple.yaml'
ac_path = markdown_path / 'ac'

# convert resolved profile catalog to markdown then assemble it after adding an item to a control
# generate, edit, assemble
test_args = f'trestle author profile-generate -n {prof_name} -o {md_name} -rs NeededExtra'.split( # noqa E501
)
test_args.extend(['-y', str(yaml_header_path)])
test_args.extend(['-s', all_sections_str])
monkeypatch.setattr(sys, 'argv', test_args)

assert Trestle().run() == 0

fc = test_utils.FileChecker(ac_path)

assert Trestle().run() == 0

assert fc.files_unchanged()

md_path = markdown_path / 'ac' / 'ac-1.md'
assert md_path.exists()
md_api = MarkdownAPI()
header, tree = md_api.processor.process_markdown(md_path)

assert header
header[const.SET_PARAMS_TAG]['ac-1_prm_1'][const.PARAM_VALUE_ORIGIN] = 'coming from xyz corporate policy'

md_api.write_markdown_with_header(md_path, header, tree.content.raw_text)

# assemble based on set_parameters_flag
test_args = f'trestle author profile-assemble -n {prof_name} -m {md_name} -o {assembled_prof_name}'.split()
test_args.append('-sp')
assembled_prof_dir.mkdir()
monkeypatch.setattr(sys, 'argv', test_args)
assert Trestle().run() == 0

profile, _ = ModelUtils.load_model_for_class(tmp_trestle_dir, 'my_assembled_prof',
prof.Profile, FileContentType.JSON)

# grabs first parameter in line and test out the value
assert profile.modify.set_parameters[0].props[1].value == 'coming from xyz corporate policy'

profile.modify.set_parameters[0].props[1].value = 'this is a change test'

ModelUtils.save_top_level_model(profile, tmp_trestle_dir, 'my_assembled_prof', FileContentType.JSON)

# convert resolved profile catalog to markdown then assemble it after adding an item to a control
# generate, edit, assemble
test_args = f'trestle author profile-generate -n {assembled_prof_name} -o {md_name} -rs NeededExtra --force-overwrite'.split( # noqa E501
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test includes overwrite of the profile at the end to proof that the markdown gets modified after a profile json is modified as well for param_value_origin prop

)
test_args.extend(['-y', str(yaml_header_path)])
test_args.extend(['-s', all_sections_str])
monkeypatch.setattr(sys, 'argv', test_args)

assert Trestle().run() == 0
2 changes: 2 additions & 0 deletions trestle/common/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,8 @@

GUIDELINES = 'guidelines'

PARAM_VALUE_ORIGIN = 'param-value-origin'

LABEL = 'label'

SECTIONS_TAG = TRESTLE_TAG + 'sections'
Expand Down
10 changes: 10 additions & 0 deletions trestle/common/model_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,16 @@ def dict_to_parameter(param_dict: Dict[str, Any]) -> common.Parameter:
if const.AGGREGATES in param_dict:
# removing aggregates as this is prop just informative in markdown
param_dict.pop(const.AGGREGATES)
param_value_origin = None
if const.PARAM_VALUE_ORIGIN in param_dict:
param_value_origin = param_dict.pop(const.PARAM_VALUE_ORIGIN)
if param_value_origin is not None:
props.append(common.Property(name=const.PARAM_VALUE_ORIGIN, value=param_value_origin))
else:
raise TrestleError(
f'Parameter value origin property for parameter {param_dict["id"]}'
'is None and it should have a value'
)
if const.ALT_IDENTIFIER in param_dict:
# removing alt-identifier as this is prop just informative in markdown
param_dict.pop(const.ALT_IDENTIFIER)
Expand Down
8 changes: 8 additions & 0 deletions trestle/core/catalog/catalog_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,14 @@ def _get_display_name_and_ns(param: common.Parameter) -> Tuple[Optional[str], Op
return prop.value, ns
return None, None

@staticmethod
def _get_param_value_origin_and_ns(param: common.Parameter) -> Tuple[Optional[str], Optional[str]]:
for prop in as_list(param.props):
if prop.name == const.PARAM_VALUE_ORIGIN:
ns = str(prop.ns) if prop.ns else None
return prop.value, ns
return None, None

@staticmethod
def _prune_controls(md_path: pathlib.Path, written_controls: Set[str]) -> List[str]:
"""Search directory and remove any controls that were not written out."""
Expand Down
11 changes: 10 additions & 1 deletion trestle/core/catalog/catalog_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,12 @@ def _construct_set_parameters_dict(
for param_id, param_dict in control_param_dict.items():
# if the param is in the full_param_dict, load its contents first and mark as profile-values
display_name = ''
param_value_origin = ''
if param_id in profile_set_param_dict:
# get the param from the profile set_param
param = profile_set_param_dict[param_id]
display_name, _ = CatalogInterface._get_display_name_and_ns(param)
param_value_origin, _ = CatalogInterface._get_param_value_origin_and_ns(param)
# assign its contents to the dict
new_dict = ModelUtils.parameter_to_dict(param, True)
if const.VALUES in new_dict:
Expand Down Expand Up @@ -190,14 +192,21 @@ def _construct_set_parameters_dict(
# adds display name, if no display name then do not add to dict
if display_name != '' and display_name is not None:
new_dict[const.DISPLAY_NAME] = display_name
# adds param_Value_origin
if param_value_origin != '' and param_value_origin is not None:
new_dict[const.PARAM_VALUE_ORIGIN] = param_value_origin
else:
# puts it empty for user to fill it out mandatorily
new_dict[const.PARAM_VALUE_ORIGIN] = 'Added by Control Owner'
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This value needs to be changed after Prashant confims which is the default value for the field. @vikas-agarwal76 . In the meantime I'm using a placeholder value

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it required to populate the value for param value origin?

key_order = (
const.LABEL,
const.GUIDELINES,
const.VALUES,
const.AGGREGATES,
const.ALT_IDENTIFIER,
const.DISPLAY_NAME,
const.PROFILE_VALUES
const.PROFILE_VALUES,
const.PARAM_VALUE_ORIGIN
)
ordered_dict = {k: new_dict[k] for k in key_order if k in new_dict.keys()}
set_param_dict[param_id] = ordered_dict
Expand Down
Loading