summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kurilin <akurilin@mirantis.com>2015-09-09 14:02:42 +0300
committerAndrey Kurilin <akurilin@mirantis.com>2015-09-10 15:54:38 +0300
commita96e9d57c56e53f4e02701d2ae9f9194bb6e3d5b (patch)
treef85533602fa4df6a5f696b752851d8bcd1092157
parente612205ab850b291a78e539d15923c8716d90158 (diff)
downloadpython-novaclient-a96e9d57c56e53f4e02701d2ae9f9194bb6e3d5b.tar.gz
Restrict direct usage of novaclient.v2.client
A lot of project uses incorrect import of versioned novaclient client obj (i.e. novaclient.v2.client.Client). It leads to unability to change interface of such inner classes. This patch updates docs to include warning note and add warning message to `novaclient.v2.client.Client` object. Change-Id: Ifeba391716d3d51d6a75a53cad405e1ec595e27b Related-Bug: #1493576
-rw-r--r--README.rst2
-rw-r--r--doc/source/api.rst37
-rw-r--r--novaclient/client.py25
-rw-r--r--novaclient/v2/client.py52
4 files changed, 69 insertions, 47 deletions
diff --git a/README.rst b/README.rst
index 00a361de..9725cd52 100644
--- a/README.rst
+++ b/README.rst
@@ -1,5 +1,5 @@
Python bindings to the OpenStack Nova API
-==================================================
+=========================================
This is a client for the OpenStack Nova API. There's a Python API (the
``novaclient`` module), and a command-line script (``nova``). Each
diff --git a/doc/source/api.rst b/doc/source/api.rst
index 8bcb219b..ded67ed6 100644
--- a/doc/source/api.rst
+++ b/doc/source/api.rst
@@ -1,5 +1,5 @@
The :mod:`novaclient` Python API
-==================================
+================================
.. module:: novaclient
:synopsis: A client for the OpenStack Nova API.
@@ -14,7 +14,10 @@ First create a client instance with your credentials::
>>> from novaclient import client
>>> nova = client.Client(VERSION, USERNAME, PASSWORD, PROJECT_ID, AUTH_URL)
-Here ``VERSION`` can be: ``1.1``, ``2``.
+Here ``VERSION`` can be a string or ``novaclient.api_versions.APIVersion`` obj.
+If you prefer string value, you can use ``1.1`` (deprecated now), ``2`` or
+``2.X`` (where X is a microversion).
+
Alternatively, you can create a client instance using the keystoneclient
session API::
@@ -23,9 +26,9 @@ session API::
>>> from keystoneclient import session
>>> from novaclient import client
>>> auth = v2.Password(auth_url=AUTH_URL,
- username=USERNAME,
- password=PASSWORD,
- tenant_name=PROJECT_ID)
+ ... username=USERNAME,
+ ... password=PASSWORD,
+ ... tenant_name=PROJECT_ID)
>>> sess = session.Session(auth=auth)
>>> nova = client.Client(VERSION, session=sess)
@@ -33,6 +36,23 @@ For more information on this keystoneclient API, see `Using Sessions`_.
.. _Using Sessions: http://docs.openstack.org/developer/python-keystoneclient/using-sessions.html
+It is also possible to use an instance as a context manager in which case
+there will be a session kept alive for the duration of the with statement::
+
+ >>> from novaclient import client
+ >>> with client.Client(VERSION, USERNAME, PASSWORD,
+ ... PROJECT_ID, AUTH_URL) as nova:
+ ... nova.servers.list()
+ ... nova.flavors.list()
+ ...
+
+It is also possible to have a permanent (process-long) connection pool,
+by passing a connection_pool=True::
+
+ >>> from novaclient import client
+ >>> nova = client.Client(VERSION, USERNAME, PASSWORD, PROJECT_ID,
+ ... AUTH_URL, connection_pool=True)
+
Then call methods on its managers::
>>> nova.servers.list()
@@ -51,6 +71,13 @@ Then call methods on its managers::
>>> nova.servers.create("my-server", flavor=fl)
<Server: my-server>
+.. warning:: Direct initialization of ``novaclient.v2.client.Client`` object
+ can cause you to "shoot yourself in the foot". See launchpad bug-report
+ `1493576`_ for more details.
+
+.. _1493576: https://launchpad.net/bugs/1493576
+
+
Reference
---------
diff --git a/novaclient/client.py b/novaclient/client.py
index 15925554..f7ac8702 100644
--- a/novaclient/client.py
+++ b/novaclient/client.py
@@ -785,6 +785,27 @@ def get_client_class(version):
def Client(version, *args, **kwargs):
- """Initialize client object based on given version."""
+ """Initialize client object based on given version.
+
+ HOW-TO:
+ The simplest way to create a client instance is initialization with your
+ credentials::
+
+ >>> from novaclient import client
+ >>> nova = client.Client(VERSION, USERNAME, PASSWORD,
+ ... PROJECT_ID, AUTH_URL)
+
+ Here ``VERSION`` can be a string or
+ ``novaclient.api_versions.APIVersion`` obj. If you prefer string value,
+ you can use ``1.1`` (deprecated now), ``2`` or ``2.X``
+ (where X is a microversion).
+
+
+ Alternatively, you can create a client instance using the keystoneclient
+ session API. See "The novaclient Python API" page at
+ python-novaclient's doc.
+ """
api_version, client_class = _get_client_class_and_version(version)
- return client_class(api_version=api_version, *args, **kwargs)
+ kwargs.pop("direct_use", None)
+ return client_class(api_version=api_version, direct_use=False,
+ *args, **kwargs)
diff --git a/novaclient/v2/client.py b/novaclient/v2/client.py
index 1c195d5a..d48c062f 100644
--- a/novaclient/v2/client.py
+++ b/novaclient/v2/client.py
@@ -14,6 +14,7 @@
# under the License.
from novaclient import client
+from novaclient.i18n import _LW
from novaclient.v2 import agents
from novaclient.v2 import aggregates
from novaclient.v2 import availability_zones
@@ -53,44 +54,8 @@ class Client(object):
"""
Top-level object to access the OpenStack Compute API.
- Create an instance with your creds::
-
- >>> client = Client(USERNAME, PASSWORD, PROJECT_ID, AUTH_URL)
-
- Or, alternatively, you can create a client instance using the
- keystoneclient.session API::
-
- >>> from keystoneclient.auth.identity import v2
- >>> from keystoneclient import session
- >>> from novaclient import client
- >>> auth = v2.Password(auth_url=AUTH_URL,
- username=USERNAME,
- password=PASSWORD,
- tenant_name=PROJECT_ID)
- >>> sess = session.Session(auth=auth)
- >>> nova = client.Client(VERSION, session=sess)
-
- Then call methods on its managers::
-
- >>> nova.servers.list()
- ...
- >>> nova.flavors.list()
- ...
-
- It is also possible to use an instance as a context manager in which
- case there will be a session kept alive for the duration of the with
- statement::
-
- >>> with Client(USERNAME, PASSWORD, PROJECT_ID, AUTH_URL) as client:
- ... client.servers.list()
- ... client.flavors.list()
- ...
-
- It is also possible to have a permanent (process-long) connection pool,
- by passing a connection_pool=True::
-
- >>> client = Client(USERNAME, PASSWORD, PROJECT_ID,
- ... AUTH_URL, connection_pool=True)
+ .. warning:: All scripts and projects should not initialize this class
+ directly. It should be done via `novaclient.client.Client` interface.
"""
def __init__(self, username=None, api_key=None, project_id=None,
@@ -103,7 +68,7 @@ class Client(object):
auth_system='keystone', auth_plugin=None, auth_token=None,
cacert=None, tenant_id=None, user_id=None,
connection_pool=False, session=None, auth=None,
- api_version=None, **kwargs):
+ api_version=None, direct_use=True, **kwargs):
"""
:param str username: Username
:param str api_key: API Key
@@ -136,6 +101,15 @@ class Client(object):
:param api_version: Compute API version
:type api_version: novaclient.api_versions.APIVersion
"""
+ if direct_use:
+ import warnings
+
+ warnings.warn(
+ _LW("'novaclient.v2.client.Client' is not designed to be "
+ "initialized directly. It is inner class of novaclient. "
+ "Please, use 'novaclient.client.Client' instead. "
+ "Related lp bug-report: 1493576"))
+
# FIXME(comstud): Rename the api_key argument above when we
# know it's not being used as keyword argument