def testStateChange(self): # Sinple state change, no actions tplt = ('Value boo (one)\nValue hoo (two)\n\n' 'Start\n ^$boo -> State1\n\nState1\n ^$hoo -> Start\n\n' 'EOF') t = textfsm.TextFSM(StringIO(tplt)) data = 'one' t.ParseText(data) self.assertEqual(t._cur_state[0].match, '^$hoo') self.assertEqual('one', t._GetValue('boo').value) self.assertEqual(None, t._GetValue('hoo').value) self.assertEqual(t._result, []) # State change with actions. tplt = ('Value boo (one)\nValue hoo (two)\n\n' 'Start\n ^$boo -> Next.Record State1\n\n' 'State1\n ^$hoo -> Start\n\n' 'EOF') t = textfsm.TextFSM(StringIO(tplt)) data = 'one' t.ParseText(data) self.assertEqual(t._cur_state[0].match, '^$hoo') self.assertEqual(None, t._GetValue('boo').value) self.assertEqual(None, t._GetValue('hoo').value) self.assertEqual(t._result, [['one', '']])
def testList(self): tplt = ('Value List boo (on.)\n' 'Value hoo (tw.)\n\n' 'Start\n ^$boo\n ^$hoo -> Next.Record\n\n' 'EOF') t = textfsm.TextFSM(StringIO(tplt)) data = 'one\ntwo\non0\ntw0' result = t.ParseText(data) self.assertEqual(str(result), ("[[['one'], 'two'], " "[['on0'], 'tw0']]")) tplt = ('Value List,Filldown boo (on.)\n' 'Value hoo (on.)\n\n' 'Start\n ^$boo -> Continue\n ^$hoo -> Next.Record\n\n' 'EOF') t = textfsm.TextFSM(StringIO(tplt)) data = 'one\non0\non1' result = t.ParseText(data) self.assertEqual(str(result), ("[[['one'], 'one'], " "[['one', 'on0'], 'on0'], " "[['one', 'on0', 'on1'], 'on1']]")) tplt = ('Value List,Required boo (on.)\n' 'Value hoo (tw.)\n\n' 'Start\n ^$boo -> Continue\n ^$hoo -> Next.Record\n\n' 'EOF') t = textfsm.TextFSM(StringIO(tplt)) data = 'one\ntwo\ntw2' result = t.ParseText(data) self.assertEqual(str(result), ("[[['one'], 'two']]"))
def testParseText(self): # Trivial FSM, no records produced. tplt = 'Value unused (.)\n\nStart\n ^Trivial SFM\n' t = textfsm.TextFSM(StringIO(tplt)) data = 'Non-matching text\nline1\nline 2\n' self.assertFalse(t.ParseText(data)) # Matching. data = 'Matching text\nTrivial SFM\nline 2\n' self.assertFalse(t.ParseText(data)) # Simple FSM, One Variable no options. tplt = 'Value boo (.*)\n\nStart\n ^$boo -> Next.Record\n\nEOF\n' t = textfsm.TextFSM(StringIO(tplt)) # Matching one line. # Tests 'Next' & 'Record' actions. data = 'Matching text' result = t.ParseText(data) self.assertEqual(str(result), "[['Matching text']]") # Matching two lines. Reseting FSM before Parsing. t.Reset() data = 'Matching text\nAnd again' result = t.ParseText(data) self.assertEqual(str(result), "[['Matching text'], ['And again']]") # Two Variables and singular options. tplt = ('Value Required boo (one)\nValue Filldown hoo (two)\n\n' 'Start\n ^$boo -> Next.Record\n ^$hoo -> Next.Record\n\n' 'EOF\n') t = textfsm.TextFSM(StringIO(tplt)) # Matching two lines. Only one records returned due to 'Required' flag. # Tests 'Filldown' and 'Required' options. data = 'two\none' result = t.ParseText(data) self.assertEqual(str(result), "[['one', 'two']]") t = textfsm.TextFSM(StringIO(tplt)) # Matching two lines. Two records returned due to 'Filldown' flag. data = 'two\none\none' t.Reset() result = t.ParseText(data) self.assertEqual(str(result), "[['one', 'two'], ['one', 'two']]") # Multiple Variables and options. tplt = ('Value Required,Filldown boo (one)\n' 'Value Filldown,Required hoo (two)\n\n' 'Start\n ^$boo -> Next.Record\n ^$hoo -> Next.Record\n\n' 'EOF\n') t = textfsm.TextFSM(StringIO(tplt)) data = 'two\none\none' result = t.ParseText(data) self.assertEqual(str(result), "[['one', 'two'], ['one', 'two']]")
def testReEnteringState(sefl): """Issue 2. TextFSM should leave file pointer at top of template file.""" tplt = 'Value boo (.*)\n\nStart\n ^$boo -> Next Stop\n\nStop\n ^abc\n' output_text = 'one\ntwo' tmpl_file = StringIO(tplt) t = textfsm.TextFSM(tmpl_file) t.ParseText(output_text) t = textfsm.TextFSM(tmpl_file) t.ParseText(output_text)
def testTextFSM(self): # Trivial template buf = 'Value Beer (.*)\n\nStart\n ^\w\n' buf_result = buf f = StringIO(buf) t = textfsm.TextFSM(f) self.assertEqual(str(t), buf_result) # Slightly more complex, multple vars. buf = 'Value A (.*)\nValue B (.*)\n\nStart\n ^\w\n\nState1\n ^.\n' buf_result = buf f = StringIO(buf) t = textfsm.TextFSM(f) self.assertEqual(str(t), buf_result) # Complex template, multiple vars and states with comments (no var options). buf = """# Header # Header 2 Value Beer (.*) Value Wine (\w+) # An explanation. Start ^hi there ${Wine}. -> Next.Record State1 State1 ^\w ^$Beer .. -> Start # Some comments ^$$ -> Next ^$$ -> End End # Tail comment. """ buf_result = """Value Beer (.*) Value Wine (\w+) Start ^hi there ${Wine}. -> Next.Record State1 State1 ^\w ^$Beer .. -> Start ^$$ -> Next ^$$ -> End """ f = StringIO(buf) t = textfsm.TextFSM(f) self.assertEqual(str(t), buf_result)
def testError(self): tplt = ('Value Required boo (on.)\n' 'Value Filldown,Required hoo (on.)\n\n' 'Start\n ^$boo -> Continue\n ^$hoo -> Error') t = textfsm.TextFSM(StringIO(tplt)) data = 'one' self.assertRaises(textfsm.TextFSMError, t.ParseText, data) tplt = ('Value Required boo (on.)\n' 'Value Filldown,Required hoo (on.)\n\n' 'Start\n ^$boo -> Continue\n ^$hoo -> Error "Hello World"') t = textfsm.TextFSM(StringIO(tplt)) self.assertRaises(textfsm.TextFSMError, t.ParseText, data)
def parse_cisco_show_inventory(content): """ convert the output of a show inventory command to a list of product IDs :param content: :return: """ if type(content) is not str: raise AttributeError("content must be a string data type") # remove empty lines and leading and trailing whitespace sanitized_content = "\n".join( [line.strip() for line in content.splitlines() if line != ""]) template = io.StringIO() template.write("""\ Value name (.+) Value description (.*) Value productid (\S*) Value vid (\S*) Value Required serialnumber (\S+) Start ^NAME: "${name}", DESCR: "${description}" ^PID: ${productid}.*VID: ${vid}.*SN: ${serialnumber} -> Record """) template.seek(0) show_inventory_template = textfsm.TextFSM(template) fsm_results = show_inventory_template.ParseText(sanitized_content) return [line[2] for line in fsm_results if line[2] != ""]
def format_response(dnac, res_json, human, fsm, table): if human: for response in res_json: success = response['commandResponses']['SUCCESS'] failure = response['commandResponses']['FAILURE'] devuuid = response["deviceUuid"] for key in success.keys(): print('{ip}: {command}:\n{success}\n{failure}'.format( ip=deviceid_to_ip(dnac, devuuid), command=key, success=success[key], failure=failure)) elif fsm: # need to generate this in an optimal way # could have more than one command # should fail if this does not work? template = open(fsm) re_table = textfsm.TextFSM(template) table_keys = re_table.header if table: print('IP,Name,Command,' + ','.join(table_keys)) for response in res_json: re_table.Reset() success = response['commandResponses']['SUCCESS'] failure = response['commandResponses']['FAILURE'] devuuid = response["deviceUuid"] for key in success.keys(): if success: raw = re_table.ParseText(success[key]) # will return a list of lists. a command may return a table, i.e. multiple values base = '{ip},{name},{command},'.format( ip=deviceid_to_ip(dnac, devuuid), name=deviceid_to_name(dnac, devuuid), command=key) if table: # join all raw fields together comma sepperated. Append the base to the start of each line formatted = "\n".join( list( map(lambda x: base.__add__(x), (map(lambda x: ','.join(x), raw))))) else: formatted = base + ([ ",".join([ x + ":" + y for (x, y) in zip(table_keys, record) ]) for record in raw ]) print(formatted) if failure: print('{ip},{command},FAILURE {failure}'.format( ip=deviceid_to_ip(dnac, devuuid), command=key, failure=failure)) else: print(json.dumps(res_json, indent=2))
def testKey(self): tplt = ('Value Required boo (on.)\n' 'Value Required,Key hoo (on.)\n\n' 'Start\n ^$boo -> Continue\n ^$hoo -> Record') t = textfsm.TextFSM(StringIO(tplt)) self.assertTrue('Key' in t._GetValue('hoo').OptionNames()) self.assertTrue('Key' not in t._GetValue('boo').OptionNames())
def testValidRegexp(self): """RegexObjects uncopyable in Python 2.6.""" tplt = 'Value boo (fo*)\n\nStart\n ^$boo -> Record\n' t = textfsm.TextFSM(StringIO(tplt)) data = 'f\nfo\nfoo\n' result = t.ParseText(data) self.assertEqual(str(result), "[['f'], ['fo'], ['foo']]")
def testParseNullText(self): # Simple FSM, One Variable no options. tplt = 'Value boo (.*)\n\nStart\n ^$boo -> Next.Record\n\n' t = textfsm.TextFSM(StringIO(tplt)) # Null string data = '' result = t.ParseText(data) self.assertEqual(result, [])
def testContinue(self): tplt = ('Value Required boo (on.)\n' 'Value Filldown,Required hoo (on.)\n\n' 'Start\n ^$boo -> Continue\n ^$hoo -> Continue.Record') t = textfsm.TextFSM(StringIO(tplt)) data = 'one\non0' result = t.ParseText(data) self.assertEqual(str(result), ("[['one', 'one'], ['on0', 'on0']]"))
def get_route(context, target, prefix): """Get output of 'show ip route <prefix> and parse it.""" commands = ["show ip route {}".format(prefix)] with context.get_connection("cli") as cli: response = cli.execute(commands) fsm = textfsm.TextFSM(IOS_SHOW_IP_ROUTE_PREFIX_TEMPLATE) parsed_output = fsm.ParseText(response[0]) key_list = ["entry", "known_via", "admin_distance", "metric", "nexthop"] return dict(zip(key_list, parsed_output[0]))
def testGetValuesByAttrib(self): tplt = ('Value Required boo (on.)\n' 'Value Required,List hoo (on.)\n\n' 'Start\n ^$boo -> Continue\n ^$hoo -> Record') # Explicit default. t = textfsm.TextFSM(StringIO(tplt)) self.assertEqual(t.GetValuesByAttrib('List'), ['hoo']) self.assertEqual(t.GetValuesByAttrib('Filldown'), []) result = t.GetValuesByAttrib('Required') result.sort() self.assertEqual(result, ['boo', 'hoo'])
def textfsm_extractor(cls, template_name, raw_text): """ Applies a TextFSM template over a raw text and return the matching table. Main usage of this method will be to extract data form a non-structured output from a network device and return the values in a table format. :param cls: Instance of the driver class :param template_name: Specifies the name of the template to be used :param raw_text: Text output as the devices prompts on the CLI :return: table-like list of entries """ textfsm_data = list() cls.__class__.__name__.replace('Driver', '') current_dir = os.path.dirname(os.path.abspath(sys.modules[cls.__module__].__file__)) template_dir_path = '{current_dir}/utils/textfsm_templates'.format( current_dir=current_dir ) template_path = '{template_dir_path}/{template_name}.tpl'.format( template_dir_path=template_dir_path, template_name=template_name ) try: fsm_handler = textfsm.TextFSM(open(template_path)) except IOError: raise napalm.base.exceptions.TemplateNotImplemented( "TextFSM template {template_name}.tpl is not defined under {path}".format( template_name=template_name, path=template_dir_path ) ) except textfsm.TextFSMTemplateError as tfte: raise napalm.base.exceptions.TemplateRenderException( "Wrong format of TextFSM template {template_name}: {error}".format( template_name=template_name, error=py23_compat.text_type(tfte) ) ) objects = fsm_handler.ParseText(raw_text) for obj in objects: index = 0 entry = {} for entry_value in obj: entry[fsm_handler.header[index].lower()] = entry_value index += 1 textfsm_data.append(entry) return textfsm_data
def testReset(self): tplt = 'Value boo (.*)\n\nStart\n ^$boo -> Next.Record\n\nEOF\n' t = textfsm.TextFSM(StringIO(tplt)) data = 'Matching text' result1 = t.ParseText(data) t.Reset() result2 = t.ParseText(data) self.assertEqual(str(result1), str(result2)) tplt = ('Value boo (one)\nValue hoo (two)\n\n' 'Start\n ^$boo -> State1\n\n' 'State1\n ^$hoo -> Start\n\n' 'EOF') t = textfsm.TextFSM(StringIO(tplt)) data = 'one' t.ParseText(data) t.Reset() self.assertEqual(t._cur_state[0].match, '^$boo') self.assertEqual(t._GetValue('boo').value, None) self.assertEqual(t._GetValue('hoo').value, None) self.assertEqual(t._result, [])
def testEOF(self): # Implicit EOF. tplt = 'Value boo (.*)\n\nStart\n ^$boo -> Next\n' t = textfsm.TextFSM(StringIO(tplt)) data = 'Matching text' result = t.ParseText(data) self.assertEqual(str(result), "[['Matching text']]") # EOF explicitly suppressed in template. tplt = 'Value boo (.*)\n\nStart\n ^$boo -> Next\n\nEOF\n' t = textfsm.TextFSM(StringIO(tplt)) result = t.ParseText(data) self.assertEqual(str(result), '[]') # Implicit EOF suppressed by argument. tplt = 'Value boo (.*)\n\nStart\n ^$boo -> Next\n' t = textfsm.TextFSM(StringIO(tplt)) result = t.ParseText(data, eof=False) self.assertEqual(str(result), '[]')
def testEnd(self): # End State, EOF is skipped. tplt = 'Value boo (.*)\n\nStart\n ^$boo -> End\n ^$boo -> Record\n' t = textfsm.TextFSM(StringIO(tplt)) data = 'Matching text A\nMatching text B' result = t.ParseText(data) self.assertEqual(str(result), "[]") # End State, with explicit Record. tplt = 'Value boo (.*)\n\nStart\n ^$boo -> Record End\n' t = textfsm.TextFSM(StringIO(tplt)) result = t.ParseText(data) self.assertEqual(str(result), "[['Matching text A']]") # EOF state transition is followed by implicit End State. tplt = 'Value boo (.*)\n\nStart\n ^$boo -> EOF\n ^$boo -> Record\n' t = textfsm.TextFSM(StringIO(tplt)) result = t.ParseText(data) self.assertEqual(str(result), "[['Matching text A']]")
def _parse_cli_output(cli_output_file_fullpath: str, parser_fullpath: str) -> Optional[List]: # TODO try finally with open(cli_output_file_fullpath, 'r') as cli_file: cli_output = cli_file.read() tfsm_template = open(parser_fullpath) re_table = jtextfsm.TextFSM(tfsm_template) re_table_header = re_table.header parsed_output = re_table.ParseText(cli_output) tfsm_template.close() return [re_table_header] + parsed_output
def parseOutput(self, commandOutput, tempateFileName): try: pathToFile = '/etc/textfsm-templates/' + str( tempateFileName).strip() log.info(" Template File Name %s . Output to be parse %s", str(tempateFileName), str(commandOutput)) template = open(pathToFile) re_table = textfsm.TextFSM(template) templateOutput = re_table.ParseText(commandOutput) log.info("Template Output %s ", str(templateOutput)) return templateOutput except Exception as e: log.warning("Parsing Template Got failed.Error msg %s", str(e)) return "ErrorTemplate Parsing Failed"
def get_ospf_neighbors(driver, device): # TODO Normalize output dictionary if driver == "eos": command_output = device.cli(["show ip ospf neighbor"])["show ip ospf neighbor"] fsm_handler = textfsm.TextFSM(open('templates/textfsm/arista_eos_show_ip_ospf_neighbor.template')) elif driver == "junos": command_output = device.cli(["show ospf neighbor"])["show ospf neighbor"] fsm_handler = textfsm.TextFSM(open('templates/textfsm/juniper_junos_show_ospf_neighbor.template')) else: raise NoDriverException("Driver {} not supported by the get_ospf_neighbors method!".format(driver)) textfsm_data = list() objects = fsm_handler.ParseText(command_output) for obj in objects: index = 0 entry = {} for entry_value in obj: entry[fsm_handler.header[index].lower()] = entry_value index += 1 textfsm_data.append(entry) return textfsm_data
def testClear(self): # Clear Filldown variable. # Tests 'Clear'. tplt = ('Value Required boo (on.)\n' 'Value Filldown,Required hoo (tw.)\n\n' 'Start\n ^$boo -> Next.Record\n ^$hoo -> Next.Clear') t = textfsm.TextFSM(StringIO(tplt)) data = 'one\ntwo\nonE\ntwO' result = t.ParseText(data) self.assertEqual(str(result), ("[['onE', 'two']]")) # Clearall, with Filldown variable. # Tests 'Clearall'. tplt = ('Value Filldown boo (on.)\n' 'Value Filldown hoo (tw.)\n\n' 'Start\n ^$boo -> Next.Clearall\n' ' ^$hoo') t = textfsm.TextFSM(StringIO(tplt)) data = 'one\ntwo' result = t.ParseText(data) self.assertEqual(str(result), ("[['', 'two']]"))
def get_interfaces(context,target,interfaces='all'): ''' Executes 'show interfaces <interface>' command and returns a list of interfaces with all its attributes. Arguments: target: Target device interfaces: (Optional) A comma-separated list of interfaces. If not specified, all interfaces are collected. ''' INTERFACE_IOS_TEMPLATE = StringIO.StringIO(dedent("""\ Value name (\S+) Value description (.*) Value admin_status (up|administratively down) Value oper_status (up|down) Value ip_address (\S+) Value bandwidth (\d+) Value input_rate (\d+) Value output_rate (\d+) Value input_bytes (\d+) Value output_bytes (\d+) Start ^\S+ is (up|administratively down) -> Continue.Record ^${name}\s*is\s*${admin_status},\s*line protocol\s*is\s*${oper_status} ^\s*Description: ${description} ^\s*Internet address is ${ip_address} ^\s*MTU.*, BW ${bandwidth} ^\s*.*input rate ${input_rate} ^\s*.*output rate ${output_rate} ^\s*.*packets input, ${input_bytes} ^\s*.*packets output, ${output_bytes} """)) if interfaces == 'all': commands = ['show interfaces'] else: commands = [ 'show interfaces {}'.format(intf) for intf in interfaces.split(",") ] with context.get_connection('cli') as cli: response = cli.execute(commands) fsm = textfsm.TextFSM(INTERFACE_IOS_TEMPLATE) interface_attributes = fsm.header INTERFACE = namedtuple('INTERFACE', interface_attributes) parsed_result = fsm.ParseText(("\n").join(response)) return [ INTERFACE(*intf_attributes) for intf_attributes in parsed_result ]
def testValidateFSM(self): # No Values. f = StringIO('\nNotStart\n') self.assertRaises(textfsm.TextFSMTemplateError, textfsm.TextFSM, f) # No states. f = StringIO('Value unused (.)\n\n') self.assertRaises(textfsm.TextFSMTemplateError, textfsm.TextFSM, f) # No 'Start' state. f = StringIO('Value unused (.)\n\nNotStart\n') self.assertRaises(textfsm.TextFSMTemplateError, textfsm.TextFSM, f) # Has 'Start' state with valid destination f = StringIO('Value unused (.)\n\nStart\n') t = textfsm.TextFSM(f) t.states['Start'] = [] t.states['Start'].append(textfsm.TextFSMRule('^.* -> Start')) t._ValidateFSM() # Invalid destination. t.states['Start'].append(textfsm.TextFSMRule('^.* -> bogus')) self.assertRaises(textfsm.TextFSMTemplateError, t._ValidateFSM) # Now valid again. t.states['bogus'] = [] t.states['bogus'].append(textfsm.TextFSMRule('^.* -> Start')) t._ValidateFSM() # Valid destination with options. t.states['bogus'] = [] t.states['bogus'].append( textfsm.TextFSMRule('^.* -> Next.Record Start')) t._ValidateFSM() # Error with and without messages string. t.states['bogus'] = [] t.states['bogus'].append(textfsm.TextFSMRule('^.* -> Error')) t._ValidateFSM() t.states['bogus'].append(textfsm.TextFSMRule('^.* -> Error "Boo hoo"')) t._ValidateFSM()
def testFillup(self): """Fillup should work ok.""" tplt = """Value Required Col1 ([^-]+) Value Fillup Col2 ([^-]+) Value Fillup Col3 ([^-]+) Start ^$Col1 -- -- -> Record ^$Col1 $Col2 -- -> Record ^$Col1 -- $Col3 -> Record ^$Col1 $Col2 $Col3 -> Record """ data = """ 1 -- B1 2 A2 -- 3 -- B3 """ t = textfsm.TextFSM(StringIO(tplt)) result = t.ParseText(data) self.assertEqual( "[['1', 'A2', 'B1'], ['2', 'A2', 'B3'], ['3', '', 'B3']]", str(result))
you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.''' import jtextfsm as textfsm import json import os dispaysnmpcommunity = """<5900>display snmp community Community name: private Group name: private Storage-type: nonVolatile Community name: public Group name: public Storage-type: nonVolatile <5900>""" template = open("./templates/dispaysnmpcommunity.textfsm") re_table = textfsm.TextFSM(template) fsm_results = re_table.ParseText(dispaysnmpcommunity) for i in fsm_results: print(i)
def va_verify_app_log(self, policy_name=None, app_log_profile_name=None, policy_template=None): """ :param policy_name: :param app_log_profile_name: :param policy_template: :return: True if app-log profile is associated with policy else False """ logger.info("We are in ::" + sys._getframe().f_code.co_name) mandatory = [app_log_profile_name] if not policy_template: policy_template = "policy_template" for param in mandatory: if not param: # TODO: raise ValueError raise ValueError(" The app profile parameter is not provided, \ This is mandetory Argument\n") if policy_name: cmd = "show policy name {}".format(policy_name) else: cmd = "show policy" output = self._access.exec_command(cmd) logger.info("TextFSM parsing POC") policy_template = open(policy_template) policy_table = jtextfsm.TextFSM(policy_template) logger.debug("CLI OUTPUT :\n" + output + "\n\n\n\n") policy_fsm_results = policy_table.ParseText(output) # Results will be writen to output file outputfile_name = open("show_policy_output.csv", "w+") outfile = outputfile_name for s in policy_table.header: outfile.write("%s;" % s) outfile.write("\n") # Iterate for all the rows logger.info(" Here is the result parsed using TextFSM:") counter = 0 for row in policy_fsm_results: logger.info(" Row :" + str(counter) + " columns :" + str(row)) for s in row: outfile.write("%s;" % s) outfile.write("\n") counter += 1 logger.info(" Number of records:" + str(counter)) exit() # below code will do regular pattern matching parsed = self._va_parse_app_profile(output) logger.debug(parsed) for line in parsed: app_log_profile_name = app_log_profile_name if line[1] == policy_name and app_log_profile_name in line[8]: logger.info(" The profile is associated with policy") return True else: logger.error(" The app profile is not \ associated with policy") return False
def run_commands(username, password, switchfile, searchstring): print("Running, please wait...") # OPEN INPUT/OUTPUT FILES # devices = ly(switchfile) with open("./output.log", 'w') as fout: # GRAB CDP NEIGHBORS # for type in devices: if type == 'IOS': for ip in devices[type]: connect_dict = { 'device_type': 'cisco_ios', 'ip': ip, 'username': username, 'password': password } fout.write("\nSwitch: {}\n".format(ip)) fout.write("------------------------\n") try: net_connect = ConnectHandler(**connect_dict) except NetMikoTimeoutException: fout.write("\nUnable to connect (timeout) !\n\n\n\n") continue except NetMikoAuthenticationException: fout.write( "\nUnable to connect (authentication failure) !\n\n\n\n" ) continue output = net_connect.send_command( "show cdp neighbor detail") template = open( "cisco_ios_show_cdp_neighbors_detail.template") re_table = jtextfsm.TextFSM(template) fsm_results = re_table.ParseText(output) # FORMAT NEIGHBORS OUTPUT(LIST OF LIST) INTO PYTHON LIST OF DICTIONARY VALUES (neighbor, port, ip address, etc) # cdpneighbors = [] for neighbor in fsm_results: tempdevice = {} for position, header in enumerate(re_table.header): tempdevice[header] = neighbor[position] cdpneighbors.append(tempdevice) # SEARCH FOR DEVICES AND PRINT/SAVE OUTPUT # found = 0 for device in cdpneighbors: if searchstring in device['PLATFORM']: found += 1 fout.write( "\nConnected device: {} found on port: {}\n". format(device['DESTINATION_HOST'], device['LOCAL_PORT'])) fout.write( net_connect.send_command( "show run interface {}".format( device['LOCAL_PORT']))) fout.write( "\nFound {} devices matching \'{}\'\n\n\n\n".format( found, searchstring)) fout.close() print("\nFinished, output located in \'output.log\' file\n")
def template_parser(filename, raw_output): template_file = '/home/amit/Code/automation/auto_operations/templates/' + filename template_handler = open(template_file) re_table = textfsm.TextFSM(template_handler) result = re_table.ParseText(raw_output) return result
def findSourceRouter(self, hostname, sourceIPs, username, password): Next = 0 Previous = 0 pHandler = "" pHostname = "" rangeList = xrange(0, 2000, 2) baseRouter = 0 shvrfIP = sourceIPs ipSplit = str(sourceIPs).split(".") firstLP = str(ipSplit[0]) + "." + str(ipSplit[1]) + "." + str( ipSplit[2]) + "." try: paths = [] while 1: rHandler = self.connect(hostname, username, password) if str(hostname) in paths: print "conection failed" print paths print hostname router = "->".join(paths) log.warning( 'Unable to find soure router due to last router in chain got login failed. %s ', str(router)) return "Unable to find source router due to last router in chain got login failed. " + str( router) #return paths[-2] else: paths.append(str(hostname)) if "Error" in str(rHandler): log.warning('Connection got failed') return "Connection got failed.So skipped source router finding process.Process stopped at " + hostname + " router" else: if Next in rangeList: pHandler = rHandler pHostname = hostname Next = Next + 1 if baseRouter == 0: command = 'sh ip bgp vpnv4 all | in i' + str(firstLP) else: command = 'sh ip bgp vpnv4 all ' + str(sourceIPs) output = self.runCommand(rHandler, command, hostname) if output: if "Errorrun" in str(output): log.warning("Running command on Router got failed") return "Running command on Router got failed.So skipped source router finding process.Process stopped at " + hostname + " router" else: if baseRouter == 0: lPrefix = self.parsingShowBgpForPrefix( output, command, firstLP, sourceIPs) if "ErrorParser" in str(lPrefix): log.warning("Parser Error.") return "Running command on Router got failed.So skipped source router finding process.Process stopped at " + hostname + " router" elif lPrefix: command = "sh ip bgp vpnv4 all " + str( lPrefix) else: command = 'sh ip route ' + str(sourceIPs) output = self.runCommand( rHandler, command, hostname) if output: cRouter = self.checkSoureRouter( output, command) if "ErrorParser" in str(cRouter): return "Running command on Router got failed.So skipped source router finding process.Process stopped at " + hostname + " router" elif "Yes" in str(cRouter): log.info( 'Source Router IP: %s and router handle %s', str(hostname), str(rHandler)) return hostname elif "No" in str(cRouter): PEAddress = self.parsingShowIPRouter( output, command) if "ErrorParser" in str(PEAddress): log.warning("Parsing error") return "Running command on Router got failed.So skipped source router finding process.Process stopped at " + hostname + " router" elif PEAddress: hostname = PEAddress continue else: log.warning( 'Command output nothing.So consider current router as source router' ) return 'Command came output nothing.So stopping source roure finding process. Process stopped at ' + hostname + ' router' #command="sh ip bgp vpnv4 all "+str(hostname) sourceIPs = lPrefix output = self.runCommand( rHandler, command, hostname) baseRouter = 1 else: pass cRouter = self.checkSoureRouter(output, command) if "ErrorParser" in str(cRouter): return "Running command on Router got failed.So skipped source router finding process.Process stopped at " + hostname + " router" elif "Yes" in str(cRouter): log.info( 'Source Router IP %s and router handle %s', str(hostname), str(rHandler)) vrfName = self.parsingVRFTable(output, command) if vrfName: if "ErrorParser" in str(vrfName): log.warning("Parser Error.") return "Running command on Router got failed.So skipped source router finding process.Process stopped at " + hostname + " router" else: command = 'sh ip route vrf ' + str( vrfName) + ' ' + str(shvrfIP) output = self.runCommand( rHandler, command, hostname) if "Errorrun" in str(output): log.warning( "Running command on Router got failed" ) return "Running command on Router got failed.So skipped source router finding process.Process stopped at " + hostname + " router" else: log.info('%s Command output %s', str(command), str(output)) command = 'traceroute vrf ' + str( vrfName) + ' ' + str( shvrfIP) + ' numeric' output = self.runCommand( rHandler, command, hostname) if "Errorrun" in str(output): log.warning( "Running command on Router got failed" ) return "Running command on Router got failed.So skipped source router finding process.Process stopped at " + hostname + " router" else: log.info('%s Command output %s', str(command), str(output)) template = open( "traceroute.txtfsm") re_table = textfsm.TextFSM( template) traceroute = re_table.ParseText( output) print "traceroute", traceroute tPath = stracePath( 'ops.emc-corp.net', '*****@*****.**', '$V(0r!0N3t') nPath = tPath.getNodeNamePath( traceroute) print "Npath", nPath rPath = tPath.getIPPath(traceroute) print "rpath ", rPath return rPath elif "No" in str(cRouter): PEAddress = self.parsingShowBgpAll( output, command) if "ErrorParser" in str(PEAddress): log.warning("Parsing error") return "Running command on Router got failed.So skipped source router finding process.Process stopped at " + hostname + " router" elif PEAddress: hostname = PEAddress else: log.warning( 'Command output nothing.So consider current router as source router' ) return 'Command output nothing.So stopping source roure finding process. Process stopped at ' + hostname + ' router' else: command = 'sh ip route ' + str(sourceIPs) output = self.runCommand(rHandler, command, hostname) if output: cRouter = self.checkSoureRouter(output, command) if "ErrorParser" in str(cRouter): return "Running command on Router got failed.So skipped source router finding process.Process stopped at " + hostname + " router" elif "Yes" in str(cRouter): log.info( 'Source Router IP: %s and router handle %s', str(hostname), str(rHandler)) return hostname elif "No" in str(cRouter): PEAddress = self.parsingShowIPRouter( output, command) if "ErrorParser" in str(PEAddress): log.warning("Parsing error") return "Running command on Router got failed.So skipped source router finding process.Process stopped at " + hostname + " router" elif PEAddress: hostname = PEAddress else: log.warning( 'Command output nothing.So consider current router as source router' ) return 'Command output nothing.So stopping source roure finding process. Process stopped at ' + hostname + ' router' except Exception as e: log.warning("Exception occured %s ", str(e)) return "Exception occured .Error msg " + str(e)