Add API versioning support

* Specific versions supported are managed in XXXXXX.client.py with a
  mapping from version to client class.  This is based on the scheme
  that is included in novaclient; none of the other client libs have
  that capability.

Change-Id: I930b197f1189e7f52c3b0096e73e0773cf925542
This commit is contained in:
Dean Troyer 2012-05-10 15:47:59 -05:00
parent 9d224b3bf8
commit 712a8c7f9c
6 changed files with 40 additions and 13 deletions

@ -54,9 +54,7 @@ class ClientManager(object):
tenant_name=None, tenant_id=None,
username=None, password=None,
region_name=None,
identity_api_version=None,
compute_api_version=None,
image_api_version=None,
api_version=None,
):
self._token = token
self._url = url
@ -66,9 +64,7 @@ class ClientManager(object):
self._username = username
self._password = password
self._region_name = region_name
self._identity_api_version = identity_api_version
self._compute_api_version = compute_api_version
self._image_api_version = image_api_version
self._api_version = api_version
self._service_catalog = None
if not self._url:

@ -39,6 +39,12 @@ class EndpointNotFound(Exception):
pass
class UnsupportedVersion(Exception):
"""Indicates that the user is trying to use an unsupported
version of the API"""
pass
class ClientException(Exception):
"""
The base exception class for all exceptions this library raises.

@ -20,6 +20,7 @@ Common client utilities
"""
import os
import sys
import uuid
import prettytable
@ -67,3 +68,10 @@ def env(*vars, **kwargs):
if value:
return value
return kwargs.get('default', '')
def import_class(import_str):
"""Returns a class from a string including module and class."""
mod_str, _sep, class_str = import_str.rpartition('.')
__import__(mod_str)
return getattr(sys.modules[mod_str], class_str)

@ -27,7 +27,7 @@ def make_client(instance):
"""
LOG.debug('instantiating compute client')
client = nova_client.Client(
version=instance._compute_api_version,
version=instance._api_version['compute'],
username=instance._username,
api_key=instance._password,
project_id=instance._tenant_name,

@ -17,23 +17,42 @@
import logging
from keystoneclient.v2_0 import client as identity_client
from openstackclient.common import exceptions as exc
from openstackclient.common import utils
LOG = logging.getLogger(__name__)
API_VERSIONS = {
'2.0': 'keystoneclient.v2_0.client.Client',
}
def get_client_class(version):
"""Returns the client class for the requested API version
"""
try:
client_path = API_VERSIONS[str(version)]
except (KeyError, ValueError):
msg = "Invalid client version '%s'. must be one of: %s" % (
(version, ', '.join(API_VERSIONS.keys())))
raise exc.UnsupportedVersion(msg)
return utils.import_class(client_path)
def make_client(instance):
"""Returns an identity service client.
"""
identity_client = get_client_class(instance._api_version['identity'])
if instance._url:
LOG.debug('instantiating identity client: token flow')
client = identity_client.Client(
client = identity_client(
endpoint=instance._url,
token=instance._token,
)
else:
LOG.debug('instantiating identity client: password flow')
client = identity_client.Client(
client = identity_client(
username=instance._username,
password=instance._password,
tenant_name=instance._tenant_name,

@ -172,9 +172,7 @@ class OpenStackShell(App):
username=self.options.os_username,
password=self.options.os_password,
region_name=self.options.os_region_name,
identity_api_version=self.options.os_identity_api_version,
compute_api_version=self.options.os_compute_api_version,
image_api_version=self.options.os_image_api_version,
api_version=self.api_version,
)
return