def _print_result( result: Result, attrs: List[str] = None, failed: bool = False, severity_level: int = logging.INFO, ) -> None: attrs = attrs or ["diff", "result", "stdout"] if isinstance(attrs, str): attrs = [attrs] if isinstance(result, AggregatedResult): msg = result.name print("{}{}{}{}".format(Style.BRIGHT, Fore.CYAN, msg, "*" * (80 - len(msg)))) for host, host_data in sorted(result.items()): title = ("" if host_data.changed is None else " ** changed : {} ".format(host_data.changed)) msg = "* {}{}".format(host, title) print("{}{}{}{}".format(Style.BRIGHT, Fore.BLUE, msg, "*" * (80 - len(msg)))) _print_result(host_data, attrs, failed, severity_level) elif isinstance(result, MultiResult): _print_individual_result(result[0], attrs, failed, severity_level, task_group=True) for r in result[1:]: _print_result(r, attrs, failed, severity_level) color = _get_color(result[0], failed) msg = "^^^^ END {} ".format(result[0].name) print("{}{}{}{}".format(Style.BRIGHT, color, msg, "^" * (80 - len(msg)))) elif isinstance(result, Result): _print_individual_result(result, attrs, failed, severity_level)
def print_result( result: Result, host: Optional[str] = None, nr_vars: List[str] = None, failed: bool = False, severity_level: int = logging.INFO, ) -> None: updated_agg_result = AggregatedResult(result.name) for hostname, multi_result in result.items(): updated_multi_result = MultiResult(result.name) for r in multi_result: if isinstance(r.result, str) and r.result.startswith("Task skipped"): continue else: updated_multi_result.append(r) if updated_multi_result: updated_agg_result[hostname] = updated_multi_result if not updated_agg_result: return LOCK.acquire() try: _print_result(updated_agg_result, host, nr_vars, failed, severity_level) finally: LOCK.release()
def _print_result( self, result: Result, vars: List[str] = None, failed: bool = False, severity_level: int = logging.info, ) -> None: if isinstance(result, AggregatedResult): msg = f"{result.name} (hosts: {len(result)}" if result.failed: msg += ", failed: True" if result.failed_hosts: msg += f", failed_hosts: {list(result.failed_hosts.keys())})" else: msg += ")" self.console.print(f"{msg}", style=Style(underline=True, color="black")) for host, host_data in sorted(result.items()): msg = f"{host} " result_details = [] if host_data.changed: result_details.append("changed = True") if host_data.failed: result_details.append("failed = True") if result_details: msg += "(" + ", ".join(result_details) + ")" self.console.print( f"* {msg}", style=Style(color="blue"), ) self._print_result(host_data, vars, failed, severity_level) elif isinstance(result, MultiResult): self.current_indent += 1 self._print_individual_result(result[0], group=True, vars=vars) for r in result[1:]: self._print_result(r, vars, failed, severity_level) self.current_indent -= 1 elif isinstance(result, Result): self._print_individual_result(result, vars=vars)
def assert_result(result: Result, expected: dict): if isinstance(result, AggregatedResult): for _h, r in result.items(): assert r.changed == expected.get("changed", False) assert r.failed == expected.get("failed", False) if r.exception: assert_result(r, expected) else: if "result_file" in expected: assert r.result == load_json(expected["result_file"]) else: assert r.result == expected.get("result", {}) elif isinstance(result, MultiResult): for r in result[1:]: if r.exception: assert str(r.exception) == expected.get("result", {})
def _write_results( result: Result, dirname: str, attrs: List[str] = None, failed: bool = False, severity_level: int = logging.INFO, write_host: bool = False, count: Optional[int] = None, no_errors: bool = False, append: bool = False, ) -> None: attrs = attrs or ["diff", "result", "stdout"] if isinstance(attrs, str): attrs = [attrs] if isinstance(result, AggregatedResult): result = dict(sorted(result.items())) if isinstance(count, int): l = len(result) if count >= 0: _ = [0, l and count] elif (l + count) < 0: _ = [0, l] else: _ = [l + count, l] result = dict(islice(result.items()), *_) for host_data in result.values(): _write_results( host_data, dirname, attrs, failed, severity_level, write_host, no_errors=no_errors, append=append, ) elif isinstance(result, MultiResult): _write_individual_result( result[0], dirname, attrs, failed, severity_level, task_group=True, write_host=write_host, no_errors=no_errors, append=append, ) for r in result[1:]: _write_results( r, dirname, attrs, failed, severity_level, write_host, no_errors=no_errors, append=append, ) elif isinstance(result, Result): _write_individual_result( result, dirname, attrs, failed, severity_level, write_host=write_host, no_errors=no_errors, append=append, )
def print_structured_result( result: Result, host: Optional[str] = None, nr_vars: Optional[List[str]] = None, failed: bool = False, severity_level: int = logging.INFO, parser: str = "textfsm", to_dict: bool = True, fail_to_string: bool = False, ) -> None: """ Prints the :obj:`nornir.core.task.Result` from a previous task to screen Arguments: result: from a previous task host: nornir host object for the task nr_vars: Which attributes you want to print failed: if `True` assume the task failed severity_level: Print only errors with this severity level or higher parser: textfsm|genie -- parser to parse output with fail_to_string: fallback to printing unstructured output or have tasks skipped (because print_result won't print empty lists which scrapli returns if parsing fails) """ updated_agg_result = AggregatedResult(result.name) for hostname, multi_result in result.items(): updated_multi_result = MultiResult(result.name) for individual_result in multi_result: scrapli_responses = getattr(individual_result, "scrapli_response", None) if isinstance(scrapli_responses, Response): scrapli_responses = [scrapli_responses] if not scrapli_responses: updated_multi_result.append(individual_result) continue for scrapli_response in scrapli_responses: parser_method = getattr(scrapli_response, f"{parser}_parse_output") updated_result = Result( host=individual_result.host, changed=individual_result.changed, diff=individual_result.diff, exception=individual_result.exception, failed=individual_result.failed, name=individual_result.name, severity_level=individual_result.severity_level, stderr=individual_result.stderr, stdout=individual_result.stdout, ) structured_result = parser_method(to_dict=to_dict) if not structured_result and fail_to_string: updated_result.result = scrapli_response.result else: updated_result.result = structured_result updated_multi_result.append(updated_result) if updated_multi_result: updated_agg_result[hostname] = updated_multi_result # noqa LOCK.acquire() try: _print_result(updated_agg_result, host, nr_vars, failed, severity_level) finally: LOCK.release()