Ejemplo n.º 1
0
import sys
import textfsm
from tabulate import tabulate

template = sys.argv[1]
output_file = sys.argv[2]

with open(template) as f, open(output_file) as output:
    re_table = textfsm.TextFSM(f)
    header = re_table.header
    result = re_table.ParseText(output.read())
    # print(result)
    print(tabulate(result, headers=header))

## Print the result ##
##  $ python output/Cisco_IOS_Parsing.py output/cisco_ios_show_interfaces.template output/show_int  ##
##  $ python output/Cisco_IOS_Parsing.py output/cisco_ios_show_interfaces.template output/show_int > parse.csv ##
## https://pyneng.readthedocs.io/en/latest/book/21_textfsm/textfsm_examples.html ##
Ejemplo n.º 2
0
    secret = sys.argv[4]

    try:
        print("collect CDP information from device %s..." % target_ip)
        cdp_det_result = get_cdp_neighbor_details(ip=target_ip,
                                                  username=username,
                                                  password=password,
                                                  enable_secret=secret)

        found_hosts = []
        nodes = []
        edges = []

        # parse the show cdp details command using TextFSM
        print("parse results...")
        re_table = textfsm.TextFSM(open("show_cdp_neighbor_detail.textfsm"))
        fsm_results = re_table.ParseText(cdp_det_result)
        local_hostname = "not discovered"

        counter = 1
        for e in fsm_results:
            if len(nodes) == 0:
                # add local node (always ID 1)
                node = {"id": counter, "label": e[0], "group": "root_device"}

                counter += 1
                nodes.append(node)

            # add new node
            remote_node = e[1]
            if remote_node not in found_hosts:
import textfsm

traceroute = """
r2#traceroute 90.0.0.9 source 33.0.0.2
traceroute 90.0.0.9 source 33.0.0.2
Type escape sequence to abort.
Tracing the route to 90.0.0.9
VRF info: (vrf in name/id, vrf out name/id)
  1 10.0.12.1 1 msec 0 msec 0 msec
  2 15.0.0.5  0 msec 5 msec 4 msec
  3 57.0.0.7  4 msec 1 msec 4 msec
  4 79.0.0.9  4 msec *  1 msec
"""

with open("traceroute.template") as f:
    fsm = textfsm.TextFSM(f)
    result = fsm.ParseText(traceroute)

print(fsm.header)
print(result)
Ejemplo n.º 4
0
 {'DUPLEX': 'auto',
  'PORT_NAME': 'Gi0/1/3',
  'PORT_TYPE': '10/100/1000BaseTX',
  'SPEED': 'auto',
  'STATUS': 'notconnect',
  'VLAN': '1'}]'''

import textfsm
from pprint import pprint

template = open("Ex2_sh_int_status.textfsm")

with open("Ex1_sh_int_status.txt") as f:
    raw_data = f.read()

re_table = textfsm.TextFSM(template)
sh_int_status_op = re_table.ParseText(raw_data)
template.close()

sh_int_status_list = []

for intf_entry in sh_int_status_op:
    intf_dict = {}
    port_name = intf_entry[0]
    intf_dict["PORT_NAME"] = port_name
    status = intf_entry[1]
    intf_dict["STATUS"] = status
    vlan = intf_entry[2]
    intf_dict["VLAN"] = vlan
    duplex = intf_entry[3]
    intf_dict["DUPLEX"] = duplex
Ejemplo n.º 5
0
def parse_output(tmpl, showcmd):
    with open(tmpl) as f:
        re_table = textfsm.TextFSM(f)
        header = re_table.header
        result = re_table.ParseText(showcmd)
    return [header, result]
Ejemplo n.º 6
0
import textfsm

traceroute = """
r2#traceroute 90.0.0.9 source 33.0.0.2
traceroute 90.0.0.9 source 33.0.0.2
Type escape sequence to abort.
Tracing the route to 90.0.0.9
VRF info: (vrf in name/id, vrf out name/id)
  1 10.0.12.1 1 msec 0 msec 0 msec
  2 15.0.0.5  0 msec 5 msec 4 msec
  3 57.0.0.7  4 msec 1 msec 4 msec
  4 79.0.0.9  4 msec *  1 msec
"""

with open("traceroute.template") as template:
    fsm = textfsm.TextFSM(template)
    result = fsm.ParseText(traceroute)

print(fsm.header)
print(result)
"""
Example:

['ID', 'Hop']
[['1', '10.0.12.1'], ['2', '15.0.0.5'], ['3', '57.0.0.7'], ['4', '79.0.0.9']]
"""
Ejemplo n.º 7
0
import telnetlib
import time

username = raw_input('Enter username for device login:'******'Enter the corresponding password:'******'device.txt', 'r')
f2 = open('ciscocommand.txt', 'r')

# Creates list based on f1
devices = f1.readlines()
commands = f2.readlines()
template_file = sys.argv[1]
fsm = textfsm.TextFSM(open(template_file))
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
data = []

for device in devices:
    column = device.split()
    data.append([column[0]])
    data[-1].append(column[1])
    print column[0]

    def connectviatelnet():
        try:
            fsm = textfsm.TextFSM(open(template_file))
            output = "Connecting using Telnet"
            print output
Ejemplo n.º 8
0
def extract(template_path, raw_text=None, raw_text_file=None, saltenv="base"):
    r"""
    Extracts the data entities from the unstructured
    raw text sent as input and returns the data
    mapping, processing using the TextFSM template.

    template_path
        The path to the TextFSM template.
        This can be specified using the absolute path
        to the file, or using one of the following URL schemes:

        - ``salt://``, to fetch the template from the Salt fileserver.
        - ``http://`` or ``https://``
        - ``ftp://``
        - ``s3://``
        - ``swift://``

    raw_text: ``None``
        The unstructured text to be parsed.

    raw_text_file: ``None``
        Text file to read, having the raw text to be parsed using the TextFSM template.
        Supports the same URL schemes as the ``template_path`` argument.

    saltenv: ``base``
        Salt fileserver envrionment from which to retrieve the file.
        Ignored if ``template_path`` is not a ``salt://`` URL.

    CLI Example:

    .. code-block:: bash

        salt '*' textfsm.extract salt://textfsm/juniper_version_template raw_text_file=s3://junos_ver.txt
        salt '*' textfsm.extract http://some-server/textfsm/juniper_version_template raw_text='Hostname: router.abc ... snip ...'

    Jinja template example:

    .. code-block:: jinja

        {%- set raw_text = 'Hostname: router.abc ... snip ...' -%}
        {%- set textfsm_extract = salt.textfsm.extract('https://some-server/textfsm/juniper_version_template', raw_text) -%}

    Raw text example:

    .. code-block:: text

        Hostname: router.abc
        Model: mx960
        JUNOS Base OS boot [9.1S3.5]
        JUNOS Base OS Software Suite [9.1S3.5]
        JUNOS Kernel Software Suite [9.1S3.5]
        JUNOS Crypto Software Suite [9.1S3.5]
        JUNOS Packet Forwarding Engine Support (M/T Common) [9.1S3.5]
        JUNOS Packet Forwarding Engine Support (MX Common) [9.1S3.5]
        JUNOS Online Documentation [9.1S3.5]
        JUNOS Routing Software Suite [9.1S3.5]

    TextFSM Example:

    .. code-block:: text

        Value Chassis (\S+)
        Value Required Model (\S+)
        Value Boot (.*)
        Value Base (.*)
        Value Kernel (.*)
        Value Crypto (.*)
        Value Documentation (.*)
        Value Routing (.*)

        Start
        # Support multiple chassis systems.
          ^\S+:$$ -> Continue.Record
          ^${Chassis}:$$
          ^Model: ${Model}
          ^JUNOS Base OS boot \[${Boot}\]
          ^JUNOS Software Release \[${Base}\]
          ^JUNOS Base OS Software Suite \[${Base}\]
          ^JUNOS Kernel Software Suite \[${Kernel}\]
          ^JUNOS Crypto Software Suite \[${Crypto}\]
          ^JUNOS Online Documentation \[${Documentation}\]
          ^JUNOS Routing Software Suite \[${Routing}\]

    Output example:

    .. code-block:: json

        {
            "comment": "",
            "result": true,
            "out": [
                {
                    "kernel": "9.1S3.5",
                    "documentation": "9.1S3.5",
                    "boot": "9.1S3.5",
                    "crypto": "9.1S3.5",
                    "chassis": "",
                    "routing": "9.1S3.5",
                    "base": "9.1S3.5",
                    "model": "mx960"
                }
            ]
        }
    """
    ret = {"result": False, "comment": "", "out": None}
    log.debug("Using the saltenv: {}".format(saltenv))
    log.debug("Caching {} using the Salt fileserver".format(template_path))
    tpl_cached_path = __salt__["cp.cache_file"](template_path, saltenv=saltenv)
    if tpl_cached_path is False:
        ret["comment"] = "Unable to read the TextFSM template from {}".format(
            template_path
        )
        log.error(ret["comment"])
        return ret
    try:
        log.debug(
            "Reading TextFSM template from cache path: {}".format(tpl_cached_path)
        )
        # Disabling pylint W8470 to nto complain about fopen.
        # Unfortunately textFSM needs the file handle rather than the content...
        # pylint: disable=W8470
        tpl_file_handle = fopen(tpl_cached_path, "r")
        # pylint: disable=W8470
        log.debug(tpl_file_handle.read())
        tpl_file_handle.seek(0)  # move the object position back at the top of the file
        fsm_handler = textfsm.TextFSM(tpl_file_handle)
    except textfsm.TextFSMTemplateError as tfte:
        log.error("Unable to parse the TextFSM template", exc_info=True)
        ret[
            "comment"
        ] = "Unable to parse the TextFSM template from {}: {}. Please check the logs.".format(
            template_path, tfte
        )
        return ret
    if not raw_text and raw_text_file:
        log.debug("Trying to read the raw input from {}".format(raw_text_file))
        raw_text = __salt__["cp.get_file_str"](raw_text_file, saltenv=saltenv)
        if raw_text is False:
            ret[
                "comment"
            ] = "Unable to read from {}. Please specify a valid input file or text.".format(
                raw_text_file
            )
            log.error(ret["comment"])
            return ret
    if not raw_text:
        ret["comment"] = "Please specify a valid input file or text."
        log.error(ret["comment"])
        return ret
    log.debug("Processing the raw text:")
    log.debug(raw_text)
    objects = fsm_handler.ParseText(raw_text)
    ret["out"] = _clitable_to_dict(objects, fsm_handler)
    ret["result"] = True
    return ret
def build_iproute_template():
	""" 
	This is the information for the show ip route template. It comes directly from:
		https://github.com/networktocode/ntc-templates/blob/master/templates/cisco_ios_show_ip_route.template
	This script will make this file.	
	"""

	fileContents = [
		'Value Filldown PROTOCOL (\w)\n', 
		'Value Filldown TYPE (\w{0,2})\n', 
		'Value Required,Filldown NETWORK (\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\n', 
		'Value Filldown MASK (\d{1,2})\n', 
		'Value DISTANCE (\d+)\n', 
		'Value METRIC (\d+)\n', 
		'Value NEXTHOP_IP (\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\n', 
		'Value NEXTHOP_IF ([A-Z][\w\-\.:/]+)\n', 
		'Value UPTIME (\d[\w:\.]+)\n', 
		'\n', 
		'Start\n', 
		'  ^Gateway.* -> Routes\n', 
		'\n', 
		'Routes\n', 
		'  # For "is (variably )subnetted" line, capture mask, clear all values.\n', 
		'  ^\s+\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}\/${MASK}\sis -> Clear\n', 
		'  #\n', 
		'  # Match directly connected route with explicit mask\n', 
		'  ^${PROTOCOL}(\s|\*)${TYPE}\s+${NETWORK}\/${MASK}\sis\sdirectly\sconnected,\s${NEXTHOP_IF} -> Record\n', 
		'  #\n', 
		'  # Match directly connected route (mask is inherited from "is subnetted")\n', 
		'  ^${PROTOCOL}(\s|\*)${TYPE}\s+${NETWORK}\sis\sdirectly\sconnected,\s${NEXTHOP_IF} -> Record\n', 
		'  #\n',
		'  # Match regular routes, with mask, where all data in same line\n',
		'  ^${PROTOCOL}(\s|\*)${TYPE}\s+${NETWORK}\/${MASK}\s\[${DISTANCE}/${METRIC}\]\svia\s${NEXTHOP_IP}(,\s${UPTIME})?(,\s${NEXTHOP_IF})? -> Record\n',
		'  #\n',
		'  # Match regular route, all one line, where mask is learned from "is subnetted" line\n',
		'  ^${PROTOCOL}(\s|\*)${TYPE}\s+${NETWORK}\s\[${DISTANCE}\/${METRIC}\]\svia\s${NEXTHOP_IP}(,\s${UPTIME})?(,\s${NEXTHOP_IF})? -> Record\n',
		'  #\n',
		'  # Match route with no via statement (Null via protocol)\n',
		'  ^${PROTOCOL}(\s|\*)${TYPE}\s+${NETWORK}\/${MASK}\s\[${DISTANCE}/${METRIC}\],\s${UPTIME},\s${NEXTHOP_IF} -> Record\n',
		'  #\n',
		'  # Match "is a summary" routes (often Null0)\n',
		'  ^${PROTOCOL}(\s|\*)${TYPE}\s+${NETWORK}\/${MASK}\sis\sa\ssummary,\s${UPTIME},\s${NEXTHOP_IF} -> Record\n',
		'  #\n',
		'  # Match regular routes where the network/mask is on the line above the rest of the route\n',
		'  ^${PROTOCOL}(\s|\*)${TYPE}\s+${NETWORK}\/${MASK} -> Next\n',
		'  #\n',
		'  # Match regular routes where the network only (mask from subnetted line) is on the line above the rest of the route\n',
		'  ^${PROTOCOL}(\s|\*)${TYPE}\s+${NETWORK} -> Next\n',
		'  #\n',
		'  # Match the rest of the route information on line below network (and possibly mask)\n',
		'  ^\s+\[${DISTANCE}\/${METRIC}\]\svia\s${NEXTHOP_IP}(,\s${UPTIME})?(,\s${NEXTHOP_IF})? -> Record\n',
		'  #\n',
		'  # Match load-balanced routes\n',
		'  ^\s+\[${DISTANCE}\/${METRIC}\]\svia\s${NEXTHOP_IP} -> Record\n',
		'  #\n',
		'  # Clear all variables on empty lines\n',
		'  ^\s* -> Clearall\n',
		'\n',
		'EOF\n',	
	]

	with tempfile.TemporaryFile('w+t') as curTemplate:
		# build the tempfile with the template information
		curTemplate.writelines(fileContents)

		# go to the beginning of the file
		curTemplate.seek(0)
		
		# build the parser
		parser = textfsm.TextFSM(curTemplate)

		return parser
Ejemplo n.º 10
0
    
import textfsm
traceroute = '''
r2#traceroute 90.0.0.9 source 33.0.0.2
traceroute 90.0.0.9 source 33.0.0.2
Type escape sequence to abort.
Tracing the route to 90.0.0.9
VRF info: (vrf in name/id, vrf out name/id)
1 10.0.12.1 1 msec 0 msec 0 msec
2 15.0.0.5 0 msec 5 msec 4 msec
3 57.0.0.7 4 msec 1 msec 4 msec
4 79.0.0.9 4 msec * 1 msec
'''

template = open('traceroute.textfsm')  # содержимое файла с шаблоном TextFSM считывается в переменную template
fsm = textfsm.TextFSM(template)        # класс, который обрабатывает шаблон и создает из него объект в TextFSM    
result = fsm.ParseText(traceroute)     # метод, который обрабатывает переданный вывод согласно шаблону 
#                                       и возвращает список списков, в котором каждый элемент - это обработанная строка    

print(fsm.header)                      # я заголовок: print(fsm.header) , который содержит имена переменных и результат обработки
print(result)

Результат выполнения скрипта:
$ python parse_traceroute.py
['ID', 'Hop']
[['1', '10.0.12.1'], ['2', '15.0.0.5'], ['3', '57.0.0.7'], ['4', '79.0.0.9']]


Строки, которые совпали с описанным шаблоном, возвращаются в виде списка
списков. Каждый элемент - это список, который состоит из двух элементов: номера
хопа и IP-адреса.
Ejemplo n.º 11
0
def read_template(template_name: str) -> textfsm.TextFSM:
    with open_asset(template_name) as fp:
        return textfsm.TextFSM(fp)
Ejemplo n.º 12
0
import textfsm
template = "templates/juniper_junos_show_lldp_neighbors_interface.textfsm"
raw_text_data = "tests/alcatel_sros/show_lldp_neighbor-match/alcatel_sros_show_lldp_neighbor-match.raw"
re_table = textfsm.TextFSM(open(template))
data = re_table.ParseText("""LLDP Neighbor Information:
Local Information:
Index: 1 Time to live: 120 Time mark: Thu Nov 26 06:41:24 2015 Age: 1 secs
Local Interface    : ge-0/0/8
Parent Interface   : -
Local Port ID      : 518
Ageout Count       : 0

Neighbour Information:
Chassis type       : Mac address
Chassis ID         : 88:e0:f3:1f:14:e0
Port type          : Locally assigned
Port ID            : 880
Port description   : ge-0/0/8
System name        : bng-nw6moj.juniper.net

System Description : Juniper Networks, Inc. ex4300-24p Ethernet Switch, kernel JUNOS 14.1I20151125_0548_rajjs, Build date: 2015-11-25 06:06:58 UTC Copyright (c) 1996-2015 Juniper Networks, Inc.

System capabilities
        Supported: Bridge Router
        Enabled  : Bridge Router

Management address
        Address Type      : IPv4(1)
        Address           : 10.204.39.232
        Interface Number  : 33
        Interface Subtype : ifIndex(2)
Ejemplo n.º 13
0
Begin
  ^${Port}\s+${Vlans}$$ -> Record
  ^Port\s+Vlans allowed and active in management domain$$ -> End
""")


#------------Allowed Vlan Parser TextFSM

for int_col_num in range(2, len(short_interfaces_dictionary) + 2):
    interface = short_interfaces_dictionary[int_col_num]

    print(interface)
    allowed_vlan_output = connect.send_command("""show interface """ + interface + """ trunk""")

    fsm = textfsm.TextFSM(allowed_vlan_parser_template)
    result = fsm.ParseText(allowed_vlan_output)
    row_id=get_key(interface,short_interfaces_dictionary)
    try:
        print(result[0][1])
        worksheet.cell(row_id, 8).value = result[0][1]
        worksheet.cell(row_id, 9).value = "Trunk"

    except:
        worksheet.cell(row_id, 9).value = "Access"
        print("Have no result")
        worksheet.cell(row_id, 8).value = "No Result"



workbook.save("helper.xlsx")