diff --git a/bin/keystone-manage b/bin/keystone-manage index bcc27195eb..e551c47e2f 100755 --- a/bin/keystone-manage +++ b/bin/keystone-manage @@ -18,11 +18,11 @@ from keystone import cli if __name__ == '__main__': - dev_conf = os.path.join(possible_topdir, - 'etc', - 'keystone.conf') - config_files = None - if os.path.exists(dev_conf): - config_files = [dev_conf] + dev_conf = os.path.join(possible_topdir, + 'etc', + 'keystone.conf') + config_files = None + if os.path.exists(dev_conf): + config_files = [dev_conf] - cli.main(argv=sys.argv, config_files=config_files) + cli.main(argv=sys.argv, config_files=config_files) diff --git a/keystone/cli.py b/keystone/cli.py index 93e3620564..e178a31b64 100644 --- a/keystone/cli.py +++ b/keystone/cli.py @@ -33,316 +33,317 @@ config.register_cli_bool('id-only', class BaseApp(cli.log.LoggingApp): - def __init__(self, *args, **kw): - kw.setdefault('name', self.__class__.__name__.lower()) - super(BaseApp, self).__init__(*args, **kw) + def __init__(self, *args, **kw): + kw.setdefault('name', self.__class__.__name__.lower()) + super(BaseApp, self).__init__(*args, **kw) - def add_default_params(self): - for args, kw in DEFAULT_PARAMS: - self.add_param(*args, **kw) + def add_default_params(self): + for args, kw in DEFAULT_PARAMS: + self.add_param(*args, **kw) - def _parse_keyvalues(self, args): - kv = {} - for x in args: - key, value = x.split('=', 1) - # make lists if there are multiple values - if key.endswith('[]'): - key = key[:-2] - existing = kv.get(key, []) - existing.append(value) - kv[key] = existing - else: - kv[key] = value - return kv + def _parse_keyvalues(self, args): + kv = {} + for x in args: + key, value = x.split('=', 1) + # make lists if there are multiple values + if key.endswith('[]'): + key = key[:-2] + existing = kv.get(key, []) + existing.append(value) + kv[key] = existing + else: + kv[key] = value + return kv class DbSync(BaseApp): - """Sync the database.""" + """Sync the database.""" - name = 'db_sync' + name = 'db_sync' - def __init__(self, *args, **kw): - super(DbSync, self).__init__(*args, **kw) + def __init__(self, *args, **kw): + super(DbSync, self).__init__(*args, **kw) - def main(self): - for k in ['identity', 'catalog', 'policy', 'token']: - driver = utils.import_object(getattr(CONF, k).driver) - if hasattr(driver, 'db_sync'): - driver.db_sync() + def main(self): + for k in ['identity', 'catalog', 'policy', 'token']: + driver = utils.import_object(getattr(CONF, k).driver) + if hasattr(driver, 'db_sync'): + driver.db_sync() class ClientCommand(BaseApp): - ACTION_MAP = None + ACTION_MAP = None - def _attr_name(self): - return '%ss' % self.__class__.__name__.lower() + def _attr_name(self): + return '%ss' % self.__class__.__name__.lower() - def _cmd_name(self): - return self.__class__.__name__.lower() + def _cmd_name(self): + return self.__class__.__name__.lower() - def __init__(self, *args, **kw): - super(ClientCommand, self).__init__(*args, **kw) - if not self.ACTION_MAP: - self.ACTION_MAP = {'help': 'help'} - self.add_param('action', nargs='?', default='help') - self.add_param('keyvalues', nargs='*') - self.client = kc.Client(CONF.endpoint, token=CONF.auth_token) - self.handle = getattr(self.client, self._attr_name()) - self._build_action_map() + def __init__(self, *args, **kw): + super(ClientCommand, self).__init__(*args, **kw) + if not self.ACTION_MAP: + self.ACTION_MAP = {'help': 'help'} + self.add_param('action', nargs='?', default='help') + self.add_param('keyvalues', nargs='*') + self.client = kc.Client(CONF.endpoint, token=CONF.auth_token) + self.handle = getattr(self.client, self._attr_name()) + self._build_action_map() - def _build_action_map(self): - actions = {} - for k in dir(self.handle): - if not k.startswith('_'): - actions[k] = k - self.ACTION_MAP.update(actions) + def _build_action_map(self): + actions = {} + for k in dir(self.handle): + if not k.startswith('_'): + actions[k] = k + self.ACTION_MAP.update(actions) - def main(self): - """Given some keyvalues create the appropriate data in Keystone.""" - action_name = self.ACTION_MAP[self.params.action] - if action_name == 'help': - self.print_help() - sys.exit(1) + def main(self): + """Given some keyvalues create the appropriate data in Keystone.""" + action_name = self.ACTION_MAP[self.params.action] + if action_name == 'help': + self.print_help() + sys.exit(1) - kv = self._parse_keyvalues(self.params.keyvalues) - try: - f = getattr(self.handle, action_name) - resp = f(**kv) - except Exception: - logging.exception('') - raise + kv = self._parse_keyvalues(self.params.keyvalues) + try: + f = getattr(self.handle, action_name) + resp = f(**kv) + except Exception: + logging.exception('') + raise - if CONF.id_only and getattr(resp, 'id'): - print resp.id - return + if CONF.id_only and getattr(resp, 'id'): + print resp.id + return - if resp is None: - return + 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 + # 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) + print json.dumps(o) - def print_help(self): - CONF.set_usage(CONF.usage.replace( - 'COMMAND', '%s SUBCOMMAND' % self._cmd_name())) - CONF.print_help() + def print_help(self): + CONF.set_usage(CONF.usage.replace( + 'COMMAND', '%s SUBCOMMAND' % self._cmd_name())) + CONF.print_help() - methods = self._get_methods() - print_commands(methods) + methods = self._get_methods() + print_commands(methods) - def _get_methods(self): - o = {} - for k in dir(self.handle): - if k.startswith('_'): - continue - if k in ('find', 'findall', 'api', 'resource_class'): - continue - o[k] = getattr(self.handle, k) - return o + def _get_methods(self): + o = {} + for k in dir(self.handle): + if k.startswith('_'): + continue + if k in ('find', 'findall', 'api', 'resource_class'): + continue + o[k] = getattr(self.handle, k) + return o class Role(ClientCommand): - """Role CRUD functions.""" - pass + """Role CRUD functions.""" + pass class Service(ClientCommand): - """Service CRUD functions.""" - pass + """Service CRUD functions.""" + pass class Token(ClientCommand): - """Token CRUD functions.""" - pass + """Token CRUD functions.""" + pass class Tenant(ClientCommand): - """Tenant CRUD functions.""" - pass + """Tenant CRUD functions.""" + pass class User(ClientCommand): - """User CRUD functions.""" + """User CRUD functions.""" - pass + pass class Ec2(ClientCommand): - def _attr_name(self): - return self.__class__.__name__.lower() + def _attr_name(self): + return self.__class__.__name__.lower() CMDS = {'db_sync': DbSync, - 'role': Role, - 'service': Service, - 'token': Token, - 'tenant': Tenant, - 'user': User, - 'ec2': Ec2, - } + 'role': Role, + 'service': Service, + 'token': Token, + 'tenant': Tenant, + 'user': User, + 'ec2': Ec2, + } class CommandLineGenerator(object): - """A keystoneclient lookalike to generate keystone-manage commands. + """A keystoneclient lookalike to generate keystone-manage commands. - One would use it like so: + 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'] + >>> 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' + cmd = 'keystone-manage' - def __init__(self, cmd=None, execute=False, **kw): - if cmd: - self.cmd = cmd - self.flags = kw - self.execute = execute + 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) + def __getattr__(self, key): + return _Manager(self, key) class _Manager(object): - def __init__(self, parent, name): - self.parent = parent - self.name = name + 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) + 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 __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 __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 __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 __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 __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 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:]]) + 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 __getattr__(self, key): + try: + return self[key] + except KeyError: + raise AttributeError(key) def print_commands(cmds): - print - print "Available commands:" - o = [] - max_length = max([len(k) for k in cmds]) + 2 - for k, cmd in sorted(cmds.iteritems()): - initial_indent = '%s%s: ' % (' ' * (max_length - len(k)), k) - tw = textwrap.TextWrapper(initial_indent=initial_indent, - subsequent_indent=' ' * (max_length + 2), - width=80) - o.extend(tw.wrap( - (cmd.__doc__ and cmd.__doc__ or 'no docs').strip().split('\n')[0])) - print '\n'.join(o) + print + print "Available commands:" + o = [] + max_length = max([len(k) for k in cmds]) + 2 + for k, cmd in sorted(cmds.iteritems()): + initial_indent = '%s%s: ' % (' ' * (max_length - len(k)), k) + tw = textwrap.TextWrapper(initial_indent=initial_indent, + subsequent_indent=' ' * (max_length + 2), + width=80) + o.extend(tw.wrap( + (cmd.__doc__ and cmd.__doc__ or 'no docs').strip().split('\n')[0])) + print '\n'.join(o) def run(cmd, args): - return CMDS[cmd](argv=args).run() + return CMDS[cmd](argv=args).run() def main(argv=None, config_files=None): - CONF.reset() - args = CONF(config_files=config_files, args=argv) + CONF.reset() + args = CONF(config_files=config_files, args=argv) - if len(args) < 2: - CONF.print_help() - print_commands(CMDS) - sys.exit(1) + if len(args) < 2: + CONF.print_help() + print_commands(CMDS) + sys.exit(1) - cmd = args[1] - if cmd in CMDS: - return run(cmd, (args[:1] + args[2:])) + cmd = args[1] + if cmd in CMDS: + return run(cmd, (args[:1] + args[2:])) diff --git a/keystone/common/logging.py b/keystone/common/logging.py index 7ef073763b..a9aaccfced 100644 --- a/keystone/common/logging.py +++ b/keystone/common/logging.py @@ -45,11 +45,11 @@ SysLogHandler = SysLogHandler def log_debug(f): - @functools.wraps(f) - def wrapper(*args, **kw): - logging.debug('%s(%s, %s) ->', f.func_name, str(args), str(kw)) - rv = f(*args, **kw) - logging.debug(pprint.pformat(rv, indent=2)) - logging.debug('') - return rv - return wrapper + @functools.wraps(f) + def wrapper(*args, **kw): + logging.debug('%s(%s, %s) ->', f.func_name, str(args), str(kw)) + rv = f(*args, **kw) + logging.debug(pprint.pformat(rv, indent=2)) + logging.debug('') + return rv + return wrapper diff --git a/keystone/common/utils.py b/keystone/common/utils.py index 3ee9489441..95a1b97103 100644 --- a/keystone/common/utils.py +++ b/keystone/common/utils.py @@ -161,38 +161,38 @@ def check_password(password, hashed): # From python 2.7 def check_output(*popenargs, **kwargs): - r"""Run command with arguments and return its output as a byte string. + r"""Run command with arguments and return its output as a byte string. - If the exit code was non-zero it raises a CalledProcessError. The - CalledProcessError object will have the return code in the returncode - attribute and output in the output attribute. + If the exit code was non-zero it raises a CalledProcessError. The + CalledProcessError object will have the return code in the returncode + attribute and output in the output attribute. - The arguments are the same as for the Popen constructor. Example: + The arguments are the same as for the Popen constructor. Example: - >>> check_output(["ls", "-l", "/dev/null"]) - 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' + >>> check_output(["ls", "-l", "/dev/null"]) + 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' - The stdout argument is not allowed as it is used internally. - To capture standard error in the result, use stderr=STDOUT. + The stdout argument is not allowed as it is used internally. + To capture standard error in the result, use stderr=STDOUT. - >>> check_output(["/bin/sh", "-c", - ... "ls -l non_existent_file ; exit 0"], - ... stderr=STDOUT) - 'ls: non_existent_file: No such file or directory\n' - """ - if 'stdout' in kwargs: - raise ValueError('stdout argument not allowed, it will be overridden.') - logging.debug(' '.join(popenargs[0])) - process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs) - output, unused_err = process.communicate() - retcode = process.poll() - if retcode: - cmd = kwargs.get("args") - if cmd is None: - cmd = popenargs[0] - raise subprocess.CalledProcessError(retcode, cmd) - return output + >>> check_output(["/bin/sh", "-c", + ... "ls -l non_existent_file ; exit 0"], + ... stderr=STDOUT) + 'ls: non_existent_file: No such file or directory\n' + """ + if 'stdout' in kwargs: + raise ValueError('stdout argument not allowed, it will be overridden.') + logging.debug(' '.join(popenargs[0])) + process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs) + output, unused_err = process.communicate() + retcode = process.poll() + if retcode: + cmd = kwargs.get("args") + if cmd is None: + cmd = popenargs[0] + raise subprocess.CalledProcessError(retcode, cmd) + return output def git(*args): - return check_output(['git'] + list(args)) + return check_output(['git'] + list(args)) diff --git a/setup.py b/setup.py index 6c1ce8486d..5f52c70252 100755 --- a/setup.py +++ b/setup.py @@ -1,5 +1,6 @@ from setuptools import setup, find_packages + setup(name='keystone', version='2012.1', description="Authentication service for OpenStack", @@ -10,5 +11,5 @@ setup(name='keystone', packages=find_packages(exclude=['test', 'bin']), scripts=['bin/keystone', 'bin/keystone-manage'], zip_safe=False, - install_requires = ['setuptools', 'python-keystoneclient'], + install_requires=['setuptools', 'python-keystoneclient'], )