def _list(self, url, response_key, obj_class=None, body=None, limit=None, items=None): resp = None if items is None: items = [] if body: resp, body = self.api.client.post(url, body=body) else: resp, body = self.api.client.get(url) if obj_class is None: obj_class = self.resource_class data = body[response_key] # NOTE(ja): keystone returns values as list as {'values': [ ... ]} # unlike other services which just return the list... if isinstance(data, dict): try: data = data['values'] except KeyError: pass with self.completion_cache('human_id', obj_class, mode="w"): with self.completion_cache('uuid', obj_class, mode="w"): items_new = [obj_class(self, res, loaded=True) for res in data if res] if limit: limit = int(limit) margin = limit - len(items) if margin <= len(items_new): # If the limit is reached, return the items. items = items + items_new[:margin] return common_base.ListWithMeta(items, resp) else: items = items + items_new else: items = items + items_new # It is possible that the length of the list we request is longer # than osapi_max_limit, so we have to retrieve multiple times to # get the complete list. next = None if 'volumes_links' in body: volumes_links = body['volumes_links'] if volumes_links: for volumes_link in volumes_links: if 'rel' in volumes_link and 'next' == volumes_link['rel']: next = volumes_link['href'] break if next: # As long as the 'next' link is not empty, keep requesting it # till there is no more items. items = self._list(next, response_key, obj_class, None, limit, items) return common_base.ListWithMeta(items, resp)
def test_list_with_meta(self): resp = create_response_obj_with_header() obj = common_base.ListWithMeta([], resp) self.assertEqual([], obj) # Check request_ids attribute is added to obj self.assertTrue(hasattr(obj, 'request_ids')) self.assertEqual([REQUEST_ID], obj.request_ids)
def delete_image_metadata(self, volume, keys): """Delete specified keys from volume's image metadata. :param volume: The :class:`Volume`. :param keys: A list of keys to be removed. """ response_list = [] for key in keys: resp, body = self._action("os-unset_image_metadata", volume, {'key': key}) response_list.append(resp) return common_base.ListWithMeta([], response_list)
def delete_metadata(self, volume, keys): """Delete specified keys from volumes metadata. :param volume: The :class:`Volume`. :param keys: A list of keys to be removed. """ response_list = [] for k in keys: resp, body = self._delete("/volumes/%s/metadata/%s" % (base.getid(volume), k)) response_list.append(resp) return common_base.ListWithMeta([], response_list)
def delete_metadata(self, snapshot, keys): """Delete specified keys from snapshot metadata. :param snapshot: The :class:`Snapshot`. :param keys: A list of keys to be removed. """ response_list = [] snapshot_id = base.getid(snapshot) for k in keys: resp, body = self._delete("/snapshots/%s/metadata/%s" % (snapshot_id, k)) response_list.append(resp) return common_base.ListWithMeta([], response_list)
def list(self, search_opts=None): """ List all volume encryption types. :param volume_types: a list of volume types :return: a list of :class: VolumeEncryptionType instances """ # Since the encryption type is a volume type extension, we cannot get # all encryption types without going through all volume types. volume_types = self.api.volume_types.list() encryption_types = [] list_of_resp = [] for volume_type in volume_types: encryption_type = self._get("/types/%s/encryption" % base.getid(volume_type)) if hasattr(encryption_type, 'volume_type_id'): encryption_types.append(encryption_type) list_of_resp.extend(encryption_type.request_ids) return common_base.ListWithMeta(encryption_types, list_of_resp)
def findall(self, **kwargs): """ Find all items with attributes matching ``**kwargs``. This isn't very efficient for search options which require the Python side filtering(e.g. 'human_id') """ # Want to search for all tenants here so that when attempting to delete # that a user like admin doesn't get a failure when trying to delete # another tenant's volume by name. search_opts = {'all_tenants': 1} # Pass 'name' or 'display_name' search_opts to server filtering to # increase search performance. if 'name' in kwargs: search_opts['name'] = kwargs['name'] elif 'display_name' in kwargs: search_opts['display_name'] = kwargs['display_name'] found = common_base.ListWithMeta([], None) searches = kwargs.items() listing = self.list(search_opts=search_opts) found.append_request_ids(listing.request_ids) # Not all resources attributes support filters on server side # (e.g. 'human_id' doesn't), so when doing findall some client # side filtering is still needed. for obj in listing: try: if all( getattr(obj, attr) == value for (attr, value) in searches): found.append(obj) except AttributeError: continue return found
def list(self, search_opts): return common_base.ListWithMeta(self.resources, fakes.REQUEST_ID)