MERAKI | API and Webhooks

Marcx
Conversationalist

MERAKI | API and Webhooks

I am seeking assistance with a Python script I’m developing to notify me via email when WAN2 goes down. Despite setting up an API key and webhook through Ngrok, the script isn't sending notifications as expected. Additionally, I need guidance on how to access and monitor directly network appliances to check the status of WAN1 and WAN2, as the current Meraki alert system only supports WAN1. Could you please help me troubleshoot the script, provide instructions for accessing appliance status, and suggest how to configure notifications specifically for WAN2? Your expertise would be greatly appreciated. Thank you for your time and support.

7 Replies 7
PhilipDAth
Kind of a big deal
Kind of a big deal

Are you able to post the bit you think is going wrong?

Marcx
Conversationalist

I would like to confirm whether my understanding of your response is accurate. Specifically, I am seeking clarification on whether the section in question pertains to posting the bit that triggers an email notification. If this is indeed the case, I have encountered an issue where I am unable to post it directly, and can only do so using Postman. Your assistance in clarifying this matter would be greatly appreciated. Thank you.

sungod
Kind of a big deal

q: I am seeking assistance with a Python script I’m developing to notify me via email when WAN2 goes down. Despite setting up an API key and webhook through Ngrok, the script isn't sending notifications as expected.

 

a: you need to post your script for people to be able to review/advise

 

q: Additionally, I need guidance on how to access and monitor directly network appliances to check the status of WAN1 and WAN2, as the current Meraki alert system only supports WAN1.

 

a: see https://developer.cisco.com/meraki/api-v1/get-organization-appliance-uplink-statuses/

 

q: Could you please help me troubleshoot the script, provide instructions for accessing appliance status, and suggest how to configure notifications specifically for WAN2?

 

a: again, post the script. I do not think there's a Dashboard notification for WAN2, you would need to create a script that checks status periodically, for instance you might be able to simply ping it.

John_on_API
Meraki Employee
Meraki Employee

Status, latency, etc. changes can be alerted on for WAN2 and other uplinks with the Meraki Insight feature set. I think it's included in the SD-WAN license tier.

sungod
Kind of a big deal

I never noticed that! Just configured it.

 

Yes, Insight is included in the SD-WAN tier.

 

 

Marcx
Conversationalist

Here's the script i am having trouble on checking the internet connection of the ip address from other network.

import platform
import subprocess
import requests
import smtplib
from email.mime.text import MIMEText
import meraki
import time
from datetime import datetime, timedelta

# Your API key and configurations
API_KEY = ""
NETWORK_ID = ""  # Network ID of the device
DEVICE_SERIAL = ""  # Serial number of the device
# Gmail configurations
SMTP_SERVER = ''
SMTP_PORT = 587
SMTP_USER = ''
SMTP_PASSWORD = ''
NOTIFY_EMAIL = 'i'

# Initialize Meraki Dashboard API
dashboard = meraki.DashboardAPI(API_KEY)

