Merge "Make client constructor optional"
This commit is contained in:
commit
4de73f0550
@ -325,16 +325,16 @@ Constructing Legacy Client objects
|
||||
|
||||
If all you want to do is get a Client object from a python-*client library,
|
||||
and you want it to do all the normal things related to clouds.yaml, `OS_`
|
||||
environment variables, a hepler function is provided.
|
||||
environment variables, a hepler function is provided. The following
|
||||
will get you a fully configured `novaclient` instance.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import argparse
|
||||
|
||||
from novaclient import client
|
||||
import os_client_config
|
||||
|
||||
nova = os_client_config.make_client('compute', client.Client)
|
||||
nova = os_client_config.make_client('compute')
|
||||
|
||||
If you want to do the same thing but also support command line parsing.
|
||||
|
||||
@ -342,11 +342,10 @@ If you want to do the same thing but also support command line parsing.
|
||||
|
||||
import argparse
|
||||
|
||||
from novaclient import client
|
||||
import os_client_config
|
||||
|
||||
nova = os_client_config.make_client(
|
||||
'compute', client.Client, options=argparse.ArgumentParser())
|
||||
'compute', options=argparse.ArgumentParser())
|
||||
|
||||
If you want to get fancier than that in your python, then the rest of the
|
||||
API is avaiable to you. But often times, you just want to do the one thing.
|
||||
|
@ -12,6 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import importlib
|
||||
import warnings
|
||||
|
||||
from keystoneauth1 import adapter
|
||||
@ -20,9 +21,44 @@ from keystoneauth1 import session
|
||||
import requestsexceptions
|
||||
|
||||
from os_client_config import _log
|
||||
from os_client_config import constructors
|
||||
from os_client_config import exceptions
|
||||
|
||||
|
||||
def _get_client(service_key):
|
||||
class_mapping = constructors.get_constructor_mapping()
|
||||
if service_key not in class_mapping:
|
||||
raise exceptions.OpenStackConfigException(
|
||||
"Service {service_key} is unkown. Please pass in a client"
|
||||
" constructor or submit a patch to os-client-config".format(
|
||||
service_key=service_key))
|
||||
mod_name, ctr_name = class_mapping[service_key].rsplit('.', 1)
|
||||
lib_name = mod_name.split('.')[0]
|
||||
try:
|
||||
mod = importlib.import_module(mod_name)
|
||||
except ImportError:
|
||||
raise exceptions.OpenStackConfigException(
|
||||
"Client for '{service_key}' was requested, but"
|
||||
" {mod_name} was unable to be imported. Either import"
|
||||
" the module yourself and pass the constructor in as an argument,"
|
||||
" or perhaps you do not have python-{lib_name} installed.".format(
|
||||
service_key=service_key,
|
||||
mod_name=mod_name,
|
||||
lib_name=lib_name))
|
||||
try:
|
||||
ctr = getattr(mod, ctr_name)
|
||||
except AttributeError:
|
||||
raise exceptions.OpenStackConfigException(
|
||||
"Client for '{service_key}' was requested, but although"
|
||||
" {mod_name} imported fine, the constructor at {fullname}"
|
||||
" as not found. Please check your installation, we have no"
|
||||
" clue what is wrong with your computer.".format(
|
||||
service_key=service_key,
|
||||
mod_name=mod_name,
|
||||
fullname=class_mapping[service_key]))
|
||||
return ctr
|
||||
|
||||
|
||||
def _make_key(key, service_type):
|
||||
if not service_type:
|
||||
return key
|
||||
@ -217,7 +253,7 @@ class CloudConfig(object):
|
||||
return endpoint
|
||||
|
||||
def get_legacy_client(
|
||||
self, service_key, client_class, interface_key=None,
|
||||
self, service_key, client_class=None, interface_key=None,
|
||||
pass_version_arg=True, **kwargs):
|
||||
"""Return a legacy OpenStack client object for the given config.
|
||||
|
||||
@ -254,6 +290,9 @@ class CloudConfig(object):
|
||||
Client constructor, so this is in case anything
|
||||
additional needs to be passed in.
|
||||
"""
|
||||
if not client_class:
|
||||
client_class = _get_client(service_key)
|
||||
|
||||
# Because of course swift is different
|
||||
if service_key == 'object-store':
|
||||
return self._get_swift_client(client_class=client_class, **kwargs)
|
||||
|
28
os_client_config/constructors.py
Normal file
28
os_client_config/constructors.py
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
_json_path = os.path.join(
|
||||
os.path.dirname(os.path.realpath(__file__)), 'constructors.json')
|
||||
_class_mapping = None
|
||||
|
||||
|
||||
def get_constructor_mapping():
|
||||
global _class_mapping
|
||||
if not _class_mapping:
|
||||
with open(_json_path, 'r') as json_file:
|
||||
_class_mapping = json.load(json_file)
|
||||
return _class_mapping
|
10
os_client_config/constructos.json
Normal file
10
os_client_config/constructos.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"compute": "novaclient.client.Client",
|
||||
"database": "troveclient.client.Client",
|
||||
"identity": "keystoneclient.client.Client",
|
||||
"image": "glanceclient.Client",
|
||||
"network": "neutronclient.neutron.client.Client",
|
||||
"object-store": "swiftclient.client.Connection",
|
||||
"orchestration": "heatclient.client.Client",
|
||||
"volume": "cinderclient.client.Client"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user