Alertra API: Use Python To Automate Maintenance

Introduction

How long does your maintenance window last? In this tutorial you will learn how to programmatically control Alertra maintenance windows without having to access the Alertra web user interface. This will allow you fine grained control over how long the actual maintenance window lasts so that there are fewer gaps in the coverage of your devices. This tutorial will use Python to demonstrate the technique.

Concept

To access your device's maintenance schedule via the Alertra API we will perform the following steps:

  1. Request an API key from support.
  2. Get a list of devices.
  3. Use the device ID to act on that device.

You only need to get an API key once. Send us an email from your primary Alertra account and we'll send you a key. Since the website doesn't force device names to be unique within your account, you need the device list to determine what the unique device identifier is for the one you want to act upon. The Alertra API is implemented as a REST service which uses HTTP URLs, command types and data exchange mechanisms. The Python source code presented here requires the third-party Requests package to manage the HTTP. You can instead use the built in urllib package, but Requests is much, much easier to use.

Steps

Source Code The source code implements a class to wrap the Alertra API. The class has 3 public methods to start maintenance, stop maintenance, and get a list of devices respectively. The remainder of the code implements a command line interface for the wrapper. The tutorial explains the basic Python code to interface with the Alertra API, while the source code provides an implementation for you as an example. The wrapper class is not meant to be made a part of a production environment, but merely to show how to interface with the API.

Step 1

First we need to get the list of devices. Using the class wrapper you would do this:

from alertraapi import AlertraAPI
api = AlertraAPI("YOUR ACCOUNT KEY")
r = api.getDevices()
if r.status_code == 200:
    devices = r.json()

r is a response object that is returned by Requests; you use it to get the json formatted data containing the device list. The json data is a list containing dictionary objects for each item. So you can access the individual devices like this:

for device in devices:
    print device['ShortName'],device['device_id']

Behind the scenes, the wrapper is doing something like this when you call getDevices():

url = "https://api.alertra.com/v1.1/devices"
headers = {'Alertra-API-Key':accountAPIKey}
r = requests.get(url,data=None,headers=headers)

although the details are a little more complicated to make the calling mechanism generic enough to be reused by the rest of the wrapper class.

Step 2

Once we have a device ID, we can use it to put a device into maintenance. Using the wrapper class it works like this:

from alertraapi import AlertraAPI
api = AlertraAPI("YOUR ACCOUNT KEY")
duration = "01:00"
r = api.startMaintenance(deviceID,duration)

where duration is the length of time the device should be put into maintenance for. In this case the device was put into maintenance for 1 hour. The wrapper class is making this call to the API:

url = "https://api.alertra.com/v1.1/devices/start-maintenance"
headers = {'Alertra-API-Key':accountAPIKey}
data = json.dumps({'Duration':duration})
r = requests.put(url,data=data,headers=headers)

If the call succeeded, r.status_code will be equal to 200, anything else and the call failed.

Step 3

To bring the device out of maintenance using the wrapper class we do this:

from alertraapi import AlertraAPI
api = AlertraAPI("YOUR ACCOUNT KEY")
r = api.stopMaintenance(deviceID)

This will cause Alertra to cancel the maintenance and resume checking the device. The wrapper class is doing this on our behalf:

url = "https://api.alertra.com/v1.1/devices/stop-maintenance"
headers = {'Alertra-API-Key':accountAPIKey}
r = requests.put(url,data=None,headers=headers)

If the call succeeded, r.status_code will be equal to 200, anything else and the call failed.

Summary

Using the Alertra API you can easily start and stop maintenance on any of your devices. Doing this as part of your automated maintenance routine allows you to insure that Alertra won't be checking your devices during the maintenance and will resume checking them as soon as the maintenance is over.

Source Code

Listing 1. alertraapi.py

#!/usr/bin/env python

import sys
import json
import requests

class AlertraAPI:

    def __init__(self, apikey):
        """apikey is provided by Alertra support and is account and user specific.
        Contact support to request an API key for your account."""

        self.version = "v1.1"
        self.url = "https://api.alertra.com"
        self.apikey = apikey

    def getDevices(self,filter='All',offset=0,limit=25):
        parms = {'Offset':offset,'Limit':25}
        r = self.__get("devices")
        return r

    def startMaintenance(self,deviceID,duration):
        operation = "devices/%s/start-maintenance" % deviceID
        parms = {'Duration':duration}
        self.__put(operation,parms)

    def stopMaintenance(self,deviceID):
        operation = "devices/%s/stop-maintenance" % deviceID
        self.__put(operation)

    def __get(self,operation=None,parms=None):
        url = "%s/%s/%s" % (AlertraAPI.url,AlertraAPI.version,operation)
        headers = {'Alertra-API-Key':self.apikey}
        data = parms
        if not parms is None:
            data = json.dumps(parms)

        r = requests.get(url,data=data,headers=headers)
        return r

    def __put(self,operation=None,parms=None):
        url = "%s/%s/%s" % (AlertraAPI.url,AlertraAPI.version,operation)
        headers = {'Alertra-API-Key':self.apikey}
        data = parms
        if not parms is None:
            data = json.dumps(parms)

        r = requests.put(url,data=data,headers=headers)
        return r

if __name__ == "__main__":

    api = AlertraAPI("YOUR API KEY")
    command = sys.argv[1]
    r = None

    if command == "start-maintenance":
        deviceID = sys.argv[2]
        duration = sys.argv[3]
        r = api.startMaintenance(deviceID,duration)
    elif command == "stop-maintenance":
        deviceID = sys.argv[2]
        r = api.stopMaintenance(deviceID)
    elif command == "getdevices":
        r = api.getDevices()
        if not r is None:
            if r.status_code == 200:
                devices = api.json()
                for device in devices:
                    print device['ShortName'],device['device_id']
    else:
        print "usage: %s [getdevices|start-maintenance|stop-maintenance]"
        sys.exit(1)

    if not r is None:
        if not r is None:
            if not r.status_code == 200:
                sys.stderr.write('alertraapi failed: %d %s\n' % (r.status_code,r.reason) )
                sys.exit(1)
    else:
        sys.stderr.write('alertraapi unknown request error\n')
        sys.exit(1)