GMBYTES https://gmbytes.com/ Glenn McCallum Tech Bytes Tue, 07 Sep 2021 16:45:14 +0000 en-US hourly 1 https://gmbytes.com/wp-content/uploads/2021/08/cropped-android-chrome-512x512-1-32x32.png GMBYTES https://gmbytes.com/ 32 32 Tkinter python GUI package https://gmbytes.com/tkinter-python-gui-package/ https://gmbytes.com/tkinter-python-gui-package/#respond Tue, 07 Sep 2021 16:06:29 +0000 https://gmbytes.com/?p=287 I decided to teach myself Tkinter and build a little program to help quickly search and ping/connect to networking devices....

continue reading »

The post Tkinter python GUI package appeared first on GMBYTES.

]]>
I decided to teach myself Tkinter and build a little program to help quickly search and ping/connect to networking devices. The tkinter package (“Tk interface”) is the standard Python interface to the Tcl/Tk GUI toolkit. Both Tk and tkinter are available on most Unix platforms, including macOS, as well as on Windows systems.

End result we will make

What this post will end up making

So tkinter has some learning curve but ideally you just want to layout your program in boxes and then fill those items with buttons, text boxes and anything you want to build. You can see a more detailed documentation here.

This little program grew as I learnt more and more about layouts and positioning and was built to be packaged up and run on a Windows box as the buttons run commands on Windows OS. I have added a few devices into the CSV file as a placeholder but this helped our team search for devices across all the customers we managed.

I split up the program into 3 sections

  1. top-Frame (orange)
  2. Centre-Frame split into
    1. ctr-left (red)
    2. ctr-right (red)
  3. Bottom Frame (blue)

I will break down the code sections below and there is full code on my github https://github.com/glennmccallum/tkinter-nms-helper

Code

from tkinter import *
from tkinter import ttk
import pandas as pd
import os

This code is imported to run tkinter and pandas to read in the csv

#----main----#
host = ""
# Read in csv using pandas
devices = pd.read_csv("all_devices.csv")

# Get All hostnames in a sorted List
hostnames = devices['Hostname']
hostnames = list(hostnames)
hostnames = sorted(hostnames)
# Get All Companies in a sorted List
companies = devices['Company'].unique()
companies = list(companies)
companies = sorted(companies)

This is reading in the csv using pandas and then extracing and sorting the hostnames and customers in alphabetical order.

# Initalise Tkinter
root = Tk()
# Title on window
root.title('NMS HELPER 2.0')
# favicon for window
root.iconbitmap("favicon.ico")
# Size of window
root.geometry('{}x{}'.format(460, 375))

Setup the window using tkinter, naming the, adding a favicon and sizing the window

# create all of the main containers
top_frame = Frame(root, bg='#333333', width=450, height=50, pady=3)
center = Frame(root, bg='gray2', width=50, height=40, padx=3, pady=3)
btm_frame = Frame(root, bg='#333333', width=450, height=45, pady=3)

# layout all of the main containers
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)

# Set the way window can expand
top_frame.grid(row=0, sticky="ew")
center.grid(row=1, sticky="nsew")
btm_frame.grid(row=3, sticky="ew")

This sets up the top, centre and bottom frames of the window

# Create the widgets for the top frame
# Search Label and place in topframe
searchLabel = Label(top_frame, text="Filter Hostname:", bg='#333333', fg="grey")
# Entry textbox for user to filter results in topframe
entry = Entry(top_frame, bg='grey', font=(12))
# give curser focus 
entry.focus()
# when user adds charactrs to filter pass to on_keyrelease function
entry.bind('<KeyRelease>', on_keyrelease)
# Clear search Button assigned to top frame, if pressed pass to clearEntry function
clearSearch = Button(top_frame, text = "Clear Search", command = clearEntry)
# Company seach dropdown comboxbox in top frame
comboBoxLabel = Label(top_frame, text="Filter Company:", bg='#333333', fg="grey")
# Fill the combobox with companies
comboBox = ttk.Combobox(top_frame, values=companies)
# If user selects a company pass to callbackFunc to filter hostnames
comboBox.bind("<<ComboboxSelected>>", callbackFunc)

# layout the widgets in the top frame
searchLabel.grid(row=0, column=0)
entry.grid(row=0, column=1)
clearSearch.grid(row=0, column=2, padx=3, pady=3)
comboBoxLabel.grid(row=1, column=0)
comboBox.grid(row=1, column=1)

This is setting up widgets in Top Frame

# create the center widgets row and columns 
center.grid_rowconfigure(0, weight=1)
center.grid_columnconfigure(0, weight=1)
center.grid_columnconfigure(1, weight=1)
center.grid_columnconfigure(2, weight=4)

# layout the widgets in center frame
ctr_left = Frame(center, bg='#333333')
ctr_mid = Frame(center, bg='#333333')
ctr_right = Frame(center, bg='#333333', padx=3, pady=3)
ctr_left.grid(row=0, column=0, sticky="nsew")
ctr_mid.grid(row=0, column=1, sticky="nsew")
ctr_right.grid(row=0, column=2, sticky="nsew")

# create the widgets in the ctr_left Frame
scrollbar = Scrollbar(ctr_left)
# Make listbox with a black background and grey text
listbox = Listbox(ctr_left, bd=0, background="black", fg="grey",selectbackground="grey", font = (12))

# layout the scrollbar and listbox and attach in the ctr_left Frame
scrollbar.pack(side=RIGHT, fill=Y)
listbox.pack(fill = BOTH, expand=True)
listbox.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=listbox.yview)
# For debugging to show selection was selected in terminal
listbox.bind('<<ListboxSelect>>', on_select)

This sets up the centre_left frame with listbox to list the devices and attach the scrollbar to listbox.

# Show all hostnames when first opening program
listbox_update(hostnames)

shows all the hostnames in the list box when starting the program, listbox_update function explained in a bit

# create the widgets in the centre Right Frame to display hostname details
hostnameLabel = Label(ctr_mid, text="HOSTNAME:", bg='#333333', fg="grey",font = (12))
hostname_entry = Entry(ctr_right, text="",bg='grey',font = (12))

# layout the widgets in the ctr_right Frame
hostnameLabel.pack(fill = X, expand=True)
hostname_entry.pack(fill = X, expand=True)

I wont list all of the text fields but this is a snapshot of how I created the labels and the fields to be dynamically populated

