From d4f2bf5fdefca433ee81075dd28be6f1b7387b50 Mon Sep 17 00:00:00 2001 From: termie Date: Tue, 24 Jan 2012 23:01:51 -0800 Subject: add a bunch of basic tests for the cli --- keystone/cli.py | 146 +++++++++++++++++++++++++++++++++++++++++++++++- keystone/common/wsgi.py | 1 - keystone/test.py | 1 - 3 files changed, 144 insertions(+), 4 deletions(-) (limited to 'keystone') diff --git a/keystone/cli.py b/keystone/cli.py index 814ef513..0469ab3a 100644 --- a/keystone/cli.py +++ b/keystone/cli.py @@ -1,8 +1,10 @@ from __future__ import absolute_import +import json import logging import os import sys +import StringIO import textwrap import cli.app @@ -19,7 +21,7 @@ config.register_cli_str('endpoint', default='http://localhost:$admin_port/v2.0', #group='ks', conf=CONF) -config.register_cli_str('auth_token', +config.register_cli_str('auth-token', default='$admin_token', #group='ks', help='asdasd', @@ -113,7 +115,29 @@ class ClientCommand(BaseApp): if CONF.id_only and getattr(resp, 'id'): print resp.id return - print resp + + if resp is None: + return + + # NOTE(termie): this is ugly but it is mostly because the keystoneclient + # code doesn't give us very serializable instance objects + if type(resp) in [type(list()), type(tuple())]: + o = [] + for r in resp: + d = {} + for k, v in sorted(r.__dict__.iteritems()): + if k[0] == '_' or k == 'manager': + continue + d[k] = v + o.append(d) + else: + o = {} + for k, v in sorted(resp.__dict__.iteritems()): + if k[0] == '_' or k == 'manager': + continue + o[k] = v + + print json.dumps(o) def print_help(self): CONF.set_usage(CONF.usage.replace( @@ -175,6 +199,122 @@ CMDS = {'db_sync': DbSync, } +class CommandLineGenerator(object): + """A keystoneclient lookalike to generate keystone-manage commands. + + One would use it like so: + + >>> gen = CommandLineGenerator(id_only=None) + >>> cl = gen.ec2.create(user_id='foo', tenant_id='foo') + >>> cl.to_argv() + ... ['keystone-manage', + '--id-only', + 'ec2', + 'create', + 'user_id=foo', + 'tenant_id=foo'] + + """ + + cmd = 'keystone-manage' + + def __init__(self, cmd=None, execute=False, **kw): + if cmd: + self.cmd = cmd + self.flags = kw + self.execute = execute + + def __getattr__(self, key): + return _Manager(self, key) + + +class _Manager(object): + def __init__(self, parent, name): + self.parent = parent + self.name = name + + def __getattr__(self, key): + return _CommandLine(cmd=self.parent.cmd, + flags=self.parent.flags, + manager=self.name, + method=key, + execute=self.parent.execute) + + +class _CommandLine(object): + def __init__(self, cmd, flags, manager, method, execute=False): + self.cmd = cmd + self.flags = flags + self.manager = manager + self.method = method + self.execute = execute + self.kw = {} + + def __call__(self, **kw): + self.kw = kw + if self.execute: + logging.debug('generated cli: %s', str(self)) + out = StringIO.StringIO() + old_out = sys.stdout + sys.stdout = out + try: + main(self.to_argv()) + except SystemExit as e: + pass + finally: + sys.stdout = old_out + rv = out.getvalue().strip().split('\n')[-1] + try: + loaded = json.loads(rv) + if type(loaded) in [type(list()), type(tuple())]: + return [DictWrapper(**x) for x in loaded] + elif type(loaded) is type(dict()): + return DictWrapper(**loaded) + except Exception: + logging.exception('Could not parse JSON: %s', rv) + return rv + return self + + def __flags(self): + o = [] + for k, v in self.flags.iteritems(): + k = k.replace('_', '-') + if v is None: + o.append('--%s' % k) + else: + o.append('--%s=%s' % (k, str(v))) + return o + + def __manager(self): + if self.manager.endswith('s'): + return self.manager[:-1] + return self.manager + + def __kw(self): + o = [] + for k, v in self.kw.iteritems(): + o.append('%s=%s' % (k, str(v))) + return o + + def to_argv(self): + return ([self.cmd] + + self.__flags() + + [self.__manager(), self.method] + + self.__kw()) + + def __str__(self): + args = self.to_argv() + return ' '.join(args[:1] + ['"%s"' % x for x in args[1:]]) + + +class DictWrapper(dict): + def __getattr__(self, key): + try: + return self[key] + except KeyError: + raise AttributeError(key) + + def print_commands(cmds): print print "Available commands:" @@ -195,7 +335,9 @@ def run(cmd, args): def main(argv=None, config_files=None): + CONF.reset() args = CONF(config_files=config_files, args=argv) + if len(args) < 2: CONF.print_help() print_commands(CMDS) diff --git a/keystone/common/wsgi.py b/keystone/common/wsgi.py index fafa9694..34caec2c 100644 --- a/keystone/common/wsgi.py +++ b/keystone/common/wsgi.py @@ -196,7 +196,6 @@ class Application(BaseApplication): creds = user_token_ref['metadata'].copy() creds['user_id'] = user_token_ref['user'].get('id') creds['tenant_id'] = user_token_ref['tenant'].get('id') - print creds # Accept either is_admin or the admin role assert self.policy_api.can_haz(context, ('is_admin:1', 'roles:admin'), diff --git a/keystone/test.py b/keystone/test.py index 9e1137a7..42655142 100644 --- a/keystone/test.py +++ b/keystone/test.py @@ -146,7 +146,6 @@ class TestCase(unittest.TestCase): for tenant_id in tenants: self.identity_api.add_user_to_tenant(tenant_id, user['id']) setattr(self, 'user_%s' % user['id'], user_copy) - print user_copy for role in fixtures.ROLES: rv = self.identity_api.create_role(role['id'], role) -- cgit