Cycle Port

Jason-907
Getting noticed

Cycle Port

We are having an issue with a PoE device that only seems to crop up every few days. It appears that the devices have an inherent problem that the vendor needs to fix with a firmware update. In the meantime, the workaround is to go into the switch and click the "cycle port" button. I'll end up writing a python script that will loop through the switches in my organization and cycle to ports that have a tag for the problem devices. Is there a way to cycle a port through the API?

 

I know I could disable and enable the port using: 

meraki.updateswitchport(apikey, serialnum, portnum, name=None, tags=None, enabled=False, 
porttype=None, vlan=None,voicevlan=None, allowedvlans=None, poe=None, isolation=None,
rstp=None, stpguard=None, accesspolicynum=None, suppressprint=False) meraki.updateswitchport(apikey, serialnum, portnum, name=None, tags=None, enabled=True,
porttype=None, vlan=None,voicevlan=None, allowedvlans=None, poe=None, isolation=None,
rstp=None, stpguard=None, accesspolicynum=None, suppressprint=False)

However, this sends alerts of changes to the switch ports whereas the "cycle port" button doesn't send any alerts. I'd like to cut down on the spam if possible as I would end up with alerts from all of our networks every morning.

 

 

9 REPLIES 9
NolanHerring
Kind of a big deal

I've never been able to find an API that has cycle port option. I looked for it because I wanted to use it to reboot access points (which I ended up doing a separate python script/API call for which is the reboot API call).

So as of right now, there isn't an option for API to cycle port. Hopefully in the future they'll provide that.
Nolan Herring | nolanwifi.com
TwitterLinkedIn
PhilipDAth
Kind of a big deal
Kind of a big deal

If this is a Meraki Switch (MS) then configure a port schedule instead.

 

https://documentation.meraki.com/MS/Access_Control/Port_Schedules


@PhilipDAth wrote:

If this is a Meraki Switch (MS) then configure a port schedule instead.


I'll take a look at it, but I want it go off and back on immediately. It seems like this method would require the port to be down for 1/2 an hour at a minimum.


> It seems like this method would require the port to be down for 1/2 an hour at a minimum.

 

Correct.  You can't do it at a horrible time of the day like 2am?


@PhilipDAth wrote:

> It seems like this method would require the port to be down for 1/2 an hour at a minimum.

 

Correct.  You can't do it at a horrible time of the day like 2am?


No--Security cameras. What's happening is if we use the most efficient format, the cameras will lose communication with the server and ends up buffering everything until the server or camera reboots. Our camera guy just does it manually, but he was hoping we could automate. I'll test it out and just deal with the spam.

Since the API endpoint doesn't seem to exist, have you tried adapting your script to:

  • Disable the email alert that is triggered by the port status change
  • Disable the port
  • Enable the port
  • Enable the email alert again

 

Of course you'll need to get the network ID for each switch but that shouldn't be a big problem.


@Raphael_M wrote:

Since the API endpoint doesn't seem to exist, have you tried adapting your script to:

  • Disable the email alert that is triggered by the port status change
  • Disable the port
  • Enable the port
  • Enable the email alert again

 

Of course you'll need to get the network ID for each switch but that shouldn't be a big problem.


That is a clever solution, but the alerts are set for configuration changes, not port status changes, so this wouldn't actually solve this one for me.

I wanted to add to this since I really needed a solution and I had to make my own.

 

For this script you need two text files: device_serials.txt and tag.txt  in the same directory as your python script.

  • device_serials has device serial numbers per line
  • tag has the tag of the switch port

How it works:

  • It scans the device serials matching those in the device_serials.txt file.
  • All the ports in that switch that have the tag written in the tag.txt file will be cycled. 
  • I made it it like this so that I could target specific ports on a switch.

 

Here's my script, which is based on Meraki tagging.

With a little Python know-how, this is easy to modify this based on device properties:

 

#By Josh Carbajal

import meraki
import requests
import json
from datetime import datetime

#DECLARATIONS
API_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
dashboard = meraki.DashboardAPI(API_KEY)
payload = None
headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
    "X-Cisco-Meraki-API-Key": API_KEY
}
dt = datetime.now().strftime("%Y_%m_%d-%I.%M.%S.%p")
divider = "\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"

#FUNCTIONS
def getresponse(serialnumber):
    url = "https://api.meraki.com/api/v1/devices/{}/switch/ports".format(serialnumber)
    response = requests.request('GET', url, headers=headers, data = payload)
    refined = json.loads(response.text)
    if 'errors' in refined:
        print("Could not establish a good API handshake with device serial ({})".format(serialnumber))
        logFile.write("\nCould not establish a good API handshake with device serial ({}).\n".format(serialnumber))
        logFile.write(divider)
    else:
        switch = dashboard.devices.getDevice(serial)
        name = switch['name']
        logFile.write("\nDevice {}, with serial {} found.".format(name, serialnumber))
        findRebootTag(refined, serialnumber)

def findRebootTag(goodresponse, serialnumber):
    ports = []
    for device in goodresponse:
        if tag in device['tags']:
            print(device)
            ports.append(str(device['portId']))
        else:
            pass
    print(ports)
    logFile.write("\nDevice serial: {}.\tPorts tagged with {}: {}".format(serialnumber, tag, ports))
    cycle(ports, serialnumber)

def cycle(ports, serialnumber):
    if ports:
        for port_number in ports:
            print("Port number: " + port_number)
        #cycleAll = dashboard.switch.cycleDeviceSwitchPorts(serialnumber, ports)
        logFile.write("\nCycling ports {} for device serial {}.\n".format(ports, serialnumber))
        logFile.write(divider)
    else:
        print("No ports tagged with {} found for device serial ({})".format(tag, serialnumber))
        logFile.write("\nNo ports tagged with {} found for device serial ({}).\n".format(tag, serialnumber))
        logFile.write(divider)

#MAIN RUN
tagFile = open("tag.txt", "r")
tag = tagFile.read()
tagFile.close()
logFile = open("{}.txt".format(dt), "w")
logFile.write("Log: Meraki API via Python custom script\n")
with open("device_serials.txt") as txtfile:
    serialtxt = txtfile.read().splitlines()
    for serial in serialtxt:
        if serial:
            getresponse(serial)
        else:
            pass
    logFile.close()

 

As you can see, it creates a log named with a datetime stamp. If you want to automate this kind of stuff, use Task Scheduler, for example, and run the python script with a batch file. 

LearningIsFun
Getting noticed

Posting update as I was looking for this API call.

 

https://developer.cisco.com/meraki/api/cycle-device-switch-ports/

Get notified when there are additional replies to this discussion.