# create the buttons in the Bottom Frame to send to each function to action
ping = Button(btm_frame, text = "PING", command = pingDevice, font = (12))
ssh = Button(btm_frame, text = "SSH", command = sshDevice, font = (12))
telnet = Button(btm_frame, text = "TELNET", command = telnetDevice, font = (12))
http = Button(btm_frame, text = "HTTP", command = httpDevice, font = (12))
https = Button(btm_frame, text = "HTTPS", command = httpsDevice, font = (12))
vnc = Button(btm_frame, text = "VNC", command = vncDevice, font = (12))

# layout the widgets in the Bottom Frame
ping.grid(row=0, column=1, padx=3, pady=3)
ssh.grid(row=0, column=2, padx=3, pady=3)
telnet.grid(row=0, column=3, padx=3, pady=3)
http.grid(row=0, column=4, padx=3, pady=3)
https.grid(row=0, column=5, padx=3, pady=3)
vnc.grid(row=0, column=6, padx=3, pady=3)

Create the buttons in the bottom frame

# run the program
root.mainloop()

Run the program

Functions called from the above code

# Keep filtering listbox when user enters characters in textbox
def on_keyrelease(event):

    # Get value from Entrybox
    value = event.widget.get()
    # Strip whitespaces and convert to lower case
    value = value.strip().lower()

    # If nothing entered display all hostnames
    if value == '':
        data = hostnames
    # else serach hostnames and display any that match string
    else:
        data = []
        for item in hostnames:
            if value in item.lower():
                data.append(item)                

    # Update hostanmes in listbox
    listbox_update(data)

This function was binding to textbox when user typed in to filter the list of devices after each key is pressed it is filters the listbox

# Used to populate the listbox from data entered
def listbox_update(data):
    # delete previous data
    listbox.delete(0, 'end')

    # sorting data 
    data = sorted(data, key=str.lower)

    # put new data
    for item in data:
        listbox.insert('end', item)

listbox_update populates the listbox from the data entered in the text box

# For debugging purposes to show active seclection in terminal
def on_select(event):
    # display element selected on list
    print('(event) previous:', event.widget.get('active'))
    print('(event)  current:', event.widget.get(event.widget.curselection()))
    print('---')
    infoDevice()

Just a debug function to see what the user selected in the terminal

# Get IP of selection from CSV file
def getSelection():
    # Get Current Selection
    selected = listbox.curselection()
    # Get the value of selection
    for item in selected:
        host = listbox.get(item)
    # From selected hostname get the IP from CSV file
    ip = devices.loc[devices['Hostname'] == host, 'IP'].item()

    #return the IP of selected device
    return ip

Once user clicks on a hostname it them looks up the device in csv and returns the IP address

# Used for clear search button to clear all fields
def clearEntry():
    # clear search
    entry.delete(0, 'end')
    # clear data in textbox and update listbox
    value = ''
    data = hostnames
    listbox_update(data)
    # leave curser in focus in textbox
    entry.focus()

    # clear out all device infomration fields
    hostname_entry.delete(0,END)
    natIp_entry.delete(0,END)
    custIp_entry.delete(0,END)
    customer_entry.delete(0,END)
    model_entry.delete(0,END)
    serial_entry.delete(0,END)
    circuit_entry.delete(0,END)
    site_entry.delete(0,END)
    critical_entry.delete(0,END)
    sla_entry.delete(0,END)
    version_entry.delete(0,END)

    #Clear out dropdown cobo box
    comboBox.set('')

Used when you click on the clear button so it resets the filter and clears out all fields

# used for Ping Button
def pingDevice():
    # Get IP from selection
    ip = getSelection()
    # Start cmd and ping IP
    os.system("start cmd /k ping " + ip + " -t")

# used for SSH Button
def sshDevice():
    # Get IP from selection
    ip = getSelection()
    # Start cmd and SSH to IP using Putty
    os.system("start cmd /k putty.exe -ssh " + ip + " 22")

# used for TELNET Button
def telnetDevice():
    # Get IP from selection
    ip = getSelection()
    # Start cmd and telnet to IP using Putty
    os.system("start cmd /k putty.exe -telnet " + ip + " 23")

# used for HTTP Button
def httpDevice():
    # Get IP from selection
    ip = getSelection()
    # Start browser and http to IP
    url = "http://" + ip
    os.startfile(url)

# used for HTTPS Button
def httpsDevice():
    # Get IP from selection
    ip = getSelection()
    # Start browser and https to IP
    url = "https://" + ip
    os.startfile(url)

# used for VNC Button
def vncDevice():
    # Get IP from selection
    ip = getSelection()
    # Start cmd and telnet to IP using Putty
    os.system("start cmd /k vncviewer.exe " + ip)

The functions when you click on each of the buttons. This was built for Windows box so either runs a ping using command prompt or putty.exe for ssh and telnet, opens browser for http and https and uses vncviewer.exe to vnc to host.

# used to get info from CSV for selected device
def infoDevice():
    # Get Current Selection
    selected = listbox.curselection()

    # Get the value of selection
    for item in selected:
        host = listbox.get(item)

    # Get all fields required from CSV
    ip = devices.loc[devices['Hostname'] == host, 'IP'].item()
    cust_ip = devices.loc[devices['Hostname'] == host, 'Customer IP'].item()
    customer = devices.loc[devices['Hostname'] == host, 'Company'].item()
    models = devices.loc[devices['Hostname'] == host, 'Model'].item()
    sn = devices.loc[devices['Hostname'] == host, 'Serial number'].item()
    circuit = devices.loc[devices['Hostname'] == host, 'Circuits'].item()
    site = devices.loc[devices['Hostname'] == host, 'Site'].item()
    critical = devices.loc[devices['Hostname'] == host, 'Critical'].item()
    sla = devices.loc[devices['Hostname'] == host, 'SLA'].item()
    version = devices.loc[devices['Hostname'] == host, 'OS Version'].item()

    # Display results in text fields
    hostname_entry.delete(0,END)
    hostname_entry.insert(0,host)
    natIp_entry.delete(0,END)
    natIp_entry.insert(0,ip)
    custIp_entry.delete(0,END)
    custIp_entry.insert(0,cust_ip)
    customer_entry.delete(0,END)
    customer_entry.insert(0,customer)
    model_entry.delete(0,END)
    model_entry.insert(0,models)
    serial_entry.delete(0,END)
    serial_entry.insert(0,sn)
    circuit_entry.delete(0,END)
    circuit_entry.insert(0,circuit)
    site_entry.delete(0,END)
    site_entry.insert(0,site)
    critical_entry.delete(0,END)
    critical_entry.insert(0,critical)
    sla_entry.delete(0,END)
    sla_entry.insert(0,sla)
    version_entry.delete(0,END)
    version_entry.insert(0,version)

