Update network user guide to point to ansible.utils.cli_parse module and add docs for validate plugin (#75104)

* Update network user guide to point to ansible.utils.cli_parse module as ansible.netcommon.cli_parse is deprecated from ansible.netcommon 2.0.0 release
pull/75297/head
Ashwini Mhatre 3 years ago committed by GitHub
parent 2a759cbe20
commit d016499dcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,3 @@
---
bugfixes:
- Update network user guide to explain use of cli_parse and validate plugins.

@ -4,7 +4,7 @@
Parsing semi-structured text with Ansible
*****************************************
The :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.
The :ref:`cli_parse <ansible_collections.ansible.utils.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.
.. contents::
@ -14,7 +14,7 @@ The :ref:`cli_parse <ansible_collections.ansible.netcommon.cli_parse_module>` mo
Understanding the CLI parser
=============================
The `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.
The `ansible.utils <https://galaxy.ansible.com/ansible/utils>`_ collection version 1.0.0 or later includes the :ref:`cli_parse <ansible_collections.ansible.utils.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.
Why parse the text?
--------------------
@ -67,7 +67,7 @@ Because ``cli_parse`` uses a plugin based architecture, it can use additional pa
.. note::
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.
The ``ansible.netcommon.native`` and ``ansible.utils.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.
Parsing with the native parsing engine
--------------------------------------
@ -145,7 +145,7 @@ The following example task uses ``cli_parse`` with the native parser and the exa
.. code-block:: yaml
- name: "Run command and parse with native"
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
command: show interface
parser:
name: ansible.netcommon.native
@ -247,7 +247,7 @@ The following example task uses ``cli_parse`` with the native parser and the exa
.. code-block:: yaml
- name: Run command and parse
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
command: ip addr show
parser:
name: ansible.netcommon.native
@ -293,10 +293,10 @@ Example task:
.. code-block:: yaml
- name: "Run command and parse as json"
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
command: show interface | json
parser:
name: ansible.netcommon.json
name: ansible.utils.json
register: interfaces
Taking a deeper dive into this task:
@ -319,7 +319,7 @@ Example task:
.. code-block:: yaml
- name: "Run command and parse with ntc_templates"
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
command: show interface
parser:
name: ansible.netcommon.ntc_templates
@ -378,7 +378,7 @@ Example task:
.. code-block:: yaml
- name: "Run command and parse with pyats"
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
command: show interface
parser:
name: ansible.netcommon.pyats
@ -488,10 +488,10 @@ The following task uses the example template for ``textfsm`` with the ``cli_pars
.. code-block:: yaml
- name: "Run command and parse with textfsm"
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
command: show interface
parser:
name: ansible.netcommon.textfsm
name: ansible.utils.textfsm
set_fact: interfaces
Taking a deeper dive into this task:
@ -552,10 +552,10 @@ The following task uses this template to parse the ``show interface`` command ou
.. code-block:: yaml
- name: "Run command and parse with ttp"
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
command: show interface
parser:
name: ansible.netcommon.ttp
name: ansible.utils.ttp
set_fact: interfaces
Taking a deeper dive in this task:
@ -618,10 +618,10 @@ This example task runs the ``show interface`` command and parses the output as X
.. code-block:: yaml
- name: "Run command and parse as xml"
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
command: show interface | xml
parser:
name: ansible.netcommon.xml
name: ansible.utils.xml
set_fact: interfaces
.. note::
@ -663,7 +663,7 @@ Use the ``template_path`` option to override the default template path in the ta
.. code-block:: yaml
- name: "Run command and parse with native"
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
command: show interface
parser:
name: ansible.netcommon.native
@ -678,7 +678,7 @@ Use the ``command`` suboption for the ``parser`` to configure the command the pa
.. code-block:: yaml
- name: "Run command and parse with native"
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
command: sho int
parser:
name: ansible.netcommon.native
@ -692,14 +692,14 @@ Use the ``os`` suboption to the parser to directly set the OS instead of using `
.. code-block:: yaml
- name: Use ios instead of iosxe for pyats
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
command: show something
parser:
name: ansible.netcommon.pyats
os: ios
- name: Use linux instead of fedora from ansible_distribution
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
command: ps -ef
parser:
name: ansible.netcommon.native
@ -715,7 +715,7 @@ Use the ``text`` option instead of ``command`` to parse text collected earlier
# using /home/user/templates/filename.yaml
- name: "Parse text from previous task"
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
text: "{{ output['stdout'] }}"
parser:
name: ansible.netcommon.native
@ -723,7 +723,7 @@ Use the ``text`` option instead of ``command`` to parse text collected earlier
# using /home/user/templates/filename.yaml
- name: "Parse text from file"
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
text: "{{ lookup('file', 'path/to/file.txt') }}"
parser:
name: ansible.netcommon.native
@ -731,7 +731,7 @@ Use the ``text`` option instead of ``command`` to parse text collected earlier
# using templates/nxos_show_version.yaml
- name: "Parse text from previous task"
ansible.netcommon.cli_parse:
ansible.utils.cli_parse:
text: "{{ sho_version['stdout'] }}"
parser:
name: ansible.netcommon.native

@ -19,6 +19,7 @@ If you're new to Ansible, or new to using Ansible for network automation, start
network_resource_modules
network_best_practices_2.5
cli_parsing
validate
network_debug_troubleshooting
network_working_with_command_output
faq

@ -0,0 +1,164 @@
.. _validate_data:
*************************************************
Validate data against set criteria with Ansible
*************************************************
The :ref:`validate <ansible_collections.ansible.utils.validate_module>` module validates data against your predefined criteria using a validation engine. You can pull this data from a device or file, validate it against your defined criteria, and use the results to identify configuration or operational state drift and optionally take remedial action.
.. contents::
:local:
Understanding the validate plugin
==================================
The `ansible.utils <https://galaxy.ansible.com/ansible/utils>`_ collection includes the :ref:`validate <ansible_collections.ansible.utils.validate_module>` module.
To validate data:
#. Pull in structured data or convert your data to structured format with the :ref:`cli_parse <ansible_collections.ansible.utils.cli_parse_module>` module.
#. Define the criteria to test that data against.
#. Select a validation engine and test the data to see if it is valid based on the selected criteria and validation engine.
The structure of the data and the criteria depends on the validation engine you select. The examples here use the ``jsonschema`` validation engine provided in the `ansible.utils <https://galaxy.ansible.com/ansible/utils>`_ collection.Red Hat Ansible Automation Platform subscription supports limited use if jsonschema public APIs as documented.
Structuring the data
=====================
You can pull previously structured data from a file, or use the :ref:`cli_parse <ansible_collections.ansible.utils.cli_parse_module>` module to structure your data.
The following example fetches the operational state of some network (Cisco NXOS) interfaces and translates that state to structured data using the ``ansible.netcommon.pyats`` parser.
.. code-block:: yaml
---
- hosts: nxos
connection: ansible.netcommon.network_cli
gather_facts: false
vars:
ansible_network_os: cisco.nxos.nxos
ansible_user: "changeme"
ansible_password: "changeme"
tasks:
- name: "Fetch interface state and parse with pyats"
ansible.utils.cli_parse:
command: show interface
parser:
name: ansible.netcommon.pyats
register: nxos_pyats_show_interface
- name: print structured interface state data
ansible.builtin.debug:
msg: "{{ nxos_pyats_show_interface['parsed'] }}"
----
This results in the following structured data.
.. code-block:: text
ok: [nxos] => {
"changed": false,
"parsed": {
"Ethernet2/1": {
"admin_state": "down",
"auto_mdix": "off",
"auto_negotiate": false,
"bandwidth": 1000000,
"beacon": "off"
<--output omitted-->
},
"Ethernet2/10": {
"admin_state": "down",
"auto_mdix": "off",
"auto_negotiate": false,
"bandwidth": 1000000,
"beacon": "off",
<--output omitted-->
}
}
}
See :ref:`cli_parsing` for details on how to parse semi-structured data into structured data.
Defining the criteria to validate against
=========================================
This example uses the `jsonschema <https://pypi.org/project/jsonschema/>`_ validation engine to parse the JSON structured data we created in the prior section. the criteria defines the state we want the data to conform to. In this instance, we can validate against a desired admin state of ``up`` for all the interfaces.
The criteria for ``jsonschema`` in this example is as follows:
.. code-block:: text
$cat criteria/nxos_show_interface_admin_criteria.json
{
"type" : "object",
"patternProperties": {
"^.*": {
"type": "object",
"properties": {
"admin_state": {
"type": "string",
"pattern": "up"
}
}
}
}
}
Validating the data
====================
Now that we have the structured data and the criteria, we can validate this data with the :ref:`validate <ansible_collections.ansible.utils.validate_module>` module.
The following tasks check if the current state of the interfaces match the desired state defined in the criteria file.
.. code-block:: yaml
- name: Validate interface admin state
ansible.utils.validate:
data: "{{ nxos_pyats_show_interface['parsed'] }}"
criteria:
- "{{ lookup('file', './criteria/nxos_show_interface_admin_criteria.json') | from_json }}"
engine: ansible.utils.jsonschema
ignore_errors: true
register: result
- name: Print the interface names that do not satisfy the desired state
ansible.builtin.debug:
msg: "{{ item['data_path'].split('.')[0] }}"
loop: "{{ result['errors'] }}"
when: "'errors' in result"
In these tasks, we have:
#. Set ``data`` to the structured JSON data from the :ref:`cli_parse <ansible_collections.ansible.utils.cli_parse_module>` module.
#. Set ``criteria`` to the JSON criteria file we defined.
#. Set the validate engine to ``jsonschema``.
.. note::
The value of the criteria option can be a list and should be in a format that is defined by the validation engine used. You need to install the `jsonschema <https://pypi.org/project/jsonschema/>`_ on the control node for this example.
The tasks output a list of errors indicating interfaces that do not have admin value in ``up`` state.
.. code-block:: text
TASK [Validate interface for admin state] ***********************************************************************************************************
fatal: [nxos02]: FAILED! => {"changed": false, "errors": [{"data_path": "Ethernet2/1.admin_state", "expected": "up", "found": "down", "json_path": "$.Ethernet2/1.admin_state", "message": "'down' does not match 'up'", "relative_schema": {"pattern": "up", "type": "string"}, "schema_path": "patternProperties.^.*.properties.admin_state.pattern", "validator": "pattern"}, {"data_path": "Ethernet2/10.admin_state", "expected": "up", "found": "down", "json_path": "$.Ethernet2/10.admin_state", "message": "'down' does not match 'up'", "relative_schema": {"pattern": "up", "type": "string"}, "schema_path": "patternProperties.^.*.properties.admin_state.pattern", "validator": "pattern"}], "msg": "Validation errors were found.\nAt 'patternProperties.^.*.properties.admin_state.pattern' 'down' does not match 'up'. \nAt 'patternProperties.^.*.properties.admin_state.pattern' 'down' does not match 'up'. \nAt 'patternProperties.^.*.properties.admin_state.pattern' 'down' does not match 'up'. "}
...ignoring
TASK [Print the interface names that do not satisfy the desired state] ****************************************************************************
Monday 14 December 2020 11:05:38 +0530 (0:00:01.661) 0:00:28.676 *******
ok: [nxos] => {
"msg": "Ethernet2/1"
}
ok: [nxos] => {
"msg": "Ethernet2/10"
}
This shows Ethernet2/1 and Ethernet2/10 are not in the desired state based on the defined criteria. You can create a report or take further action to remediate this to bring the interfaces to the desired state based on the defined criteria.
Loading…
Cancel
Save