diff options
| author | Ziad Sawalha <github@highbridgellc.com> | 2011-12-15 23:32:19 -0600 |
|---|---|---|
| committer | Ziad Sawalha <github@highbridgellc.com> | 2011-12-16 12:00:47 -0600 |
| commit | 4ba7e7bc9c71b88e488c9ab4bdf9178a62e1deea (patch) | |
| tree | 382d1effda24ebbbfdd4877b2b64f12795480721 | |
| parent | ee6f844aed42564fa4f2a1a63246af23cf9d7eac (diff) | |
| download | keystone-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__.py | 95 | ||||
| -rw-r--r-- | keystone/test/unit/test_keystone_manage.py | 27 |
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() |
