Working with the Python Keystone Client with OpenStack Keystone

Post to Twitter

Keystone is an OpenStack project that provides Identity, Token, Catalog and Policy services for use specifically by projects in the OpenStack family. For the python-keystoneclient there’s a Python API (the keystoneclient module), and a command-line script (keystone). I’m going to cover the Python API part today.


Note: I’m not going to cover Keystone’s new PKI abilities (as of Grizzly). I’m going to stick with the UUID approach for this article. I’ll also be using Python version 2.7.5.

If you don’t have a Keystone server running you can follow my article on how to easily get Keystone up and running on Ubuntu.

Okay, from here I’ll assume your Keystone server is working and is located at 127.0.0.1 (localhost), simply adjust the IP address as needed.

Create a new project folder (I used virtualenv to keep my main site-packages clean) and add a file called app.py. Then install the Python Keystone Client:

$ pip install python-keystoneclient

Let’s first find out all the users entered in Keystone. In the app.py file add the following code:

from keystoneclient.v2_0 import client


if __name__ == "__main__":
    admin_client = client.Client(token='012345SECRET99TOKEN012345',
                       endpoint='http://127.0.0.1:35357/v2.0')
    print(admin_client.users.list())

Adjust the token parameter to the admin token you entered in the Keystone configuration file when you originally set it up.

The results for me look like this:

[<User {u'email': u'admin@domain.com', u'tenantId': None, u'enabled': True, u'name': u'admin', u'id': u'0d868d8e2cf34b4c943c18108f6c9311'}>, <User {u'email': u'demo-user@domain.com', u'tenantId': None, u'enabled': True, u'name': u'demo-user', u'id': u'3e639ee250974dfc824fe164ab6df1d9'}>, <User {u'email': u'servic-user@edomain.com', u'tenantId': None, u'enabled': True, u'name': u'service-user', u'id': u'e47d435b63d544c7b544271bb50db1c3'}>]

If you want to get the tenants back try this:

from keystoneclient.v2_0 import client


if __name__ == "__main__":
    admin_client = client.Client(token='012345SECRET99TOKEN012345',
                       endpoint='http://127.0.0.1:35357/v2.0')
    print(admin_client.tenants.list())

The results for me look like this:

[<Tenant {u'enabled': True, u'description': None, u'name': u'demo-tenant', u'id': u'd220c4e0297c11e39213f23c91aec05e'}>, <Tenant {u'enabled': True, u'description': None, u'name': u'admin-tenant', u'id': u'ad4577e0acab4cf6e345b49ccf9a9802'}>]

If you want to print out the roles for a particular user, in this case the demo-user (the id is: 3e639ee250974dfc824fe164ab6df1d9) you can do this:

from keystoneclient.v2_0 import client


if __name__ == "__main__":
    admin_client = client.Client(token='012345SECRET99TOKEN012345',
                       endpoint='http://127.0.0.1:35357/v2.0')
    print admin_client.roles.roles_for_user('3e639ee250974dfc824fe164ab6df1d9', tenant='d220c4e0297c11e39213f23c91aec05e')

The results for me look like this:

[<Role {u'id': u'98780e26e39b4fd593ecabcc9527ec54', u'name': u'member'}>]

I probably could’ve named things a little better but you should be able to see the role for demo-user is member in the demo-tenant (demo-tenant’s id is: d220c4e0297c11e39213f23c91aec05e).

Note:
Keep in mind there are plenty more admin type calls you can make and whatever you can do with the Python Keystone Client you can also do with tools like cURL if you wish to look over this page on the Keystone website. You can also create/mofify/etc. using the client.

Let’s now go get an auth token from Keystone and then verify it.

Right now we will take the role of a user. In this case the demo-user. Let’s make the call to get our auth token.

from keystoneclient.v2_0 import client
from keystoneclient.exceptions import AuthorizationFailure, Unauthorized


if __name__ == "__main__":
    try:
        keystone = client.Client(username='demo-user',
                                 password='PASSWORD',
                                 auth_url='http://127.0.0.1:5000/v2.0')
        print(keystone.auth_token)
    except AuthorizationFailure as auf:
        print(auf.message)
    except Unauthorized as unauth:
        print(unauth.message)

Assuming it worked this will print out a very long auth token.

Now we pretend we are an endpoint and will take that token and verify it’s valid. Normally in this case you would have a service user setup to do this with the correct permissions. I’m going to use the admin token though in this case to verify that demo-user’s token is valid. Also, keep mind that the token will be passed in the HTTP headers (X-AUTH-TOKEN) but in the code below I’m just going to store what we previously got back from the demo-user’s call to get a new token (above code).

from keystoneclient.v2_0 import client
from keystoneclient.exceptions import AuthorizationFailure, Unauthorized


if __name__ == "__main__":
    auth_token = 'TOKEN_FROM_ABOVE_FOR_DEMO_USER'

    admin_client = client.Client(token='012345SECRET99TOKEN012345', endpoint='127.0.0.1:35357/v2.0')

    try:
        auth_result = admin_client.tokens.authenticate(token=auth_token, tenant_id='OPTIONAL TENANT ID')
        print(auth_result)

        if auth_result:
            print('The token is valid')

    except Unauthorized as unauth:
        print(unauth.message)
    except Exception as ex:
        print(ex.message)

You should see that the token is valid and you will also get a bunch of information on the token including the expiration date, etc.

The Python-KeystoneClient is pretty powerful. This just touches on a few features but should get you started. Keep in mind you can use this in WSGI applications as well.

Post to Twitter

This entry was posted in Open Source, OpenStack, Python, Ubuntu. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>