def get_network_name(network_id😞
    """Get the name of the network for the given network ID."""
    network = dashboard.networks.getNetwork(network_id)
    return network.get('name', 'Unknown Network')

def get_device_details(network_id, serial😞
    """Get device details for the given serial number and network ID."""
    devices = dashboard.networks.getNetworkDevices(network_id)
    for device in devices:
        if device['serial'] == serial:
            return device
    print(f"Device with serial {serial} not found in network ID: {network_id}")
    return None

def check_internet(url="http://www.google.com"😞
    """Check if a request to the given URL is successful."""
    try:
        print(f"Testing connectivity to {url}...")
        response = requests.get(url, timeout=10)
        if response.status_code == 200:
            print(f"Successful request to {url}. Status code: {response.status_code}")
            return True
        else:
            print(f"Request to {url} returned status code: {response.status_code}. Connectivity might be unreliable.")
            return False
    except requests.RequestException as e:
        print(f"Request to {url} failed with exception: {e}. Connectivity might be down.")
        return False

def check_ping(ip_address😞
    """Check if the IP address responds to a ping request."""
    try:
        print(f"Pinging {ip_address}...")
        # Determine the correct ping command based on the platform
        param = '-n' if platform.system().lower() == 'windows' else '-c'
        result = subprocess.run(['ping', param, '4', ip_address], capture_output=True, text=True)
        if result.returncode == 0:
            print(f"Ping successful to {ip_address}.\n{result.stdout}")
            return True
        else:
            print(f"Ping failed to {ip_address}.\n{result.stderr}")
            return False
    except Exception as e:
        print(f"Ping failed with exception: {e}")
        return False

def get_wan_status(device😞
    """Check WAN1 and WAN2 status and internet connectivity sequentially."""
    wan1_ip = device.get('wan1Ip', None)
    wan2_ip = device.get('wan2Ip', None)
   
    # Initialize WAN statuses
    wan1_status = "Not Connected"
    wan2_status = "Not Connected"
   
    # Check WAN1 IP Address
    if wan1_ip:
        print(f"WAN1 IP Address available: {wan1_ip}")
        # Check internet connectivity for WAN1
        if check_internet():
            wan1_status = "Active"
        else:
            wan1_status = "Failed"
    else:
        print("WAN1 IP Address not available.")
   
    # Check WAN2 IP Address
    if wan2_ip:
        print(f"WAN2 IP Address available: {wan2_ip}")
        # Check internet connectivity for WAN2
        if check_internet() and check_ping(wan2_ip😞
            wan2_status = "Active"
        else:
            wan2_status = "Failed"
    else:
        print("WAN2 IP Address not available.")
        wan2_status = "Not Connected"
   
    return wan1_status, wan2_status

def send_email(subject, body😞
    """Send an email notification using Gmail SMTP server."""
    msg = MIMEText(body)
    msg['Subject'] = subject
    msg['From'] = SMTP_USER
    msg['To'] = NOTIFY_EMAIL

    try:
        with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
            server.starttls()
            server.login(SMTP_USER, SMTP_PASSWORD)
            server.send_message(msg)
        print(f"Email sent to {NOTIFY_EMAIL}.")
    except Exception as e:
        print(f"Failed to send email: {e}")

def main():
    # Initialize previous statuses and last update time
    last_wan1_status = None
    last_wan2_status = None
    last_update_time = datetime.now()
   
    while True:
        print("Checking WAN Status...")

        device = get_device_details(NETWORK_ID, DEVICE_SERIAL)
        if device:
            network_name = get_network_name(NETWORK_ID)
            # Check WAN status
            wan1_status, wan2_status = get_wan_status(device)
           
            # Print WAN status
            print(f"Network: {network_name}")
            print(f"WAN1 Status: {wan1_status}")
            print(f"WAN2 Status: {wan2_status}")
           
            # Check if status has changed
            if (wan1_status != last_wan1_status) or (wan2_status != last_wan2_status😞
                # Prepare email content
                subject = f"WAN Status Update for {network_name}"
                body = (f"Network: {network_name}\n"
                        f"WAN1 Status: {wan1_status}\n"
                        f"WAN2 Status: {wan2_status}")
                send_email(subject, body)
               
                # Update last known status and time
                last_wan1_status = wan1_status
                last_wan2_status = wan2_status
                last_update_time = datetime.now()
            else:
                # Check if 24 hours have passed since the last update
                if datetime.now() - last_update_time >= timedelta(hours=24😞
                    # Prepare reminder email content
                    subject = f"Reminder: No WAN Status Change for {network_name}"
                    body = (f"Network: {network_name}\n"
                            f"WAN1 Status: {last_wan1_status}\n"
                            f"WAN2 Status: {last_wan2_status}\n"
                            f"Note: No status change detected for 24 hours.")
                    send_email(subject, body)
                    # Update last update time to avoid repeated reminders
                    last_update_time = datetime.now()
        else:
            print("Unable to retrieve device details.")
       
        # Indicate the next check cycle
        print("Checking WAN Status...\n")
       
        # Wait for a short period before checking again
        time.sleep(30)  # Check every 10 seconds

if __name__ == "__main__":
    main()
MartinS
Building a reputation

Apologies for the thread hijack, but if you don't fancy running and maintaining your own script, there are plenty of ecosystem partners who can help with this:

Cisco Meraki Marketplace | Cisco Meraki

 

Declaring an interest, I work for one 🙂

 

Highlight Service Observability Platform for SD-WAN | Cisco Meraki Marketplace

---
COO
Highlight - Service Observability Platform
www.highlight.net
Get notified when there are additional replies to this discussion.