ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Salt 网络自动化实战:用 textfsm 执行模块将设备 CLI 文本解析为结构化数据

Salt 网络自动化实战:用 textfsm 执行模块将设备 CLI 文本解析为结构化数据 运维配置管理后端【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址https://gitcode.com/gh_mirrors/sa/salt点击查看免费下载Salt 提供的textfsm执行模块salt/modules/textfsm_mod.py借助 Google 开源的 TextFSM 模板引擎把网络设备返回的纯文本输出解析为 JSON 可序列化的结构化数据是 salt-proxy NAPALM 网络自动化场景中把不可读的 show 命令输出转化为可编程的键值数据的关键一环。本文以模块源码与官方文档为据完整讲解textfsm.extract与textfsm.index两个函数的参数、调用方式、模板与索引文件的写法以及底层实现原理和单元测试验证读完即可在 Salt 环境含 proxy minion中落地使用。模块概述与加载机制textfsm模块在 salt/modules/textfsm_mod.py 中实现自2018.3.0版本加入。其核心能力是使用 TextFSM 模板处理纯文本提取数据实体输出为 JSON 可序列化的数据结构方便在其它模块中复用或直接在渲染器Jinja、Mako、Genshi 等中使用同时支持 proxy minion__proxyenabled__ [*]因此可直接用于通过salt-proxy管理的网络设备如 Juniper、Cisco 等。依赖与虚拟名加载模块唯一的外部依赖是textfsmPython 库官方文档明确要求安装方式为pip install textfsm模块在导入时分别尝试引入textfsm与textfsm.clitable后者用于index函数并用HAS_TEXTFSM/HAS_CLITABLE两个标志记录结果try: import textfsm HAS_TEXTFSM True except ImportError: HAS_TEXTFSM False try: from textfsm import clitable HAS_CLITABLE True except ImportError: HAS_CLITABLE False __virtualname__ textfsm__virtual__()在HAS_TEXTFSM为真时返回虚拟名textfsm否则返回(False, The textfsm execution module failed to load: requires the textfsm library.)——即未安装 textfsm 时整个模块不会被加载在 tests/pytests/unit/modules/test_textfsm_mod.py 的test_dunder_virtual中对该行为做了直接断言。单元测试文件同样通过pytest.importorskip(textfsm, ...)在缺少依赖时跳过整个测试套件。返回值统一结构extract与index两个函数均返回一个固定结构的三元字典{result: False, comment: , out: None}result布尔值解析是否成功comment失败原因或空字符串out成功时为字典列表每条记录一个字典失败时为None。函数一textfsm.extract——按指定模板解析文本extract使用一个明确的 TextFSM 模板对原始文本进行解析适合已知模板、需要精确控制解析过程的场景。参数详解参数默认值说明template_path必填TextFSM 模板路径支持绝对路径或 URL 方案salt://Salt 文件服务器、http://、https://、ftp://、s3://、swift://raw_textNone待解析的非结构化文本raw_text_fileNone存放待解析文本的文件支持的 URL 方案与template_path相同saltenvbaseSalt 文件服务器环境仅当template_path为salt://URL 时生效raw_text与raw_text_file二选一若两者都给出raw_text优先若都为空函数返回Please specify a valid input file or text.。调用方式CLI 与 JinjaCLI 示例模板从 Salt 文件服务器取、原始文本从 S3 取或模板走 HTTP、文本直接内联salt * textfsm.extract salt://textfsm/juniper_version_template raw_text_files3://junos_ver.txt salt * textfsm.extract http://some-server/textfsm/juniper_version_template raw_textHostname: router.abc ... snip ...Jinja 模板示例执行模块可在渲染阶段直接被调用将解析结果直接落入状态数据{%- set raw_text Hostname: router.abc ... snip ... -%} {%- set textfsm_extract salt.textfsm.extract(https://some-server/textfsm/juniper_version_template, raw_text) -%}完整实战案例解析 Juniper 版本信息待解析的原始文本模拟show version的输出Hostname: router.abc Model: mx960 JUNOS Base OS boot [9.1S3.5] JUNOS Base OS Software Suite [9.1S3.5] JUNOS Kernel Software Suite [9.1S3.5] JUNOS Crypto Software Suite [9.1S3.5] JUNOS Packet Forwarding Engine Support (M/T Common) [9.1S3.5] JUNOS Packet Forwarding Engine Support (MX Common) [9.1S3.5] JUNOS Online Documentation [9.1S3.5] JUNOS Routing Software Suite [9.1S3.5]TextFSM 模板Value声明字段及其正则Start以下为状态机规则Value Chassis (\S) Value Required Model (\S) Value Boot (.*) Value Base (.*) Value Kernel (.*) Value Crypto (.*) Value Documentation (.*) Value Routing (.*) Start # Support multiple chassis systems. ^\S:$$ - Continue.Record ^${Chassis}:$$ ^Model: ${Model} ^JUNOS Base OS boot \[${Boot}\] ^JUNOS Software Release \[${Base}\] ^JUNOS Base OS Software Suite \[${Base}\] ^JUNOS Kernel Software Suite \[${Kernel}\] ^JUNOS Crypto Software Suite \[${Crypto}\] ^JUNOS Online Documentation \[${Documentation}\] ^JUNOS Routing Software Suite \[${Routing}\]解析结果JSON{ comment: , result: true, out: [ { kernel: 9.1S3.5, documentation: 9.1S3.5, boot: 9.1S3.5, crypto: 9.1S3.5, chassis: , routing: 9.1S3.5, base: 9.1S3.5, model: mx960 } ] }注意观察两点Value Required Model中的Required关键字使model字段成为必填项缺失时整条记录被丢弃而chassis字段因输入文本中没有独立的Hostname:之前的机箱行而保持空字符串——这正是 TextFSM 模板的语义在输出中的直接体现。底层实现与关键调用链从源码看extract的执行流程为缓存模板通过__salt__cp.cache_file将salt://、http(s)://、s3://等远程模板缓存到本地。若返回False函数返回Unable to read the TextFSM template from {template_path}。单元测试test_extract_cache_file_false精确断言了该错误分支。读取并校验模板用salt.utils.files.fopen打开缓存文件读取内容后seek(0)回到文件头部再交给textfsm.TextFSM(tpl_file_handle)构造解析器。源码注释特别说明TextFSM 需要文件句柄而非内容字符串因此必须先读到文件再回绕游标。若模板语法非法捕获textfsm.TextFSMTemplateError返回Unable to parse the TextFSM template from ...。测试test_extract_cache_file_raw_text_exception通过在模板中故意把Value Routing写成Xalue Routing验证了这一错误路径。获取原始文本当raw_text为空而raw_text_file给定时通过__salt__cp.get_file_str读取文件内容读取失败同样返回明确的comment测试test_extract_cache_file_raw_text_get_file_str_false覆盖。解析并结构化为字典fsm_handler.ParseText(raw_text)得到行记录再经模块内的_clitable_to_dict(objects, fsm_handler)把每一行转换为字典——键取自fsm_handler.header[index].lower()即模板字段名统一转为小写作为输出键名这就是输出中Model变成model的原因。函数二textfsm.index——按平台与命令自动选模板与extract必须显式指定模板不同index依据平台信息 命令名通过 TextFSM 的clitableCommand Line Interface table索引机制自动识别应使用哪个模板适合大规模异构设备场景。其输出结构与extract完全一致。参数详解参数默认值说明command必填在设备上执行的命令用于匹配索引platformNone平台名与 TextFSM 索引文件中的定义一致指定后platform_grain_name被忽略platform_grain_nameNone用于识别平台名的 grain 名称也可在 minion 配置或 pillar 中配置为textfsm_platform_grainplatform_column_namePlatform索引文件中标识平台的列名大小写敏感须与索引文件完全一致也可配置为textfsm_platform_column_nameoutputNone设备原始输出文本output_fileNone存放设备原始输出的文件支持file://、salt://、http://、https://、ftp://、s3://、swift://textfsm_pathNone模板存放目录要求扁平结构索引文件 若干模板支持绝对路径或上述 URL 方案也可配置为textfsm_pathindex_fileindex索引文件名位于textfsm_path下也可配置为textfsm_index_filesaltenvbase仅对salt://路径生效include_emptyFalse是否包含textfsm_path下的空文件include_patNoneglob 或正则正则需以E前缀过滤待缓存文件exclude_patNoneglob 或正则正则需以E前缀排除文件与include_pat同用时优先排除TextFSM 索引文件格式索引文件默认为textfsm_path下的index例如salt://textfsm/index是 CSV 风格的表头 数据行Template, Hostname, Vendor, Command juniper_version_template, .*, Juniper, sh[[ow]] ve[[rsion]]含义为当平台列默认Platform这里用Vendor列匹配Juniper、命令匹配sh[[ow]] ve[[rsion]][[ ]]表示该位置可匹配任意字符时选用juniper_version_template模板。官方文档建议为了便于使用索引文件中的值应尽量设计为可以直接用 grains 匹配的内容。三种 CLI 调用形态显式指定平台salt * textfsm.index sh ver platformJuniper output_filesalt://textfsm/juniper_version_example textfsm_pathsalt://textfsm/自定义平台列名索引文件使用Vendor列salt * textfsm.index sh ver output_filesalt://textfsm/juniper_version_example textfsm_pathftp://textfsm/ platform_column_nameVendor通过 grain 自动识别平台salt * textfsm.index sh ver output_filesalt://textfsm/juniper_version_example textfsm_pathhttps://some-server/textfsm/ platform_column_nameVendor platform_grain_namevendor用配置简化调用将以下选项定义在proxyminion 配置或 pillar 中即可省略大部分参数textfsm_platform_grain: vendor textfsm_path: salt://textfsm/ textfsm_platform_column_name: Vendor此时 CLI 调用简化为salt * textfsm.index sh ver output_filesalt://textfsm/juniper_version_example对应的还有textfsm_index_file可配置自定义索引文件名。配置优先级为函数参数 __opts__minion 配置__pillar__从源码可见platform_grain_name、textfsm_path、index_file、platform_column_name都遵循__opts__.get(...) or __pillar__.get(...)的回退链。Jinja 内联使用与 NAPALM 联动index最常见的实战场景是与 NAPALM 的net.cli配合先在设备上执行命令拿到原始输出再交给textfsm.index自动解析{%- set command sh ver -%} {%- set output salt.net.cli(command) -%} {%- set textfsm_extract salt.textfsm.index(command, outputoutput) -%}底层实现与关键调用链index的执行流程比extract多出模板发现环节平台识别未显式传platform时从配置读取textfsm_platform_grain再用__grains__.get(platform_grain_name)取平台名grain 缺失时返回Unable to identify the platform name using the {grain} grain.未配置任何识别方式时返回No platform specified, no platform grain identifier configured.。缓存整个模板目录__salt__cp.cache_dir把整个目录拉到本地取首个文件的目录作为缓存根os.path.dirname(textfsm_cachedir_ret[0])再将index_file拼接到其下。构造 CliTableclitable.CliTable(index_file_path, textfsm_cachedir)读取索引匹配属性attrs {Command: command, platform_column_name: platform}。读取输出并解析output_file经cp.get_file_str读取随后textfsm_obj.ParseCmd(output, attrs)完成模板匹配与解析结果同样经_clitable_to_dict转成字典列表。错误处理匹配不到模板时捕获clitable.CliTableError返回Unable to process the output: ...。单元测试test_index_platform_name_grains_output_specified_no_attribute以sr ver拼错的命令验证了这一分支错误信息会原样展示匹配属性如No template found for attributes: {Command: sr ver, Platform: textfsm_platform_grain}——这是排查索引匹配问题时的第一线索。常见错误与排查建议结合源码与 tests/pytests/unit/modules/test_textfsm_mod.py 中的失败路径用例可归纳出以下高频问题错误信息触发条件排查方向requires the textfsm library未安装 textfsm模块未加载pip install textfsm确认 minion 重启后textfsm出现在salt * sys.list_modulesUnable to read the TextFSM template from ...cp.cache_file失败检查salt://路径、saltenv、文件服务器挂载Unable to parse the TextFSM template from ...模板语法错误查看 minion 日志中Unable to parse the TextFSM template的完整异常堆栈Unable to read from {file}. Please specify a valid input file or text.raw_text_file/output_file读取失败检查文件 URL 方案是否受支持、远端是否可达Please specify a valid input file or text./Please specify a valid output text or file既未传文本也未传文件至少提供raw_text/output或对应文件参数No platform specified, no platform grain identifier configured.index未给平台也未配 grain显式传platform或配置textfsm_platform_grainUnable to fetch from {path}. Is the TextFSM path correctly specified?cp.cache_dir返回空确认textfsm_path是目录且包含索引与模板No template found for attributes: ...CliTableError平台列/命令与索引不匹配核对platform_column_name大小写敏感与Command写法索引中命令支持[[ ]]模糊匹配TextFSM does not seem that has clitable embedded.所用 textfsm 版本不含 clitable升级 textfsm 库版本版本演进备注在 doc/topics/releases/3003.rst 的发布说明中记录了一次与本模块直接相关的修复Restoring functionality of the textfsm module when using textfsm_path argument (#58499)。这意味着textfsm_path参数在特定版本曾出现过功能回归当前仓库源码中已恢复其完整工作路径cp.cache_dirclitable.CliTable实际部署时如遇该参数行为异常可优先检查 Salt 版本与本次修复的关系。总结textfsm执行模块为 Salt 网络自动化提供了模板化文本解析的标准能力extract面向已知模板场景参数少、链路短适合在状态或 pillar 渲染中直接内联使用index面向自动选模板场景借助 clitable 索引与 grains 平台识别适合在 salt-proxy 大规模管理异构网络设备时与 NAPALMnet.cli联动两者都输出{result, comment, out}统一结构out为可直接落入 JSON 的字典列表模板字段名自动转小写全部远程资源模板、文本、目录经由 Salt 文件服务器cp.cache_file/cp.get_file_str/cp.cache_dir统一拉取支持salt://、http(s)://、ftp://、s3://、swift://等方案天然与 Salt 的 saltenv 与 pillar/opts 配置体系集成。如需进一步验证或扩展可直接阅读 salt/modules/textfsm_mod.py 的完整实现以及 tests/pytests/unit/modules/test_textfsm_mod.py 中覆盖的成功与失败路径用例两者可作为编写自有模板与调试解析逻辑的参照基准。赞分享运维配置管理后端【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址https://gitcode.com/gh_mirrors/sa/salt点击查看免费下载相关推荐Salt 网络设备自动化使用 pyeapi 执行模块管理 Arista 交换机Salt 网络设备自动化使用 pyeapi 执行模块管理 Arista 交换机 本文基于 Salt 开源仓库中的 arista_pyeapi 执行模块 htt运维配置管理后端Netmiko与TextFSM集成如何解析网络设备输出为结构化数据Netmiko与TextFSM的完美结合为网络工程师提供了一种强大的自动化工具能够将复杂的网络设备输出快速转换为易于处理的结构化数据格式。这种集成方案彻底改变网络通信后端Salt 网络自动化使用 NAPALM BGP 执行模块管理网络设备 BGP 配置与邻居会话Salt 网络自动化使用 NAPALM BGP 执行模块管理网络设备 BGP 配置与邻居会话 本文以 Salt 仓库中的 BGP 执行模块 salt.mod运维配置管理后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表