使用 Ansible 解析半结构化文本

cli_parse 这个模组,可将诸如网络配置这样的半结构化数据,解析为结构化数据,从而允许以编程方式使用来自该设备的数据。咱们可在一个 playbook 中,从网络设备中提取信息并更新某个 CMDB。用例包括自动化的故障排除、创建动态文档、更新 IPAM(IP 地址管理,IP address management)工具等。

掌握 CLI 解析器

1.0.0 或更高版本的 ansible.utils 专辑,包含了可运行 CLI 命令并解析半结构化文本输出的 cli_parse 模组。咱们可在仅支持某种命令行界面,且这些命令被执行后会返回半结构化文本的某个设备、主机,或某种平台上,使用 cli_parse 模组。cli_parse 模组既可以在设备上运行 CLI 命令,并返回某种解析结果,也可以仅解析任何文本文档。cli_parse 模组包含了与各种解析引擎连接的 cli_parser 插件。

为何要解析文本?

将诸如网络配置这样的半结构化数据,解析为结构化数据后,实现该设备数据的编程使用。用例包括自动化的故障排除、创建动态文档、更新 IPAM(IP 地址管理)工具等。咱们可能更偏向使用 Ansible 原生完成此目的,以利用一些原生的 Ansible 结构,比如:

  • 有条件地运行其他任务或角色的 when 子句,the when clause;
  • 检查配置及运行状态合规性的 assert 模组;
  • 生成配置及运行状态信息报告的 template 模组;
  • 生成主机、设备或平台命令、配置的模板及 commandconfig 模组;
  • 补充原生事实信息的当前平台 facts 模组。

通过将半结构化文本,解析为 Ansible 的原生数据结构,咱们可以充分利用 Ansible 的那些网络模组与插件。

何时不解析文本

在下列情况下,咱们不应解析半结构化文本:

  • 设备、主机或平台有着 RESTAPI 且返回的是 JSON;
  • 即有 Ansible 的事实模组,已经返回了所需数据(译注:结构化数据);
  • 已有那些用于设备与资源配置管理的 Ansible 网络资源模组。

解析命令行 CLI

cli_parse 模组,包括了以下的 cli_parsing 插件:

  • native

Ansible 内置的原生解析引擎,无需额外的 python 库。

  • xml

将 XML 解析为某种 Ansible 原生的数据结构。

  • textfsm

一个用于解析半结构化文本,实现了一种基于模板的状态机的 python 模组。

  • ntc_templates

支持各种平台和命令的一些预定义的 textfsm 模板包。

  • ttp

使用模板进行半结构化文本解析的一个库,具有一些简化流程的能力。

  • pyats

使用 Cisco 测试自动化与验证解决方案 1 所包含的那些解析器。

1, Cisco Test Automation & Validation Solution,Cisco pyATS: Network Test & Automation Solution

  • json

将 CLI 处输出的 JSON,转换为 Ansible 的原生数据结构。

译注:上述 cli_parse 用到的 cli_parsing 插件,需要安装 textfsmntc_templatesttpjcgeniepyats Python 模组 python -m pip install textfsm ntc_templates ttp jc genie pyats

尽管 Ansible 包含许多可将 XML 转换为 Ansible 原生数据结构的插件,但 cli_parse 模组可在单个的任务中,同时在设备上运行返回 XML 的命令,并返回转换后的数据。

由于 cli_parse 使用了基于插件的架构,因此他可以使用任何 Ansible 专辑中别的解析引擎。

注意ansible.netcommon.nativeansible.utils.json 两个解析引擎,在 Red Hat Ansible 自动化平台订阅下有完整支持。Red Hat Ansible 自动化平台订阅的支持仅限于 ntc_templatespyATStextfsmxmltodict 及一些公共 API(如文档所示)的使用。

使用原生解析引擎解析

原生解析引擎包含在 cli_parse 模组中。他使用正则表达式捕获数据,以产生出解析后的数据结构。原生解析引擎需要一个 YAML 模板文件,来解析命令的输出。

  • 网络示例

这个示例使用某个网络设备命令的输出,并应用一个原生模板,生成 Ansible 结构化数据格式的输出。

来自网络设备的 show interface 命令输出如下:

