Merge pull request #10 from ed-/pagination

Pagination
This commit is contained in:
Tim Simpson
2012-06-01 12:40:41 -07:00
6 changed files with 117 additions and 22 deletions

View File

@@ -81,12 +81,18 @@ class InstanceCommands(object):
except:
print sys.exc_info()[1]
def list(self):
def list(self, limit=None, marker=None):
"""List all instances for account"""
dbaas = common.get_client()
if limit:
limit = int(limit, 10)
try:
for instance in dbaas.instances.list():
instances = dbaas.instances.list(limit, marker)
for instance in instances:
_pretty_print(instance._info)
if instances.links:
for link in instances.links:
_pretty_print(link)
except:
print sys.exc_info()[1]
@@ -160,12 +166,16 @@ class DatabaseCommands(object):
except:
print sys.exc_info()[1]
def list(self, id):
def list(self, id, limit=None, marker=None):
"""List the databases"""
dbaas = common.get_client()
try:
for database in dbaas.databases.list(id):
databases = dbaas.databases.list(id, limit, marker)
for database in databases:
_pretty_print(database._info)
if databases.links:
for link in databases.links:
_pretty_print(link)
except:
print sys.exc_info()[1]
@@ -196,12 +206,16 @@ class UserCommands(object):
except:
print sys.exc_info()[1]
def list(self, id):
def list(self, id, limit=None, marker=None):
"""List all the users for an instance"""
dbaas = common.get_client()
try:
for user in dbaas.users.list(id):
users = dbaas.users.list(id, limit, marker)
for user in users:
_pretty_print(user._info)
if users.next:
for link in users.next:
_pretty_print(link)
except:
print sys.exc_info()[1]

View File

@@ -37,7 +37,7 @@ class ReddwarfHTTPClient(HTTPClient):
def __init__(self, user, apikey, tenant, auth_url, service_name,
service_url=None,
auth_strategy=None, **kwargs):
auth_strategy=None, **kwargs):
super(ReddwarfHTTPClient, self).__init__(user, apikey, tenant,
auth_url,
**kwargs)

View File

@@ -74,6 +74,18 @@ def print_commands(commands):
sys.exit(2)
def limit_url(url, limit=None, marker=None):
if not limit and not marker:
return url
query = []
if marker:
query.append("marker=%s" % marker)
if limit:
query.append("limit=%s" % limit)
query = '?' + '&'.join(query)
return url + query
class APIToken(object):
"""A token object containing the user, apikey and token which
is pickleable."""
@@ -111,3 +123,34 @@ class Auth(object):
print apitoken._token
except:
print sys.exc_info()[1]
class Paginated(object):
""" Pretends to be a list if you iterate over it, but also keeps a
next property you can use to get the next page of data. """
def __init__(self, items=[], next_marker=None, links=[]):
self.items = items
self.next = next_marker
self.links = links
def __len__(self):
return len(self.items)
def __iter__(self):
return self.items.__iter__()
def __getitem__(self, key):
return self.items[key]
def __setitem__(self, key, value):
self.items[key] = value
def __delitem(self, key):
del self.items[key]
def __reversed__(self):
return reversed(self.items)
def __contains__(self, needle):
return needle in self.items

View File

