1.. _cli_parsing:
2
3*****************************************
4Parsing semi-structured text with Ansible
5*****************************************
6
7The :ref:`cli_parse <ansible_collections.ansible.netcommon.cli_parse_module>` module parses semi-structured data such as network configurations into structured data to allow programmatic use of the data from that device. You can pull information from a network device and update a CMDB in one playbook. Use cases include automated troubleshooting, creating dynamic documentation, updating IPAM (IP address management) tools and so on.
8
9
10.. contents::
11   :local:
12
13
14Understanding the CLI parser
15=============================
16
17The `ansible.netcommon <https://galaxy.ansible.com/ansible/netcommon>`_ collection version 1.2.0 or later  includes the :ref:`cli_parse <ansible_collections.ansible.netcommon.cli_parse_module>` module that can run CLI commands and parse the semi-structured text output. You can use the ``cli_parse`` module on a device, host, or platform that only supports a command-line interface and the commands issued return semi-structured text. The ``cli_parse`` module can either run a CLI command on a device and return a parsed result or can simply parse any text document. The ``cli_parse`` module includes cli_parser plugins to interface with a variety of parsing engines.
18
19Why parse the text?
20--------------------
21
22Parsing semi-structured data such as network configurations into structured data allows programmatic use of the data from that device. Use cases include automated troubleshooting, creating dynamic documentation, updating IPAM (IP address management) tools and so on. You may prefer to do this with Ansible natively to take advantage of native Ansible constructs such as:
23
24-  The ``when`` clause to conditionally run other tasks or roles
25-  The ``assert`` module to check configuration and operational state compliance
26-  The ``template`` module to generate reports about configuration and operational state information
27-  Templates and ``command`` or ``config`` modules to generate host, device, or platform commands or configuration
28-  The current platform ``facts`` modules to supplement native facts information
29
30By parsing semi-structured text into Ansible native data structures, you can take full advantage of Ansible's network modules and plugins.
31
32
33When not to parse the text
34---------------------------
35
36You should not parse semi-structured text when:
37
38-  The device, host, or platform has a RESTAPI and returns JSON.
39-  Existing Ansible facts modules already return the desired data.
40-  Ansible network resource modules exist for configuration management of the device and resource.
41
42Parsing the CLI
43=========================
44
45The ``cli_parse`` module includes the following cli_parsing plugins:
46
47``native``
48  The native parsing engine built into Ansible and requires no addition python libraries
49``xml``
50  Convert XML to an Ansible native data structure
51``textfsm``
52  A python module which implements a template based state machine for parsing semi-formatted text
53``ntc_templates``
54  Predefined ``textfsm`` templates packages supporting a variety of platforms and commands
55``ttp``
56  A library for semi-structured text parsing using templates, with added capabilities to simplify the process
57``pyats``
58  Uses the parsers included with the Cisco Test Automation & Validation Solution
59``json``
60  Converts JSON output at the CLI to an Ansible native data structure
61
62Although Ansible contains a number of plugins that can convert XML to Ansible native data structures, the ``cli_parse`` module runs the command on devices that return XML and returns the converted data in a single task.
63
64Because ``cli_parse`` uses a plugin based architecture, it can use additional parsing engines from any Ansible collection.
65
66.. note::
67
68	The ``ansible.netcommon.native``  and ``ansible.netcommon.json`` parsing engines are fully supported with a Red Hat Ansible Automation Platform subscription. Red Hat Ansible Automation Platform subscription support is limited to the use of the ``ntc_templates``, pyATS, ``textfsm``, ``xmltodict``, public APIs as documented.
69
70Parsing with the native parsing engine
71--------------------------------------
72
73The native parsing engine is included with the ``cli_parse`` module. It uses data captured using regular expressions to populate the parsed data structure. The native parsing engine requires a YAML template file to parse the command output.
74
75Networking example
76^^^^^^^^^^^^^^^^^^
77
78This example uses the output of a network device command and applies a native template to produce an output in Ansible structured data format.
79
80The ``show interface`` command output from the network device looks as follows:
81
82.. code-block:: console
83
84   Ethernet1/1 is up
85   admin state is up, Dedicated Interface
86     Hardware: 100/1000/10000 Ethernet, address: 5254.005a.f8bd (bia 5254.005a.f8bd)
87     MTU 1500 bytes, BW 1000000 Kbit, DLY 10 usec
88     reliability 255/255, txload 1/255, rxload 1/255
89     Encapsulation ARPA, medium is broadcast
90     Port mode is access
91     full-duplex, auto-speed
92     Beacon is turned off
93     Auto-Negotiation is turned on  FEC mode is Auto
94     Input flow-control is off, output flow-control is off
95     Auto-mdix is turned off
96     Switchport monitor is off
97     EtherType is 0x8100
98     EEE (efficient-ethernet) : n/a
99     Last link flapped 4week(s) 6day(s)
100     Last clearing of "show interface" counters never
101   <...>
102
103
104Create the native template to match this output and store it as ``templates/nxos_show_interface.yaml``:
105
106.. code-block:: yaml
107
108   ---
109   - example: Ethernet1/1 is up
110     getval: '(?P<name>\S+) is (?P<oper_state>\S+)'
111     result:
112       "{{ name }}":
113         name: "{{ name }}"
114         state:
115           operating: "{{ oper_state }}"
116     shared: true
117
118   - example: admin state is up, Dedicated Interface
119     getval: 'admin state is (?P<admin_state>\S+),'
120     result:
121       "{{ name }}":
122         name: "{{ name }}"
123         state:
124           admin: "{{ admin_state }}"
125
126   - example: "  Hardware: Ethernet, address: 5254.005a.f8b5 (bia 5254.005a.f8b5)"
127     getval: '\s+Hardware: (?P<hardware>.*), address: (?P<mac>\S+)'
128     result:
129       "{{ name }}":
130         hardware: "{{ hardware }}"
131         mac_address: "{{ mac }}"
132
133
134This native parser template is structured as a list of parsers, each containing the following key-value pairs:
135
136-  ``example`` - An example line of the text line to be parsed
137-  ``getval`` - A regular expression using named capture groups to store the extracted data
138-  ``result`` - A data tree, populated as a template, from the parsed data
139-  ``shared`` - (optional) The shared key makes the parsed values available to the rest of the parser entries until matched again.
140
141The following example task uses ``cli_parse`` with the native parser and the example template above to parse the ``show interface`` command from a Cisco NXOS device:
142
143.. code-block:: yaml
144
145   - name: "Run command and parse with native"
146     ansible.netcommon.cli_parse:
147       command: show interface
148         parser:
149           name: ansible.netcommon.native
150       set_fact: interfaces
151
152Taking a deeper dive into this task:
153
154- The ``command`` option provides the command you want to run on the device or host. Alternately, you can provide text from a previous command with the ``text`` option instead.
155- The ``parser`` option provides information specific to the parser engine.
156- The ``name`` suboption provides the fully qualified collection name (FQCN) of the parsing engine (``ansible.netcommon.native``).
157- The ``cli_parse`` module, by default, looks for the template in the templates directory as ``{{ short_os }}_{{ command }}.yaml``.
158
159  - The ``short_os`` in the template filename is derived from either the host ``ansible_network_os`` or ``ansible_distribution``.
160  - Spaces in the network or host command are replace with ``_`` in the ``command`` portion of the template filename. In this example, the ``show interfaces`` network CLI command becomes ``show_interfaces`` in the filename.
161
162.. note::
163
164	``ansible.netcommon.native`` parsing engine is fully supported with a Red Hat Ansible Automation Platform subscription.
165
166Lastly in this task, the ``set_fact`` option sets the following ``interfaces`` fact for the device based on the now-structured data returned from ``cli_parse``:
167
168.. code-block:: yaml
169
170   Ethernet1/1:
171       hardware: 100/1000/10000 Ethernet
172       mac_address: 5254.005a.f8bd
173       name: Ethernet1/1
174       state:
175       admin: up
176       operating: up
177   Ethernet1/10:
178       hardware: 100/1000/10000 Ethernet
179       mac_address: 5254.005a.f8c6
180   <...>
181
182
183Linux example
184^^^^^^^^^^^^^
185
186You can also use the native parser to run commands and parse output from Linux hosts.
187
188The output of a sample Linux  command (``ip addr show``) looks as follows:
189
190.. code-block:: bash
191
192   1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
193       link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
194       inet 127.0.0.1/8 scope host lo
195          valid_lft forever preferred_lft forever
196       inet6 ::1/128 scope host
197          valid_lft forever preferred_lft forever
198   2: enp0s31f6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
199       link/ether x2:6a:64:9d:84:19 brd ff:ff:ff:ff:ff:ff
200   3: wlp2s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
201       link/ether x6:c2:44:f7:41:e0 brd ff:ff:ff:ff:ff:ff permaddr d8:f2:ca:99:5c:82
202
203Create the native template to match this output and store it as ``templates/fedora_ip_addr_show.yaml``:
204
205.. code-block:: yaml
206
207   ---
208   - example: '1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000'
209     getval: |
210       (?x)                                                # free-spacing
211       \d+:\s                                              # the interface index
212       (?P<name>\S+):\s                                    # the name
213       <(?P<properties>\S+)>                               # the properties
214       \smtu\s(?P<mtu>\d+)                                 # the mtu
215       .*                                                  # gunk
216       state\s(?P<state>\S+)                               # the state of the interface
217     result:
218       "{{ name }}":
219           name: "{{ name }}"
220           loopback: "{{ 'LOOPBACK' in stats.split(',') }}"
221           up: "{{ 'UP' in properties.split(',')  }}"
222           carrier: "{{ not 'NO-CARRIER' in properties.split(',') }}"
223           broadcast: "{{ 'BROADCAST' in properties.split(',') }}"
224           multicast: "{{ 'MULTICAST' in properties.split(',') }}"
225           state: "{{ state|lower() }}"
226           mtu: "{{ mtu }}"
227     shared: True
228
229   - example: 'inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0'
230     getval: |
231      (?x)                                                 # free-spacing
232      \s+inet\s(?P<inet>([0-9]{1,3}\.){3}[0-9]{1,3})       # the ip address
233      /(?P<bits>\d{1,2})                                   # the mask bits
234     result:
235       "{{ name }}":
236           ip_address: "{{ inet }}"
237           mask_bits: "{{ bits }}"
238
239.. note::
240
241	 The ``shared`` key in the parser template allows the interface name to be used in subsequent parser entries. The use of examples and free-spacing mode with the regular expressions makes the template easier to read.
242
243The following example task uses ``cli_parse`` with the native parser and the example template above to parse the Linux output:
244
245.. code-block:: yaml
246
247   - name: Run command and parse
248     ansible.netcommon.cli_parse:
249       command: ip addr show
250       parser:
251         name: ansible.netcommon.native
252       set_fact: interfaces
253
254This task assumes you previously gathered facts to determine the ``ansible_distribution`` needed to locate the template. Alternately, you could provide the path in the  ``parser/template_path`` option.
255
256
257Lastly in this task, the ``set_fact`` option sets the following ``interfaces`` fact for the host, based on the now-structured data returned from ``cli_parse``:
258
259.. code-block:: yaml
260
261   lo:
262     broadcast: false
263     carrier: true
264     ip_address: 127.0.0.1
265     mask_bits: 8
266     mtu: 65536
267     multicast: false
268     name: lo
269     state: unknown
270     up: true
271   enp64s0u1:
272     broadcast: true
273     carrier: true
274     ip_address: 192.168.86.83
275     mask_bits: 24
276     mtu: 1500
277     multicast: true
278     name: enp64s0u1
279     state: up
280     up: true
281   <...>
282
283
284Parsing JSON
285-------------
286
287Although Ansible will natively convert serialized JSON to Ansible native data when recognized, you can also use the ``cli_parse`` module for this conversion.
288
289Example task:
290
291.. code-block:: yaml
292
293   - name: "Run command and parse as json"
294     ansible.netcommon.cli_parse:
295       command: show interface | json
296       parser:
297         name: ansible.netcommon.json
298       register: interfaces
299
300Taking a deeper dive into this task:
301
302- The ``show interface | json`` command is issued on the device.
303- The output is set as the ``interfaces`` fact for the device.
304- JSON support is provided primarily for playbook consistency.
305
306.. note::
307
308	The use of ``ansible.netcommon.json`` is fully supported with a Red Hat Ansible Automation Platform subscription
309
310Parsing with ntc_templates
311----------------------------
312
313The ``ntc_templates`` python library includes pre-defined ``textfsm`` templates for parsing a variety of network device commands output.
314
315Example task:
316
317.. code-block:: yaml
318
319   - name: "Run command and parse with ntc_templates"
320     ansible.netcommon.cli_parse:
321       command: show interface
322       parser:
323         name: ansible.netcommon.ntc_templates
324       set_fact: interfaces
325
326Taking a deeper dive into this task:
327
328- The ``ansible_network_os`` of the device is converted to the ntc_template format ``cisco_nxos``. Alternately, you can provide the ``os`` with the ``parser/os`` option instead.
329- The ``cisco_nxos_show_interface.textfsm`` template, included with the ``ntc_templates`` package, parses the output.
330- See `the ntc_templates README <https://github.com/networktocode/ntc-templates/blob/master/README.md>`_ for additional information about the ``ntc_templates`` python library.
331
332.. note::
333
334	Red Hat Ansible Automation Platform subscription support is limited to the use of the ``ntc_templates`` public APIs as documented.
335
336
337This task and and the predefined template sets the following fact as the ``interfaces`` fact for the host:
338
339.. code-block:: yaml
340
341   interfaces:
342   - address: 5254.005a.f8b5
343     admin_state: up
344     bandwidth: 1000000 Kbit
345     bia: 5254.005a.f8b5
346     delay: 10 usec
347     description: ''
348     duplex: full-duplex
349     encapsulation: ARPA
350     hardware_type: Ethernet
351     input_errors: ''
352     input_packets: ''
353     interface: mgmt0
354     ip_address: 192.168.101.14/24
355     last_link_flapped: ''
356     link_status: up
357     mode: ''
358     mtu: '1500'
359     output_errors: ''
360     output_packets: ''
361     speed: 1000 Mb/s
362   - address: 5254.005a.f8bd
363     admin_state: up
364     bandwidth: 1000000 Kbit
365     bia: 5254.005a.f8bd
366     delay: 10 usec
367
368
369Parsing with pyATS
370----------------------
371
372``pyATS`` is part of the Cisco Test Automation & Validation Solution. It includes many predefined parsers for a number of network platforms and commands. You can use the predefined parsers that are part of the ``pyATS`` package with the ``cli_parse`` module.
373
374Example task:
375
376.. code-block:: yaml
377
378   - name: "Run command and parse with pyats"
379     ansible.netcommon.cli_parse:
380       command: show interface
381       parser:
382         name: ansible.netcommon.pyats
383       set_fact: interfaces
384
385
386Taking a deeper dive into this task:
387
388- The ``cli_parse`` modules converts the ``ansible_network_os`` automatically (in this example, ``ansible_network_os`` set to ``cisco.nxos.nxos``, converts to ``nxos`` for pyATS.  Alternately, you can set the OS with the ``parser/os`` option instead.
389- Using a combination of the command and OS, the pyATS selects the following parser: https://pubhub.devnetcloud.com/media/genie-feature-browser/docs/#/parsers/show%2520interface.
390- The ``cli_parse`` module sets ``cisco.ios.ios`` to ``iosxe`` for pyATS. You can override this with the ``parser/os`` option.
391- ``cli_parse`` only uses the predefined parsers in pyATS. See the `pyATS documentation <https://developer.cisco.com/docs/pyats/>`_ and the full list of `pyATS included parsers <https://pubhub.devnetcloud.com/media/genie-feature-browser/docs/#/parsers>`_.
392
393.. note::
394
395	Red Hat Ansible Automation Platform subscription support is limited to the use of the pyATS public APIs as documented.
396
397
398This task sets the following fact as the ``interfaces`` fact for the host:
399
400.. code-block:: yaml
401
402   mgmt0:
403     admin_state: up
404     auto_mdix: 'off'
405     auto_negotiate: true
406     bandwidth: 1000000
407     counters:
408       in_broadcast_pkts: 3
409       in_multicast_pkts: 1652395
410       in_octets: 556155103
411       in_pkts: 2236713
412       in_unicast_pkts: 584259
413       rate:
414         in_rate: 320
415         in_rate_pkts: 0
416         load_interval: 1
417         out_rate: 48
418         out_rate_pkts: 0
419       rx: true
420       tx: true
421     delay: 10
422     duplex_mode: full
423     enabled: true
424     encapsulations:
425       encapsulation: arpa
426     ethertype: '0x0000'
427     ipv4:
428       192.168.101.14/24:
429         ip: 192.168.101.14
430         prefix_length: '24'
431     link_state: up
432     <...>
433
434
435Parsing with textfsm
436---------------------
437
438``textfsm`` is a Python module which implements a template-based state machine for parsing semi-formatted text.
439
440The following sample``textfsm`` template is stored as ``templates/nxos_show_interface.textfsm``
441
442.. code-block:: text
443
444
445   Value Required INTERFACE (\S+)
446   Value LINK_STATUS (.+?)
447   Value ADMIN_STATE (.+?)
448   Value HARDWARE_TYPE (.\*)
449   Value ADDRESS ([a-zA-Z0-9]+.[a-zA-Z0-9]+.[a-zA-Z0-9]+)
450   Value BIA ([a-zA-Z0-9]+.[a-zA-Z0-9]+.[a-zA-Z0-9]+)
451   Value DESCRIPTION (.\*)
452   Value IP_ADDRESS (\d+\.\d+\.\d+\.\d+\/\d+)
453   Value MTU (\d+)
454   Value MODE (\S+)
455   Value DUPLEX (.+duplex?)
456   Value SPEED (.+?)
457   Value INPUT_PACKETS (\d+)
458   Value OUTPUT_PACKETS (\d+)
459   Value INPUT_ERRORS (\d+)
460   Value OUTPUT_ERRORS (\d+)
461   Value BANDWIDTH (\d+\s+\w+)
462   Value DELAY (\d+\s+\w+)
463   Value ENCAPSULATION (\w+)
464   Value LAST_LINK_FLAPPED (.+?)
465
466   Start
467     ^\S+\s+is.+ -> Continue.Record
468     ^${INTERFACE}\s+is\s+${LINK_STATUS},\sline\sprotocol\sis\s${ADMIN_STATE}$$
469     ^${INTERFACE}\s+is\s+${LINK_STATUS}$$
470     ^admin\s+state\s+is\s+${ADMIN_STATE},
471     ^\s+Hardware(:|\s+is)\s+${HARDWARE_TYPE},\s+address(:|\s+is)\s+${ADDRESS}(.*bia\s+${BIA})*
472     ^\s+Description:\s+${DESCRIPTION}
473     ^\s+Internet\s+Address\s+is\s+${IP_ADDRESS}
474     ^\s+Port\s+mode\s+is\s+${MODE}
475     ^\s+${DUPLEX}, ${SPEED}(,|$$)
476     ^\s+MTU\s+${MTU}.\*BW\s+${BANDWIDTH}.\*DLY\s+${DELAY}
477     ^\s+Encapsulation\s+${ENCAPSULATION}
478     ^\s+${INPUT_PACKETS}\s+input\s+packets\s+\d+\s+bytes\s\*$$
479     ^\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\*$$
480     ^\s+${OUTPUT_PACKETS}\s+output\s+packets\s+\d+\s+bytes\s\*$$
481     ^\s+${OUTPUT_ERRORS}\s+output\s+error\s+\d+\s+collision\s+\d+\s+deferred\s+\d+\s+late\s+collision\s\*$$
482     ^\s+Last\s+link\s+flapped\s+${LAST_LINK_FLAPPED}\s\*$$
483
484The following task uses the example template for ``textfsm`` with the ``cli_parse`` module.
485
486.. code-block:: yaml
487
488   - name: "Run command and parse with textfsm"
489     ansible.netcommon.cli_parse:
490       command: show interface
491       parser:
492         name: ansible.netcommon.textfsm
493       set_fact: interfaces
494
495Taking a deeper dive into this task:
496
497- The ``ansible_network_os`` for the device (``cisco.nxos.nxos``) is converted to ``nxos``. Alternately you can provide the OS in the ``parser/os`` option instead.
498- The textfsm template name defaulted to ``templates/nxos_show_interface.textfsm`` using a combination of the OS and command run. Alternately you can override the generated template path with the ``parser/template_path`` option.
499- See the `textfsm README <https://github.com/google/textfsm>`_ for details.
500- ``textfsm`` was previously made available as a filter plugin. Ansible users should transition to the ``cli_parse`` module.
501
502.. note::
503
504	Red Hat Ansible Automation Platform subscription support is limited to the use of the ``textfsm`` public APIs as documented.
505
506This task sets the following fact as the ``interfaces`` fact for the host:
507
508.. code-block:: yaml
509
510   - ADDRESS: X254.005a.f8b5
511     ADMIN_STATE: up
512     BANDWIDTH: 1000000 Kbit
513     BIA: X254.005a.f8b5
514     DELAY: 10 usec
515     DESCRIPTION: ''
516     DUPLEX: full-duplex
517     ENCAPSULATION: ARPA
518     HARDWARE_TYPE: Ethernet
519     INPUT_ERRORS: ''
520     INPUT_PACKETS: ''
521     INTERFACE: mgmt0
522     IP_ADDRESS: 192.168.101.14/24
523     LAST_LINK_FLAPPED: ''
524     LINK_STATUS: up
525     MODE: ''
526     MTU: '1500'
527     OUTPUT_ERRORS: ''
528     OUTPUT_PACKETS: ''
529     SPEED: 1000 Mb/s
530   - ADDRESS: X254.005a.f8bd
531     ADMIN_STATE: up
532     BANDWIDTH: 1000000 Kbit
533     BIA: X254.005a.f8bd
534
535
536Parsing with TTP
537-----------------
538
539TTP is a Python library for semi-structured text parsing using templates. TTP uses a jinja-like syntax to limit the need for regular expressions. Users familiar with jinja templating may find the TTP template syntax familiar.
540
541The following is an example TTP template stored as ``templates/nxos_show_interface.ttp``:
542
543.. code-block:: jinja
544
545   {{ interface }} is {{ state }}
546   admin state is {{ admin_state }}{{ ignore(".\*") }}
547
548The following task uses this template to parse the ``show interface`` command output:
549
550.. code-block:: yaml
551
552   - name: "Run command and parse with ttp"
553     ansible.netcommon.cli_parse:
554       command: show interface
555       parser:
556         name: ansible.netcommon.ttp
557       set_fact: interfaces
558
559Taking a deeper dive in this task:
560
561- The default template path ``templates/nxos_show_interface.ttp`` was generated using the ``ansible_network_os`` for the host and ``command`` provided.
562- TTP supports several additional variables that will be passed to the parser. These include:
563
564  - ``parser/vars/ttp_init`` -  Additional parameter passed when the parser is initialized.
565  - ``parser/vars/ttp_results`` -  Additional parameters used to influence the parser output.
566  - ``parser/vars/ttp_vars`` -  Additional variables made available in the template.
567
568- See the `TTP documentation <https://ttp.readthedocs.io>`_ for details.
569
570
571The task sets the follow fact as the ``interfaces`` fact for the host:
572
573.. code-block:: yaml
574
575   - admin_state: up,
576     interface: mgmt0
577     state: up
578   - admin_state: up,
579     interface: Ethernet1/1
580     state: up
581   - admin_state: up,
582     interface: Ethernet1/2
583     state: up
584
585
586Converting XML
587-----------------
588
589Although Ansible contains a number of plugins that can convert XML to Ansible native data structures, the ``cli_parse`` module runs the command on devices that return XML and returns the converted data in a single task.
590
591This example task runs the ``show interface`` command and parses the output as XML:
592
593.. code-block:: yaml
594
595   - name: "Run command and parse as xml"
596       ansible.netcommon.cli_parse:
597         command: show interface | xml
598         parser:
599           name: ansible.netcommon.xml
600     set_fact: interfaces
601
602.. note::
603
604	Red Hat Ansible Automation Platform subscription support is limited to the use of the ``xmltodict`` public APIs as documented.
605
606This task sets the ``interfaces`` fact for the host based on this returned output:
607
608.. code-block:: yaml
609
610   nf:rpc-reply:
611     '@xmlns': http://www.cisco.com/nxos:1.0:if_manager
612     '@xmlns:nf': urn:ietf:params:xml:ns:netconf:base:1.0
613     nf:data:
614       show:
615         interface:
616           __XML__OPT_Cmd_show_interface_quick:
617             __XML__OPT_Cmd_show_interface___readonly__:
618               __readonly__:
619                 TABLE_interface:
620                   ROW_interface:
621                   - admin_state: up
622                     encapsulation: ARPA
623                     eth_autoneg: 'on'
624                     eth_bia_addr: x254.005a.f8b5
625                     eth_bw: '1000000'
626
627
628Advanced use cases
629===================
630
631The ``cli_parse`` module supports several features to support more complex uses cases.
632
633Provide a full template path
634-----------------------------
635
636Use the ``template_path`` option to override the default template path in the task:
637
638.. code-block:: yaml
639
640   - name: "Run command and parse with native"
641     ansible.netcommon.cli_parse:
642       command: show interface
643       parser:
644         name: ansible.netcommon.native
645         template_path: /home/user/templates/filename.yaml
646
647
648Provide command to parser different than the command run
649-----------------------------------------------------------
650
651Use the ``command`` suboption for the ``parser`` to configure the command the parser expects if it is different from the command ``cli_parse`` runs:
652
653.. code-block:: yaml
654
655   - name: "Run command and parse with native"
656     ansible.netcommon.cli_parse:
657       command: sho int
658       parser:
659         name: ansible.netcommon.native
660         command: show interface
661
662Provide a custom OS value
663--------------------------------
664
665Use the ``os`` suboption to the parser to directly set the OS instead of using ``ansible_network_os`` or ``ansible_distribution`` to generate the template path or with the specified parser engine:
666
667.. code-block:: yaml
668
669   - name: Use ios instead of iosxe for pyats
670     ansible.netcommon.cli_parse:
671       command: show something
672       parser:
673         name: ansible.netcommon.pyats
674         os: ios
675
676   - name: Use linux instead of fedora from ansible_distribution
677     ansible.netcommon.cli_parse:
678       command: ps -ef
679       parser:
680         name: ansible.netcommon.native
681         os: linux
682
683
684Parse existing text
685--------------------
686
687Use the ``text`` option  instead of ``command`` to parse text collected earlier in the playbook.
688
689.. code-block:: yaml
690
691   # using /home/user/templates/filename.yaml
692   - name: "Parse text from previous task"
693     ansible.netcommon.cli_parse:
694       text: "{{ output['stdout'] }}"
695       parser:
696         name: ansible.netcommon.native
697         template_path: /home/user/templates/filename.yaml
698
699    # using /home/user/templates/filename.yaml
700   - name: "Parse text from file"
701     ansible.netcommon.cli_parse:
702       text: "{{ lookup('file', 'path/to/file.txt') }}"
703       parser:
704         name: ansible.netcommon.native
705         template_path: /home/user/templates/filename.yaml
706
707   # using templates/nxos_show_version.yaml
708   - name: "Parse text from previous task"
709     ansible.netcommon.cli_parse:
710       text: "{{ sho_version['stdout'] }}"
711       parser:
712         name: ansible.netcommon.native
713         os: nxos
714         command: show version
715
716
717.. seealso::
718
719  * :ref:`develop_cli_parse_plugins`
720