From bf73f56f0e0bb3f84f2db64d3f4dae060aa62632 Mon Sep 17 00:00:00 2001 From: Alejandro Jose Leiva Palomo Date: Thu, 5 Oct 2023 10:03:07 -0600 Subject: [PATCH] feat: adding validate template type to author docs command Signed-off-by: Alejandro Jose Leiva Palomo --- .../arch-design/ssad/mock/arch-design_v1.md | 14 ++++++ .../arch-design/ssad/mock/arch-design_v2.md | 14 ++++++ .../mock/cloud_security_baseline_checklist.md | 17 ++++++++ .../second_service_name/arch-design_v1.md | 14 ++++++ .../cloud_security_baseline_checklist.md | 17 ++++++++ .../arch-design_template/1.0.0/arch-design.md | 14 ++++++ .../cloud_security_baseline_checklist.md | 17 ++++++++ .../cloud_security_baseline_checklist.md | 17 ++++++++ .../arch-design_template/2.0.0/arch-design.md | 14 ++++++ .../trestle/core/commands/author/docs_test.py | 39 +++++++++++++++++ trestle/core/commands/author/docs.py | 43 ++++++++++++++++--- 11 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 tests/data/author/docs/arch-design/ssad/mock/arch-design_v1.md create mode 100644 tests/data/author/docs/arch-design/ssad/mock/arch-design_v2.md create mode 100644 tests/data/author/docs/arch-design/ssad/mock/cloud_security_baseline_checklist.md create mode 100644 tests/data/author/docs/arch-design/ssad/second_service_name/arch-design_v1.md create mode 100644 tests/data/author/docs/arch-design/ssad/second_service_name/cloud_security_baseline_checklist.md create mode 100644 tests/data/author/docs/arch-design_template/1.0.0/arch-design.md create mode 100644 tests/data/author/docs/arch-design_template/1.0.0/cloud_security_baseline_checklist.md create mode 100644 tests/data/author/docs/arch-design_template/1.1.1/cloud_security_baseline_checklist.md create mode 100644 tests/data/author/docs/arch-design_template/2.0.0/arch-design.md diff --git a/tests/data/author/docs/arch-design/ssad/mock/arch-design_v1.md b/tests/data/author/docs/arch-design/ssad/mock/arch-design_v1.md new file mode 100644 index 000000000..53ba5c0dd --- /dev/null +++ b/tests/data/author/docs/arch-design/ssad/mock/arch-design_v1.md @@ -0,0 +1,14 @@ +--- +authors: tmp +owner: tmp +valid: + from: null + to: null +x-trestle-template-type: arch-design +x-trestle-template-version: 1.0.0 +--- +# System architecture + +## Overview + +## Security model diff --git a/tests/data/author/docs/arch-design/ssad/mock/arch-design_v2.md b/tests/data/author/docs/arch-design/ssad/mock/arch-design_v2.md new file mode 100644 index 000000000..a39c22907 --- /dev/null +++ b/tests/data/author/docs/arch-design/ssad/mock/arch-design_v2.md @@ -0,0 +1,14 @@ +--- +authors: tmp +owner: tmp +valid: + from: null + to: null +x-trestle-template-type: arch-design +x-trestle-template-version: 2.0.0 +--- +# System architecture + +## Overview + +## Security model diff --git a/tests/data/author/docs/arch-design/ssad/mock/cloud_security_baseline_checklist.md b/tests/data/author/docs/arch-design/ssad/mock/cloud_security_baseline_checklist.md new file mode 100644 index 000000000..f0da0b50f --- /dev/null +++ b/tests/data/author/docs/arch-design/ssad/mock/cloud_security_baseline_checklist.md @@ -0,0 +1,17 @@ +--- +authors: tmp +owner: tmp +valid: + from: + to: +x-trestle-template-type: cloud_security_baseline_checklist +x-trestle-template-version: 1.1.1 +--- + +# Network architectures + +## External interconnections + +## Corporate interconnections + +## Out of scope interconnections diff --git a/tests/data/author/docs/arch-design/ssad/second_service_name/arch-design_v1.md b/tests/data/author/docs/arch-design/ssad/second_service_name/arch-design_v1.md new file mode 100644 index 000000000..53ba5c0dd --- /dev/null +++ b/tests/data/author/docs/arch-design/ssad/second_service_name/arch-design_v1.md @@ -0,0 +1,14 @@ +--- +authors: tmp +owner: tmp +valid: + from: null + to: null +x-trestle-template-type: arch-design +x-trestle-template-version: 1.0.0 +--- +# System architecture + +## Overview + +## Security model diff --git a/tests/data/author/docs/arch-design/ssad/second_service_name/cloud_security_baseline_checklist.md b/tests/data/author/docs/arch-design/ssad/second_service_name/cloud_security_baseline_checklist.md new file mode 100644 index 000000000..735db606b --- /dev/null +++ b/tests/data/author/docs/arch-design/ssad/second_service_name/cloud_security_baseline_checklist.md @@ -0,0 +1,17 @@ +--- +authors: tmp +owner: tmp +valid: + from: + to: +x-trestle-template-type: cloud_security_baseline_checklist +x-trestle-template-version: 1.0.0 +--- + +# Network architecture + +## External interconnections + +## Corporate interconnections + +## Out of scope interconnections diff --git a/tests/data/author/docs/arch-design_template/1.0.0/arch-design.md b/tests/data/author/docs/arch-design_template/1.0.0/arch-design.md new file mode 100644 index 000000000..53ba5c0dd --- /dev/null +++ b/tests/data/author/docs/arch-design_template/1.0.0/arch-design.md @@ -0,0 +1,14 @@ +--- +authors: tmp +owner: tmp +valid: + from: null + to: null +x-trestle-template-type: arch-design +x-trestle-template-version: 1.0.0 +--- +# System architecture + +## Overview + +## Security model diff --git a/tests/data/author/docs/arch-design_template/1.0.0/cloud_security_baseline_checklist.md b/tests/data/author/docs/arch-design_template/1.0.0/cloud_security_baseline_checklist.md new file mode 100644 index 000000000..735db606b --- /dev/null +++ b/tests/data/author/docs/arch-design_template/1.0.0/cloud_security_baseline_checklist.md @@ -0,0 +1,17 @@ +--- +authors: tmp +owner: tmp +valid: + from: + to: +x-trestle-template-type: cloud_security_baseline_checklist +x-trestle-template-version: 1.0.0 +--- + +# Network architecture + +## External interconnections + +## Corporate interconnections + +## Out of scope interconnections diff --git a/tests/data/author/docs/arch-design_template/1.1.1/cloud_security_baseline_checklist.md b/tests/data/author/docs/arch-design_template/1.1.1/cloud_security_baseline_checklist.md new file mode 100644 index 000000000..f0da0b50f --- /dev/null +++ b/tests/data/author/docs/arch-design_template/1.1.1/cloud_security_baseline_checklist.md @@ -0,0 +1,17 @@ +--- +authors: tmp +owner: tmp +valid: + from: + to: +x-trestle-template-type: cloud_security_baseline_checklist +x-trestle-template-version: 1.1.1 +--- + +# Network architectures + +## External interconnections + +## Corporate interconnections + +## Out of scope interconnections diff --git a/tests/data/author/docs/arch-design_template/2.0.0/arch-design.md b/tests/data/author/docs/arch-design_template/2.0.0/arch-design.md new file mode 100644 index 000000000..a39c22907 --- /dev/null +++ b/tests/data/author/docs/arch-design_template/2.0.0/arch-design.md @@ -0,0 +1,14 @@ +--- +authors: tmp +owner: tmp +valid: + from: null + to: null +x-trestle-template-type: arch-design +x-trestle-template-version: 2.0.0 +--- +# System architecture + +## Overview + +## Security model diff --git a/tests/trestle/core/commands/author/docs_test.py b/tests/trestle/core/commands/author/docs_test.py index 3a2db9e8a..8f873de07 100644 --- a/tests/trestle/core/commands/author/docs_test.py +++ b/tests/trestle/core/commands/author/docs_test.py @@ -721,3 +721,42 @@ def test_template_validate_flags_invalid_body( command_validate = 'trestle author docs template-validate -tn test_task -hv' execute_command_and_assert(command_validate, 1, monkeypatch) + + +def test_multiple_dif_templates_recursive( + testdata_dir: pathlib.Path, tmp_trestle_dir: pathlib.Path, monkeypatch: MonkeyPatch +) -> None: + """Test instance folder with multiple different template types inside a > 1 folder hierarchy.""" + task_template_folder = tmp_trestle_dir / '.trestle/author/test_task/' + test_template_folder = testdata_dir / 'author/docs/arch-design_template' + test_instances_folder = testdata_dir / 'author/docs/arch-design' + task_instance_folder = tmp_trestle_dir / 'test_task/' + + shutil.copytree(test_template_folder, task_template_folder) + + shutil.copytree(test_instances_folder, task_instance_folder) + + command_validate = 'trestle author docs validate -tn test_task -r -vtt' + execute_command_and_assert(command_validate, 0, monkeypatch) + + # Remove template type from instance and test to fail + task_markdown = task_instance_folder / 'ssad/mock/arch-design_v1.md' + md_api = MarkdownAPI() + header, tree = md_api.processor.process_markdown(task_markdown) + del header['x-trestle-template-type'] + + md_api.write_markdown_with_header(task_markdown, header, tree.content.raw_text) + + execute_command_and_assert(command_validate, 1, monkeypatch) + # set template type to arch-design again + header['x-trestle-template-type'] = 'arch-design' + + # Modify template headeing from instance and test to fail + a_node = tree.get_node_for_key('# System architecture', True) + + assert a_node + + tree.content.raw_text = tree.content.raw_text.replace('# System architecture', '# Not the heading expected') + md_api.write_markdown_with_header(task_markdown, header, tree.content.raw_text) + + execute_command_and_assert(command_validate, 1, monkeypatch) diff --git a/trestle/core/commands/author/docs.py b/trestle/core/commands/author/docs.py index 75a02d381..f341cea38 100644 --- a/trestle/core/commands/author/docs.py +++ b/trestle/core/commands/author/docs.py @@ -84,6 +84,13 @@ def _init_arguments(self) -> None: action='store_true' ) + self.add_argument( + author_const.TEMPLATE_TYPE_VALIDATE_SHORT, + author_const.TEMPLATE_TYPE_VALIDATE_LONG, + help=author_const.TEMPLATE_TYPE_VALIDATE_HELP, + action='store_true' + ) + def _run(self, args: argparse.Namespace) -> int: try: status = 1 @@ -110,7 +117,8 @@ def _run(self, args: argparse.Namespace) -> int: args.recurse, args.readme_validate, args.template_version, - args.ignore + args.ignore, + args.validate_template_type ) return status @@ -199,7 +207,8 @@ def _validate_dir( recurse: bool, readme_validate: bool, template_version: Optional[str] = None, - ignore: Optional[str] = None + ignore: Optional[str] = None, + validate_by_type_field: bool = False ) -> int: """ Validate md files in a directory with option to recurse. @@ -238,7 +247,26 @@ def _validate_dir( versione_template_dir = TemplateVersioning.get_versioned_template_dir( self.template_dir, instance_version ) - template_file = versione_template_dir / self.template_name + # checks on naming template name out of type header if needed + if validate_by_type_field: + # get template name out of its type which essentially needs to be the same + template_name = md_api.processor.fetch_value_from_header( + item_path, author_const.TEMPLATE_TYPE_HEADER + ) + # throw an error if template type is not present + if template_name is None: + logger.error( + f'INVALID: Instance file {item_path} does not have' + f' {author_const.TEMPLATE_TYPE_HEADER}' + ' field in its header and can not be validated using optional parameter validate' + ' template type field' + ) + status = 1 + return status + template_name = template_name + '.md' + template_file = versione_template_dir / template_name + else: # continues regular flow without template type + template_file = versione_template_dir / self.template_name if not template_file.is_file(): raise TrestleError( f'Required template file: {self.rel_dir(template_file)} does not exist. Exiting.' @@ -265,7 +293,8 @@ def _validate_dir( recurse, readme_validate, template_version, - ignore + ignore, + validate_by_type_field ) if rc != 0: status = rc @@ -280,7 +309,8 @@ def validate( recurse: bool, readme_validate: bool, template_version: str, - ignore: str + ignore: str, + validate_by_type_field: bool ) -> int: """ Validate task. @@ -306,5 +336,6 @@ def validate( recurse, readme_validate, template_version, - ignore + ignore, + validate_by_type_field )