Introduction to the OpenStack SDK

Nick Wurzer

OpenStack is open source software for running cloud services. Recently I worked on a Python program that would scan ARC cloud instances and determine which instances have been running longer than their allotted time. This mostly used the compute API which is a proxy for OpenStack’s Nova service.

Guide to the Docs

I found it a bit tricky to get started with the OpenStack documentation, so I’ll give a brief overview of what I’ve found useful. Using the OpenStack SDK gives a good overview of all the services available in OpenStack and their corresponding Python classes. Getting Started may also be helpful to get an overview of the different layers and how to connect to a cloud. For most projects, the Connection class will be used, regardless of the service proxy being used. For the instance scanning program, I found the Compute page helpful, but the API for other services are documented as well. This page lists functions in the Compute class. It has useful information about Compute attributes and keyword arguments that can be used in functions in the Connection class such as for filtering.

SDK Layers

The OpenStack SDK is split into three layers. The cloud layer is the highest layer represented through Connection objects. The Connection class has attributes whose types are classes that represent the different available services. Compute is an attribute of Connection, and its API is part of the proxy layer. The Proxy layer is built on top of the Resource layer which generally will not be used by application developers, but for the sake of completeness Compute’s resource layer corresponds to the compute.v2.server.Server class.

Code Examples

List Servers

Once we have our connection object by running conn = openstack.connect(cloud=<some cloud>), we can list available servers with conn.list_servers(). By default this function only lists servers within the current auth-scoped project (whichever project you are currently authenticated to). To list servers from all projects that your token has access to, use the parameter all_projects=True. You may also want to set the parameter detailed=True depending on what information you want to pull from the server list. Lastly, you may want to filter Servers in some way, which can be done with a dictionary where keys are server attributes. The possible arguments for compute servers can be found in the List Servers section of the compute docs. To get servers from all projects in the active state, we might call:

conn.list_servers(all_projects=True, filters={'vm_state': 'active'})

List Projects

The similarly named function list_projects() can be used to list projects. It can also be filtered with a dictionary of project attributes. The project API can be found in the Identity proxy.

List Flavors

Flavours can be listed with list_flavors() and extra details can be gotten by setting the parameter get_extra=True

Getting Attributes

Once we have various objects, we can get their attributes through class attributes. Some examples are listed below, but their attributes can be found in their respective proxy API documentation like in Compute.

Servers

for server in conn.list_servers(all_projects=True, detailed=True):
    print(server.metadata, server.name, server.flavor)

Flavors

for flavor in conn.list_flavors():
    print(flavor.name, flavor.id)

Setting Attributes

There are various setter functions for Connections. Some examples are listed below, and again, the attributes that can be set are in the proxy layer documentation.

Servers

for server in conn.list_servers(all_projects=True):
    conn.set_server_metadata(server.id, {'some_metadata_key': 'some string value'})

The same could be done by:

for server in conn.list_servers(all_projects=True):
    conn.update_server(server.id, metadata={'some_metadata_key': 'some string value'})

The same could also be done through the proxy layer instead of the cloud layer by:

for server in conn.compute.servers(all_projects=True):
    conn.compute.set_server_metadata(server.id, {'some_key':'some value'})

Updating many server attributes could be done by creating a dictionary of the attributes and their values, and unpacking the arguments. For example:

my_attributes = {
    'tags': ['bob', 'bill'],
    metadata':{'some_metadata_key: 'some string value'}
}
for server in conn.list_servers(all_projects=True):
    update_server(server.id, **my_attributes)

Update functions for other proxies are similarly used such as update_project().

Other Functions

There are many other functions connection documentation for creating, updating, deleting, searching or listing various proxies and adding, setting or removing their attributes. I don’t have experience with these so I won’t cover them, but I hope with this introduction you’ll have an easier time navigating the documentation and getting started using the OpenStack SDK.