diff --git a/README.md b/README.md index 3535bb7c2..587d7dcd0 100755 --- a/README.md +++ b/README.md @@ -172,7 +172,9 @@ optional arguments: --test TEST search result for test --tags TAGS List of device tags to limit scope of testing --list Display internal data + --json Display data in json format --table Result represented in tables + --save SAVE Save output to file. Only valid for --list and --json --all-results Display all test cases results. Default table view (Only valid with --table) --by-host Provides summary of test results per device (Only valid with --table) --by-test Provides summary of test results per test case (Only valid with --table) diff --git a/anta/result_manager/__init__.py b/anta/result_manager/__init__.py index 03f10ec9a..0d150da8b 100644 --- a/anta/result_manager/__init__.py +++ b/anta/result_manager/__init__.py @@ -10,6 +10,7 @@ from typing import List, Any from anta.result_manager.models import ListResult, TestResult +from anta.tools import pydantic_to_dict logger = logging.getLogger(__name__) @@ -107,7 +108,7 @@ def get_results(self, output_format: str = "native") -> Any: return list(self._result_entries) if output_format == "json": - return json.loads(str([result.json() for result in self._result_entries])) + return json.dumps(pydantic_to_dict(self._result_entries), indent=4) # Default return for native format. return self._result_entries diff --git a/anta/tools.py b/anta/tools.py new file mode 100644 index 000000000..7bc742cc9 --- /dev/null +++ b/anta/tools.py @@ -0,0 +1,35 @@ +#!/usr/bin/python +# coding: utf-8 -*- + +""" +Toolkit for ANTA. +""" + +import logging +from typing import Union, Any +from .inventory.models import InventoryDevices +from .result_manager.models import ListResult + +# pylint: disable=W1309 + +logger = logging.getLogger(__name__) +logger.setLevel(logging.DEBUG) + + +def pydantic_to_dict(pydantic_list: Union[InventoryDevices, ListResult]) -> Any: + """ + Convert Pydantic object into a dict + + Mimic .dict() option from pydantic but overwrite IPv4Address nodes + + Args: + pydantic_list: Iterable pydantic object + + Returns: + dict: dictionary object + """ + result = [] + for device in pydantic_list: + dev_dict = {k: str(v) for k, v in device} + result.append(dev_dict) + return result diff --git a/scripts/check-devices.py b/scripts/check-devices.py index 16eed0866..09777d2e8 100644 --- a/scripts/check-devices.py +++ b/scripts/check-devices.py @@ -32,6 +32,7 @@ from rich.logging import RichHandler from rich.panel import Panel from rich.pretty import pprint +from rich import print_json import anta.loader from anta.inventory import AntaInventory @@ -71,7 +72,7 @@ def cli_manager() -> argparse.Namespace: default='examples/inventory.yml', help='ANTA Inventory file') parser.add_argument('--catalog', '-c', required=False, - default='examples/tests_custom.yaml', help='ANTA Tests cagtalog') + default='examples/tests_custom.yaml', help='ANTA Tests catalog') ############################# # Device connectivity @@ -106,10 +107,18 @@ def cli_manager() -> argparse.Namespace: parser.add_argument('--list', required=False, action='store_true', help='Display internal data') + parser.add_argument('--json', required=False, action='store_true', + help='Display data in json format') + # Display result using a table (default is TRUE) parser.add_argument('--table', required=False, action='store_true', help='Result represented in tables') + ############################# + # Options for saving outputs + parser.add_argument('--save', required=False, + default=None, help='Save output to file. Only valid for --list and --json') + ############################# # Options for table report @@ -181,12 +190,23 @@ def cli_manager() -> argparse.Namespace: if cli_options.list: console.print(Panel('List results of all tests', style='cyan')) pprint(manager.get_results(output_format="list")) + if cli_options.save is not None: + with open(cli_options.save, 'w', encoding='utf-8') as fout: + fout.write(str(manager.get_results(output_format="list"))) + + if cli_options.json: + console.print(Panel('JSON results of all tests', style='cyan')) + print_json(manager.get_results(output_format="json")) + if cli_options.save is not None: + with open(cli_options.save, 'w', encoding='utf-8') as fout: + fout.write(manager.get_results(output_format="json")) if cli_options.table: reporter = ReportTable() if cli_options.all_results or (not cli_options.by_test and not cli_options.by_host): console.print(reporter.report_all(result_manager=manager, host=cli_options.hostip, testcase=cli_options.test)) + # To print only report per Test case if cli_options.by_test: console.print(reporter.report_summary_tests(