summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZiad Sawalha <github@highbridgellc.com>2011-12-15 23:32:19 -0600
committerZiad Sawalha <github@highbridgellc.com>2011-12-16 12:00:47 -0600
commit4ba7e7bc9c71b88e488c9ab4bdf9178a62e1deea (patch)
tree382d1effda24ebbbfdd4877b2b64f12795480721
parentee6f844aed42564fa4f2a1a63246af23cf9d7eac (diff)
downloadkeystone-4ba7e7bc9c71b88e488c9ab4bdf9178a62e1deea.tar.gz
keystone-4ba7e7bc9c71b88e488c9ab4bdf9178a62e1deea.tar.xz
keystone-4ba7e7bc9c71b88e488c9ab4bdf9178a62e1deea.zip
Format keystone-manage output better
This makes the output of keystone-manage list commands much prettier: $ ./keystone-manage tenant list --------------------------------------------------------------- | Tenants | --------------------------------------------------------------- | id | name | enabled | --------------------------------------------------------------- | e028069d28a5440c9028aa1c5111cef6 | customer-x | True | | 01ad238f97a648709e68f3148b157f88 | ANOTHER:TENANT | True | | 67ce3d68bc49427abed2c409a2213b3c | project-y | False | --------------------------------------------------------------- It also starts a unit test to test keystone-manage. Change-Id: I0e679795d6050ed401609fce3de0c16e234d21da
-rw-r--r--keystone/manage/__init__.py95
-rw-r--r--keystone/test/unit/test_keystone_manage.py27
2 files changed, 100 insertions, 22 deletions
diff --git a/keystone/manage/__init__.py b/keystone/manage/__init__.py
index 6c59df4c..bf50d25a 100644
--- a/keystone/manage/__init__.py
+++ b/keystone/manage/__init__.py
@@ -140,13 +140,6 @@ def process(*args):
optional_arg = (lambda args, x:
len(args) > x and str(args[x]).strip() or None)
- def print_table(header_row, rows):
- """Prints a lists of lists as table in a human readable format"""
- print "\t".join(header_row)
- print '-' * 79
- rows = [[str(col) for col in row] for row in rows]
- print "\n".join(["\t".join(row) for row in rows])
-
# Execute command
if (object_type, action) == ('user', 'add'):
require_args(args, 4, 'No password specified for fourth argument')
@@ -155,7 +148,8 @@ def process(*args):
print "SUCCESS: User %s created." % object_id
elif (object_type, action) == ('user', 'list'):
- print_table(('id', 'name', 'enabled', 'tenant'), api.list_users())
+ print Table('Users', ['id', 'name', 'enabled', 'tenant'],
+ api.list_users())
elif (object_type, action) == ('user', 'disable'):
if api.disable_user(name=object_id):
@@ -169,7 +163,7 @@ def process(*args):
print "SUCCESS: Tenant %s created." % object_id
elif (object_type, action) == ('tenant', 'list'):
- print_table(('id', 'name', 'enabled'), api.list_tenants())
+ print Table('Tenants', ['id', 'name', 'enabled'], api.list_tenants())
elif (object_type, action) == ('tenant', 'disable'):
if api.disable_tenant(name=object_id):
@@ -186,12 +180,12 @@ def process(*args):
tenant = optional_arg(args, 2)
if tenant:
# print with users
- print 'Role assignments for tenant %s' % tenant
- print_table(('User', 'Role'),
- api.list_roles(tenant=tenant))
+ print Table('Role assignments for tenant %s' % tenant,
+ ['User', 'Role'],
+ api.list_roles(tenant=tenant))
else:
# print without tenants
- print_table(('id', 'name', 'service_id', 'description'),
+ print Table('Roles', ['id', 'name', 'service_id', 'description'],
api.list_roles())
elif (object_type, action) == ('role', 'grant'):
@@ -223,13 +217,13 @@ def process(*args):
elif (object_type, action) == ('endpointTemplates', 'list'):
tenant = optional_arg(args, 2)
if tenant:
- print 'Endpoints for tenant %s' % tenant
- print_table(('service', 'region', 'Public URL'),
- api.list_tenant_endpoints(tenant))
+ print Table('Endpoints for tenant %s' % tenant,
+ ['id', 'service', 'region', 'Public URL'],
+ api.list_tenant_endpoints(tenant))
else:
- print 'All EndpointTemplates'
- print_table(('id', 'service', 'type', 'region', 'enabled',
- 'is_global', 'Public URL', 'Admin URL'),
+ print Table('All EndpointTemplates', ['id', 'service', 'type',
+ 'region', 'enabled', 'is_global', 'Public URL',
+ 'Admin URL'],
api.list_endpoint_templates())
elif (object_type, action) == ('endpoint', 'add'):
@@ -250,7 +244,7 @@ def process(*args):
print "SUCCESS: Token %s created." % (object_id,)
elif (object_type, action) == ('token', 'list'):
- print_table(('token', 'user', 'expiration', 'tenant'),
+ print Table('Tokens', ('token', 'user', 'expiration', 'tenant'),
api.list_tokens())
elif (object_type, action) == ('token', 'delete'):
@@ -273,8 +267,9 @@ def process(*args):
print "SUCCESS: Service %s created successfully." % (object_id,)
elif (object_type, action) == ('service', 'list'):
- print_table(('id', 'name', 'type', 'owner_id', 'description'),
- api.list_services())
+ print Table('Services',
+ ('id', 'name', 'type', 'owner_id', 'description'),
+ api.list_services())
elif object_type == 'service':
raise optparse.OptParseError(ACTION_NOT_SUPPORTED % ('services'))
@@ -395,6 +390,62 @@ def do_db_sync(options, args):
migration.db_sync(options, version=db_version)
+class Table:
+ """Prints data in table for console output
+
+ Syntax print Table("This is the title",
+ ["Header1","Header2","H3"],
+ [[1,2,3],["Hi","everybody","How are you??"],[None,True,[1,2]]])
+
+ """
+ def __init__(self, title=None, headers=None, rows=None):
+ self.title = title
+ self.headers = headers if headers is not None else []
+ self.rows = rows if rows is not None else []
+ self.nrows = len(self.rows)
+ self.fieldlen = []
+
+ ncols = len(headers)
+
+ for h in range(ncols):
+ max = 0
+ for row in rows:
+ if len(str(row[h])) > max:
+ max = len(str(row[h]))
+ self.fieldlen.append(max)
+
+ for i in range(len(headers)):
+ if len(str(headers[i])) > self.fieldlen[i]:
+ self.fieldlen[i] = len(str(headers[i]))
+
+ self.width = sum(self.fieldlen) + (ncols - 1) * 3 + 4
+
+ def __str__(self):
+ bar = "-" * self.width
+ if self.title:
+ title = "| " + self.title + " " * \
+ (self.width - 3 - (len(self.title))) + "|"
+ out = [bar, title, bar]
+ else:
+ out = []
+ header = ""
+ for i in range(len(self.headers)):
+ header += "| %s" % (str(self.headers[i])) + " " * \
+ (self.fieldlen[i] - len(str(self.headers[i]))) + " "
+ header += "|"
+ out.append(header)
+ out.append(bar)
+ for i in self.rows:
+ line = ""
+ for j in range(len(i)):
+ line += "| %s" % (str(i[j])) + " " * \
+ (self.fieldlen[j] - len(str(i[j]))) + " "
+ out.append(line + "|")
+
+ out.append(bar)
+ return "\r\n".join(out)
+
+
def main(args=None):
try:
process(*parse_args(args))
diff --git a/keystone/test/unit/test_keystone_manage.py b/keystone/test/unit/test_keystone_manage.py
new file mode 100644
index 00000000..9b501b1f
--- /dev/null
+++ b/keystone/test/unit/test_keystone_manage.py
@@ -0,0 +1,27 @@
+import os
+import subprocess
+import sys
+import unittest
+
+possible_topdir = os.path.normpath(os.path.join(os.path.abspath(__file__),
+ os.pardir,
+ os.pardir,
+ os.pardir,
+ os.pardir))
+
+
+class TestKeystoneManage(unittest.TestCase):
+ """
+ Functional tests for the keystone-manage client.
+ """
+
+ def test_check_can_call_keystone_manage(self):
+ """
+ Test that we can call keystone-manage
+ """
+ result = subprocess.check_output([os.path.join(possible_topdir, 'bin',
+ 'keystone-manage'), '--help'])
+ self.assertIn('Usage', result)
+
+if __name__ == '__main__':
+ unittest.main()