The aim of this project is to provide an more effective mechanism to provision users from LDAP into cloudstack. Currently Cloudstack enables LDAP authentication. In this authentication users must be first setup in Cloudstack. Once the user is setup in Cloudstack they can authenticate using their LDAP username and password. This project will improve Cloudstack LDAP integration by enabling users be setup automatically using their LDAP credentials.
A detailed version of the proposal is available at: http://ianduffy.ie/cloudstack-ldap.pdf
I have created a blogspot blog in order to document progress made with the project.
Within the community bonding period learning was focused on how to do things "The apache way". This required getting used to communication over the mailing list, developing a relationship with my mentor, learning to use git, adding documentation to the project and finally creating a patch that was submitted to the review board.
During this stage I did a lot of research. I setup my cloudstack development environment and investigated the current LDAP implementation within Cloudstack.
Along with this I exploded the testing framework developed for Cloudstack. Within the Coding stage this became very important.
During the code stage I began to investigate the current LDAP implementation. This includes:
After reviewing this code and implementation for some time I realised that it wasn't the most maintainable code. I realised I could extend it if required. But it would involve creating more unmaintainable code and it would be messy. This goes against my own principles of developing quality. This made me make the steep but justified decision to completely redo the LDAP implementation within Cloudstack. By doing this I did expanded the scope of the project.
I began to research the most appropriate way of structuring this. I started of by redoing the implementation. This meant creating the following classes(Excluding DAOs):
From this I had a solid foundation for creating API commands to allow the user to interact with an LDAP server. I went on to create the following commands:
Along with this global configuration options were added this includes:
With this implementation I believe it allows for a much more extendable and flexible approach. The whole implementation is abstracted from the Cloudstack codebase using the "plugin" model. This allows all of the LDAP features to be contained within one place. Along with this the implementation supplies a good foundation. A side affect of redoing the implementation allowed me to add support for multiple LDAP servers. This means failover is support, so for example, if you have a standard ActiveDirectory with primary and secondary domain controller. Both can be added to Cloudstack which will allow it to fall over to either one assume one is down.
The API changes required me to update the UI interface within Cloudstack. With the improved API implementation this was easier. The Global Settings -> Ldap Configuration page has support for multiple LDAP servers however it only requires a hostname and port. All "global" ldap settings are set within the global settings page.
I have a few security concerns around the implementation of the security authenticators within Cloudstack. From testing I have done it seems to work on a fail over system. That is:
User attempts to authenticate with a password, authentication attempts to happen against the internal Cloudstack database, it fails, it moves onto LDAP.
This raises a concern for me as it means if an LDAP user is deleted. Initially the user will be given a randomly generated password within the Cloudstack database. However if they have changed their Cloudstack password they will still be able to login. Along with this they will be able to authenticate using their API keys. I believe this is a issue beyond the scope of this project but if somebody has advice to fix this I'm all ears. I do not plan to make it easy for a user to change their password. When LDAP is enabled i.e. listLdapConfiguration returns 1 or more results the UI will disable/change account ui features accordingly. That said they will be able to execute the API function of updateUser.
I do realise I could implement checks within the updateUser API command to disable the updating of passwords within the Cloudstack database when LDAP is enabled however I feel this is imposing on the codebase too much.
For testing I have included an embedded LDAP server. This can be launched by running:
Once this is up integration tests can be launched with:
If you wish to use this LDAP server for development purposes you can. Just add a host on the LDAP Configuration page with hostname: localhost port: 10389
Progress on UI features is slow. At the moment I have a list of LDAP users coming up when you click add account. You can pick an user and then fill in the optional information.