Used to populate the fields about the device once user selects it

# used for Dropdown when selecting a specific company
# display only hostnames in that company
def callbackFunc(event):
    company_Selected = comboBox.get()
    print (company_Selected)
    # locate all hostnames under that copany selected
    data = devices.loc[devices.Company == company_Selected, 'Hostname']
    # update data in listbox
    listbox_update(data)

Used to display only hosts that are related to the customer user picks from the dropdown list

This started out as a learning experience about tkinter and kept evolving so there might be a better way to set out the layout but this worked for me.

Please find the full code on my github https://github.com/glennmccallum/tkinter-nms-helper

The post Tkinter python GUI package appeared first on GMBYTES.

]]>
https://gmbytes.com/tkinter-python-gui-package/feed/ 0
TextFSM parse Cisco output https://gmbytes.com/textfsm-parse-cisco-output/ https://gmbytes.com/textfsm-parse-cisco-output/#respond Sat, 04 Sep 2021 15:59:27 +0000 https://gmbytes.com/?p=263 I recently got a file with all the show cdp neighbour detail from 200 routers in a network and was...

continue reading »

The post TextFSM parse Cisco output appeared first on GMBYTES.

]]>
I recently got a file with all the show cdp neighbour detail from 200 routers in a network and was required to produce a report to show all the devices and their direct connections.

I have cut the output to 3 routers for this example and simplified the output to Router1 to Router3

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Router1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
terminal length 0
Router1#show cdp neighbors detail
-------------------------
Device ID: Switch1
Entry address(es): 
  IP address: 1.1.1.1
Platform: cisco WS-C2960-48PST-L,  Capabilities: Switch IGMP 
Interface: GigabitEthernet0/1/0,  Port ID (outgoing port): FastEthernet0/48
Holdtime : 139 sec

Version :
Cisco IOS Software, C2960 Software (C2960-LANBASEK9-M), Version 12.2(55)SE5, RELEASE SOFTWARE (fc1)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2012 by Cisco Systems, Inc.
Compiled Thu 09-Feb-12 19:11 by prod_rel_team

advertisement version: 2
Protocol Hello:  OUI=0x00000C, Protocol ID=0x0112; payload len=27, value=00000000FFFFFFFF010221FF00000000000034A84E680E80FF0000
VTP Management Domain: 'toxfree'
Native VLAN: 1
Duplex: full
Management address(es): 
  IP address: 1.1.1.1


Total cdp entries displayed : 1
Router1#

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Router2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
terminal length 0
Router2#show cdp neighbors detail
-------------------------
Device ID: Switch2
Entry address(es): 
  IP address: 1.1.1.2
Platform: Cisco C867VAE-K9,  Capabilities: Router Trans-Bridge Source-Route-Bridge Switch IGMP 
Interface: GigabitEthernet0/0/0,  Port ID (outgoing port): GigabitEthernet1
Holdtime : 175 sec

Version :
Cisco IOS Software, C860 Software (C860VAE2-ADVSECK9-M), Version 15.6(3)M3a, RELEASE SOFTWARE (fc2)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2017 by Cisco Systems, Inc.
Compiled Tue 19-Sep-17 00:39 by prod_rel_team

advertisement version: 2
VTP Management Domain: ''
Native VLAN: 5
Duplex: full
Management address(es): 
  IP address: 1.1.1.2

-------------------------
Device ID: Switch3
Entry address(es): 
  IP address: 1.1.1.3
Platform: cisco WS-C2960X-24PS-L,  Capabilities: Switch IGMP 
Interface: GigabitEthernet0/1/0,  Port ID (outgoing port): GigabitEthernet1/0/24
Holdtime : 167 sec

Version :
Cisco IOS Software, C2960X Software (C2960X-UNIVERSALK9-M), Version 15.2(2)E4, RELEASE SOFTWARE (fc2)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2016 by Cisco Systems, Inc.
Compiled Fri 12-Feb-16 22:57 by prod_rel_team

advertisement version: 2
Protocol Hello:  OUI=0x00000C, Protocol ID=0x0112; payload len=27, value=00000000FFFFFFFF010221FF0000000000005006ABCB6980FF0000
VTP Management Domain: ''
Native VLAN: 1
Duplex: full
Management address(es): 
  IP address: 1.1.1.3


Total cdp entries displayed : 2
Router2#

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Router3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
terminal length 0
Router3#show cdp neighbors detail
-------------------------
Device ID: Switch4
Entry address(es): 
  IP address: 1.1.1.4
Platform: cisco WS-C3560CG-8PC-S,  Capabilities: Switch IGMP 
Interface: GigabitEthernet0/1/0,  Port ID (outgoing port): GigabitEthernet0/9
Holdtime : 143 sec

Version :
Cisco IOS Software, C3560C Software (C3560c405ex-UNIVERSALK9-M), Version 15.2(2)E4, RELEASE SOFTWARE (fc2)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2016 by Cisco Systems, Inc.
Compiled Sat 13-Feb-16 02:28 by prod_rel_team

advertisement version: 2
Protocol Hello:  OUI=0x00000C, Protocol ID=0x0112; payload len=27, value=00000000FFFFFFFF010221FF0000000000009C57AD04C500FF0000
VTP Management Domain: ''
Native VLAN: 1
Duplex: full
Management address(es): 
  IP address: 1.1.1.4


Total cdp entries displayed : 1
Router3#

Create a folder named textfsm and save the above output as show_cdp.txt

I am using Sublime Text, python 3.8 and TextFSM to complete this so you can follow along

I am going to assume you already have Python installed so lets install TextFSM, im using Ubuntu so

sudo apt install python3-textfsm

You can download all the textfsm templates from https://github.com/networktocode/ntc-templates but we are only going to use the template named cisco_ios_show_cdp_neighbors_detail.textfsm also shown below

