Friday, May 27, 2011

OpenStack Nova and Dashboard authorization using existing LDAP

Our current integration task involves using goSA as the central management utility. goSA internally uses the LDAP repository for all of its data. So we had to find a solution to make both OpenStack Nova and Dashboard authenticate and authorize users using goSA's LDAP structures.

LDAP in Nova

Nova stores its users, projects and roles (global and per-project) in LDAP. Necessary schema files are in /nova/auth dir in the Nova source distribution. The following describes how Nova stores each of these object types.

Users are stored as objects with a novaUser class. They have mandatory accessKey, secretKey and isNovaAdmin (self-explanatory) attributes along with customizable attributes set by flags ldap_user_id_attribute (uid by default) and ldap_user_name_attribute (cn). To use the latter ones, it assigns person, organizationalPerson and inetOrgPerson to all newly created users. All users are stored and searched for in the LDAP subtree defined by ldap_user_subtree and ldap_user_unit.

If you want to manage user creation and deletion from some other place (such as goSA in our case), you can set the ldap_user_modify_only flag to True.

Projects are objects with the widely used groupOfNames class in the subtree defined by the ldap_project_subtree flag. Nova uses the cn attribute for the project name, description for description, member for the list of members' DNs, owner for the project manager's DN. All of these attributes are common for user (and any object) groups management, so it's easy to integrate Nova projects with an existing user groups management system (e.g. goSA).

Roles are also stored as groupOfNames, with similar cn, description and member attributes. Nova has hard-coded roles: cloudadmin, itsec, sysadmin, netadmin, developer. Global roles are stored in a subtree defined by role_project_subtree, cn's are defined by the ldap_cloudadmin, ldap_itsec, ldap_sysadmin, ldap_netadmin and ldap_developer flags respectively. Per-project roles are stored right under the project's DN with cn set to the role's name.

LDAP in Dashboard

To make Dashboard authorize users in LDAP, I use the django-ldap-auth module.
First, you need to install it using your preferred package manager (easy_install django-auth-ldap is sufficient). Second, you need to add it to Dashboard's in AUTHENTICATION_BACKENDS and set up AUTH_LDAP_SERVER_URI to your LDAP URI and AUTH_LDAP_USER_DN_TEMPLATE to Python's template of users' DN; in our case, it should be "ldap_user_id_attribute=%(user)s,ldap_user_subtree".

Note that in you override default settings, so if you want to just add a backend to AUTHENTICATION_BACKENDS, you should use +=. Also if you want to totally disable ModelBackend like we did, you can use = as well.

Also note that to make Dashboard work, you'll have to create an account in Nova with admin privileges and a project with the same name as the account. You can either set all parameters in LDAP by hand or add it using nova-manage user admin using one of usernames from LDAP.

Configuration examples

Let's say goSA is managing the organization exampleorg in the domain on LDAP at ldap:// To make use of its users and groups for Nova's user, projects and roles, we wrote configs like this:

By the way, to make goSA the central user management utility, we created a special plugin that manages Nova users. The plugin can be found here. It looks like this: