async def match_textfsm_templates(template_match: TFSMTemplateMatch): attrs = { 'Command': template_match.command, 'Platform': template_match.driver } tfsm_index_file = config.txtfsm_index_file # can we move this into a utility or something @Will? # accesses TextFSM internals because there's no other option # TFSM Internals assume that there might be more than one template match. I'm not sure when that would be the # case, or why it would be useful, but I'm honoring that here as well. cli_table = CliTable(index_file=config.txtfsm_index_file, template_dir=Path(tfsm_index_file).parent) index: IndexTable = cli_table.index row_idx = index.GetRowMatch(attrs) if not row_idx: raise ValueError(f'No template found for {attrs}') template_details = cli_table.index.index[row_idx] template_details['template_text'] = '' template_file_handles = [] # I don't like this, but this seems to be the only way given how TFSM works :'( try: template_file_handles = cli_table._TemplateNamesToFiles(template_details['Template']) for f in template_file_handles: template_details['template_text'] += f.read() finally: for f in template_file_handles: f.close() return template_details
def _textfsm_get_template(platform: str, command: str): """ Find correct TextFSM template based on platform and command executed Args: platform: ntc-templates device type; i.e. cisco_ios, arista_eos, etc. command: string of command that was executed (to find appropriate template) Returns: None or TextIOWrapper of opened template """ try: from textfsm.clitable import CliTable # noqa import ntc_templates # noqa except ModuleNotFoundError as exc: err = f"Module '{exc.name}' not installed!" msg = f"***** {err} {'*' * (80 - len(err))}" fix = ( f"To resolve this issue, install '{exc.name}'. You can do this in one of the following" " ways:\n" "1: 'pip install -r requirements-textfsm.txt'\n" "2: 'pip install ssh2net[textfsm]'" ) warning = "\n" + msg + "\n" + fix + "\n" + msg warnings.warn(warning) return None template_dir = pkg_resources.resource_filename("ntc_templates", "templates") cli_table = CliTable("index", template_dir) template_index = cli_table.index.GetRowMatch({"Platform": platform, "Command": command}) if not template_index: return None template_name = cli_table.index.index[template_index]["Template"] template = open(f"{template_dir}/{template_name}") return template