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.
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:
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.
How it works:
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.
Posting update as I was looking for this API call.
https://developer.cisco.com/meraki/api/cycle-device-switch-ports/