A beginners guide to the MAAS REST API (using Python and Requests)

A beginners guide to the MAAS REST API (using Python and Requests)

MAAS (Metal as a Service) is a hardware provisioning and orchestration system developed by Canonical (my employer). Cutting to the chase, MAAS provides a HTTP based API to allow users to control any aspect of the system programatically. Whilst there is documentation for this API, it is slightly fragmented and assumes a decent level of understanding of how ‘Restful APIs’ work. My goal in this blog post is to guide someone with a good understanding of Python and some knowledge of HTTP, through setting themselves up to start writing programs which use this API.

Prerequisites

Before starting, you should have access to a running instance of MAAS, which has at least an admin user account created on it. I won’t help you with that here, but the MAAS docs lay it all out. Provided that is in place, you will need the API key for that user. This is available on the User Preferences page (in the top right corner). This key and the URL of the MAAS server are required for the next step.

From a Python modules point-of-view, we are going to be working with Requests. This is the premier HTTP library available for Python today and offers a rich and easy to use interface for working with HTTP. Install this however you see fit and make sure you can:

>>> import requests

Authentication

Most API calls to MAAS require the user to be authenticated. To do these we need to provide a dictionary of headers to the Requests library. This dictionary can be generated  using the following code snippet:

import oauth.oauth as oauth
import httplib2
import uuid

def get_auth_headers(url, apikey):
    consumer_key, key, secret = apikey.split(':')
    resource_tok_string = "oauth_token_secret=%s&oauth_token=%s" % (
        secret, key)
    resource_token = oauth.OAuthToken.from_string(resource_tok_string)
    consumer_token = oauth.OAuthConsumer(consumer_key, "")

    oauth_request = oauth.OAuthRequest.from_consumer_and_token(
        consumer_token, token=resource_token, http_url=site,
        parameters={'oauth_nonce': uuid.uuid4().hex})
    oauth_request.sign_request(
        oauth.OAuthSignatureMethod_PLAINTEXT(), consumer_token,
        resource_token)
    headers = oauth_request.to_header()
    headers['Accept'] = 'application/json'
    return headers

Note that I snuck a little something extra in, where on the second last line I set the ‘Accept’ header to ‘application/json’. This is not strictly required, but things will be much easier if the API gives us back straight-up JSON rather than anything else.

Sending Requests

Now that you have a way of getting the authentication headers, the rest is really straightforward. There are four types of requests that can be sent to MAAS (these concepts are general to HTTP and not MAAS specific)

GET

This type of request retrieves information on entities stored in MAAS. No parameters are required and they are very simple to send:

response = requests.get('http://mymaas.com:5240/MAAS/api/2.0/machines/', headers=get_auth_headers(apikey))

Upon returning, you can check if the call was successful and what the status code was (this is common to all requests) and the response text.

response.ok # True if successful, False otherwise
response.status_code
response.text

Assuming the call was successful, it should normally be possible to get the JSON output like so:

output = response.json()

POST

This type of request usually creates entities in MAAS, although it is also utilised in a slightly non-standard way in order to issue commands. There will usually be some parameters required for the request, which should be defined in a dictionary and passed like so:

data = {
    'architecture': 'amd64/generic',
    'mac_addresses': '00:00:00:00:00:00',
    'power_type': 'manual',
}
response = requests.post(
    'http://mymaas.com:5240/MAAS/api/2.0/machines/',
    data=data,
    headers=get_auth_headers(apikey)
)

As above for GET requests, you can access the status and output of the command quite easily. POST requests usually return a JSON representation of whatever they created.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s