Check Vlan404 Occurrences
Summary
[!info]
Network information were modified to protect the privacy of the organization
Since there were issues with flapping Vlan in my workplace's DMVPN topology, I wrote a script that gets run at 7:45am through crontab. The script checks for occurrences of Vlan404 by regular expression in the log through a list of known sites that has Vlan404. After the script parses through the list of sites, then it would email the team whether or not it found any occurrences of Vlan404 mentioned in the log.
Since the no autostate command was implemented in all sites, then theoretically there should not be any site that would have the Vlan404 flapping in its' log. However, new sites come up daily with terminating DMVPN Tunnel and the Vlan404 network that lives in that topology so this script keeps the site in monitoring and in check for possible deviation from the standard.
Crontab Schedule
Email Results
Python Source Code
#!/usr/bin/python3.7
from netmiko import ConnectHandler
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import netmiko
import paramiko
import re
from time import gmtime, strftime
from datetime import date
from datetime import datetime, timezone
from random import randrange
def send_Email(sender, receiver, message):
msg = MIMEMultipart('alternative')
msg['Subject'] = "VLAN404 Flapping Check"
msg['From'] = "Server@localhost"
msg['To'] = "receivers@domain.com"
htmlmsg = MIMEText(message, 'html')
msg.attach(htmlmsg)
try:
smtpObj = smtplib.SMTP("emailrelayserver.domain.com", 25)
smtpObj.sendmail(sender, receivers, msg.as_string())
except smtplib.SMTPException:
print("Unable to send email")
# Get the current date and time
today = datetime.now()
month_abbr = today.strftime("%b")
command = "show log | i " + month_abbr + " " + str(today.day)
# Get the month in a human-readable format
# Print the current datetime with the month abbreviated
myMsg = ""
found = False
regex = re.compile(r"\bVlan404\b")
sender = "Server@localhost"
receivers = ["receivers@domain.com"]
nonconnected_routers = []
with open("List of Possible Vlan404 Sites.txt", "r") as f:
# Iterate over the lines of the file.
for line in f:
router = {
'device_type': 'cisco_ios',
'host': str(line),
'username': 'cisco',
'password': 'cisco123',
}
try:
router_connected = ConnectHandler(**router)
output = router_connected.send_command(command)
prompt = router_connected.find_prompt()
hostname = prompt.split()[-1]
matches = regex.findall(output)
if len(matches) > 0:
myMsg = myMsg + str(hostname) + " has " + str(len(matches)) + " of occurrences of Vlan404 " + "<br/>"
found = True
except paramiko.ssh_exception.AuthenticationException as e:
# Handle the exception.
print('Error connecting to device: {}'.format(e))
nonconnected_routers.append(str(line))
continue
except paramiko.ssh_exception.NoValidConnectionsError as e2:
print('Error connecting to device: {}'.format(e2))
nonconnected_routers.append(str(line))
continue
except netmiko.NetmikoAuthenticationException:
# Print a message and skip the device
print("Authentication failed for device - %s" %(str(line)))
nonconnected_routers.append(str(line))
continue
except netmiko.NetmikoTimeoutException:
# Print a message and skip the device
print("Connection timed out for device - %s " %(str(line)))
nonconnected_routers.append(str(line))
continue
finally:
# Close the connection to the device.
router_connected.disconnect()
pass
if found is False:
myMsg = "No occurrences happened on " + str(month_abbr) + ", " + str(today.day) + " " + str(today.year)
if len(nonconnected_routers) > 0:
myMsg = myMsg + "<br/> <br/>"
for ip in nonconnected_routers:
if len(ip) > 0:
myMsg = myMsg + "Unable to connected to " + ip + " <br/>"
send_Email(sender, receivers, myMsg)