109 lines
3.0 KiB
Python
109 lines
3.0 KiB
Python
"""
|
|
xml parser
|
|
|
|
This is the xml parser for use with the cli_parse module and action plugin
|
|
https://github.com/martinblech/xmltodict
|
|
"""
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
|
|
__metaclass__ = type
|
|
|
|
DOCUMENTATION = """
|
|
author: Bradley Thornton (@cidrblock)
|
|
name: xml
|
|
short_description: Define configurable options for C(xml) sub-plugin of M(ansible.utils.cli_parse) module
|
|
description:
|
|
- This plugin documentation provides the configurable options that can be passed
|
|
to the M(ansible.utils.cli_parse) plugins when I(ansible.utils.xml) is used as a value for
|
|
I(name) option.
|
|
version_added: 1.0.0
|
|
"""
|
|
|
|
EXAMPLES = r"""
|
|
- name: "Run command and parse with xml"
|
|
ansible.utils.cli_parse:
|
|
command: "show interface | xml"
|
|
parser:
|
|
name: ansible.utils.xml
|
|
register: nxos_xml_command
|
|
|
|
- name: "Pass text and parse with xml"
|
|
ansible.utils.cli_parse:
|
|
text: "{{ lookup('ansible.builtin.file', '/home/user/files/nxos_show_interface.xml') }}"
|
|
parser:
|
|
name: ansible.utils.xml
|
|
os: nxos
|
|
register: nxos_xml_text
|
|
"""
|
|
|
|
from ansible.module_utils._text import to_native
|
|
from ansible.module_utils.basic import missing_required_lib
|
|
|
|
from ansible_collections.ansible.utils.plugins.plugin_utils.base.cli_parser import CliParserBase
|
|
|
|
|
|
try:
|
|
import xmltodict
|
|
|
|
HAS_XMLTODICT = True
|
|
except ImportError:
|
|
HAS_XMLTODICT = False
|
|
|
|
|
|
class CliParser(CliParserBase):
|
|
"""The xml parser class
|
|
Convert an xml string to structured data using xmltodict
|
|
"""
|
|
|
|
DEFAULT_TEMPLATE_EXTENSION = None
|
|
PROVIDE_TEMPLATE_CONTENTS = False
|
|
|
|
@staticmethod
|
|
def _check_reqs():
|
|
"""Check the prerequisites for the xml parser"""
|
|
errors = []
|
|
if not HAS_XMLTODICT:
|
|
errors.append(missing_required_lib("xmltodict"))
|
|
|
|
return errors
|
|
|
|
def parse(self, *_args, **_kwargs):
|
|
"""Std entry point for a cli_parse parse execution
|
|
|
|
:return: Errors or parsed text as structured data
|
|
:rtype: dict
|
|
|
|
:example:
|
|
|
|
The parse function of a parser should return a dict:
|
|
{"errors": [a list of errors]}
|
|
or
|
|
{"parsed": obj}
|
|
"""
|
|
errors = self._check_reqs()
|
|
if errors:
|
|
return {"errors": errors}
|
|
|
|
cli_output = self._task_args.get("text")
|
|
|
|
network_os = self._task_args.get("parser").get("os") or self._task_vars.get(
|
|
"ansible_network_os",
|
|
)
|
|
# the nxos | xml includes a odd garbage line at the end, so remove it
|
|
if not network_os:
|
|
self._debug("network_os value is not set")
|
|
|
|
if network_os and "nxos" in network_os:
|
|
splitted = cli_output.splitlines()
|
|
if splitted[-1] == "]]>]]>":
|
|
cli_output = "\n".join(splitted[:-1])
|
|
|
|
try:
|
|
parsed = xmltodict.parse(cli_output)
|
|
return {"parsed": parsed}
|
|
except Exception as exc:
|
|
msg = "XML parser returned an error while parsing. Error: {err}"
|
|
return {"errors": [msg.format(err=to_native(exc))]}
|