Ethernet1/1 is up
admin state is up, Dedicated Interface
  Hardware: 100/1000/10000 Ethernet, address: 5254.005a.f8bd (bia 5254.005a.f8bd)
  MTU 1500 bytes, BW 1000000 Kbit, DLY 10 usec
  reliability 255/255, txload 1/255, rxload 1/255
  Encapsulation ARPA, medium is broadcast
  Port mode is access
  full-duplex, auto-speed
  Beacon is turned off
  Auto-Negotiation is turned on  FEC mode is Auto
  Input flow-control is off, output flow-control is off
  Auto-mdix is turned off
  Switchport monitor is off
  EtherType is 0x8100
  EEE (efficient-ethernet) : n/a
  Last link flapped 4week(s) 6day(s)
  Last clearing of "show interface" counters never
<...>

译注:这是一台思科 NXOS 设备的 sh int 命令输出。

创建出与之输出相匹配的原生模板,并将其存储为 templates/nxos_show_interface.yaml

{{#include ../../network_run/nxos_show_interface.yaml}}

这个原生解析器模板,是按一个解析器列表组织的,每个解析器都包含以下这些键值对:

  • example - 要解析文本行的一个示例行;
  • getval - 使用一些命名捕获组存储所提取数据的一个正则表达式;
  • result - 从解析数据中以模板形式填充的数据树;
  • shared - 以解析出的数据,产生自一个模板的数据树。

下面的示例任务使用了 cli_parse 与原生解析器,与上面的示例模板,解析来自某个 Cisco NXOS 设备的 show interface 命令:

---
- hosts: nxos-sw
  gather_facts: no

  tasks:
    - name: "Run command and parse with native"
      ansible.utils.cli_parse:
        command: sho int
        parser:
          command: show interface
          name: ansible.netcommon.native
        set_fact: interfaces

    - debug:
        msg: "{{ interfaces }}"

来深入研究以下这个任务:

  • 其中的 command 选项,提供了咱们要在设备或主机上运行的命令。或者,咱们也可以使用 text 选项,提供某个先前命令的文本;
  • parser 选项提供了特定于解析器引擎的信息;
  • name 子选项提供了解析引擎的完全合格专辑名字(FQCN,ansible.builtin.native);
  • 默认情况下,cli_parse 模组会在 templates 目录下,查找模板 {{ short_os }}_{ command }}.yaml
    • 模板文件名中的 short_os 派生自主机的 ansible_network_osansible_distribution 变量;
    • 在模板文件名的 command 部分,网络或主机命令中的空格会以 _ 替换。在本例中,show interfaces 这个网络 CLI 命令,在文件名中就成为了 show_interfaces

注意ansible.netcommon.native 解析引擎在 Red Hat Ansible 自动化平台订阅下受完整支持。

这个任务的最后,set_fact 选项会根据 cli_parse 返回的已结构化数据,设置该设备的以下 interfaces 事实:

Ethernet1/1:
    hardware: 100/1000/10000 Ethernet
    mac_address: 5254.005a.f8bd
    name: Ethernet1/1
    state:
    admin: up
    operating: up
Ethernet1/10:
    hardware: 100/1000/10000 Ethernet
    mac_address: 5254.005a.f8c6
# ...
  • Linux 示例

咱们还可使用这个原生解析器,在 Linux 上运行命令及解析输出。

一个示例 Linux 命令(ip addr show)的输出如下:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:90:33:26 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.61/24 brd 192.168.122.255 scope global dynamic noprefixroute enp1s0
       valid_lft 3199sec preferred_lft 3199sec
    inet6 fe80::5054:ff:fe90:3326/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

创建出与此输出匹配的原生模板,并将其存储为 templates/almalinux_ip_addr_show.yaml

{{#include ../../network_run/almalinux_ip_addr_show.yaml}}

注意:解析器模板中的 shared 键,允许接口名称在后续解析器条目中使用。正则表达式中示例和自由间距模式的使用,使模板更易于阅读。

下面的示例任务使用原生解析器下的 cli_parse,与上述示例模板,解析 Linux 的输出:

---
- hosts: almalinux-61
  gather_facts: no

  tasks:
    - name: Run command and parse
      ansible.utils.cli_parse:
        command: ip addr show
        parser:
          name: ansible.netcommon.native
          template_path: templates/linux_ip_addr_show.yml
        set_fact: interfaces


    - debug:
        msg: "{{ interfaces }}"

这个任务假定咱们之前已经收集了相关信息,以确定出找到模板所需的 ansible_distribution。或者,咱们也可以在 parser/template_path 选项中提供这个路径。

译注:这里使用 setup 任务收集 distributionos_family 两项主机事实上,以便后面的 cli_parse 模组可以找到正确的模板。此外将此任务用到的模板,放在任务 YAML 旁边也可以找到。

此任务的最后,set_fact 选项会根据 cli_parse 所返回的已结构化数据,为主机设置以下 interfaces 事实:

lo:
  broadcast: false
  carrier: true
  ip_address: 127.0.0.1
  mask_bits: 8
  mtu: 65536
  multicast: false
  name: lo
  state: unknown
  up: true
enp64s0u1:
  broadcast: true
  carrier: true
  ip_address: 192.168.86.83
  mask_bits: 24
  mtu: 1500
  multicast: true
  name: enp64s0u1
  state: up
  up: true
# ...

解析 JSON

虽然 Ansible 会在识别到序列化 JSON 时,原生地将其转换为 Ansible 的原生数据,但咱们也可使用 cli_parse 模组进行这种转换。

示例任务:

---
- hosts: nxos-sw
  gather_facts: no

  tasks:
    - name: "Run command and parse as json"
      ansible.utils.cli_parse:
        command: show interface | json
        parser:
          name: ansible.utils.json
        set_fact: interfaces

    - debug:
        msg: "{{ interfaces }}"

深入探究一下这个任务:

  • show interface | json 这个命令会在设备上执行;
  • 输出被设置为该设备的 interfaces 事实;
  • JSON 支持主要是为了保持 playbook 的一致性而提供。

注意ansible.netcommon.json 解析引擎在 Red Hat Ansible 自动化平台订阅下受完整支持。

使用 ntc_templates 解析命令行输出

ntc_templates 这个 python 库,包含了一些用于解析各种网络设备命令输出的预定义 textfsm 模板。

示例任务:

---
- hosts: nxos-sw,ios-sw,arista-sw
  gather_facts: no

  tasks:
    - name: "Run command and parse with ntc_templates"
      ansible.utils.cli_parse:
        command: show interface
        parser:
          name: ansible.netcommon.ntc_templates
        set_fact: interfaces


    - debug:
        msg: "{{ interfaces }}"

深入探究一下这个任务:

  • 设备的 ansible_network_os 变量,会转换为 ntc_template 的格式 cisc_nxos。此外,咱们也可使用 parser/os 选项提供 os 变量;
  • 包含在 ntc_templates Python 包中的 cisco_nxos_show_interface.textfsm 模板,会解析输出;
  • 有关 ntc_templates 这个 python 库的更多信息,请参阅 ntc_templatesREADME

注意:如文档所示,Red Hat Ansible 自动化平台的订阅的支持,仅限于 ntc_templates 公共 API 的使用。

此任务及预定义模板,会将以下事实设置为该主机的 interfaces 事实:

interfaces:
- address: 5254.005a.f8b5
  admin_state: up
  bandwidth: 1000000 Kbit
  bia: 5254.005a.f8b5
  delay: 10 usec
  description: ''
  duplex: full-duplex
  encapsulation: ARPA
  hardware_type: Ethernet
  input_errors: ''
  input_packets: ''
  interface: mgmt0
  ip_address: 192.168.101.14/24
  last_link_flapped: ''
  link_status: up
  mode: ''
  mtu: '1500'
  output_errors: ''
  output_packets: ''
  speed: 1000 Mb/s
- address: 5254.005a.f8bd
  admin_state: up
  bandwidth: 1000000 Kbit
  bia: 5254.005a.f8bd
  delay: 10 usec

使用 pyATS 解析

pyATS 是思科测试自动化与验证解决方案的一部分。他包含了许多适用于多种网络平台和命令的预定义解析器。咱们可通过 cli_parse 模组使用这些 pyATS 软件包中的预定义解析器。

示例任务:

---
- hosts: nxos-sw,iosxe-sw
  gather_facts: no

  tasks:
    - name: "Run command and parse with ntc_templates"
      ansible.utils.cli_parse:
        command: show interface
        parser:
          name: ansible.netcommon.pyats
        set_fact: interfaces


    - debug:
        msg: "{{ interfaces }}"

深入探究一下这个任务:

  • cli_parse 模组会自动转换 ansible_network_os,本例中 ansible_network_os 被设置为 cisco.nxos.nxos,就会转换到 pyATSnxos。另外,咱们也可使用 parser/os 选项,设置操作系统;
  • 使用命令与操作系统的组合,pyATS 选择了以下解析器:show interfaces
  • cli_parse 模组会将 cisco.ios.ios 设置为 pyATSiosxe。咱们可使用 parser/os 选项覆盖此设置;
  • cli_parse 只会使用 pyATS 中的那些预定义解析器。请参阅 pyATS 文档pyATS 包含的解析器 的完整列表。

注意:如文档所示,Red Hat Ansible 自动化平台订阅的支持,仅限于 pyATS 公共 API 的使用。

这个任务会将以下事实,设置为该主机的 interfaces 事实:

mgmt0:
  admin_state: up
  auto_mdix: 'off'
  auto_negotiate: true
  bandwidth: 1000000
  counters:
    in_broadcast_pkts: 3
    in_multicast_pkts: 1652395
    in_octets: 556155103
    in_pkts: 2236713
    in_unicast_pkts: 584259
    rate:
      in_rate: 320
      in_rate_pkts: 0
      load_interval: 1
      out_rate: 48
      out_rate_pkts: 0
    rx: true
    tx: true
  delay: 10
  duplex_mode: full
  enabled: true
  encapsulations:
    encapsulation: arpa
  ethertype: '0x0000'
  ipv4:
    192.168.101.14/24:
      ip: 192.168.101.14
      prefix_length: '24'
  link_state: up
  # ...

使用 textfsm 解析

textfsm 是个实现了一种用于解析半格式化文本的基于模板状态机的 Python 模组。

以下示例 textfsm 模板,保存在 templates/nxos_show_interface.textfsm

Value Required INTERFACE (\S+)
Value LINK_STATUS (.+?)
Value ADMIN_STATE (.+?)
Value HARDWARE_TYPE (.\*)
Value ADDRESS ([a-zA-Z0-9]+.[a-zA-Z0-9]+.[a-zA-Z0-9]+)
Value BIA ([a-zA-Z0-9]+.[a-zA-Z0-9]+.[a-zA-Z0-9]+)
Value DESCRIPTION (.\*)
Value IP_ADDRESS (\d+\.\d+\.\d+\.\d+\/\d+)
Value MTU (\d+)
Value MODE (\S+)
Value DUPLEX (.+duplex?)
Value SPEED (.+?)
Value INPUT_PACKETS (\d+)
Value OUTPUT_PACKETS (\d+)
Value INPUT_ERRORS (\d+)
Value OUTPUT_ERRORS (\d+)
Value BANDWIDTH (\d+\s+\w+)
Value DELAY (\d+\s+\w+)
Value ENCAPSULATION (\w+)
Value LAST_LINK_FLAPPED (.+?)

Start
  ^\S+\s+is.+ -> Continue.Record
  ^${INTERFACE}\s+is\s+${LINK_STATUS},\sline\sprotocol\sis\s${ADMIN_STATE}$$
  ^${INTERFACE}\s+is\s+${LINK_STATUS}$$
  ^admin\s+state\s+is\s+${ADMIN_STATE},
  ^\s+Hardware(:|\s+is)\s+${HARDWARE_TYPE},\s+address(:|\s+is)\s+${ADDRESS}(.*bia\s+${BIA})*
  ^\s+Description:\s+${DESCRIPTION}
  ^\s+Internet\s+Address\s+is\s+${IP_ADDRESS}
  ^\s+Port\s+mode\s+is\s+${MODE}
  ^\s+${DUPLEX}, ${SPEED}(,|$$)
  ^\s+MTU\s+${MTU}.\*BW\s+${BANDWIDTH}.\*DLY\s+${DELAY}
  ^\s+Encapsulation\s+${ENCAPSULATION}
  ^\s+${INPUT_PACKETS}\s+input\s+packets\s+\d+\s+bytes\s\*$$
  ^\s+${INPUT_ERRORS}\s+input\s+error\s+\d+\s+short\s+frame\s+\d+\s+overrun\s+\d+\s+underrun\s+\d+\s+ignored\s\*$$
  ^\s+${OUTPUT_PACKETS}\s+output\s+packets\s+\d+\s+bytes\s\*$$
  ^\s+${OUTPUT_ERRORS}\s+output\s+error\s+\d+\s+collision\s+\d+\s+deferred\s+\d+\s+late\s+collision\s\*$$
  ^\s+Last\s+link\s+flapped\s+${LAST_LINK_FLAPPED}\s\*$$

下面这个任务使用了该 textfsm 模板与 cli_parse 模组。

---
- hosts: nxos-sw
  gather_facts: no

  tasks:
    - name: "Run command and parse with textfsm"
      ansible.utils.cli_parse:
        command: show interface
        parser:
          name: ansible.utils.textfsm
        set_fact: interfaces

    - debug:
        msg: "{{ interfaces }}"

深入探究一下这个任务:

  • 设备的 ansible_network_os 变量 (cisco.nxos.nxos),会被转换为 nxos。咱们也可在 parser/os 这个选项中提供操作系统;
  • 使用操作系统和所运行命令的组合,textfsm 的模板名称就默认为 templates/nxos_show_interface.textfsm。咱们也可使用 parser/template_path 选项,覆盖这个生成的模板路径;
  • 详情请查看 textfsm README
  • textfsm 先前是作为过滤器插件提供的。Ansible 用户应过渡到 cli_parse 模组。

注意:如文档所示,Red Hat Ansible 自动化平台订阅的支持,仅限于 testfsm 公共 API 的使用。

这个任务会将以下事实,设置为主机的 interfaces 事实:

- ADDRESS: X254.005a.f8b5
  ADMIN_STATE: up
  BANDWIDTH: 1000000 Kbit
  BIA: X254.005a.f8b5
  DELAY: 10 usec
  DESCRIPTION: ''
  DUPLEX: full-duplex
  ENCAPSULATION: ARPA
  HARDWARE_TYPE: Ethernet
  INPUT_ERRORS: ''
  INPUT_PACKETS: ''
  INTERFACE: mgmt0
  IP_ADDRESS: 192.168.101.14/24
  LAST_LINK_FLAPPED: ''
  LINK_STATUS: up
  MODE: ''
  MTU: '1500'
  OUTPUT_ERRORS: ''
  OUTPUT_PACKETS: ''
  SPEED: 1000 Mb/s
- ADDRESS: X254.005a.f8bd
  ADMIN_STATE: up
  BANDWIDTH: 1000000 Kbit
  BIA: X254.005a.f8bd
...

使用 TTP 解析

TTP 是个使用模板进行半结构化文本解析的 Python 库。TTP 使用类似于 Jinja 的语法,限制了对正则表达式的需求。熟悉 Jinja 模板的用户,可能会发现 TTP 模板语法很熟悉。

以下是个存储为 templates/nxos_show_interface.ttpTTP 模板示例:

{{ interface }} is {{ state }}
admin state is {{ admin_state }}{{ ignore(".\*") }}
  Hardware:  {{ media_type }}, address: {{ mac_address }} (bia {{ bia }})
  Internet Address is {{ ip_address }}
  MTU {{ mtu }} bytes, BW {{ bandwidth }}, DLY 10 usec

下面这个任务使用该模板,解析 show interface 命令的输出:

---
- hosts: nxos-sw
  gather_facts: no


  tasks:
    - name: "Run command and parse with ttp"
      ansible.utils.cli_parse:
        command: show interface
        parser:
          name: ansible.utils.ttp
        set_fact: interfaces


    - debug:
        msg: "{{ interfaces }}"

深入探究一下这个任务:

  • 默认模板路径 templates/nxos_show_interface.ttp 是使用主机的 ansible_network_os 变量与 command 选项生成的;
  • TTP 还支持将传递给解析器的几个其他变量。这些变量包括:
    • parser/vars/ttp_init - 解析器初始化时,传递的附加参数;
    • parser/vars/ttp_results - 用于影响解析器输出的附加参数;
    • parser/vars/ttp_vars - 模板中可用的附加变量。

该任务会将以下事实,设置为主机的 interfaces 事实:

- admin_state: up,
  interface: mgmt0
  state: up
- admin_state: up,
  interface: Ethernet1/1
  state: up
- admin_state: up,
  interface: Ethernet1/2
  state: up

使用 JC 解析

JC 是个可将数十种常见 Linux/UNIX/macOS/Windows 命令行工具及文件类型的输出,转换为 python 字典或字典列表,以更易于解析的 python 库。JC 是 community.general 专辑中的一种过滤器插件。

以下是个使用 JC 解析 dig 命令输出的示例:

---
- hosts: almalinux-61
  gather_facts: no


  tasks:
    - package:
        name: bind-utils
        state: present

    - shell: dig example.com
      register: result

    - set_fact:
        myvar: "{{ result.stdout | community.general.jc('dig') }}"

    - debug:
        msg: "The IP is: {{ myvar[0].answer[0].data }}"
  • JC 项目及文档,可在 此处 找到;
  • 更多信息,请参阅此 博客条目

转换 XML

尽管 Ansible 包含许多可将 XML 转换为 Ansible 原生数据结构的插件,但 cli_parse 模组可在单个任务中,同时在设备上运行返回 XML 的命令,并返回转换后的数据。

下面这个示例任务,会运行 show interface 命令并将输出解析为 XML:

---
- hosts: nxos-sw
  gather_facts: no


  tasks:
    - name: "Run command and parse as xml"
      ansible.utils.cli_parse:
        command: show interface | xml
        parser:
          name: ansible.utils.xml
      register: interfaces

    - debug:
        msg: "{{ interfaces }}"

注意:如文档所示,Red Hat Ansible 自动化平台订阅的支持,仅限于 xmltodict 的公共 API 的使用。

这个任务会根据如下返回的输出,设置主机的 interfaces 事实:

nf:rpc-reply:
  '@xmlns': http://www.cisco.com/nxos:1.0:if_manager
  '@xmlns:nf': urn:ietf:params:xml:ns:netconf:base:1.0
  nf:data:
    show:
      interface:
        __XML__OPT_Cmd_show_interface_quick:
          __XML__OPT_Cmd_show_interface___readonly__:
            __readonly__:
              TABLE_interface:
                ROW_interface:
                - admin_state: up
                  encapsulation: ARPA
                  eth_autoneg: 'on'
                  eth_bia_addr: x254.005a.f8b5
                  eth_bw: '1000000'

高级用例

cli_parse 模组还有着多个支持更复杂用例的特性。

提供完整模板路径

在任务中使用 template_path 选项,覆盖默认的模板路径:

- name: "Run command and parse with native"
  ansible.utils.cli_parse:
    command: show interface
    parser:
      name: ansible.netcommon.native
      template_path: /home/user/templates/filename.yaml

向解析器提供不同于 command 所运行的命令

如果解析器期望使用的命令,不同于 cli_parse 所运行的命令,则可使用 parsercommand 子选项,配置解析器期望使用的命令:

- name: "Run command and parse with native"
  ansible.utils.cli_parse:
    command: sho int
    parser:
      name: ansible.netcommon.native
      command: show interface

提供自定义的操作系统值

使用解析器的 os 子选项直接设置操作系统,而非使用 ansible_network_osansible_distribution 主机变量,生成模板路径或使用指定解析器引擎:

- name: Use ios instead of iosxe for pyats
  ansible.utils.cli_parse:
    command: show something
    parser:
      name: ansible.netcommon.pyats
      os: ios

- name: Use linux instead of fedora from ansible_distribution
  ansible.utils.cli_parse:
    command: ps -ef
    parser:
      name: ansible.netcommon.native
      os: linux

解析既有文本

使用 text 而非 command 选项,解析 playbook 中较早收集的文本。

# using /home/user/templates/filename.yaml
- name: "Parse text from previous task"
  ansible.utils.cli_parse:
    text: "{{ output['stdout'] }}"
    parser:
      name: ansible.netcommon.native
      template_path: /home/user/templates/filename.yaml

 # using /home/user/templates/filename.yaml
- name: "Parse text from file"
  ansible.utils.cli_parse:
    text: "{{ lookup('file', 'path/to/file.txt') }}"
    parser:
      name: ansible.netcommon.native
      template_path: /home/user/templates/filename.yaml

# using templates/nxos_show_version.yaml
- name: "Parse text from previous task"
  ansible.utils.cli_parse:
    text: "{{ sho_version['stdout'] }}"
    parser:
      name: ansible.netcommon.native
      os: nxos
      command: show version

(End)

Last change: 2025-03-18, commit: 6463a7d

小额打赏,赞助 xfoss.com 长存......

微信 | 支付宝

若这里内容有帮助到你,请选择上述方式向 xfoss.com 捐赠。