nodejitsu/pkgcloud — pull request #102 by kenperkins (2013-04-10 22:24:00+00:00)
Title: Integrate OpenStack Identity into pkgcloud

### Overview

This PR is the first step in a plan to integrate more tight coupling and code-sharing between Rackspace and OpenStack, given the commonality between the services.

##### There are a few key points that this PR addresses:

1. Introduce an `Identity` class for Openstack. Includes models for `ServiceCatalog` and `Service`
2. Rework `Openstack.Client.auth` to outsource the authentication to the newly created `Identity` class, as well as the deserialization of the service catalog
3. Refactor the base `Client` to move all of the rackspace/openstack specific inline authentication into the `openstack.Client` and `rackspace.Client`
4. Added jsdocs to significant portions of new and refactored code
5. Updated all tests to ensure 100% passing

#### Compatibility

From a user standpoint, this change should be transparent, although there's an open question: **creating a client without a region should**:

* Select the first available region (i.e. index zero, no pun intended)
* Throw/Return an error

Currently, **the code returns an error** if you don't provide a region during creation of the client and there are any services that don't provide a region-agnostic option. **I'm open to negotiation here**; That said, I feel like we **should encourage** developers to be explicit about region, as magic behavior is likely to confusing. i.e. What if the order of the serviceCatalog endpoints is not deterministic?

### Additional Info
#### Identity/ServiceCatalog/Service Models
These models were created such that Rackspace could provide it's own Identity model inherited from Identity (to be named `RackspaceIdentity` in a future PR) and extend the authentication mechanisms. Rackspace adds `RAX-KSKEY:apiKeyCredentials` in addition to `passwordCredentials`, and this factoring allows a maximum of code-reuse.

The current [Rackspace integration](https://github.com/rackspace/pkgcloud/compare/rackspace:openstackIdentity...rackspace:rackspaceIdentity) is still in progress, I expect that to be the next PR.

#### Refactoring Base Client
As part of this change, I've moved all of the Rackspace/Openstack specific inline auth (for piping streams when an auth token is not present) into their respective Clients, making use of a new `Client._doRequest` function that is now overriden in the Rackspace and Openstack clients.

I expect the Rackspace client will actually lose code that is currently duplicated going forward.