-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #249 from tcuthbert/textfsm
Add Textfsm Feature
- Loading branch information
Showing
9 changed files
with
234 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,3 +53,7 @@ _build | |
|
||
# PyCharm | ||
.idea | ||
|
||
# 3rd party | ||
vendor/* | ||
.python-version |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import unittest | ||
import os | ||
import mock | ||
from trigger.utils.templates import * | ||
from trigger.conf import settings | ||
from contextlib import contextmanager | ||
from StringIO import StringIO | ||
import cStringIO | ||
|
||
|
||
try: | ||
import textfsm | ||
except ImportError: | ||
print(""" | ||
Woops, looks like you're missing the textfsm library. | ||
Try installing it like this:: | ||
>>> pip install gtextfsm | ||
""") | ||
|
||
|
||
cli_data = """*02:00:42.743 UTC Sat Feb 20 2016""" | ||
|
||
text_fsm_data = """Value TIME (\d+:\d+:\d+\.\d+) | ||
Value TIMEZONE (\w+) | ||
Value DAYWEEK (\w+) | ||
Value MONTH (\w+) | ||
Value DAY (\d+) | ||
Value YEAR (\d+) | ||
Start | ||
^[\*]?${TIME}\s${TIMEZONE}\s${DAYWEEK}\s${MONTH}\s${DAY}\s${YEAR} -> Record | ||
""" | ||
|
||
class CheckTemplates(unittest.TestCase): | ||
"""Test structured CLI object data.""" | ||
|
||
def setUp(self): | ||
data = cStringIO.StringIO(text_fsm_data) | ||
self.re_table = textfsm.TextFSM(data) | ||
self.assertTrue(isinstance(self.re_table, textfsm.textfsm.TextFSM)) | ||
|
||
def testTemplatePath(self): | ||
"""Test that template path is correct.""" | ||
t_path = get_template_path("show clock", dev_type="cisco_ios") | ||
self.failUnless("vendor/ntc_templates/cisco_ios_show_clock.template" in t_path) | ||
|
||
def testGetTextFsmObject(self): | ||
"""Test that we get structured data back from cli output.""" | ||
data = get_textfsm_object(self.re_table, cli_data) | ||
self.assertTrue(isinstance(data, dict)) | ||
keys = ['dayweek', 'time', 'timezone', 'year', 'day', 'month'] | ||
for key in keys: | ||
self.assertTrue(data.has_key(key)) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#coding=utf-8 | ||
|
||
""" | ||
Templating functions for unstructured CLI output. | ||
""" | ||
|
||
__author__ = 'Thomas Cuthbert' | ||
__maintainer__ = 'Thomas Cuthbert' | ||
__email__ = 'tcuthbert90@gmail.com' | ||
__copyright__ = 'Copyright 2016 Trigger Org' | ||
|
||
|
||
import sys | ||
import os | ||
from trigger.conf import settings | ||
from twisted.python import log | ||
|
||
try: | ||
import textfsm | ||
except ImportError: | ||
print(""" | ||
Woops, looks like you're missing the textfsm library. | ||
Try installing it like this:: | ||
>>> pip install gtextfsm | ||
""") | ||
|
||
|
||
# Exports | ||
__all__ = ('get_template_path', 'load_cmd_template', 'get_textfsm_object') | ||
|
||
|
||
def get_template_path(cmd, dev_type=None): | ||
""" | ||
Return textfsm templates from the directory pointed to by the TEXTFSM_TEMPLATE_DIR trigger variable. | ||
:param dev_type: Type of device ie cisco_ios, arista_eos | ||
:type dev_type: str | ||
:param cmd: CLI command to load template. | ||
:type cmd: str | ||
:returns: String template path | ||
""" | ||
t_dir = settings.TEXTFSM_TEMPLATE_DIR | ||
return os.path.join(t_dir, '{1}_{2}.template'.format(t_dir, dev_type, cmd.replace(' ', '_'))) or None | ||
|
||
|
||
def load_cmd_template(cmd, dev_type=None): | ||
""" | ||
:param dev_type: Type of device ie cisco_ios, arista_eos | ||
:type dev_type: str | ||
:param cmd: CLI command to load template. | ||
:type cmd: str | ||
:returns: String template path | ||
""" | ||
try: | ||
with open(get_template_path(cmd, dev_type=dev_type), 'rb') as f: | ||
return textfsm.TextFSM(f) | ||
except: | ||
log.msg("Unable to load template:\n{0} :: {1}".format(cmd, dev_type)) | ||
|
||
|
||
def get_textfsm_object(re_table, cli_output): | ||
"Returns structure object from TextFSM data." | ||
from collections import defaultdict | ||
rv = defaultdict(list) | ||
keys = re_table.header | ||
values = re_table.ParseText(cli_output) | ||
l = [] | ||
for item in values: | ||
l.extend(zip(map(lambda x: x.lower(), keys), item)) | ||
|
||
for k, v in l: | ||
rv[k].append(v) | ||
|
||
return dict(rv) |