Value Required DESTINATION_HOST (\S+)
Value MANAGEMENT_IP (\d+\.\d+\.\d+\.\d+|\w+\.\w+\.\w+)
Value PLATFORM (.*)
Value REMOTE_PORT (.*)
Value LOCAL_PORT (.*)
Value SOFTWARE_VERSION (.*$)
Value CAPABILITIES (.+?)

Start
  ^Device ID: ${DESTINATION_HOST}
  ^Entry address\(es\)\s*:\s* -> ParseIP
  ^Platform\s*:\s*${PLATFORM}\s*,\s*Capabilities\s*:\s*${CAPABILITIES}\s+$$
  ^Platform\s*:\s*${PLATFORM}\s*,\s*Capabilities\s*:\s*${CAPABILITIES}$$
  ^Interface: ${LOCAL_PORT},  Port ID \(outgoing port\): ${REMOTE_PORT}
  ^Version : -> GetVersion
  # Capture time-stamp if vty line has command time-stamping turned on
  ^Load\s+for\s+
  ^Time\s+source\s+is

ParseIP
  ^.*IP address: ${MANAGEMENT_IP} -> Start
  ^Platform\s*:\s*${PLATFORM}\s*,\s*Capabilities\s*:\s*${CAPABILITIES}\s+$$ -> Start
  ^Platform\s*:\s*${PLATFORM}\s*,\s*Capabilities\s*:\s*${CAPABILITIES}$$ -> Start
  ^.* -> Start

GetVersion
  ^${SOFTWARE_VERSION} -> Record Start

Create a folder named “templates” inside textfsm folder and save the above to a file named cisco_ios_show_cdp_neighbors_detail.textfsm

Below is how I started the script to test TextFSM parsing was working

import textfsm
import json
from pprint import pprint
import re

# Load cisco output into file_data
input_file = open("show_cdp.txt", encoding='utf-8')
file_data = input_file.read()
input_file.close()

# Use textfsm show cdp neighbour detail template
template = open("templates/cisco_ios_show_cdp_neighbors_detail.textfsm")
re_table = textfsm.TextFSM(template)
parsed_output = re_table.ParseText(file_data)

# Parsed output into Dict and print using pretty print
results = [dict(zip(re_table.header, textfsm)) for textfsm in parsed_output]
pprint(results)

Save the above as textfsm_parse_cdp_neighbour_detail.py

With Sublime text you can run the script within sublime by going to Tools->Build System -> Python and then you can just press Control+b to run the script and output will be generated below

You can see that the output in bottom section of window is showing the outputs using Pretty Print but i noticed it did not capture the actual Hosts (ie Router 1, Router2, Router3)

So I made an edit in bold to the TextFSM template below to capture the Hosts to put into the report. I am only using a simple regex to capture the string before the # in each line in show_cdp.txt like

Router1#show cdp neighbors detail 

Add the below in bold to your TextFSM template

Value HOST (.*)
Value Required DESTINATION_HOST (\S+)
Value MANAGEMENT_IP (\d+\.\d+\.\d+\.\d+|\w+\.\w+\.\w+)
Value PLATFORM (.*)
Value REMOTE_PORT (.*)
Value LOCAL_PORT (.*)
Value SOFTWARE_VERSION (.*$)
Value CAPABILITIES (.+?)


Start
  ^${HOST}#show\scdp\sneighbors\sdetail
  ^Device ID: ${DESTINATION_HOST}
  ^Entry address\(es\)\s*:\s* -> ParseIP
  ^Platform\s*:\s*${PLATFORM}\s*,\s*Capabilities\s*:\s*${CAPABILITIES}\s+$$
  ^Platform\s*:\s*${PLATFORM}\s*,\s*Capabilities\s*:\s*${CAPABILITIES}$$
  ^Interface: ${LOCAL_PORT},  Port ID \(outgoing port\): ${REMOTE_PORT}
  ^Version : -> GetVersion
  # Capture time-stamp if vty line has command time-stamping turned on
  ^Load\s+for\s+
  ^Time\s+source\s+is

ParseIP
  ^.*IP address: ${MANAGEMENT_IP} -> Start
  ^Platform\s*:\s*${PLATFORM}\s*,\s*Capabilities\s*:\s*${CAPABILITIES}\s+$$ -> Start
  ^Platform\s*:\s*${PLATFORM}\s*,\s*Capabilities\s*:\s*${CAPABILITIES}$$ -> Start
  ^.* -> Start

GetVersion
  ^${SOFTWARE_VERSION} -> Record Start

Run your script file again and you will now see HOST output

Now we want to output this to a CSV file so add the below at the bottom of your script

# open csv file for output
output = open("cdp_report.csv", "w+")
cdp_report = output

# Write the csv headers on first row
print(re_table.header)
for s in re_table.header:
    cdp_report.write("%s;" % s)
cdp_report.write("\n")

# Write each result to a new row in cdp report
counter = 0
for row in parsed_output:
    print(row)
    for s in row:
        cdp_report.write("%s;" % s)
    cdp_report.write("\n")
    counter += 1

# Print to screen how many rows printed
print("\nWrote %d devices" % counter)

Run your script again in Sublime with Control+b and this should now generate a csv file named cdp_report.csv and output should look like below but there is a small issue. Can you see it?

It is missing Router2 in Cell A4. Router2 has two cdp neighbours where Router1 and Router 3 has only one cdp neighbour each. To fix this we can use a feature on TextFSM called Filldown

Filldown - value that previously matched with a regex, remembered until the next processing line (if has not been explicitly cleared or matched again). This means that the last column value that matches regex is stored and used in the following strings if this column is not present.

So go back and edit your template file and add Filldown to the first line we added in

Value Filldown HOST (.*)

Rerun your script and reopen your csv file and this should be fixed

I hope this demonstrates the power of TextFSM in a practical way to process Cisco output.

I have the full code details on my github https://github.com/glennmccallum/textfsm-parse-cisco-output

Please leave any comments below or any questions

The post TextFSM parse Cisco output appeared first on GMBYTES.

]]>
https://gmbytes.com/textfsm-parse-cisco-output/feed/ 0
Upgrade Cisco Cellular Module Firmware / Microcode https://gmbytes.com/upgrade-cisco-cellular-module-firmware-microcode/ https://gmbytes.com/upgrade-cisco-cellular-module-firmware-microcode/#respond Wed, 01 Sep 2021 05:18:15 +0000 https://gmbytes.com/?p=168 Simple breakdown of process to upgrade the microcode of Cisco Cellular LTE Module. Had a constantly flapping Cellular link and...

