Skip to content

Instantly share code, notes, and snippets.

@clay584
Last active April 18, 2019 16:53
Show Gist options
  • Select an option

  • Save clay584/78f212d4e9105406b23ca641cdaba90f to your computer and use it in GitHub Desktop.

Select an option

Save clay584/78f212d4e9105406b23ca641cdaba90f to your computer and use it in GitHub Desktop.
#
# (c) 2019, Clay Curtis <jccurtis@presidio.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.errors import AnsibleError
from ansible.module_utils._text import to_bytes, to_native, to_text
from ansible.module_utils.six import string_types
from ansible.utils.display import Display
from genie.conf.base import Device, Testbed
from genie.libs.parser.utils import get_parser
from pyats.datastructures import AttrDict
display = Display()
def genie_parse(cli_output, command=None, os=None):
"""
Uses the Cisco pyATS/Genie library to parse cli output into structured data.
:param cli_output: (String) CLI output from Cisco device
:param command: (String) CLI command that was used to generate the cli_output
:param os: (String) Operating system of the device for which cli_output was obtained.
:return: Dict object conforming to the defined genie parser schema.
https://pubhub.devnetcloud.com/media/pyats-packages/docs/genie/genie_libs/#/parsers/show%20version
"""
# Input validation
# Is the CLI output a string?
if not isinstance(cli_output, string_types):
raise AnsibleError(
"The content provided to the genie_parse filter was not a string."
)
# Is the command a string?
if not isinstance(command, string_types):
raise AnsibleError(
"The command provided to the genie_parse filter was not a string."
)
# Is the OS a string?
if not isinstance(os, string_types):
raise AnsibleError(
"The network OS provided to the genie_parse filter was not a string."
)
# Is the OS provided by the user a supported OS by Genie?
# Supported Genie OSes: https://github.com/CiscoTestAutomation/genieparser/tree/master/src/genie/libs/parser
supported_oses = ["ios", "iosxe", "iosxr", "junos", "nxos"]
if os.lower() not in supported_oses:
raise AnsibleError(
"The network OS provided ({0}) to the genie_parse filter is not a supported OS in Genie.".format(
os
)
)
# Boilerplate code to get the parser functional
tb = Testbed()
device = Device("new_device", os=os)
device.custom.setdefault("abstraction", {})["order"] = ["os"]
device.cli = AttrDict({"execute": None})
# User input checking of the command provided. Does the command have a Genie parser?
try:
get_parser(command, device)
except Exception as e:
raise AnsibleError(
"genie_parse: {0} - Available parsers: {1}".format(
to_native(e), "https://pubhub.devnetcloud.com/media/pyats-packages/docs/genie/genie_libs/#/parsers"
)
)
# Try to parse the output
try:
parsed_output = device.parse(command, output=cli_output)
return parsed_output
except Exception as e:
raise AnsibleError(
"genie_parse: {0} - Failed to parse command output. Hint: Do not use abbreviated cli commands.".format(
to_native(e)
)
)
class FilterModule(object):
""" Cisco pyATS/Genie Parser Filter """
def filters(self):
return {
# jinja2 overrides
"genie_parse": genie_parse
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment