diff --git a/saharaclient/openstack/common/apiclient/base.py b/saharaclient/openstack/common/apiclient/base.py index 5bd23aed..03322071 100644 --- a/saharaclient/openstack/common/apiclient/base.py +++ b/saharaclient/openstack/common/apiclient/base.py @@ -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 diff --git a/saharaclient/openstack/common/apiclient/client.py b/saharaclient/openstack/common/apiclient/client.py index 6d618259..2011ea2f 100644 --- a/saharaclient/openstack/common/apiclient/client.py +++ b/saharaclient/openstack/common/apiclient/client.py @@ -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) diff --git a/saharaclient/openstack/common/apiclient/fake_client.py b/saharaclient/openstack/common/apiclient/fake_client.py index b163074d..7c33929f 100644 --- a/saharaclient/openstack/common/apiclient/fake_client.py +++ b/saharaclient/openstack/common/apiclient/fake_client.py @@ -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 diff --git a/saharaclient/openstack/common/cliutils.py b/saharaclient/openstack/common/cliutils.py index 81c6b94f..70394c6c 100644 --- a/saharaclient/openstack/common/cliutils.py +++ b/saharaclient/openstack/common/cliutils.py @@ -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: