如何用TextFSM合并Cisco IOS对象组条目适配Ansible任务
解决Cisco IOS对象组TextFSM解析器的合并列表问题
问题背景
需要编写TextFSM解析器处理Cisco IOS对象组,用于Ansible剧本任务。目前无专门的IOS对象组模块,ios.ios_acls不支持对象组,ASA对象组模块与IOS不兼容,因此手动实现解析器,但当前版本无法将同一对象组下的LINES合并为单个列表,输出不符合需求。
当前解析器
Value Required,Filldown NAME ((network|service|v6-network|v6-service)\s(\S+)) Value List LINES (.*) Start ^object-group -> Continue.Clearall ^object-group ${NAME} ^ ${LINES} -> Record EOF
示例输入数据
object-group network TEST-obj-1 host 192.168.1.11 host 192.168.1.12 host 192.168.1.13 host 192.168.1.14 object-group network TEST-obj-2 host 192.168.2.21 host 192.168.2.22 host 192.168.2.33 object-group service TEST-ports tcp eq 22 tcp eq www tcp eq 443 udp eq tftp tcp eq telnet udp eq 3389
现有输出问题
当前解析器会为每个组内条目生成独立字典,同一对象组的LINES被拆分为多个单元素列表:
[ { "NAME": "network TEST-obj-1", "LINES": [ "host 192.168.1.11" ] }, { "NAME": "network TEST-obj-1", "LINES": [ "host 192.168.1.12" ] }, ... ]
期望输出
同一对象组的所有条目合并为单个LINES列表,适配Ansible ios.cli_command任务:
[ { "NAME": "network TEST-obj-1", "LINES": [ "host 192.168.1.11", "host 192.168.1.12", "host 192.168.1.13", "host 192.168.1.14" ] }, { "NAME": "network TEST-obj-2", "LINES": [ "host 192.168.2.21", "host 192.168.2.22", "host 192.168.2.33" ] }, { "NAME": "service TEST-ports", "LINES": [ "tcp eq 22", "tcp eq www", "tcp eq 443", "udp eq tftp", "tcp eq telnet", "udp eq 3389" ] } ]
修改后的TextFSM解析器
Value Required,Filldown NAME ((network|service|v6-network|v6-service)\s(\S+)) Value List LINES (.*) Start # 遇到新的object-group时,先记录上一个组(如果存在),再重置状态 ^object-group(?! ${NAME}) -> Record,Continue.Clearall # 捕获对象组名称 ^object-group ${NAME} # 积累组内条目到LINES列表 ^ ${LINES} -> Append # 文件结束时,记录最后一个对象组 EOF -> Record EOF
关键修改说明
- 调整记录时机:将
Record动作从每条组内条目移到遇到新对象组和文件结束时,确保一个组的所有条目收集完成后再生成字典。 - 使用Append动作:组内条目匹配时用
Append替代原逻辑,将条目追加到LINES列表,而非每次生成新记录。 - 新组检测逻辑:通过
^object-group(?! ${NAME})匹配新的对象组(排除当前组的重复匹配),触发上一个组的记录和状态重置。
修改后的解析器会先积累同一对象组的所有条目,直到遇到新组或文件结束时才输出该组的完整字典,实现LINES列表的合并。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

