Welcome to Bosun Plugins’s documentation!

Contents:

Devices

class bosunplugins.devices.Device

All devices that work with Bosun are subclasses of this class.

You must provide the following class-level attributes and methods:

verbose_name

str or unicode human-readable name name of this device. This is displayed in the Bosun web interface.

ports_to_scan

list or tuple of ``int``s of TCP/IP ports that the service for this device runs on. This is used when scanning the network for devices.

classmethod is_my_type(cls, host, port)

Determine if this class can interact with the class running on the given host and port.

Parameters:
  • host (str) – host to test
  • port (int) – port to test on
Returns:

True or False

When implementing this, you should use detection_timeout on any network operations. For example, if using the requests library, do something like this:

try:
    response = requests.get(url, timeout=cls.detection_timeout)
    if my_test_condition:
        return True
except (ConnectionError, Timeout):
    pass
return False
credentials_field_names

list or tuple of strings, one for each field needed for authentication. For example, this might be ['username', 'password'] or ['secret_key']. These names will be used as the kwargs for authenticate().

If no authentication is required, set this to None.

authenticate(self, **credentials)

Attempt to authenticate to the device using the given credentials.

This is not needed if credentials_field_names is None.

Parameters:credentials – dict where keys are guaranteed to be credentials_field_names and values are the user’s authentication attempt
Returns:True if authentication successful, False if not, or any other error occurs
get_uuid(self)

Get the UUID stored on the device.

Returns:the UUID for this device
Return type:str
set_uuid(self, value)

Store the UUID on the device as the given value.

Parameters:value (str) – the UUID to store on the device
connect_to_bosun(self)

Perform whatever configuration needs to be done to ensure the device is communicating with Bosun. For example, this might configure the device to use one of the listeners, described below.

is_connected_to_bosun(self)

Test whether this device is configured to communicate with Bosun properly. Should test that whatever connect_to_bosun() does is correct.

Returns:True or False

Once you have the basics down, you will want to describe the capabilites your device has, using the following decorators. When the decorated methods are called, they automatically send their return values to Crowsnest, which is why they may look naively simplistic.

@action(name)

Decorate a method that performs the named action. Decorated method must accept inputs for the named action as arguments and must return outputs.

Parameters:name (str) – dot-separated name of this action, eg 'action.generic.power.get'

An example for setting and getting the power of a device:

@Device.action('action.generic.power.get')
def get_power(self):
    # make whatever requests we need to determine the device's power
    power_value = get_the_power()

    # value must be ``True`` or ``False``
    return {
        'value': bool(power_value)
    }

@Device.action('action.generic.power.set')
def set_power(self, value):
    # according to capabilities, value is ``True`` or ``False``
    if value:
        # turn the power on for the device
        pass
    else:
        # turn the power off for the device
        pass

    # there is nothing to return for this action
    return {}
@emits(name)

Decorate a method that emits the named event. Decorated method must return outputs for the named event.

An example for the power having changed:

@Device.emits('event.generic.power.changed')
def power_changed(self, value):
    # pass the value along as ``True`` or ``False``
    return {
        'value': bool(value)
    }

Or, possibly you need to query for the value:

@Device.emits('event.generic.power.changed')
def power_changed(self):
    # query for the value
    value = get_the_power()

    # pass the value along as ``True`` or ``False``
    return {
        'value': bool(value)
    }

So, you have an event method decorated using emits(), and it generates events on Crowsnest. How do you listen to the device for changes so you can generate these events? Listeners are the key to this.

@listeners.http.route(rule, *args, **kwargs)

Sets up a Flask route for the decorated method on Bosun’s HTTP server. Any time a request is received on this route, the decorated method is called.

For more detail on the parameters of this decorator, refer directly to Flask’s route API.

Returns:bosunplugins.listeners.http.Route.

Note

rule is prepended with a class-safe prefix, to prevent collisions between routes on different Device classes. You can get the fully safe path by inspecting the path attribute of the decorated method. You can get the full URL by calling the get_url() method of the decorated method. More details about this are in bosunplugins.listeners.http.Route.

The decorated method must be a valid signature for Flask routes.

For example, to listen for an HTTP event indicating the power of a device has changed:

@Device.listeners.http.route('/power-changed')
def power_changed_handler(self):
    # you have access to the Flask request object inside the Flask request contect
    power_value = request.json['powerValue']

    # send the power changed event with the value we just got
    self.power_changed(power_value)

    # return a proper Flask response
    return '', 200
@listeners.ftp.watched_folder(path)

Set up a watched folder on Bosun’s FTP server. Any time a file is uploaded to the given path, the decorated method is called.

Parameters:path (str) – path to watch
Returns:bosunplugins.listeners.ftp.WatchedFolder

Note

path is only the end of the full path. The given path is prepended with a fully safe and isolated path to prevent collisions between Device classes. You can get this fully safe path by inspecting the path attribute of the decorated method. You can get the full URL by calling the get_url() method of the decorated method. More details about this are in bosunplugins.listeners.ftp.WatchedFolder.

Signature of the decorated method must be:

def ftp_handler(self, filelike):
    """ filelike is a StringIO instance of the uploaded file """
    pass

While you develop your plugin, you can check that you are meeting basic requirements by running the following test method.

classmethod test_subclass()

Tests that the subclass has overloaded every required method and attribute. Does some basic type checking as well.

Usage:

from myplugin import MyDevice
MyDevice.test_subclass()

The following attributes and methods may or may not be useful to you as you develop your plugin. They are all used internally, and it is highly recommended you do not overload them.

uuid

Use this to see what the UUID is for the device, anywhere except inside the get_uuid() and set_uuid() methods.

hardware_address

The hardware (MAC) address of the device.

credentials

The credentials for this device. May be None if we don’t know them.

is_authenticated

bool attribute for whether we are authenticated for this device or not.

meta

Crowsnest metadata for this device.

is_healthy()

Returns True or False for whether this device is considered healthy or not.

Healthiness requires that we are authenticated successfully and the device is connected to Bosun.

heartbeat()

A emit() decorated event generator for the heartbeat event all Crowsnest devices use.

as_dict()

Returns a dictionary representation of the device, suitable for serialization.

Listeners

class bosunplugins.listeners.http.Route

Result of using the Device.listeners.http.route() decorator.

If called, calls the decorated method.

path

Full safe path for this route.

get_url()

Returns the full URL for this route, eg 'http://1.2.3.4:5000/safe/path/to/route'.

class bosunplugins.listeners.ftp.WatchedFolder

Result of using the Device.listeners.ftp.watched_folder() decorator.

If called, calls the decorated method.

ftp_port

Port the FTP server is running on.

ftp_username

Username to access the FTP server.

ftp_password

Password to access the FTP server.

base_path

Safe base path for the class.

path

Full path to the watched folder.

get_base_url()

Returns URL for the base path, eg 'ftp://1.2.3.4:5001/safe/base/path'.

get_url()

Returns the full URL for the watche folder, eg 'ftp://1.2.3.4:5001/safe/base/path/and/watched/folder'.

Indices and tables