06-10-2019 08:55 AM
Hey everyone
I worked with a team member of mine to come up with an automated script that runs on our Ansible server that will reboot whichever Meraki access point that has 'API' at the end of its name (or really just in the name), on a weekly scheduled basis, with email reporting. This could be used I'm sure for MX or MS as well, but we are only using it for access points.
Feel free to critique. I'm not a Python person by any means, but this works great:
import json
import sys
import requests
import time
import email
import smtplib
cisco_meraki_api_Key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
organizationId = 'XXXXXX'
baseUrl = 'https://dashboard.meraki.com/api/v0/'
inventory_api_url = "organizations/{}/inventory".format(organizationId)
headers = {
'X-Cisco-Meraki-API-Key': cisco_meraki_api_Key,
'Content-Type': 'application/json'
}
get_inventory = requests.get(baseUrl+inventory_api_url,
headers=headers,
)
# Parse the get_inventory into json
inventory_json = get_inventory.json()
networkID = ""
serial = ""
# Opens or create a file name results
f = open('results.txt', "w+")
# loop over all the dictionaries inside inventory_json,
# if API is inside the dictionary it will get the NetworkID and the serial and then write it to the string above
for ap in inventory_json:
try:
if 'API' in ap['name']:
networkID = ap['networkId']
serial = ap['serial']
ap_name = ap['name']
reboot_api_call = requests.post(
baseUrl+'/networks/{}/devices/{}/reboot'.format(networkID, serial ),
headers=headers)
if reboot_api_call.status_code == 200:
print('Rebooting --->', ap_name, '---> Successful' , file=f)
print("---------------------------------------------------",file=f)
if reboot_api_call.status_code == 400:
print ('Rebooting --->', ap_name, '---> Bad Request' , file=f)
print("---------------------------------------------------",file=f)
if reboot_api_call.status_code == 403:
print ('Rebooting --->', ap_name, '---> Forbidden' , file=f)
print("---------------------------------------------------",file=f)
if reboot_api_call.status_code == 404:
print ('Rebooting --->', ap_name, '---> Not Found' , file=f)
print("---------------------------------------------------",file=f)
if reboot_api_call.status_code == 429:
print ('Rebooting --->', ap_name, '---> Too Many Requests' , file=f)
print("---------------------------------------------------",file=f)
time.sleep(2)
except:
continue
# closes the file
f.close()
# Setting up the SMTP Server
sender = 'meraki_api@company.local'
receiver = 'yourteam@company.com'
smtp_server = smtplib.SMTP(host='X.X.X.X', port=25)
f = open('results.txt', "r")
# reads the information inside the file results
script_result = f.read()
message = """From: <meraki_api@company.local>
To: <yourteam@company.com>
Subject: Meraki AP Reboot
API CODE: 200 = Successful
API CODE: 400 = Bad Request
API CODE: 403 = Forbidden
API CODE: 404 = Not Found
API CODE: 429 = Too Many Requests
{}
""".format(script_result)
# Email execution
try:
smtp_server.sendmail(sender, receiver, message)
print('Successfully sent email')
except:
print('Error: Unable to send email')
# closes the file.
f.close()
06-10-2019 09:13 AM
Is this more for just good measure to reboot APs weekly or do you manually change names on the problem APs that you want to get the weekly scheduled reboot?
06-10-2019 09:18 AM
06-10-2019 09:21 AM
07-01-2019 08:03 AM
Meraki has confirmed an issue with the beacons on the MR16 and are working on the fix. Currently, they are saying no other AP's are having this issue. We have seen similar issues on the MR18's as well however.
Thanks for the script, we will give it shot and see if it corrects our MR16 problems.
08-28-2019 07:33 AM
08-28-2019 08:21 AM
Nice script. The one thing I can see is using the inventory endpoint will return the inventory for the whole organization, including devices that have been claimed, but might not be assigned to a network and be active. I have organizations with multiple networks where we will use an AP at a site for awhile, remove it after a time, and then keep it claimed for future use. The device will retain the name it had, and if it had the API in it, the script would try to reboot it. Those devices also don't have network IDs, so you could get an exception just trying to reference that field. The exception handling would probably catch the error and keep going, but it generates extra errors and messages.
I would consider using the {{baseUrl}}/organizations/{{organizationId}}/deviceStatuses endpoint. It will only give you devices that are assigned to networks. You can also use the 'status' tag to check and see if the AP is 'offline'. No point in trying to reboot an AP that you will never be able to contact.
Just a thought.
08-28-2019 08:51 AM
08-28-2019 08:58 AM
You should just need to change the endpoint name. The fields you are using (name, serial, network ID) are in the device status endpoint too. If you want to check the status before trying to reboot, that is your call. Personally, it think it is a good check. Saves you can API call that would be going against your call limit.
08-28-2019 09:22 AM
08-29-2019 05:33 AM
Just a side note. The documentation for the {{baseUrl}}/organizations/{{organizationId}}/inventory endpoint on documenter.getpostman.com is not complete. The sample response information does not include the "name" field. When I looked at the source code provided in this topic and I saw "name" referenced, I thought it was odd, since I had used this endpoint and thought I had to get the device name through other means. Since I took the documentation as gospel, I did not look at all of the return values in the debugger until this topic came up.
I don't know about anyone else, but when I look at API documentation, I kind of expect it to be correct in terms of what is going to be returned or what needs to be included when putting/posting information. This is not the first time I have found errors on documenter.getpostman.com, either. Is there another place I should be looking for comprehensive documentation for this API? If not, Meraki please keep documenter.getpostman.com updated with the correct data regarding the API.
07-30-2020 12:46 PM
Hi Nolan
Thanks for sharing this with us. Do you have an updated script? Also, is this script written to only work on ansible since I see the import json, sys etc at the beginning of the script and not sure how I can automate this on windows task for example. Any help would be appreciated.
07-31-2020 02:26 PM
@webrama1 wrote:Hi Nolan
Thanks for sharing this with us. Do you have an updated script? Also, is this script written to only work on ansible since I see the import json, sys etc at the beginning of the script and not sure how I can automate this on windows task for example. Any help would be appreciated.
If your using Windows, then you can use WSL2 to run an Ubuntu app, or do it in a container etc., but probably easier to just use the Ubuntu app from the Windows store.
Import JSON is to import the json python library so you can parse the return data from the Meraki inventory API call, when receives the inventory and returns it as JSON data.
I should clarifiy 'ansible server' is really just a linux server i called ansible server because we were/are using it for other actual ansible tasks. However this is just python, sorry about the confusion.
07-31-2020 03:07 PM
Thank you so much for the info Nolan. I will go thru this again and let you know. Thanks!
~Rama
09-16-2020 06:03 AM
Thanks for the script, but when I use it, not all the APs get rebooted.
All my APs name end with "-AP" but about a third get rebooted.
Is there a way to just say reboot all APs?
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide