Skip to content

Commit

Permalink
Update cli_parse plugins and testcase (#182)
Browse files Browse the repository at this point in the history
Update cli_parse plugins and testcase

Reviewed-by: https://github.com/apps/ansible-zuul
  • Loading branch information
ganeshrn committed Feb 22, 2021
1 parent 60a9d9a commit 12c98d8
Show file tree
Hide file tree
Showing 38 changed files with 460 additions and 618 deletions.
2 changes: 1 addition & 1 deletion .yamllint
Expand Up @@ -2,7 +2,7 @@
extends: default

ignore: |
.tox
\.tox
changelogs/*

rules:
Expand Down
7 changes: 7 additions & 0 deletions README.md
Expand Up @@ -101,6 +101,13 @@ Name | Description
[ansible.netcommon.restconf_get](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.restconf_get_module.rst)|Fetch configuration/state data from RESTCONF enabled devices.
[ansible.netcommon.telnet](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.telnet_module.rst)|Executes a low-down and dirty telnet command

### Cli_parsers plugins
Name | Description
--- | ---
[ansible.netcommon.native](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.native_cli_parsers.rst)|Define configurable options for C(native) sub-plugin of C(cli_parse) module
[ansible.netcommon.ntc_templates](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.ntc_templates_cli_parsers.rst)|Define configurable options for C(ntc_templates) sub-plugin of C(cli_parse) module
[ansible.netcommon.pyats](https://github.com/ansible-collections/ansible.netcommon/blob/main/docs/ansible.netcommon.pyats_cli_parsers.rst)|Define configurable options for C(pyats) sub-plugin of C(cli_parse) module

<!--end collection content-->


Expand Down
5 changes: 5 additions & 0 deletions changelogs/fragments/182-cli_parse_deprecate.yaml
@@ -0,0 +1,5 @@
---
deprecated_features:
- Deprecate cli_parse module and textfsm, ttp, xml, json parser plugins as they
are moved to ansible.utils collection (https://github.com/ansible-collections/ansible.netcommon/pull/182
https://github.com/ansible-collections/ansible.utils/pull/28)
63 changes: 63 additions & 0 deletions docs/ansible.netcommon.native_cli_parsers.rst
@@ -0,0 +1,63 @@
.. _ansible.netcommon.native_cli_parsers:


************************
ansible.netcommon.native
************************

**Define configurable options for ``native`` sub-plugin of ``cli_parse`` module**


Version added: 1.0.0

.. contents::
:local:
:depth: 1


Synopsis
--------
- This plugin documentation provides the configurable options that can be passed to the *ansible.utils.cli_parse* plugins when *ansible.netcommon.native* is used as a value for *name* option.







Examples
--------

.. code-block:: yaml
- name: "Run command and parse with native"
ansible.utils.cli_parse:
command: "show interface"
parser:
name: ansible.netcommon.native
set_fact: POpqMQoJWTiDpEW
register: nxos_native_command
- name: "Pass text and template_path"
ansible.utils.cli_parse:
text: "{{ nxos_native_command['stdout'] }}"
parser:
name: ansible.netcommon.native
template_path: "/home/user/templates/nxos_show_interface.yaml"
register: nxos_native_text
Status
------


Authors
~~~~~~~

- Bradley Thornton (@cidrblock)


.. hint::
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
62 changes: 62 additions & 0 deletions docs/ansible.netcommon.ntc_templates_cli_parsers.rst
@@ -0,0 +1,62 @@
.. _ansible.netcommon.ntc_templates_cli_parsers:


*******************************
ansible.netcommon.ntc_templates
*******************************

**Define configurable options for ``ntc_templates`` sub-plugin of ``cli_parse`` module**


Version added: 1.0.0

.. contents::
:local:
:depth: 1


Synopsis
--------
- This plugin documentation provides the configurable options that can be passed to the *ansible.utils.cli_parse* plugins when *ansible.netcommon.ntc_templates* is used as a value for *name* option.







Examples
--------

.. code-block:: yaml
- name: "Run command and parse with ntc_templates"
ansible.utils.cli_parse:
command: "show interface"
parser:
name: ansible.netcommon.ntc_templates
register: nxos_ntc_templates_command
- name: "Pass text and command"
ansible.utils.cli_parse:
text: "{{ nxos_ntc_templates_command['stdout'] }}"
parser:
name: ansible.netcommon.ntc_templates
command: show interface
register: nxos_ntc_templates_text
Status
------


Authors
~~~~~~~

- Bradley Thornton (@cidrblock)


.. hint::
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
62 changes: 62 additions & 0 deletions docs/ansible.netcommon.pyats_cli_parsers.rst
@@ -0,0 +1,62 @@
.. _ansible.netcommon.pyats_cli_parsers:


***********************
ansible.netcommon.pyats
***********************

**Define configurable options for ``pyats`` sub-plugin of ``cli_parse`` module**


Version added: 1.0.0

.. contents::
:local:
:depth: 1


Synopsis
--------
- This plugin documentation provides the configurable options that can be passed to the *ansible.utils.cli_parse* plugins when *ansible.netcommon.pyats* is used as a value for *name* option.







Examples
--------

.. code-block:: yaml
- name: "Run command and parse with pyats"
ansible.utils.cli_parse:
command: "show interface"
parser:
name: ansible.netcommon.pyats
register: nxos_pyats_command
- name: "Pass text and command"
ansible.utils.cli_parse:
text: "{{ nxos_pyats_command['stdout'] }}"
parser:
name: ansible.netcommon.pyats
command: show interface
register: nxos_pyats_text
Status
------


Authors
~~~~~~~

- Bradley Thornton (@cidrblock)


.. hint::
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
2 changes: 2 additions & 0 deletions galaxy.yml
@@ -1,6 +1,8 @@
---
authors:
- Ansible Network Community (ansible-network)
dependencies:
"ansible.utils": '>=2.0.0'
license_file: LICENSE
name: netcommon
namespace: ansible
Expand Down
5 changes: 5 additions & 0 deletions meta/runtime.yml
Expand Up @@ -54,3 +54,8 @@ plugin_routing:
deprecation:
removal_date: '2022-06-01'
warning_text: See the plugin documentation for more details
action:
cli_parse:
deprecation:
removal_date: '2023-01-01'
warning_text: Use 'ansible.utils.cli_parse' module instead.
97 changes: 66 additions & 31 deletions plugins/action/cli_parse.py
Expand Up @@ -14,19 +14,19 @@
from importlib import import_module

from ansible.errors import AnsibleActionFail
from ansible.module_utils._text import to_native, to_text, to_bytes
from ansible.module_utils import basic
from ansible.module_utils._text import to_native, to_text
from ansible.module_utils.connection import (
Connection,
ConnectionError as AnsibleConnectionError,
)
from ansible.plugins.action import ActionBase
from ansible_collections.ansible.netcommon.plugins.modules.cli_parse import (
from ansible.utils.display import Display

from ansible_collections.ansible.utils.plugins.modules.cli_parse import (
DOCUMENTATION,
)
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
convert_doc_to_ansible_module_kwargs,
dict_merge,
from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import (
check_argspec,
)

# python 2.7 compat for FileNotFoundError
Expand All @@ -44,13 +44,7 @@
"mutually_exclusive": [["command", "text"]],
}


def generate_argspec():
""" Generate an argspec
"""
argspec = convert_doc_to_ansible_module_kwargs(DOCUMENTATION)
argspec = dict_merge(argspec, ARGSPEC_CONDITIONALS)
return argspec
display = Display()


class ActionModule(ActionBase):
Expand Down Expand Up @@ -86,27 +80,20 @@ def _fail_json(self, msg):
msg = msg.replace("(basic.py)", self._task.action)
raise AnsibleActionFail(msg)

def _check_argspec(self):
""" Load the doc and convert
Add the root conditionals to what was returned from the conversion
and instantiate an AnsibleModule to validate
"""
argspec = generate_argspec()
basic._ANSIBLE_ARGS = to_bytes(
json.dumps({"ANSIBLE_MODULE_ARGS": self._task.args})
)
basic.AnsibleModule.fail_json = self._fail_json
basic.AnsibleModule(**argspec)

def _extended_check_argspec(self):
""" Check additional requirements for the argspec
that cannot be covered using stnd techniques
"""
errors = []
if len(self._task.args.get("parser").get("name").split(".")) != 3:
requested_parser = self._task.args.get("parser").get("name")
if len(requested_parser.split(".")) != 3:
msg = "Parser name should be provided as a full name including collection"
errors.append(msg)
if self._task.args.get("text"):

if self._task.args.get("text") and requested_parser not in [
"ansible.utils.json",
"ansible.utils.xml",
]:
if not (
self._task.args.get("parser").get("command")
or self._task.args.get("parser").get("template_path")
Expand All @@ -129,9 +116,40 @@ def _load_parser(self, task_vars):
cref = dict(
zip(["corg", "cname", "plugin"], requested_parser.split("."))
)
parserlib = "ansible_collections.{corg}.{cname}.plugins.cli_parsers.{plugin}_parser".format(
**cref
)
if cref["cname"] == "netcommon" and cref["plugin"] in [
"json",
"textfsm",
"ttp",
"xml",
]:
cref["cname"] = "utils"
msg = (
"Use 'ansible.utils.{plugin}' for parser name instead of '{requested_parser}'."
" This feature will be removed from 'ansible.netcommon' collection in a release"
" after 2022-11-01".format(
plugin=cref["plugin"], requested_parser=requested_parser
)
)
self._display.warning(msg)
elif cref["cname"] == "netcommon" and cref["plugin"] in [
"native",
"ntc_templates",
"pyats",
]:
parserlib = "ansible_collections.{corg}.{cname}.plugins.sub_plugins.cli_parser.{plugin}_parser".format(
**cref
)
else:
msg = (
"The custom cli_parse sub-plugin location is changed from 'plugins/cli_parsers/' to 'plugins/sub_plugins/cli_parse/'."
" Move the sub-plugins to the new location and update it to use the imports from 'ansible.utils>=2.0.0' collection."
" The old sub-plugin location will no longer be supported after the end of the deprecation cycle for 'ansible.netcommon.cli_parse' module"
)

self._display.warning(msg)
parserlib = "ansible_collections.{corg}.{cname}.plugins.cli_parsers.{plugin}_parser".format(
**cref
)
try:
parsercls = getattr(import_module(parserlib), self.PARSER_CLS_NAME)
parser = parsercls(
Expand Down Expand Up @@ -285,7 +303,24 @@ def run(self, tmp=None, task_vars=None):
:return: The results from the parser
:rtype: dict
"""
self._check_argspec()
msg = (
"Use 'ansible.utils.cli_parse' instead of 'ansible.netcommon.cli_parse'."
" See the plugin documentation for more details."
" This feature will be removed from ansible.netcommon in a release after 2023-01-01"
)
display.deprecated(
msg, date="2023-01-01", collection_name="ansible.netcommon"
)

valid, argspec_result, updated_params = check_argspec(
DOCUMENTATION,
"cli_parse module",
schema_conditionals=ARGSPEC_CONDITIONALS,
**self._task.args
)
if not valid:
return argspec_result

self._extended_check_argspec()
if self._result.get("failed"):
return self._result
Expand Down

0 comments on commit 12c98d8

Please sign in to comment.