Sync oslo cliutils module

Changes -
 * Add field_labels parameter to cliutils.print_list
 * Fix response_key parameter usage in BaseManager
 * Remove unused/mutable default args
 * Centralize bash-completion in Novaclient
 * Fix E126 pep8 errors

Change-Id: I85be2a602ee650ef7f9d50f5f0fada623af8b33c
This commit is contained in:
Matthew Farrellee
2014-09-11 07:41:49 -04:00
parent 56254c171c
commit 5be2179d8c
4 changed files with 34 additions and 34 deletions

View File

@@ -32,7 +32,6 @@ from six.moves.urllib import parse
from saharaclient.openstack.common.apiclient import exceptions
from saharaclient.openstack.common.gettextutils import _
from saharaclient.openstack.common import strutils
from saharaclient.openstack.common import uuidutils
def getid(obj):
@@ -100,12 +99,13 @@ class BaseManager(HookableMixin):
super(BaseManager, self).__init__()
self.client = client
def _list(self, url, response_key, obj_class=None, json=None):
def _list(self, url, response_key=None, obj_class=None, json=None):
"""List the collection.
:param url: a partial URL, e.g., '/servers'
:param response_key: the key to be looked up in response dictionary,
e.g., 'servers'
e.g., 'servers'. If response_key is None - all response body
will be used.
:param obj_class: class for constructing the returned objects
(self.resource_class will be used by default)
:param json: data that will be encoded as JSON and passed in POST
@@ -119,7 +119,7 @@ class BaseManager(HookableMixin):
if obj_class is None:
obj_class = self.resource_class
data = body[response_key]
data = body[response_key] if response_key is not None else body
# NOTE(ja): keystone returns values as list as {'values': [ ... ]}
# unlike other services which just return the list...
try:
@@ -129,15 +129,17 @@ class BaseManager(HookableMixin):
return [obj_class(self, res, loaded=True) for res in data if res]
def _get(self, url, response_key):
def _get(self, url, response_key=None):
"""Get an object from collection.
:param url: a partial URL, e.g., '/servers'
:param response_key: the key to be looked up in response dictionary,
e.g., 'server'
e.g., 'server'. If response_key is None - all response body
will be used.
"""
body = self.client.get(url).json()
return self.resource_class(self, body[response_key], loaded=True)
data = body[response_key] if response_key is not None else body
return self.resource_class(self, data, loaded=True)
def _head(self, url):
"""Retrieve request headers for an object.
@@ -147,21 +149,23 @@ class BaseManager(HookableMixin):
resp = self.client.head(url)
return resp.status_code == 204
def _post(self, url, json, response_key, return_raw=False):
def _post(self, url, json, response_key=None, return_raw=False):
"""Create an object.
:param url: a partial URL, e.g., '/servers'
:param json: data that will be encoded as JSON and passed in POST
request (GET will be sent by default)
:param response_key: the key to be looked up in response dictionary,
e.g., 'servers'
e.g., 'server'. If response_key is None - all response body
will be used.
:param return_raw: flag to force returning raw JSON instead of
Python object of self.resource_class
"""
body = self.client.post(url, json=json).json()
data = body[response_key] if response_key is not None else body
if return_raw:
return body[response_key]
return self.resource_class(self, body[response_key])
return data
return self.resource_class(self, data)
def _put(self, url, json=None, response_key=None):
"""Update an object with PUT method.
@@ -170,7 +174,8 @@ class BaseManager(HookableMixin):
:param json: data that will be encoded as JSON and passed in POST
request (GET will be sent by default)
:param response_key: the key to be looked up in response dictionary,
e.g., 'servers'
e.g., 'servers'. If response_key is None - all response body
will be used.
"""
resp = self.client.put(url, json=json)
# PUT requests may not return a body
@@ -188,7 +193,8 @@ class BaseManager(HookableMixin):
:param json: data that will be encoded as JSON and passed in POST
request (GET will be sent by default)
:param response_key: the key to be looked up in response dictionary,
e.g., 'servers'
e.g., 'servers'. If response_key is None - all response body
will be used.
"""
body = self.client.patch(url, json=json).json()
if response_key is not None:
@@ -437,21 +443,6 @@ class Resource(object):
self._info = info
self._add_details(info)
self._loaded = loaded
self._init_completion_cache()
def _init_completion_cache(self):
cache_write = getattr(self.manager, 'write_to_completion_cache', None)
if not cache_write:
return
# NOTE(sirp): ensure `id` is already present because if it isn't we'll
# enter an infinite loop of __getattr__ -> get -> __init__ ->
# __getattr__ -> ...
if 'id' in self.__dict__ and uuidutils.is_uuid_like(self.id):
cache_write('uuid', self.id)
if self.human_id:
cache_write('human_id', self.human_id)
def __repr__(self):
reprkeys = sorted(k

View File

@@ -357,8 +357,7 @@ class BaseClient(object):
"Must be one of: %(version_map)s") % {
'api_name': api_name,
'version': version,
'version_map': ', '.join(version_map.keys())
}
'version_map': ', '.join(version_map.keys())}
raise exceptions.UnsupportedVersion(msg)
return importutils.import_class(client_path)

View File

@@ -33,7 +33,9 @@ from six.moves.urllib import parse
from saharaclient.openstack.common.apiclient import client
def assert_has_keys(dct, required=[], optional=[]):
def assert_has_keys(dct, required=None, optional=None):
required = required or []
optional = optional or []
for k in required:
try:
assert k in dct

View File

@@ -132,7 +132,7 @@ def isunauthenticated(func):
def print_list(objs, fields, formatters=None, sortby_index=0,
mixed_case_fields=None):
mixed_case_fields=None, field_labels=None):
"""Print a list or objects as a table, one row per object.
:param objs: iterable of :class:`Resource`
@@ -141,14 +141,22 @@ def print_list(objs, fields, formatters=None, sortby_index=0,
:param sortby_index: index of the field for sorting table rows
:param mixed_case_fields: fields corresponding to object attributes that
have mixed case names (e.g., 'serverId')
:param field_labels: Labels to use in the heading of the table, default to
fields.
"""
formatters = formatters or {}
mixed_case_fields = mixed_case_fields or []
field_labels = field_labels or fields
if len(field_labels) != len(fields):
raise ValueError(_("Field labels list %(labels)s has different number "
"of elements than fields list %(fields)s"),
{'labels': field_labels, 'fields': fields})
if sortby_index is None:
kwargs = {}
else:
kwargs = {'sortby': fields[sortby_index]}
pt = prettytable.PrettyTable(fields, caching=False)
kwargs = {'sortby': field_labels[sortby_index]}
pt = prettytable.PrettyTable(field_labels, caching=False)
pt.align = 'l'
for o in objs: