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)