continue reading »

The post Upgrade Cisco Cellular Module Firmware / Microcode appeared first on GMBYTES.

]]>
Simple breakdown of process to upgrade the microcode of Cisco Cellular LTE Module. Had a constantly flapping Cellular link and an upgrade of the Cellular firmware resolved the issue.

Overview of steps

  1. Download Firmware files and upload to device into specific folders
  2. Upgrade Firmware and Carrier PRI
  3. Upgrade OEM PRI

Example details

This example will focus on:

  1. Cisco 800 Series Router
  2. Telstra Carrier Sim card
  3. Firmware Before
    1. Firmware – SWI9X30C_02.20.03.01
    1. 4G Carrier PRI – 002.019_001
    2. 4G OEM PRI – 000.010
  4. Firmware Downloads
    1. 4G Firmware – 74xx_02.33.03.00.cwe
    2. 4G Carrier PRI – 7430_02.33.03.00_TELSTRA_002.067_000.nvu
    3. 4G OEM PRI – MC7430_1102644_02.33.03.00_00_Cisco_000.015_000.nvu

Download Firmware and upload to device

Download required firmware from cisco.com
Browse to https://cisco.com and download the required files above

Create folders on Router flash

Router#mkdir FW1
Create directory filename [FW1]? 
Created dir flash:/FW1
Router#
Router#mkdir FW2
Create directory filename [FW2]? 
Created dir flash:/FW1
Router#

Upload 4G Firmware and 4G Carrier PRI to one folder
Upload 74xx_02.33.03.00.cwe and 7430_02.33.03.00_TELSTRA_002.067_000.nvu to FW1 folder

example: Router# copy tftp flash:/FW1

Upload 4G OEM PRI to another folder
Upload MC7430_1102644_02.33.03.00_00_Cisco_000.015_000.nvu to FW2 folder

example: Router# copy tftp flash:/FW2

Verify /md5 for all 3 files
Always verify md5 for each file and compare it with Cisco.com file to make sure files are not corrupted

MD5 for each file
74xx_02.33.03.00.cwe
md5=5847f1d62adc3237000c6571f8d87827

7430_02.33.03.00_TELSTRA_002.067_000.nvu
md5=f7a88d663b949d28e1958903b5b916a9

MC7430_1102644_02.33.03.00_00_Cisco_000.015_000.nvu md5=58d28089be8e7dc27dffc64e26479c38
Router#cd FW1
Router#verify /md5 74xx_02.33.03.00.cwe
……………………………………………….MD5 of flash:/FW1/74xx_02.33.03.00.cwe Done!
verify /md5 (flash:/FW1/74xx_02.33.03.00.cwe) = 5847f1d62adc3237000c6571f8d87827

Make sure the responses match

Upgrade Firmware and Carrier PRI

Make sure you are back in root directory

Router#pwd
flash:/FW1/
Router#cd
Router#pwd
flash:
Router#

Run microcode command to upgrade the firmware and Carrier PRI

microcode reload cellular 0 0  modem-provision flash:FW1
Router#microcode reload cellular 0 0  modem-provision flash:FW1
Reload microcode? [confirm]
Log status of firmware download in router flash system?[confirm]
Firmware download status will be logged in flash:/fwlogfile
Microcode Reload Process launched for Cellular 38890316; hw type = 0x6F3
Router#
*****************************************************
 Modem will be upgraded!
 Upgrade process will take up to 15 minutes. During
 this time the modem will be unusable.
 Please do not remove power or reload the router during
 the upgrade process.
*****************************************************
Modem Device ID: MC7430  MODEM F/W Boot Version: SWI9X30C_02.20.03.01
Modem F/W App Version: SWI9X30C_02.20.03.01      Modem SKU ID: 1102644
Modem Package Identifier:        Modem Carrier String: 2
Modem PRI Ver: 000.010   Modem Carrier Name: TELSTRA
Modem Carrier Revision: 002.019_001

Firmware Upgrade is in Progress...
FIRMWARE INFO AFTER UPGRADE:
Modem Device ID: MC7430  MODEM F/W Boot Version: SWI9X30C_02.33.03.00
Modem F/W App Version: SWI9X30C_02.33.03.00      Modem SKU ID: 1102644
Modem Package Identifier:        Modem Carrier String: 2
Modem PRI Ver: 000.010   Modem Carrier Name: TELSTRA
Modem Carrier Revision: 002.067_000

F/W Upgrade: Firmware Upgrade has Completed Successfully
nqqqmanr01c08#
Note if you have a modular cell module the command might be 
microcode reload cellular 0 1 modem-provision flash:FW1 for Cellular 0/1/0
microcode reload cellular 0 2 modem-provision flash:FW1 for Cellular 0/2/0

After this has completed Cisco advise to wait for 2 mins to make sure the Cell module comes back online but I have seen the module reboot a couple of times after upgrade so I wait a full 5 mins at least before the next upgrade of OEM PRI, so go grab a coffee and then come back.

Check Firmware and PRI is updated to SWI9X30C_02.33.03.00 and 002.067_000

C897-LTE#show cellular 0 hardware
Modem Firmware Version = SWI9X30C_02.33.03.00
Modem Firmware built = 2018/07/25 01:10:04
Hardware Version = 0.2
Device Model ID: MC7430
International Mobile Subscriber Identity (IMSI) = 123456700002704
International Mobile Equipment Identity (IMEI) = 359074060002542
Integrated Circuit Card ID (ICCID) = 8952530076180182704
Mobile Subscriber Integrated Services
Digital Network-Number (MSISDN) =
Modem Status = Online
Current Modem Temperature = 46 deg C
PRI SKU ID = 1102644, PRI version = 002.067_000, Carrier = Telstra
OEM PRI version = 000.010

Upgrade Firmware and Carrier PRI

Run the second microcode command

microcode reload cellular 0 0 modem-provision flash:FW2
nqqqmanr01c08#microcode reload cellular 0 0 modem-provision flash:FW2
Reload microcode? [confirm]
Log status of firmware download in router flash system?[confirm]
Firmware download status will be logged in flash:/fwlogfile
Could not create Log file.
flash: may not be installed or maybe full. Continue?[confirm]
Microcode Reload Process launched for Cellular 38890316; hw type = 0x6F3
nqqqmanr01c08#
*****************************************************
 Modem will be upgraded!
 Upgrade process will take up to 15 minutes. During
 this time the modem will be unusable.
 Please do not remove power or reload the router during
 the upgrade process.
*****************************************************
Modem Device ID: MC7430  MODEM F/W Boot Version: SWI9X30C_02.33.03.00
Modem F/W App Version: SWI9X30C_02.33.03.00      Modem SKU ID: 1102644
Modem Package Identifier:        Modem Carrier String: 2
Modem PRI Ver: 000.010   Modem Carrier Name: TELSTRA
Modem Carrier Revision: 002.067_000

Firmware Upgrade is in Progress...
FIRMWARE INFO AFTER UPGRADE:
F/W Upgrade: Firmware Upgrade has Completed Successfully
nqqqmanr01c08#

Check OEM PRI is updated to 000.015

C897-LTE#show cellular 0 hardware
Modem Firmware Version = SWI9X30C_02.33.03.00 
Modem Firmware built = 2018/07/25 01:10:04
Hardware Version = 0.2
Device Model ID: MC7430
International Mobile Subscriber Identity (IMSI) = 123456700002704
International Mobile Equipment Identity (IMEI) = 359074060002542
Integrated Circuit Card ID (ICCID) = 8952530076180182704
Mobile Subscriber Integrated Services
Digital Network-Number (MSISDN) =
Modem Status = Online
Current Modem Temperature = 46 deg C
PRI SKU ID = 1102644, PRI version = 002.067_000, Carrier = Telstra  
OEM PRI version = 000.015

The post Upgrade Cisco Cellular Module Firmware / Microcode appeared first on GMBYTES.

]]>
https://gmbytes.com/upgrade-cisco-cellular-module-firmware-microcode/feed/ 0
SolarWinds – How to monitor Cisco cellular LTE backup session https://gmbytes.com/solarwinds-how-to-monitor-cisco-cellular-lte-backup-session/ https://gmbytes.com/solarwinds-how-to-monitor-cisco-cellular-lte-backup-session/#respond Wed, 18 Aug 2021 13:20:01 +0000 https://gmbytes.com/?p=193 Issue: How to monitor Cisco Cellular LTE 4G backup Session when used as a backup link (ie. only becomes active...

continue reading »

The post SolarWinds – How to monitor Cisco cellular LTE backup session appeared first on GMBYTES.

]]>
Issue:

How to monitor Cisco Cellular LTE 4G backup Session when used as a backup link (ie. only becomes active when Primary link fails)?

I will detail the minimal solution to capture all scenarios to make sure your cellular backup will work when required.

  • Alert when router is running on Cellular Backup?
  • Alert when Cellular backup has no Service?
  • Alert when Cellular Module is offline?

Background

Cisco Cellular modules either internal or modular usually run with Interface up up even though the session is not active. This doesn’t help alerting on cellular interfaces as there is no way to tell if Session is active or not by the interface status.

Some primary link interfaces also do not go into down down state to indicate an outage on Primary interface, so this also doesn’t help capturing there is an issue with primary link.

Ideally alerting on protocol is down (like BGP) on a primary link is a better option, but some WAN interfaces are running static routing which again rules out protocol alerts to indicate an issue with Primary link in all scenarios.

To avoid duplicate alerts for the same issue (ie, interface down, Protocol down) as well as the new alerts I will explain below I turned off interface and protocol alerting for any router running a Primary link and a Cellular backup.

Alert when router is running on cellular backup

Set up a custom poller to poll results from OID below. This has 3 responses as per table. We want to know when the Cellular Session becomes Active indicating that the primary link is down, router is up and running on backup connection. If the router is powered down then SolarWinds or your alerting system will have device as offline

NameOIDRESULTS
c3gGsmPacketSessionStatus1.3.6.1.4.1.9.9.661.1.3.3.2.1.1unknown(1)
Active(2)
Inactive(3)

Set up an alert trigger to alert when: Node is up and the response is Active(2) for more than 5 mins.

Alert when Cellular backup has no service

The next 2 sections will make sure the Cellular backup is in the best state to make sure it will work when required.

Set up customer poller for OID below to capture if the module can see a valid service. So this will cover the scenarios where the Sim card is not inserted or become dislodged, Sim card has been disconnected by the carrier or just no signal in location to get service.

NameOIDRESULTS
c3gGsmCurrentServiceStatus1.3.6.1.4.1.9.9.661.1.3.2.1.2unknown(1)
noService(2)
normal(3)
emergencyOnly(4)

Set Alert Trigger to alert when: Node is up and the response is not equal to normal(3) for more than 5 minutes

Alert when cellular module is offline

Like above to capture when the whole Cellular module is offline state. Might require a reload of the module, check out earlier post on how to reboot Cellular Module without rebooting the router.

Set up a customer poller for OID below to capture if Module is in offline state.

NameOIDRESULTS
c3gModemStatus1.3.6.1.4.1.9.9.661.1.3.1.1.6unknown(1)
offLine(2)
onLine(3)
lowPowerMode(4)

Set Alert Trigger to alert when: Node is up and response is not equal to OnLine(3) for more than 5 minutes

The post SolarWinds – How to monitor Cisco cellular LTE backup session appeared first on GMBYTES.

]]>
https://gmbytes.com/solarwinds-how-to-monitor-cisco-cellular-lte-backup-session/feed/ 0
Ansible backup Cisco Configuration https://gmbytes.com/ansible-backup-cisco-configuration/ https://gmbytes.com/ansible-backup-cisco-configuration/#respond Sun, 15 Aug 2021 07:10:18 +0000 https://gmbytes.com/?p=180 Quick byte on how to backup a Cisco running-configuration using ansible. Please refer to earlier post about setting up ansible...

continue reading »

The post Ansible backup Cisco Configuration appeared first on GMBYTES.

]]>
Quick byte on how to backup a Cisco running-configuration using ansible.

Please refer to earlier post about setting up ansible and using devnet routers as example to use as test lab for our playbooks.

Create Playbook

Create a new playbook named backup_config.yml and add in the following

---

- hosts: routers
  gather_facts: no
  connection: network_cli

  tasks:

  - name: BACKUP RUNNING CONFIG
    ios_config:
      backup: yes

