Tuesday, September 27, 2011

Writing custom client for the Network Administrator

In my previous post I outlined basics of the Network Administrator [1]. Today I would like to show you how to write a custom client that will be reporting events (notifications) to the Network Administrator instance. But before we start, let's take a quick look at NA's web API.

Authorization in Network Administrator's web API

Many of you may think that NA has its web API to serve data to other applications. That's true but only partially. In fact the API is mainly used as an interface for communicating with networks that are monitored. As a very fragile part of Network Administrator, it need to have a reliable security policy. That's why we decided to use OAuth, which is becoming a standard in web authorization [2]. However, we provided a different solution for debug mode (settings.py: DEBUG = True), where authorization is disabled. I believe it makes testing much easier, because you can focus on debugging a specific problem.

OAuth vs XAuth

Now, take a look at this OAuth workflow [3][4]:

1. User gets his Consumer Key and Consumer Secret from OAuth service provider.
2. Client application sends Consumer Key and Consumer Secret to get a Request Token.
3. User authorizes access to private data. Request is signed with a Request Token.
4. After authorization, client application gets an Access Token.
5. Client application can use an Access Token to access user's private data.

Read more about OAuth and you will find out why this way of authentication is so cool [5]. Just to point out the most important advantage: with OAuth-like system you don't have to expose user's credentials every time you want to access his private data. It's great, isn't it?

However, this solution has one weakness: when it comes to web API, you don't want to have any interaction with a user! That's why we decided to use our own implementation of OAuth, called XAuth. Basically it skips the third step and divides the scheme above into two independent workflows:

I. Getting the Access Token

1. User gets his Consumer Key and Consumer Secret.
2. Client application sends Consumer Key, Consumer Secret and user's credentials to get Access Token.

II. Using the Access Token

1. Client application is provided with an Access Token.
2. Using an Access Token, client application can access user's private data.

With this approach we are still using user's credentials only once. The Access Token is being stored within client application and it can be used any time you want. Of course it is possible to reset Access Token on the side of NA--in this case all clients have to re-fetch the token.

Writing custom client with NetadminXAuthClient class

If you already understand OAuth and if you like the concept of XAuth, you can begin coding. The starting point is the NetadminXAuthClient class placed in the netadmin.utils.xauth module [6]. Let's take a look at this short example script:

from netadmin.utils.xauth import NetadminXAuthClient

# all these values below should be given by a user
API_URL = 'http://ns-dev.appspot.com'

if __name__ == '__main__':

# you can skip this line if you already have the access token
access_token = client.fetch_access_token(USER_NAME, USER_PASSWORD)


# at this poing you can get or post any data, e.g.:
host_list = client.get_host_list()
for host in host_list["hosts"]:
id = host["id"]
host_data = client.get_host(id)
print host_data["host_name"], host_data["ipv4"]

Now, you can get any system information and use NetadminXAuthClient class to report it to NA instance:

import datetime
import subprocess
from subprocess import PIPE
from socket import gethostname

uptime = subprocess.Popen('/usr/bin/uptime', stdout=PIPE).communicate()[0]

description="Here goes a detailed description",
short_description="Shortly about an event",
timestamp=datetime.datetime.now(), protocol="ABCD",
event_type="INFO", hostname=gethostname(),
fields_class="CustomEvent", uptime=uptime)

The code above gets output of UNIX uptime command and sends it within Network Administrator event report. The field "uptime" isn't defined as a report_event method argument, however every extra field will be serialized and stored along with other event data. For the full list of supported arguments, see xauth module documentation [7].


That's it--these few simple methods are enough to write a custom client for the Network Administrator. Don't forget to read the source [7], where you will find all supported API methods. Also, if you have any comments, especially about the security issues, let me know, and I'll surely write you back.

[1] http://blog.umitproject.org/2011/08/network-administrator-monitoring-your.html
[2] http://wiki.oauth.net/w/page/12238551/ServiceProviders
[3] http://hueniverse.com/oauth/guide/workflow/
[4] Here you will find another nice tutorial, based on Yahoo! implementation of OAuth: http://developer.yahoo.com/oauth/guide/oauth-auth-flow.html
[5] http://oauth.net/about/
[6] The module depends on the oauth2 library: https://github.com/simplegeo/python-oauth2
[7] http://dev.umitproject.org/projects/na/repository/revisions/master/entry/netadmin/utils/xauth.py