@@ -1,6 +1,9 @@
from novaclient import base
from reddwarfclient.common import check_for_exceptions
from reddwarfclient.common import limit_url
from reddwarfclient.common import Paginated
import exceptions
import urlparse
class Database(base.Resource):
@@ -34,22 +37,32 @@ class Databases(base.ManagerWithFind):
resp, body = self.api.client.delete(url)
check_for_exceptions(resp, body)
def _list(self, url, response_key):
resp, body = self.api.client.get(url)
def _list(self, url, response_key, limit=None, marker=None):
resp, body = self.api.client.get(limit_url(url, limit, marker))
check_for_exceptions(resp, body)
if not body:
raise Exception("Call to " + url +
" did not return a body.")
return [self.resource_class(self, res) for res in body[response_key]]
links = body.get('links', [])
next_links = [link['href'] for link in links if link['rel'] == 'next']
next_marker = None
for link in next_links:
# Extract the marker from the url.
parsed_url = urlparse.urlparse(link)
query_dict = dict(urlparse.parse_qsl(parsed_url.query))
next_marker = query_dict.get('marker', None)
databases = body[response_key]
databases = [self.resource_class(self, res) for res in databases]
return Paginated(databases, next_marker=next_marker, links=links)
def list(self, instance):
def list(self, instance, limit=None, marker=None):
"""
Get a list of all Databases from the instance.
:rtype: list of :class:`Database`.
"""
return self._list("/instances/%s/databases" % base.getid(instance),
"databases")
"databases", limit, marker)
# def get(self, instance, database):
# """

View File

@@ -16,8 +16,11 @@
from novaclient import base
import exceptions
import urlparse
from reddwarfclient.common import check_for_exceptions
from reddwarfclient.common import limit_url
from reddwarfclient.common import Paginated
REBOOT_SOFT, REBOOT_HARD = 'SOFT', 'HARD'
@@ -68,19 +71,29 @@ class Instances(base.ManagerWithFind):
return self._create("/instances", body, "instance")
def _list(self, url, response_key):
resp, body = self.api.client.get(url)
def _list(self, url, response_key, limit=None, marker=None):
resp, body = self.api.client.get(limit_url(url, limit, marker))
if not body:
raise Exception("Call to " + url + " did not return a body.")
return [self.resource_class(self, res) for res in body[response_key]]
links = body.get('links', [])
next_links = [link['href'] for link in links if link['rel'] == 'next']
next_marker = None
for link in next_links:
# Extract the marker from the url.
parsed_url = urlparse.urlparse(link)
query_dict = dict(urlparse.parse_qsl(parsed_url.query))
next_marker = query_dict.get('marker', None)
instances = body[response_key]
instances = [self.resource_class(self, res) for res in instances]
return Paginated(instances, next_marker=next_marker, links=links)
def list(self):
def list(self, limit=None, marker=None):
"""
Get a list of all instances.
:rtype: list of :class:`Instance`.
"""
return self._list("/instances/detail", "instances")
return self._list("/instances/detail", "instances", limit, marker)
def index(self):
"""

View File

@@ -15,7 +15,10 @@
from novaclient import base
from reddwarfclient.common import check_for_exceptions
from reddwarfclient.common import limit_url
from reddwarfclient.common import Paginated
import exceptions
import urlparse
class User(base.Resource):
@@ -47,19 +50,28 @@ class Users(base.ManagerWithFind):
resp, body = self.api.client.delete(url)
check_for_exceptions(resp, body)
def _list(self, url, response_key):
resp, body = self.api.client.get(url)
def _list(self, url, response_key, limit=None, marker=None):
resp, body = self.api.client.get(limit_url(url, limit, marker))
check_for_exceptions(resp, body)
if not body:
raise Exception("Call to " + url +
" did not return a body.")
return [self.resource_class(self, res) for res in body[response_key]]
links = body.get('links', [])
next_links = [link['href'] for link in links if link['rel'] == 'next']
next_marker = None
for link in next_links:
# Extract the marker from the url.
parsed_url = urlparse.urlparse(link)
query_dict = dict(urlparse.parse_qsl(parsed_url.query))
next_marker = query_dict.get('marker', None)
users = [self.resource_class(self, res) for res in body[response_key]]
return Paginated(users, next_marker=next_marker, links=links)
def list(self, instance):
def list(self, instance, limit=None, marker=None):
"""
Get a list of all Users from the instance's Database.
:rtype: list of :class:`User`.
"""
return self._list("/instances/%s/users" % base.getid(instance),
"users")
"users", limit, marker)