The above will backup the hosts under “routers” we added previously in other post.

Run the playbook

Running the playbook backup_config.yml

root@macka-VirtualBox:/etc/ansible# ansible-playbook backup_config.yml 

PLAY [routers] ************************************************************************************************************

TASK [BACKUP RUNNING CONFIG] **********************************************************************************************
changed: [sandbox-iosxe-latest-1.cisco.com]
fatal: [sandbox-iosxe-recomm-1.cisco.com]: FAILED! => {"changed": false, "msg": "Error reading SSH protocol banner[Errno 104] Connection reset by peer"}

PLAY RECAP ****************************************************************************************************************
sandbox-iosxe-latest-1.cisco.com : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
sandbox-iosxe-recomm-1.cisco.com : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

root@macka-VirtualBox:/etc/ansible#

We actually see that one device completed successfully and the other failed (router was offline at the time)

Check the backups

By default backups are stored in backups directory

root@macka-VirtualBox:/etc/ansible# cd backup/
root@macka-VirtualBox:/etc/ansible/backup# ls -al
total 20
drwxr-xr-x 2 root root 4096 Aug 15 16:53 .
drwxr-xr-x 4 root root 4096 Aug 14 22:52 ..
-rw-r--r-- 1 root root 9822 Aug 15 16:53 sandbox-iosxe-latest-1.cisco.com_config.2021-08-15@16:53:25
root@macka-VirtualBox:/etc/ansible/backup# 

Yml file can be downloaded from
https://github.com/glennmccallum/Ansible

The post Ansible backup Cisco Configuration appeared first on GMBYTES.

]]>
https://gmbytes.com/ansible-backup-cisco-configuration/feed/ 0
Reboot Cisco Cellular module without rebooting router? https://gmbytes.com/reboot-cisco-cellular-module-without-rebooting-router/ https://gmbytes.com/reboot-cisco-cellular-module-without-rebooting-router/#respond Sat, 14 Aug 2021 12:04:19 +0000 https://gmbytes.com/?p=170 Is there a way to reboot 3G/4G LTE Cellular modem without rebooting the router? NOTE: the command “test cellular <interface>...

continue reading »

The post Reboot Cisco Cellular module without rebooting router? appeared first on GMBYTES.

]]>
Is there a way to reboot 3G/4G LTE Cellular modem without rebooting the router?

NOTE: the command “test cellular <interface> modem-power cycle” is a hidden command. You must configure first “service internal” before the command can be used.

You will lose connectivity to the cli for a brief moment while power cycling.

Router(config)#service internal
Router(config)#exit
Router#test cellular 0 modem-power-cycle
Modem Power cycled successfully
Router#

The post Reboot Cisco Cellular module without rebooting router? appeared first on GMBYTES.

]]>
https://gmbytes.com/reboot-cisco-cellular-module-without-rebooting-router/feed/ 0
Cisco ACL in or out syntax https://gmbytes.com/cisco-acl-in-or-out-syntax/ https://gmbytes.com/cisco-acl-in-or-out-syntax/#respond Thu, 12 Aug 2021 18:04:38 +0000 https://gmbytes.com/?p=149 Inbound or Outbound? Outbound away from router? Quick byte to have you sorted. Vlan 100 as in example above, if...

continue reading »

The post Cisco ACL in or out syntax appeared first on GMBYTES.

]]>
Inbound or Outbound? Outbound away from router? Quick byte to have you sorted.

interface Vlan100
 description GMbytes_Vlan
 ip access-group test_inbound in
 ip address 192.168.100.1 255.255.255.0

Vlan 100 as in example above, if you apply an ACL on the ‘in’ direction, the source must be within the 192.168.100.x subnet while the destination can be anything.

If you apply an ACL in the ‘out’ direction, the source can be anything while the destination can be ‘any’ or 192.168.100.x

Example inbound ACL for vlan100

csr1000v-1#show access-lists test_inbound
Extended IP access list test_inbound
    10 permit ip 192.168.0.0 0.0.0.255 any
    20 permit ip any 10.10.0.0 0.0.0.255
csr1000v-1#

Example outbound ACL for vlan100

csr1000v-1#show ip access-lists test
Extended IP access list test_outbound
    10 permit ip 10.10.0.0 0.0.0.255 any
    20 permit ip 10.10.1.0 0.0.0.255 host 192.168.100.1
csr1000v-1#

The post Cisco ACL in or out syntax appeared first on GMBYTES.

]]>
https://gmbytes.com/cisco-acl-in-or-out-syntax/feed/ 0
Ansible Cisco IOS Commands https://gmbytes.com/ansible-cisco-ios-commands/ https://gmbytes.com/ansible-cisco-ios-commands/#respond Thu, 12 Aug 2021 12:16:26 +0000 http://gmbytes.com/?p=92 This is a simple introduction of the power of Ansible and how quickly you can be up and running configuring...

continue reading »

The post Ansible Cisco IOS Commands appeared first on GMBYTES.

]]>
This is a simple introduction of the power of Ansible and how quickly you can be up and running configuring multiple hosts at once. We will install Ansible on Ubuntu, ping two cisco devnet routers and configure a Loopback Interface on both routers.

  • Cisco Devnet Lab Routers.
  • Ubuntu 20 running on Virtual Box

Install Ansible and Vim on Ubuntu

sudo apt update
sudo apt install vim
sudo apt install ansible

Remove host key check in Ansible

