Source code for ccmanage.auth

"""
Generate "real" Keystone auth objects versus the DIY methods like in
:py:mod:`hammers.osapi`
"""
import os
import sys

import keystoneauth1 as ksa
import keystoneauth1.loading
import keystoneauth1.session

from hammers.osapi import load_osrc


OS_ENV_PREFIX = 'OS_'


[docs]def add_arguments(parser): """ Inject our args into the user's :py:class:`~argparse.ArgumentParser` `parser`. The resulting argument namespace can be inspected by :py:func:`session_from_args`. """ parser.add_argument('--osrc', type=str, help='OpenStack parameters file that overrides envvars.')
def check_make_equal(m, k1, k2): """ Checks that keys `k1` and `k2` in mutable mapping `m` are equal. If they differ, a ``ValueError`` is raised. If one is missing, it is set to the value of the other. If both are missing, nothing happens. No value is returned, `m` is modified in-place. """ try: if m[k1] == m[k2]: return else: raise ValueError('values differ for keys {!r} and {!r}'.format(k1, k2)) except KeyError: # one or both of them isn't there if k1 in m: m[k2] = m[k1] elif k2 in m: m[k1] = m[k2] #else: #both missing.../shrug
[docs]def auth_from_rc(rc): """ Generates a Keystone Auth object from an OS parameter dictionary. Dict key format is the same as environment variables (``OS_AUTH_URL``, et al.) We do some dumb gymnastics because everything expects the parameters in their own cap/delim format: * envvar name: ``OS_AUTH_URL`` * loader option name: ``auth-url`` * loader argument name: ``auth_url`` """ if not all(key.startswith(OS_ENV_PREFIX) for key in rc): raise ValueError('unknown options without OS_ prefix') check_make_equal(rc, 'OS_PROJECT_NAME', 'OS_TENANT_NAME') check_make_equal(rc, 'OS_PROJECT_ID', 'OS_TENANT_ID') rc_opt_keymap = {key[3:].lower().replace('_', '-'): key for key in rc} loader = ksa.loading.get_plugin_loader('password') credentials = {} for opt in loader.get_options(): if opt.name not in rc_opt_keymap: continue credentials[opt.name.replace('-', '_')] = rc[rc_opt_keymap[opt.name]] auth = loader.load_from_options(**credentials) return auth
[docs]def session_from_vars(os_vars): """ Generates a :py:class:`keystoneauth1.session.Session` object from an OS parameter dictionary akin to :py:func:`auth_from_rc`. This one is generally more useful as the session object can be used directly with most clients: >>> from novaclient.client import Client as NovaClient >>> from ccmanage.auth import session_from_vars >>> session = session_from_vars({'OS_AUTH_URL': ...}) >>> nova = NovaClient('2', session=session) """ return ksa.session.Session(auth=auth_from_rc(os_vars))
[docs]def session_from_args(args=None, rc=False): """ Combine the ``osrc`` attribute in the namespace `args` (if provided) with the environment vars and produce a Keystone session for use by clients. Optionally return the RC dictionary with the OS vars used to construct the session as the second value in a 2-tuple if `rc` is true. """ os_vars = {k: os.environ[k] for k in os.environ if k.startswith(OS_ENV_PREFIX)} if args and args.osrc: os_vars.update(load_osrc(args.osrc)) try: session = ksa.session.Session(auth=auth_from_rc(os_vars)) except ksa.exceptions.auth_plugins.MissingRequiredOptions as e: raise RuntimeError('Missing required OS values in env/rcfile ({})'.format(str(e))) if rc: return session, os_vars else: return session