Open and edit with vi /etc/ansible/ansible.cfg
Remove comment(#) for Host Key Checking for ease of use as lab
#host_key_checking = False

sudo su - 
cd /etc/ansible
vi ansible.cfg

Sign up to devnet to access Routers

Sign up for developer.cisco.com as a great resource and then navigate to https://devnetsandbox.cisco.com/RM/Topology and find both IOS XE Always on Routers. At the time of writing this they are located at

  • Link: Devnet-Router1
  • CSR1000v Host: sandbox-iosxe-latest-1.cisco.com
    • SSH Port: 22
    • NETCONF Port: 830
    • gRPC Telemetry Port: 57500
    • RESTCONF Port: 443 (HTTPS)
  • Username: developer
  • Password: C1sco12345

  • Link: Devnet-Router2
  • CSR1000V Host: sandbox-iosxe-recomm-1.cisco.com
    • SSH Port: 22
    • NETCONF Port: 830
    • RESTCONF Ports: 443 (HTTPS)
  • Username: developer
  • Password: C1sco12345

Configure Ansible hosts file

Open to edit /etc/ansible/hosts with vi

root@macka-VirtualBox:/etc/ansible# vi hosts

Scroll down to bottom of file and add the below

[routers]

sandbox-iosxe-latest-1.cisco.com
sandbox-iosxe-recomm-1.cisco.com

[routers:vars]

ansible_user=developer
ansible_password=C1sco12345
ansible_connection=network_cli
ansible_network_os=ios
ansible_port=22

Test Ping to Routers

Using the ping module (-m ping) we are looking for a pong response

root@macka-VirtualBox:/etc/ansible# ansible routers -m ping
sandbox-iosxe-recomm-1.cisco.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
sandbox-iosxe-latest-1.cisco.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
root@macka-VirtualBox:/etc/ansible# 

Ansible IOS command

Lets get “show ip interface brief” from each of the routers with one command!!!

ansible routers -m ios_command -a "commands='show ip int brief'"
root@macka-VirtualBox:/etc/ansible# ansible routers -m ios_command -a "commands='show ip int brief'"
sandbox-iosxe-recomm-1.cisco.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "stdout": [
        "Interface              IP-Address      OK? Method Status                Protocol\nGigabitEthernet1       10.10.20.48     YES NVRAM  up                    up      \nGigabitEthernet2       10.255.255.1    YES NVRAM  down                  down    \nGigabitEthernet3       10.10.10.10     YES NVRAM  down                  down    \nVirtualPortGroup0      192.168.1.1     YES NVRAM  up                    up"
    ],
    "stdout_lines": [
        [
            "Interface              IP-Address      OK? Method Status                Protocol",
            "GigabitEthernet1       10.10.20.48     YES NVRAM  up                    up      ",
            "GigabitEthernet2       10.255.255.1    YES NVRAM  down                  down    ",
            "GigabitEthernet3       10.10.10.10     YES NVRAM  down                  down    ",
            "VirtualPortGroup0      192.168.1.1     YES NVRAM  up                    up"
        ]
    ]
}
sandbox-iosxe-latest-1.cisco.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "stdout": [
        "Interface              IP-Address      OK? Method Status                Protocol\nGigabitEthernet1       10.10.20.48     YES NVRAM  up                    up      \nGigabitEthernet1.23    unassigned      YES unset  deleted               down    \nGigabitEthernet2       unassigned      YES TFTP   administratively down down    \nGigabitEthernet2.1     unassigned      YES unset  administratively down down    \nGigabitEthernet2.2     unassigned      YES unset  deleted               down    \nGigabitEthernet2.3     unassigned      YES unset  administratively down down    \nGigabitEthernet3       unassigned      YES NVRAM  administratively down down"
    ],
    "stdout_lines": [
        [
            "Interface              IP-Address      OK? Method Status                Protocol",
            "GigabitEthernet1       10.10.20.48     YES NVRAM  up                    up      ",
            "GigabitEthernet1.23    unassigned      YES unset  deleted               down    ",
            "GigabitEthernet2       unassigned      YES TFTP   administratively down down    ",
            "GigabitEthernet2.1     unassigned      YES unset  administratively down down    ",
            "GigabitEthernet2.2     unassigned      YES unset  deleted               down    ",
            "GigabitEthernet2.3     unassigned      YES unset  administratively down down    ",
            "GigabitEthernet3       unassigned      YES NVRAM  administratively down down"
        ]
    ]
}
root@macka-VirtualBox:/etc/ansible# 

Configure an interface using an Ansible playbook

Ansible playbooks are lists of tasks that automatically execute against hosts.
Lets configure a Loopback Interface on each of the routers.

Create loopback.yml file with vi and add in the below

---

- name: General Config

  hosts: routers

  tasks:

  - name: Add loopback

    ios_interface:
      name: Loopback30
      state: present

Run playbook to configure Loopback30 on both routers

root@macka-VirtualBox:/etc/ansible# ansible-playbook loopback.yml 
[DEPRECATION WARNING]: ios_interface is kept for backwards compatibility but usage is discouraged. The module 
documentation details page may explain more about this rationale.. This feature will be removed in a future release. 
Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

PLAY [General Config] *****************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************
[WARNING]: Ignoring timeout(10) for ios_facts
[WARNING]: Ignoring timeout(10) for ios_facts
[WARNING]: default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards
ok: [sandbox-iosxe-latest-1.cisco.com]
ok: [sandbox-iosxe-recomm-1.cisco.com]

TASK [Add loopback] *******************************************************************************************************
changed: [sandbox-iosxe-latest-1.cisco.com]
changed: [sandbox-iosxe-recomm-1.cisco.com]

PLAY RECAP ****************************************************************************************************************
sandbox-iosxe-latest-1.cisco.com : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
sandbox-iosxe-recomm-1.cisco.com : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

root@macka-VirtualBox:/etc/ansible# 

If we check the show ip int brief now on the devices we will have Loopback30 configured!!

ios-xe-mgmt#show ip int brief
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.10.20.48     YES NVRAM  up                    up      
GigabitEthernet2       10.255.255.1    YES NVRAM  down                  down    
GigabitEthernet3       10.10.10.10     YES NVRAM  down                  down    
Loopback30             unassigned      YES unset  up                    up      
VirtualPortGroup0      192.168.1.1     YES NVRAM  up                    up      
ios-xe-mgmt#
csr1000v-1#show ip int brief
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       10.10.20.48     YES NVRAM  up                    up      
GigabitEthernet1.23    unassigned      YES unset  deleted               down    
GigabitEthernet2       unassigned      YES TFTP   administratively down down    
GigabitEthernet2.1     unassigned      YES unset  administratively down down    
GigabitEthernet2.2     unassigned      YES unset  deleted               down    
GigabitEthernet2.3     unassigned      YES unset  administratively down down    
GigabitEthernet3       unassigned      YES NVRAM  administratively down down    
Loopback30             unassigned      YES unset  up                    up      
csr1000v-1#

You can view other playbooks at my github as I add them there
https://github.com/glennmccallum/Ansible

The post Ansible Cisco IOS Commands appeared first on GMBYTES.

]]>
https://gmbytes.com/ansible-cisco-ios-commands/feed/ 0