config system overhaul
we're now based on nova's config system which mainly means that you will have to call config.CONF with a config file at some point during tests or running an executable
This commit is contained in:
parent
829a96b1e0
commit
feadf75760
|
@ -10,7 +10,7 @@ INMEMDB = DictKvs()
|
||||||
|
|
||||||
|
|
||||||
class KvsIdentity(object):
|
class KvsIdentity(object):
|
||||||
def __init__(self, options, db=None):
|
def __init__(self, db=None):
|
||||||
if db is None:
|
if db is None:
|
||||||
db = INMEMDB
|
db = INMEMDB
|
||||||
elif type(db) is type({}):
|
elif type(db) is type({}):
|
||||||
|
@ -189,7 +189,7 @@ class KvsIdentity(object):
|
||||||
|
|
||||||
|
|
||||||
class KvsToken(object):
|
class KvsToken(object):
|
||||||
def __init__(self, options, db=None):
|
def __init__(self, db=None):
|
||||||
if db is None:
|
if db is None:
|
||||||
db = INMEMDB
|
db = INMEMDB
|
||||||
elif type(db) is type({}):
|
elif type(db) is type({}):
|
||||||
|
@ -209,7 +209,7 @@ class KvsToken(object):
|
||||||
|
|
||||||
|
|
||||||
class KvsCatalog(object):
|
class KvsCatalog(object):
|
||||||
def __init__(self, options, db=None):
|
def __init__(self, db=None):
|
||||||
if db is None:
|
if db is None:
|
||||||
db = INMEMDB
|
db = INMEMDB
|
||||||
elif type(db) is type({}):
|
elif type(db) is type({}):
|
||||||
|
@ -251,7 +251,7 @@ class KvsCatalog(object):
|
||||||
|
|
||||||
|
|
||||||
class KvsPolicy(object):
|
class KvsPolicy(object):
|
||||||
def __init__(self, options, db=None):
|
def __init__(self, db=None):
|
||||||
if db is None:
|
if db is None:
|
||||||
db = INMEMDB
|
db = INMEMDB
|
||||||
elif type(db) is type({}):
|
elif type(db) is type({}):
|
||||||
|
|
|
@ -2,17 +2,11 @@ import logging
|
||||||
|
|
||||||
|
|
||||||
class TrivialTrue(object):
|
class TrivialTrue(object):
|
||||||
def __init__(self, options):
|
|
||||||
self.options = options
|
|
||||||
|
|
||||||
def can_haz(self, target, credentials):
|
def can_haz(self, target, credentials):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class SimpleMatch(object):
|
class SimpleMatch(object):
|
||||||
def __init__(self, options):
|
|
||||||
self.options = options
|
|
||||||
|
|
||||||
def can_haz(self, target, credentials):
|
def can_haz(self, target, credentials):
|
||||||
"""Check whether key-values in target are present in credentials."""
|
"""Check whether key-values in target are present in credentials."""
|
||||||
# TODO(termie): handle ANDs, probably by providing a tuple instead of a
|
# TODO(termie): handle ANDs, probably by providing a tuple instead of a
|
||||||
|
|
|
@ -10,9 +10,13 @@ import sqlalchemy.orm
|
||||||
import sqlalchemy.pool
|
import sqlalchemy.pool
|
||||||
import sqlalchemy.engine.url
|
import sqlalchemy.engine.url
|
||||||
|
|
||||||
|
from keystonelight import config
|
||||||
from keystonelight import models
|
from keystonelight import models
|
||||||
|
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
Base = declarative.declarative_base()
|
Base = declarative.declarative_base()
|
||||||
|
|
||||||
|
|
||||||
|
@ -121,9 +125,6 @@ class SqlBase(object):
|
||||||
_MAKER = None
|
_MAKER = None
|
||||||
_ENGINE = None
|
_ENGINE = None
|
||||||
|
|
||||||
def __init__(self, options):
|
|
||||||
self.options = options
|
|
||||||
|
|
||||||
def get_session(self, autocommit=True, expire_on_commit=False):
|
def get_session(self, autocommit=True, expire_on_commit=False):
|
||||||
"""Return a SQLAlchemy session."""
|
"""Return a SQLAlchemy session."""
|
||||||
if self._MAKER is None or self._ENGINE is None:
|
if self._MAKER is None or self._ENGINE is None:
|
||||||
|
@ -138,36 +139,17 @@ class SqlBase(object):
|
||||||
|
|
||||||
def get_engine(self):
|
def get_engine(self):
|
||||||
"""Return a SQLAlchemy engine."""
|
"""Return a SQLAlchemy engine."""
|
||||||
connection_dict = sqlalchemy.engine.url.make_url(
|
connection_dict = sqlalchemy.engine.url.make_url(CONF.sql.connection)
|
||||||
self.options.get('sql_connection'))
|
|
||||||
|
|
||||||
engine_args = {
|
engine_args = {
|
||||||
"pool_recycle": self.options.get('sql_idle_timeout'),
|
"pool_recycle": CONF.sql.idle_timeout,
|
||||||
"echo": False,
|
"echo": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
if "sqlite" in connection_dict.drivername:
|
if "sqlite" in connection_dict.drivername:
|
||||||
engine_args["poolclass"] = sqlalchemy.pool.NullPool
|
engine_args["poolclass"] = sqlalchemy.pool.NullPool
|
||||||
#elif MySQLdb and "mysql" in connection_dict.drivername:
|
|
||||||
# LOG.info(_("Using mysql/eventlet db_pool."))
|
|
||||||
# # MySQLdb won't accept 'None' in the password field
|
|
||||||
# password = connection_dict.password or ''
|
|
||||||
# pool_args = {
|
|
||||||
# "db": connection_dict.database,
|
|
||||||
# "passwd": password,
|
|
||||||
# "host": connection_dict.host,
|
|
||||||
# "user": connection_dict.username,
|
|
||||||
# "min_size": self.options.get('sql_min_pool_size'),
|
|
||||||
# "max_size": self.options.get('sql_max_pool_size'),
|
|
||||||
# "max_idle": self.options.get('sql_idle_timeout'),
|
|
||||||
# }
|
|
||||||
# creator = eventlet.db_pool.ConnectionPool(MySQLdb, **pool_args)
|
|
||||||
# engine_args["pool_size"] = self.options.get('sql_max_pool_size')
|
|
||||||
# engine_args["pool_timeout"] = self.options('sql_pool_timeout')
|
|
||||||
# engine_args["creator"] = creator.create
|
|
||||||
|
|
||||||
return sql.create_engine(self.options.get('sql_connection'),
|
return sql.create_engine(CONF.sql.connection, **engine_args)
|
||||||
**engine_args)
|
|
||||||
|
|
||||||
def get_maker(self, engine, autocommit=True, expire_on_commit=False):
|
def get_maker(self, engine, autocommit=True, expire_on_commit=False):
|
||||||
"""Return a SQLAlchemy sessionmaker using the given engine."""
|
"""Return a SQLAlchemy sessionmaker using the given engine."""
|
||||||
|
|
|
@ -22,6 +22,12 @@ import sys
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
from migrate.versioning import api as versioning_api
|
from migrate.versioning import api as versioning_api
|
||||||
|
|
||||||
|
from keystonelight import config
|
||||||
|
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from migrate.versioning import exceptions as versioning_exceptions
|
from migrate.versioning import exceptions as versioning_exceptions
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -33,36 +39,36 @@ except ImportError:
|
||||||
sys.exit("python-migrate is not installed. Exiting.")
|
sys.exit("python-migrate is not installed. Exiting.")
|
||||||
|
|
||||||
|
|
||||||
def db_sync(options, version=None):
|
def db_sync(version=None):
|
||||||
if version is not None:
|
if version is not None:
|
||||||
try:
|
try:
|
||||||
version = int(version)
|
version = int(version)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise Exception("version should be an integer")
|
raise Exception("version should be an integer")
|
||||||
|
|
||||||
current_version = db_version(options)
|
current_version = db_version()
|
||||||
repo_path = _find_migrate_repo()
|
repo_path = _find_migrate_repo()
|
||||||
if version is None or version > current_version:
|
if version is None or version > current_version:
|
||||||
return versioning_api.upgrade(
|
return versioning_api.upgrade(
|
||||||
options.get('sql_connection'), repo_path, version)
|
CONF.sql.connection, repo_path, version)
|
||||||
else:
|
else:
|
||||||
return versioning_api.downgrade(
|
return versioning_api.downgrade(
|
||||||
options.get('sql_connection'), repo_path, version)
|
CONF.sql.connection, repo_path, version)
|
||||||
|
|
||||||
|
|
||||||
def db_version(options):
|
def db_version():
|
||||||
repo_path = _find_migrate_repo()
|
repo_path = _find_migrate_repo()
|
||||||
try:
|
try:
|
||||||
return versioning_api.db_version(
|
return versioning_api.db_version(
|
||||||
options.get('sql_connection'), repo_path)
|
CONF.sql.connection, repo_path)
|
||||||
except versioning_exceptions.DatabaseNotControlledError:
|
except versioning_exceptions.DatabaseNotControlledError:
|
||||||
return db_version_control(options, 0)
|
return db_version_control(0)
|
||||||
|
|
||||||
|
|
||||||
def db_version_control(options, version=None):
|
def db_version_control(version=None):
|
||||||
repo_path = _find_migrate_repo()
|
repo_path = _find_migrate_repo()
|
||||||
versioning_api.version_control(
|
versioning_api.version_control(
|
||||||
options.get('sql_connection'), repo_path, version)
|
CONF.sql.connection, repo_path, version)
|
||||||
return version
|
return version
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
|
from keystonelight import config
|
||||||
from keystonelight import logging
|
from keystonelight import logging
|
||||||
from keystonelight.backends import kvs
|
from keystonelight.backends import kvs
|
||||||
|
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
config.register_str('template_file', group='catalog')
|
||||||
|
|
||||||
|
|
||||||
class TemplatedCatalog(kvs.KvsCatalog):
|
class TemplatedCatalog(kvs.KvsCatalog):
|
||||||
"""A backend that generates endpoints for the Catalog based on templates.
|
"""A backend that generates endpoints for the Catalog based on templates.
|
||||||
|
|
||||||
|
@ -16,7 +21,7 @@ class TemplatedCatalog(kvs.KvsCatalog):
|
||||||
|
|
||||||
http://localhost:$(public_port)s/
|
http://localhost:$(public_port)s/
|
||||||
|
|
||||||
When expanding the template it will pass in a dict made up of the options
|
When expanding the template it will pass in a dict made up of the conf
|
||||||
instance plus a few additional key-values, notably tenant_id and user_id.
|
instance plus a few additional key-values, notably tenant_id and user_id.
|
||||||
|
|
||||||
It does not care what the keys and values are but it is worth noting that
|
It does not care what the keys and values are but it is worth noting that
|
||||||
|
@ -31,19 +36,21 @@ class TemplatedCatalog(kvs.KvsCatalog):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, options, templates=None):
|
def __init__(self, templates=None):
|
||||||
self.options = options
|
|
||||||
|
|
||||||
if templates:
|
if templates:
|
||||||
self.templates = templates
|
self.templates = templates
|
||||||
else:
|
else:
|
||||||
self._load_templates(options)
|
self._load_templates(CONF.catalog.template_file)
|
||||||
|
|
||||||
super(TemplatedCatalog, self).__init__(options)
|
super(TemplatedCatalog, self).__init__()
|
||||||
|
|
||||||
def _load_templates(self, options):
|
def _load_templates(self, template_file):
|
||||||
o = {}
|
o = {}
|
||||||
for k, v in options.iteritems():
|
for line in open(template_file):
|
||||||
|
if ' = ' not in line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
k, v = line.split(' = ')
|
||||||
if not k.startswith('catalog.'):
|
if not k.startswith('catalog.'):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -64,7 +71,7 @@ class TemplatedCatalog(kvs.KvsCatalog):
|
||||||
self.templates = o
|
self.templates = o
|
||||||
|
|
||||||
def get_catalog(self, user_id, tenant_id, extras=None):
|
def get_catalog(self, user_id, tenant_id, extras=None):
|
||||||
d = self.options.copy()
|
d = dict(CONF.iteritems())
|
||||||
d.update({'tenant_id': tenant_id,
|
d.update({'tenant_id': tenant_id,
|
||||||
'user_id': user_id})
|
'user_id': user_id})
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
|
|
||||||
# the catalog interfaces
|
# the catalog interfaces
|
||||||
|
|
||||||
|
from keystonelight import config
|
||||||
from keystonelight import utils
|
from keystonelight import utils
|
||||||
|
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
class Manager(object):
|
class Manager(object):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.options = options
|
self.driver = utils.import_object(CONF.catalog.driver)
|
||||||
self.driver = utils.import_object(options['catalog_driver'],
|
|
||||||
options=options)
|
|
||||||
|
|
||||||
def get_catalog(self, context, user_id, tenant_id, extras=None):
|
def get_catalog(self, context, user_id, tenant_id, extras=None):
|
||||||
"""Return info for a catalog if it is valid."""
|
"""Return info for a catalog if it is valid."""
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
|
||||||
|
|
||||||
|
from keystonelight import cfg
|
||||||
|
|
||||||
|
|
||||||
|
class Config(cfg.ConfigOpts):
|
||||||
|
def __call__(self, config_files=None, *args, **kw):
|
||||||
|
if config_files is None:
|
||||||
|
config_files = []
|
||||||
|
self.config_file = config_files
|
||||||
|
super(Config, self).__call__(*args, **kw)
|
||||||
|
|
||||||
|
def __getitem__(self, key, default=None):
|
||||||
|
return getattr(self, key, default)
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
return setattr(self, key, value)
|
||||||
|
|
||||||
|
def iteritems(self):
|
||||||
|
for k in self._opts:
|
||||||
|
yield (k, getattr(self, k))
|
||||||
|
|
||||||
|
|
||||||
|
def register_str(*args, **kw):
|
||||||
|
group = kw.pop('group', None)
|
||||||
|
if group:
|
||||||
|
CONF.register_group(cfg.OptGroup(name=group))
|
||||||
|
return CONF.register_opt(cfg.StrOpt(*args, **kw), group=group)
|
||||||
|
|
||||||
|
|
||||||
|
CONF = Config()
|
||||||
|
|
||||||
|
|
||||||
|
register_str('admin_token', default='ADMIN')
|
||||||
|
register_str('compute_port')
|
||||||
|
register_str('admin_port')
|
||||||
|
register_str('public_port')
|
||||||
|
|
||||||
|
# sql options
|
||||||
|
register_str('connection', group='sql')
|
||||||
|
register_str('idle_timeout', group='sql')
|
||||||
|
register_str('min_pool_size', group='sql')
|
||||||
|
register_str('maz_pool_size', group='sql')
|
||||||
|
register_str('pool_timeout', group='sql')
|
||||||
|
|
||||||
|
register_str('driver', group='catalog')
|
||||||
|
register_str('driver', group='identity')
|
||||||
|
register_str('driver', group='policy')
|
||||||
|
register_str('driver', group='token')
|
|
@ -2,15 +2,16 @@
|
||||||
# backends will make use of them to return something that conforms to their
|
# backends will make use of them to return something that conforms to their
|
||||||
# apis
|
# apis
|
||||||
|
|
||||||
|
from keystonelight import config
|
||||||
from keystonelight import utils
|
from keystonelight import utils
|
||||||
|
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
class Manager(object):
|
class Manager(object):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.driver = utils.import_object(options['identity_driver'],
|
self.driver = utils.import_object(CONF.identity.driver)
|
||||||
options=options)
|
|
||||||
self.options = options
|
|
||||||
|
|
||||||
def authenticate(self, context, **kwargs):
|
def authenticate(self, context, **kwargs):
|
||||||
"""Passthru authentication to the identity driver.
|
"""Passthru authentication to the identity driver.
|
||||||
|
|
|
@ -18,13 +18,11 @@ from keystonelight import wsgi
|
||||||
|
|
||||||
|
|
||||||
class KeystoneAdminRouter(wsgi.Router):
|
class KeystoneAdminRouter(wsgi.Router):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.options = options
|
|
||||||
|
|
||||||
mapper = routes.Mapper()
|
mapper = routes.Mapper()
|
||||||
|
|
||||||
# Token Operations
|
# Token Operations
|
||||||
auth_controller = KeystoneTokenController(self.options)
|
auth_controller = KeystoneTokenController()
|
||||||
mapper.connect('/tokens',
|
mapper.connect('/tokens',
|
||||||
controller=auth_controller,
|
controller=auth_controller,
|
||||||
action='authenticate',
|
action='authenticate',
|
||||||
|
@ -39,7 +37,7 @@ class KeystoneAdminRouter(wsgi.Router):
|
||||||
conditions=dict(method=['GET']))
|
conditions=dict(method=['GET']))
|
||||||
|
|
||||||
# Tenant Operations
|
# Tenant Operations
|
||||||
tenant_controller = KeystoneTenantController(self.options)
|
tenant_controller = KeystoneTenantController()
|
||||||
mapper.connect('/tenants',
|
mapper.connect('/tenants',
|
||||||
controller=tenant_controller,
|
controller=tenant_controller,
|
||||||
action='get_tenants_for_token',
|
action='get_tenants_for_token',
|
||||||
|
@ -50,14 +48,14 @@ class KeystoneAdminRouter(wsgi.Router):
|
||||||
conditions=dict(method=['GET']))
|
conditions=dict(method=['GET']))
|
||||||
|
|
||||||
# User Operations
|
# User Operations
|
||||||
user_controller = KeystoneUserController(self.options)
|
user_controller = KeystoneUserController()
|
||||||
mapper.connect('/users/{user_id}',
|
mapper.connect('/users/{user_id}',
|
||||||
controller=user_controller,
|
controller=user_controller,
|
||||||
action='get_user',
|
action='get_user',
|
||||||
conditions=dict(method=['GET']))
|
conditions=dict(method=['GET']))
|
||||||
|
|
||||||
# Role Operations
|
# Role Operations
|
||||||
roles_controller = KeystoneRoleController(self.options)
|
roles_controller = KeystoneRoleController()
|
||||||
mapper.connect('/tenants/{tenant_id}/users/{user_id}/roles',
|
mapper.connect('/tenants/{tenant_id}/users/{user_id}/roles',
|
||||||
controller=roles_controller,
|
controller=roles_controller,
|
||||||
action='get_user_roles',
|
action='get_user_roles',
|
||||||
|
@ -68,13 +66,13 @@ class KeystoneAdminRouter(wsgi.Router):
|
||||||
conditions=dict(method=['GET']))
|
conditions=dict(method=['GET']))
|
||||||
|
|
||||||
# Miscellaneous Operations
|
# Miscellaneous Operations
|
||||||
version_controller = KeystoneVersionController(self.options)
|
version_controller = KeystoneVersionController()
|
||||||
mapper.connect('/',
|
mapper.connect('/',
|
||||||
controller=version_controller,
|
controller=version_controller,
|
||||||
action='get_version_info', module='admin/version',
|
action='get_version_info', module='admin/version',
|
||||||
conditions=dict(method=['GET']))
|
conditions=dict(method=['GET']))
|
||||||
|
|
||||||
extensions_controller = KeystoneExtensionsController(self.options)
|
extensions_controller = KeystoneExtensionsController()
|
||||||
mapper.connect('/extensions',
|
mapper.connect('/extensions',
|
||||||
controller=extensions_controller,
|
controller=extensions_controller,
|
||||||
action='get_extensions_info',
|
action='get_extensions_info',
|
||||||
|
@ -84,12 +82,11 @@ class KeystoneAdminRouter(wsgi.Router):
|
||||||
|
|
||||||
|
|
||||||
class KeystoneServiceRouter(wsgi.Router):
|
class KeystoneServiceRouter(wsgi.Router):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.options = options
|
|
||||||
mapper = routes.Mapper()
|
mapper = routes.Mapper()
|
||||||
|
|
||||||
# Token Operations
|
# Token Operations
|
||||||
auth_controller = KeystoneTokenController(self.options)
|
auth_controller = KeystoneTokenController()
|
||||||
mapper.connect('/tokens',
|
mapper.connect('/tokens',
|
||||||
controller=auth_controller,
|
controller=auth_controller,
|
||||||
action='authenticate',
|
action='authenticate',
|
||||||
|
@ -100,21 +97,21 @@ class KeystoneServiceRouter(wsgi.Router):
|
||||||
conditions=dict(methods=['POST']))
|
conditions=dict(methods=['POST']))
|
||||||
|
|
||||||
# Tenant Operations
|
# Tenant Operations
|
||||||
tenant_controller = KeystoneTenantController(self.options)
|
tenant_controller = KeystoneTenantController()
|
||||||
mapper.connect('/tenants',
|
mapper.connect('/tenants',
|
||||||
controller=tenant_controller,
|
controller=tenant_controller,
|
||||||
action='get_tenants_for_token',
|
action='get_tenants_for_token',
|
||||||
conditions=dict(methods=['GET']))
|
conditions=dict(methods=['GET']))
|
||||||
|
|
||||||
# Miscellaneous
|
# Miscellaneous
|
||||||
version_controller = KeystoneVersionController(self.options)
|
version_controller = KeystoneVersionController()
|
||||||
mapper.connect('/',
|
mapper.connect('/',
|
||||||
controller=version_controller,
|
controller=version_controller,
|
||||||
action='get_version_info',
|
action='get_version_info',
|
||||||
module='service/version',
|
module='service/version',
|
||||||
conditions=dict(method=['GET']))
|
conditions=dict(method=['GET']))
|
||||||
|
|
||||||
extensions_controller = KeystoneExtensionsController(self.options)
|
extensions_controller = KeystoneExtensionsController()
|
||||||
mapper.connect('/extensions',
|
mapper.connect('/extensions',
|
||||||
controller=extensions_controller,
|
controller=extensions_controller,
|
||||||
action='get_extensions_info',
|
action='get_extensions_info',
|
||||||
|
@ -130,13 +127,12 @@ class KeystoneAdminCrudExtension(wsgi.ExtensionRouter):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, application, options):
|
def __init__(self, application):
|
||||||
self.options = options
|
|
||||||
mapper = routes.Mapper()
|
mapper = routes.Mapper()
|
||||||
tenant_controller = KeystoneTenantController(self.options)
|
tenant_controller = KeystoneTenantController()
|
||||||
user_controller = KeystoneUserController(self.options)
|
user_controller = KeystoneUserController()
|
||||||
role_controller = KeystoneRoleController(self.options)
|
role_controller = KeystoneRoleController()
|
||||||
service_controller = KeystoneServiceController(self.options)
|
service_controller = KeystoneServiceController()
|
||||||
|
|
||||||
# Tenant Operations
|
# Tenant Operations
|
||||||
mapper.connect("/tenants", controller=tenant_controller,
|
mapper.connect("/tenants", controller=tenant_controller,
|
||||||
|
@ -270,16 +266,15 @@ class KeystoneAdminCrudExtension(wsgi.ExtensionRouter):
|
||||||
conditions=dict(method=["DELETE"]))
|
conditions=dict(method=["DELETE"]))
|
||||||
|
|
||||||
super(KeystoneAdminCrudExtension, self).__init__(
|
super(KeystoneAdminCrudExtension, self).__init__(
|
||||||
application, options, mapper)
|
application, mapper)
|
||||||
|
|
||||||
|
|
||||||
class KeystoneTokenController(service.BaseApplication):
|
class KeystoneTokenController(service.BaseApplication):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.options = options
|
self.catalog_api = catalog.Manager()
|
||||||
self.catalog_api = catalog.Manager(options)
|
self.identity_api = identity.Manager()
|
||||||
self.identity_api = identity.Manager(options)
|
self.token_api = token.Manager()
|
||||||
self.token_api = token.Manager(options)
|
self.policy_api = policy.Manager()
|
||||||
self.policy_api = policy.Manager(options)
|
|
||||||
super(KeystoneTokenController, self).__init__()
|
super(KeystoneTokenController, self).__init__()
|
||||||
|
|
||||||
def authenticate(self, context, auth=None):
|
def authenticate(self, context, auth=None):
|
||||||
|
@ -496,11 +491,10 @@ class KeystoneTokenController(service.BaseApplication):
|
||||||
|
|
||||||
|
|
||||||
class KeystoneTenantController(service.BaseApplication):
|
class KeystoneTenantController(service.BaseApplication):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.options = options
|
self.identity_api = identity.Manager()
|
||||||
self.identity_api = identity.Manager(options)
|
self.policy_api = policy.Manager()
|
||||||
self.policy_api = policy.Manager(options)
|
self.token_api = token.Manager()
|
||||||
self.token_api = token.Manager(options)
|
|
||||||
super(KeystoneTenantController, self).__init__()
|
super(KeystoneTenantController, self).__init__()
|
||||||
|
|
||||||
def get_tenants_for_token(self, context, **kw):
|
def get_tenants_for_token(self, context, **kw):
|
||||||
|
@ -578,12 +572,11 @@ class KeystoneTenantController(service.BaseApplication):
|
||||||
|
|
||||||
|
|
||||||
class KeystoneUserController(service.BaseApplication):
|
class KeystoneUserController(service.BaseApplication):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.options = options
|
self.catalog_api = catalog.Manager()
|
||||||
self.catalog_api = catalog.Manager(options)
|
self.identity_api = identity.Manager()
|
||||||
self.identity_api = identity.Manager(options)
|
self.policy_api = policy.Manager()
|
||||||
self.token_api = token.Manager(options)
|
self.token_api = token.Manager()
|
||||||
self.policy_api = policy.Manager(options)
|
|
||||||
super(KeystoneUserController, self).__init__()
|
super(KeystoneUserController, self).__init__()
|
||||||
|
|
||||||
def get_user(self, context, user_id):
|
def get_user(self, context, user_id):
|
||||||
|
@ -644,12 +637,11 @@ class KeystoneUserController(service.BaseApplication):
|
||||||
|
|
||||||
|
|
||||||
class KeystoneRoleController(service.BaseApplication):
|
class KeystoneRoleController(service.BaseApplication):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.options = options
|
self.catalog_api = catalog.Manager()
|
||||||
self.catalog_api = catalog.Manager(options)
|
self.identity_api = identity.Manager()
|
||||||
self.identity_api = identity.Manager(options)
|
self.token_api = token.Manager()
|
||||||
self.token_api = token.Manager(options)
|
self.policy_api = policy.Manager()
|
||||||
self.policy_api = policy.Manager(options)
|
|
||||||
super(KeystoneRoleController, self).__init__()
|
super(KeystoneRoleController, self).__init__()
|
||||||
|
|
||||||
def get_user_roles(self, context, user_id, tenant_id=None):
|
def get_user_roles(self, context, user_id, tenant_id=None):
|
||||||
|
@ -748,12 +740,11 @@ class KeystoneRoleController(service.BaseApplication):
|
||||||
|
|
||||||
|
|
||||||
class KeystoneServiceController(service.BaseApplication):
|
class KeystoneServiceController(service.BaseApplication):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.options = options
|
self.catalog_api = catalog.Manager()
|
||||||
self.catalog_api = catalog.Manager(options)
|
self.identity_api = identity.Manager()
|
||||||
self.identity_api = identity.Manager(options)
|
self.token_api = token.Manager()
|
||||||
self.token_api = token.Manager(options)
|
self.policy_api = policy.Manager()
|
||||||
self.policy_api = policy.Manager(options)
|
|
||||||
super(KeystoneServiceController, self).__init__()
|
super(KeystoneServiceController, self).__init__()
|
||||||
|
|
||||||
# CRUD extensions
|
# CRUD extensions
|
||||||
|
@ -783,8 +774,7 @@ class KeystoneServiceController(service.BaseApplication):
|
||||||
|
|
||||||
|
|
||||||
class KeystoneVersionController(service.BaseApplication):
|
class KeystoneVersionController(service.BaseApplication):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.options = options
|
|
||||||
super(KeystoneVersionController, self).__init__()
|
super(KeystoneVersionController, self).__init__()
|
||||||
|
|
||||||
def get_version_info(self, context, module='version'):
|
def get_version_info(self, context, module='version'):
|
||||||
|
@ -792,8 +782,7 @@ class KeystoneVersionController(service.BaseApplication):
|
||||||
|
|
||||||
|
|
||||||
class KeystoneExtensionsController(service.BaseApplication):
|
class KeystoneExtensionsController(service.BaseApplication):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.options = options
|
|
||||||
super(KeystoneExtensionsController, self).__init__()
|
super(KeystoneExtensionsController, self).__init__()
|
||||||
|
|
||||||
def get_extensions_info(self, context):
|
def get_extensions_info(self, context):
|
||||||
|
@ -803,10 +792,10 @@ class KeystoneExtensionsController(service.BaseApplication):
|
||||||
def service_app_factory(global_conf, **local_conf):
|
def service_app_factory(global_conf, **local_conf):
|
||||||
conf = global_conf.copy()
|
conf = global_conf.copy()
|
||||||
conf.update(local_conf)
|
conf.update(local_conf)
|
||||||
return KeystoneServiceRouter(conf)
|
return KeystoneServiceRouter()
|
||||||
|
|
||||||
|
|
||||||
def admin_app_factory(global_conf, **local_conf):
|
def admin_app_factory(global_conf, **local_conf):
|
||||||
conf = global_conf.copy()
|
conf = global_conf.copy()
|
||||||
conf.update(local_conf)
|
conf.update(local_conf)
|
||||||
return KeystoneAdminRouter(conf)
|
return KeystoneAdminRouter()
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from keystonelight import config
|
||||||
from keystonelight import wsgi
|
from keystonelight import wsgi
|
||||||
|
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
# Header used to transmit the auth token
|
# Header used to transmit the auth token
|
||||||
AUTH_TOKEN_HEADER = 'X-Auth-Token'
|
AUTH_TOKEN_HEADER = 'X-Auth-Token'
|
||||||
|
|
||||||
|
@ -34,7 +38,7 @@ class AdminTokenAuthMiddleware(wsgi.Middleware):
|
||||||
def process_request(self, request):
|
def process_request(self, request):
|
||||||
token = request.headers.get(AUTH_TOKEN_HEADER)
|
token = request.headers.get(AUTH_TOKEN_HEADER)
|
||||||
context = request.environ.get(CONTEXT_ENV, {})
|
context = request.environ.get(CONTEXT_ENV, {})
|
||||||
context['is_admin'] = (token == self.options['admin_token'])
|
context['is_admin'] = (token == CONF.admin_token)
|
||||||
request.environ[CONTEXT_ENV] = context
|
request.environ[CONTEXT_ENV] = context
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,16 @@
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
from keystonelight import config
|
||||||
from keystonelight import utils
|
from keystonelight import utils
|
||||||
|
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
class Manager(object):
|
class Manager(object):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.options = options
|
self.driver = utils.import_object(CONF.policy.driver)
|
||||||
self.driver = utils.import_object(options['policy_driver'],
|
|
||||||
options=options)
|
|
||||||
|
|
||||||
def can_haz(self, context, target, credentials):
|
def can_haz(self, context, target, credentials):
|
||||||
"""Check whether the given creds can perform action on target."""
|
"""Check whether the given creds can perform action on target."""
|
||||||
|
|
|
@ -97,9 +97,8 @@ class BaseApplication(wsgi.Application):
|
||||||
class TokenController(BaseApplication):
|
class TokenController(BaseApplication):
|
||||||
"""Validate and pass through calls to TokenManager."""
|
"""Validate and pass through calls to TokenManager."""
|
||||||
|
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.token_api = token.Manager(options=options)
|
self.token_api = token.Manager()
|
||||||
self.options = options
|
|
||||||
|
|
||||||
def validate_token(self, context, token_id):
|
def validate_token(self, context, token_id):
|
||||||
token_info = self.token_api.validate_token(context, token_id)
|
token_info = self.token_api.validate_token(context, token_id)
|
||||||
|
@ -115,10 +114,9 @@ class IdentityController(BaseApplication):
|
||||||
a specific driver.
|
a specific driver.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.identity_api = identity.Manager(options=options)
|
self.identity_api = identity.Manager()
|
||||||
self.token_api = token.Manager(options=options)
|
self.token_api = token.Manager()
|
||||||
self.options = options
|
|
||||||
|
|
||||||
def noop(self, context, *args, **kw):
|
def noop(self, context, *args, **kw):
|
||||||
return ''
|
return ''
|
||||||
|
@ -207,10 +205,9 @@ class IdentityController(BaseApplication):
|
||||||
|
|
||||||
|
|
||||||
class Router(wsgi.Router):
|
class Router(wsgi.Router):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.options = options
|
self.identity_controller = IdentityController()
|
||||||
self.identity_controller = IdentityController(options)
|
self.token_controller = TokenController()
|
||||||
self.token_controller = TokenController(options)
|
|
||||||
|
|
||||||
mapper = self._build_map(URLMAP)
|
mapper = self._build_map(URLMAP)
|
||||||
mapper.connect('/', controller=self.identity_controller, action='noop')
|
mapper.connect('/', controller=self.identity_controller, action='noop')
|
||||||
|
@ -238,6 +235,6 @@ class Router(wsgi.Router):
|
||||||
|
|
||||||
|
|
||||||
def app_factory(global_conf, **local_conf):
|
def app_factory(global_conf, **local_conf):
|
||||||
conf = global_conf.copy()
|
#conf = global_conf.copy()
|
||||||
conf.update(local_conf)
|
#conf.update(local_conf)
|
||||||
return Router(conf)
|
return Router()
|
||||||
|
|
|
@ -8,6 +8,7 @@ import time
|
||||||
|
|
||||||
from paste import deploy
|
from paste import deploy
|
||||||
|
|
||||||
|
from keystonelight import config
|
||||||
from keystonelight import logging
|
from keystonelight import logging
|
||||||
from keystonelight import models
|
from keystonelight import models
|
||||||
from keystonelight import utils
|
from keystonelight import utils
|
||||||
|
@ -17,7 +18,7 @@ from keystonelight import wsgi
|
||||||
ROOTDIR = os.path.dirname(os.path.dirname(__file__))
|
ROOTDIR = os.path.dirname(os.path.dirname(__file__))
|
||||||
VENDOR = os.path.join(ROOTDIR, 'vendor')
|
VENDOR = os.path.join(ROOTDIR, 'vendor')
|
||||||
TESTSDIR = os.path.join(ROOTDIR, 'tests')
|
TESTSDIR = os.path.join(ROOTDIR, 'tests')
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
cd = os.chdir
|
cd = os.chdir
|
||||||
|
|
||||||
|
@ -94,21 +95,14 @@ class TestCase(unittest.TestCase):
|
||||||
for path in self._paths:
|
for path in self._paths:
|
||||||
if path in sys.path:
|
if path in sys.path:
|
||||||
sys.path.remove(path)
|
sys.path.remove(path)
|
||||||
|
CONF.reset()
|
||||||
super(TestCase, self).tearDown()
|
super(TestCase, self).tearDown()
|
||||||
|
|
||||||
#TODO(termie): probably make this take an argument and use that for `options`
|
|
||||||
def load_backends(self):
|
def load_backends(self):
|
||||||
"""Hacky shortcut to load the backends for data manipulation.
|
"""Hacky shortcut to load the backends for data manipulation."""
|
||||||
|
self.identity_api = utils.import_object(CONF.identity.driver)
|
||||||
Expects self.options to have already been set.
|
self.token_api = utils.import_object(CONF.token.driver)
|
||||||
|
self.catalog_api = utils.import_object(CONF.catalog.driver)
|
||||||
"""
|
|
||||||
self.identity_api = utils.import_object(
|
|
||||||
self.options['identity_driver'], options=self.options)
|
|
||||||
self.token_api = utils.import_object(
|
|
||||||
self.options['token_driver'], options=self.options)
|
|
||||||
self.catalog_api = utils.import_object(
|
|
||||||
self.options['catalog_driver'], options=self.options)
|
|
||||||
|
|
||||||
def load_fixtures(self, fixtures):
|
def load_fixtures(self, fixtures):
|
||||||
"""Hacky basic and naive fixture loading based on a python module.
|
"""Hacky basic and naive fixture loading based on a python module.
|
||||||
|
@ -164,44 +158,10 @@ class TestCase(unittest.TestCase):
|
||||||
|
|
||||||
# Service catalog tests need to know the port we ran on.
|
# Service catalog tests need to know the port we ran on.
|
||||||
port = server.socket_info['socket'][1]
|
port = server.socket_info['socket'][1]
|
||||||
self._update_server_options(server, 'public_port', port)
|
CONF.public_port = port
|
||||||
self._update_server_options(server, 'admin_port', port)
|
CONF.admin_port = port
|
||||||
return server
|
return server
|
||||||
|
|
||||||
def _update_server_options(self, server, key, value):
|
|
||||||
"""Hack to allow us to make changes to the options used by backends.
|
|
||||||
|
|
||||||
A possible better solution would be to have a global config registry.
|
|
||||||
|
|
||||||
"""
|
|
||||||
last = server
|
|
||||||
|
|
||||||
applications = []
|
|
||||||
|
|
||||||
while (hasattr(last, 'applications')
|
|
||||||
or hasattr(last, 'application')
|
|
||||||
or hasattr(last, 'options')):
|
|
||||||
|
|
||||||
#logging.debug('UPDATE %s: O %s A %s AS %s',
|
|
||||||
# last.__class__,
|
|
||||||
# getattr(last, 'options', None),
|
|
||||||
# getattr(last, 'application', None),
|
|
||||||
# getattr(last, 'applications', None))
|
|
||||||
if hasattr(last, 'options'):
|
|
||||||
last.options[key] = value
|
|
||||||
|
|
||||||
# NOTE(termie): paste.urlmap.URLMap stores applications in this format
|
|
||||||
if hasattr(last, 'applications'):
|
|
||||||
for app in last.applications:
|
|
||||||
applications.append(app[1])
|
|
||||||
|
|
||||||
if hasattr(last, 'application'):
|
|
||||||
last = last.application
|
|
||||||
elif len(applications):
|
|
||||||
last = applications.pop()
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
def client(self, app, *args, **kw):
|
def client(self, app, *args, **kw):
|
||||||
return TestClient(app, *args, **kw)
|
return TestClient(app, *args, **kw)
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,17 @@
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
from keystonelight import config
|
||||||
from keystonelight import logging
|
from keystonelight import logging
|
||||||
from keystonelight import utils
|
from keystonelight import utils
|
||||||
|
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
class Manager(object):
|
class Manager(object):
|
||||||
def __init__(self, options):
|
def __init__(self):
|
||||||
self.options = options
|
self.driver = utils.import_object(CONF.token.driver)
|
||||||
self.driver = utils.import_object(options['token_driver'],
|
|
||||||
options=options)
|
|
||||||
|
|
||||||
def create_token(self, context, data):
|
def create_token(self, context, data):
|
||||||
token = uuid.uuid4().hex
|
token = uuid.uuid4().hex
|
||||||
|
|
|
@ -107,7 +107,7 @@ class Application(object):
|
||||||
but using the kwarg passing it shouldn't be necessary.
|
but using the kwarg passing it shouldn't be necessary.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return cls(**local_config)
|
return cls()
|
||||||
|
|
||||||
def __call__(self, environ, start_response):
|
def __call__(self, environ, start_response):
|
||||||
r"""Subclasses will probably want to implement __call__ like this:
|
r"""Subclasses will probably want to implement __call__ like this:
|
||||||
|
@ -182,12 +182,11 @@ class Middleware(Application):
|
||||||
def _factory(app):
|
def _factory(app):
|
||||||
conf = global_config.copy()
|
conf = global_config.copy()
|
||||||
conf.update(local_config)
|
conf.update(local_config)
|
||||||
return cls(app, conf)
|
return cls(app)
|
||||||
return _factory
|
return _factory
|
||||||
|
|
||||||
def __init__(self, application, options):
|
def __init__(self, application):
|
||||||
self.application = application
|
self.application = application
|
||||||
self.options = options
|
|
||||||
|
|
||||||
def process_request(self, req):
|
def process_request(self, req):
|
||||||
"""Called on each request.
|
"""Called on each request.
|
||||||
|
@ -315,8 +314,7 @@ class ExtensionRouter(Router):
|
||||||
|
|
||||||
Expects to be subclassed.
|
Expects to be subclassed.
|
||||||
"""
|
"""
|
||||||
def __init__(self, application, options, mapper):
|
def __init__(self, application, mapper):
|
||||||
self.options = options
|
|
||||||
self.application = application
|
self.application = application
|
||||||
|
|
||||||
mapper.connect('{path_info:.*}', controller=self.application)
|
mapper.connect('{path_info:.*}', controller=self.application)
|
||||||
|
@ -348,5 +346,5 @@ class ExtensionRouter(Router):
|
||||||
def _factory(app):
|
def _factory(app):
|
||||||
conf = global_config.copy()
|
conf = global_config.copy()
|
||||||
conf.update(local_config)
|
conf.update(local_config)
|
||||||
return cls(app, conf)
|
return cls(app)
|
||||||
return _factory
|
return _factory
|
||||||
|
|
|
@ -1,32 +1,28 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
catalog_driver = keystonelight.backends.templated.TemplatedCatalog
|
|
||||||
identity_driver = keystonelight.backends.kvs.KvsIdentity
|
|
||||||
token_driver = keystonelight.backends.kvs.KvsToken
|
|
||||||
policy_driver = keystonelight.backends.policy.SimpleMatch
|
|
||||||
public_port = 5000
|
public_port = 5000
|
||||||
admin_port = 35357
|
admin_port = 35357
|
||||||
admin_token = ADMIN
|
admin_token = ADMIN
|
||||||
|
|
||||||
# config for TemplatedCatalog, using camelCase because I don't want to do
|
|
||||||
# translations for keystone compat
|
|
||||||
catalog.RegionOne.identity.publicURL = http://localhost:$(public_port)s/v2.0
|
|
||||||
catalog.RegionOne.identity.adminURL = http://localhost:$(admin_port)s/v2.0
|
|
||||||
catalog.RegionOne.identity.internalURL = http://localhost:$(admin_port)s/v2.0
|
|
||||||
catalog.RegionOne.identity.name = 'Identity Service'
|
|
||||||
|
|
||||||
# fake compute service for now to help novaclient tests work
|
|
||||||
compute_port = 3000
|
compute_port = 3000
|
||||||
catalog.RegionOne.compute.publicURL = http://localhost:$(compute_port)s/v1.1/$(tenant_id)s
|
|
||||||
catalog.RegionOne.compute.adminURL = http://localhost:$(compute_port)s/v1.1/$(tenant_id)s
|
|
||||||
catalog.RegionOne.compute.internalURL = http://localhost:$(compute_port)s/v1.1/$(tenant_id)s
|
|
||||||
catalog.RegionOne.compute.name = 'Compute Service'
|
|
||||||
|
|
||||||
# for sql backends
|
[sql]
|
||||||
sql_connection = sqlite:///bla.db
|
connection = sqlite:///bla.db
|
||||||
sql_idle_timeout = 200
|
idle_timeout = 200
|
||||||
sql_min_pool_size = 5
|
min_pool_size = 5
|
||||||
sql_max_pool_size = 10
|
max_pool_size = 10
|
||||||
sql_pool_timeout = 200
|
pool_timeout = 200
|
||||||
|
|
||||||
|
[identity]
|
||||||
|
driver = keystonelight.backends.kvs.KvsIdentity
|
||||||
|
|
||||||
|
[catalog]
|
||||||
|
driver = keystonelight.backends.templated.TemplatedCatalog
|
||||||
|
template_file = default_catalog.templates
|
||||||
|
|
||||||
|
[token]
|
||||||
|
driver = keystonelight.backends.kvs.KvsToken
|
||||||
|
|
||||||
|
[policy]
|
||||||
|
driver = keystonelight.backends.policy.SimpleMatch
|
||||||
|
|
||||||
|
|
||||||
[filter:debug]
|
[filter:debug]
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
# config for TemplatedCatalog, using camelCase because I don't want to do
|
||||||
|
# translations for keystone compat
|
||||||
|
catalog.RegionOne.identity.publicURL = http://localhost:$(public_port)s/v2.0
|
||||||
|
catalog.RegionOne.identity.adminURL = http://localhost:$(admin_port)s/v2.0
|
||||||
|
catalog.RegionOne.identity.internalURL = http://localhost:$(admin_port)s/v2.0
|
||||||
|
catalog.RegionOne.identity.name = 'Identity Service'
|
||||||
|
|
||||||
|
# fake compute service for now to help novaclient tests work
|
||||||
|
catalog.RegionOne.compute.publicURL = http://localhost:$(compute_port)s/v1.1/$(tenant_id)s
|
||||||
|
catalog.RegionOne.compute.adminURL = http://localhost:$(compute_port)s/v1.1/$(tenant_id)s
|
||||||
|
catalog.RegionOne.compute.internalURL = http://localhost:$(compute_port)s/v1.1/$(tenant_id)s
|
||||||
|
catalog.RegionOne.compute.name = 'Compute Service'
|
|
@ -1,12 +1,21 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
catalog_driver = keystonelight.backends.kvs.KvsCatalog
|
|
||||||
identity_driver = keystonelight.backends.kvs.KvsIdentity
|
|
||||||
token_driver = keystonelight.backends.kvs.KvsToken
|
|
||||||
policy_driver = keystonelight.backends.policy.SimpleMatch
|
|
||||||
public_port = 5000
|
public_port = 5000
|
||||||
admin_port = 35357
|
admin_port = 35357
|
||||||
admin_token = ADMIN
|
admin_token = ADMIN
|
||||||
|
|
||||||
|
[identity]
|
||||||
|
driver = keystonelight.backends.kvs.KvsIdentity
|
||||||
|
|
||||||
|
[catalog]
|
||||||
|
driver = keystonelight.backends.kvs.KvsCatalog
|
||||||
|
|
||||||
|
[token]
|
||||||
|
driver = keystonelight.backends.kvs.KvsToken
|
||||||
|
|
||||||
|
[policy]
|
||||||
|
driver = keystonelight.backends.policy.SimpleMatch
|
||||||
|
|
||||||
|
|
||||||
[filter:debug]
|
[filter:debug]
|
||||||
paste.filter_factory = keystonelight.wsgi:Debug.factory
|
paste.filter_factory = keystonelight.wsgi:Debug.factory
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
catalog_driver = keystonelight.backends.templated.TemplatedCatalog
|
|
||||||
identity_driver = keystonelight.backends.kvs.KvsIdentity
|
|
||||||
token_driver = keystonelight.backends.kvs.KvsToken
|
|
||||||
policy_driver = keystonelight.backends.policy.SimpleMatch
|
|
||||||
public_port = 5000
|
public_port = 5000
|
||||||
admin_port = 35357
|
admin_port = 35357
|
||||||
admin_token = ADMIN
|
admin_token = ADMIN
|
||||||
|
|
||||||
# config for TemplatedCatalog, using camelCase because I don't want to do
|
[sql]
|
||||||
# translations for keystone compat
|
connection = sqlite:///bla.db
|
||||||
catalog.RegionOne.identity.publicURL = http://localhost:$(public_port)s/v2.0
|
idle_timeout = 200
|
||||||
catalog.RegionOne.identity.adminURL = http://localhost:$(admin_port)s/v2.0
|
min_pool_size = 5
|
||||||
catalog.RegionOne.identity.internalURL = http://localhost:$(public_port)s/v2.0
|
max_pool_size = 10
|
||||||
catalog.RegionOne.identity.name = 'Identity Service'
|
pool_timeout = 200
|
||||||
|
|
||||||
# fake compute port for now to help novaclient tests work
|
[identity]
|
||||||
compute_port = 3000
|
driver = keystonelight.backends.kvs.KvsIdentity
|
||||||
catalog.RegionOne.compute.publicURL = http://localhost:$(compute_port)s/v2.0
|
|
||||||
catalog.RegionOne.compute.adminURL = http://localhost:$(compute_port)s/v2.0
|
[catalog]
|
||||||
catalog.RegionOne.compute.internalURL = http://localhost:$(compute_port)s/v2.0
|
driver = keystonelight.backends.templated.TemplatedCatalog
|
||||||
catalog.RegionOne.compute.name = 'Compute Service'
|
template_file = default_catalog.templates
|
||||||
|
|
||||||
|
[token]
|
||||||
|
driver = keystonelight.backends.kvs.KvsToken
|
||||||
|
|
||||||
|
[policy]
|
||||||
|
driver = keystonelight.backends.policy.SimpleMatch
|
||||||
|
|
||||||
|
|
||||||
[filter:debug]
|
[filter:debug]
|
||||||
|
|
|
@ -11,16 +11,14 @@ import default_fixtures
|
||||||
class KvsIdentity(test.TestCase, test_backend.IdentityTests):
|
class KvsIdentity(test.TestCase, test_backend.IdentityTests):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(KvsIdentity, self).setUp()
|
super(KvsIdentity, self).setUp()
|
||||||
self.options = self.appconfig('default')
|
self.identity_api = kvs.KvsIdentity(db={})
|
||||||
self.identity_api = kvs.KvsIdentity(options=self.options, db={})
|
|
||||||
self.load_fixtures(default_fixtures)
|
self.load_fixtures(default_fixtures)
|
||||||
|
|
||||||
|
|
||||||
class KvsToken(test.TestCase):
|
class KvsToken(test.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(KvsToken, self).setUp()
|
super(KvsToken, self).setUp()
|
||||||
options = self.appconfig('default')
|
self.token_api = kvs.KvsToken(db={})
|
||||||
self.token_api = kvs.KvsToken(options=options, db={})
|
|
||||||
|
|
||||||
def test_token_crud(self):
|
def test_token_crud(self):
|
||||||
token_id = uuid.uuid4().hex
|
token_id = uuid.uuid4().hex
|
||||||
|
@ -40,8 +38,7 @@ class KvsToken(test.TestCase):
|
||||||
class KvsCatalog(test.TestCase):
|
class KvsCatalog(test.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(KvsCatalog, self).setUp()
|
super(KvsCatalog, self).setUp()
|
||||||
options = self.appconfig('default')
|
self.catalog_api = kvs.KvsCatalog(db={})
|
||||||
self.catalog_api = kvs.KvsCatalog(options=options, db={})
|
|
||||||
self._load_fixtures()
|
self._load_fixtures()
|
||||||
|
|
||||||
def _load_fixtures(self):
|
def _load_fixtures(self):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
from keystonelight import config
|
||||||
from keystonelight import models
|
from keystonelight import models
|
||||||
from keystonelight import test
|
from keystonelight import test
|
||||||
from keystonelight.backends import sql
|
from keystonelight.backends import sql
|
||||||
|
@ -10,20 +11,27 @@ import test_backend
|
||||||
import default_fixtures
|
import default_fixtures
|
||||||
|
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SqlIdentity(test.TestCase, test_backend.IdentityTests):
|
class SqlIdentity(test.TestCase, test_backend.IdentityTests):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(SqlIdentity, self).setUp()
|
super(SqlIdentity, self).setUp()
|
||||||
self.options = self.appconfig('default')
|
try:
|
||||||
os.unlink('bla.db')
|
os.unlink('bla.db')
|
||||||
migration.db_sync(self.options, 1)
|
except Exception:
|
||||||
self.identity_api = sql.SqlIdentity(options=self.options)
|
pass
|
||||||
|
CONF(config_files=['default.conf'])
|
||||||
|
migration.db_sync(1)
|
||||||
|
self.identity_api = sql.SqlIdentity()
|
||||||
self.load_fixtures(default_fixtures)
|
self.load_fixtures(default_fixtures)
|
||||||
|
|
||||||
|
|
||||||
#class SqlToken(test_backend_kvs.KvsToken):
|
#class SqlToken(test_backend_kvs.KvsToken):
|
||||||
# def setUp(self):
|
# def setUp(self):
|
||||||
# super(SqlToken, self).setUp()
|
# super(SqlToken, self).setUp()
|
||||||
# self.token_api = sql.SqlToken(options=options)
|
# self.token_api = sql.SqlToken()
|
||||||
# self.load_fixtures(default_fixtures)
|
# self.load_fixtures(default_fixtures)
|
||||||
|
|
||||||
# def test_token_crud(self):
|
# def test_token_crud(self):
|
||||||
|
@ -44,7 +52,7 @@ class SqlIdentity(test.TestCase, test_backend.IdentityTests):
|
||||||
#class SqlCatalog(test_backend_kvs.KvsCatalog):
|
#class SqlCatalog(test_backend_kvs.KvsCatalog):
|
||||||
# def setUp(self):
|
# def setUp(self):
|
||||||
# super(SqlCatalog, self).setUp()
|
# super(SqlCatalog, self).setUp()
|
||||||
# self.catalog_api = sql.SqlCatalog(options=options)
|
# self.catalog_api = sql.SqlCatalog()
|
||||||
# self._load_fixtures()
|
# self._load_fixtures()
|
||||||
|
|
||||||
# def _load_fixtures(self):
|
# def _load_fixtures(self):
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from keystonelight import client
|
from keystonelight import client
|
||||||
|
from keystonelight import config
|
||||||
from keystonelight import models
|
from keystonelight import models
|
||||||
from keystonelight import test
|
from keystonelight import test
|
||||||
|
|
||||||
import default_fixtures
|
import default_fixtures
|
||||||
|
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
class IdentityApi(test.TestCase):
|
class IdentityApi(test.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(IdentityApi, self).setUp()
|
super(IdentityApi, self).setUp()
|
||||||
self.options = self.appconfig('default')
|
CONF(config_files=['default.conf'])
|
||||||
self.app = self.loadapp('default')
|
self.app = self.loadapp('default')
|
||||||
|
|
||||||
self.load_backends()
|
self.load_backends()
|
||||||
|
@ -54,7 +58,7 @@ class IdentityApi(test.TestCase):
|
||||||
self.assertDictEquals(self.tenant_bar, data[0])
|
self.assertDictEquals(self.tenant_bar, data[0])
|
||||||
|
|
||||||
def test_crud_user(self):
|
def test_crud_user(self):
|
||||||
token_id = self.options['admin_token']
|
token_id = CONF.admin_token
|
||||||
c = client.TestClient(self.app, token=token_id)
|
c = client.TestClient(self.app, token=token_id)
|
||||||
user_ref = models.User(name='FOO')
|
user_ref = models.User(name='FOO')
|
||||||
resp = c.create_user(**user_ref)
|
resp = c.create_user(**user_ref)
|
||||||
|
@ -84,7 +88,7 @@ class IdentityApi(test.TestCase):
|
||||||
#self.assertEquals(delget_resp.status, '404 Not Found')
|
#self.assertEquals(delget_resp.status, '404 Not Found')
|
||||||
|
|
||||||
def test_crud_tenant(self):
|
def test_crud_tenant(self):
|
||||||
token_id = self.options['admin_token']
|
token_id = CONF.admin_token
|
||||||
c = client.TestClient(self.app, token=token_id)
|
c = client.TestClient(self.app, token=token_id)
|
||||||
tenant_ref = models.Tenant(name='BAZ')
|
tenant_ref = models.Tenant(name='BAZ')
|
||||||
resp = c.create_tenant(**tenant_ref)
|
resp = c.create_tenant(**tenant_ref)
|
||||||
|
@ -128,7 +132,7 @@ class IdentityApi(test.TestCase):
|
||||||
#self.assertEquals(delget_resp.status, '404 Not Found')
|
#self.assertEquals(delget_resp.status, '404 Not Found')
|
||||||
|
|
||||||
def test_crud_extras(self):
|
def test_crud_extras(self):
|
||||||
token_id = self.options['admin_token']
|
token_id = CONF.admin_token
|
||||||
user_id = 'foo'
|
user_id = 'foo'
|
||||||
tenant_id = 'bar'
|
tenant_id = 'bar'
|
||||||
c = client.TestClient(self.app, token=token_id)
|
c = client.TestClient(self.app, token=token_id)
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
from keystonelight import config
|
||||||
from keystonelight import test
|
from keystonelight import test
|
||||||
|
|
||||||
import default_fixtures
|
import default_fixtures
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
KEYSTONECLIENT_REPO = 'git://github.com/openstack/python-keystoneclient.git'
|
KEYSTONECLIENT_REPO = 'git://github.com/openstack/python-keystoneclient.git'
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,12 +13,12 @@ class CompatTestCase(test.TestCase):
|
||||||
|
|
||||||
def _public_url(self):
|
def _public_url(self):
|
||||||
public_port = self.public_server.socket_info['socket'][1]
|
public_port = self.public_server.socket_info['socket'][1]
|
||||||
self.options['public_port'] = public_port
|
CONF.public_port = public_port
|
||||||
return "http://localhost:%s/v2.0" % public_port
|
return "http://localhost:%s/v2.0" % public_port
|
||||||
|
|
||||||
def _admin_url(self):
|
def _admin_url(self):
|
||||||
admin_port = self.admin_server.socket_info['socket'][1]
|
admin_port = self.admin_server.socket_info['socket'][1]
|
||||||
self.options['admin_port'] = admin_port
|
CONF.admin_port = admin_port
|
||||||
return "http://localhost:%s/v2.0" % admin_port
|
return "http://localhost:%s/v2.0" % admin_port
|
||||||
|
|
||||||
def _client(self, **kwargs):
|
def _client(self, **kwargs):
|
||||||
|
@ -41,7 +42,7 @@ class MasterCompatTestCase(CompatTestCase):
|
||||||
from keystoneclient.v2_0 import client as ks_client
|
from keystoneclient.v2_0 import client as ks_client
|
||||||
reload(ks_client)
|
reload(ks_client)
|
||||||
|
|
||||||
self.options = self.appconfig('keystoneclient_compat_master')
|
CONF(config_files=['keystoneclient_compat_master.conf'])
|
||||||
self.public_app = self.loadapp('keystoneclient_compat_master',
|
self.public_app = self.loadapp('keystoneclient_compat_master',
|
||||||
name='main')
|
name='main')
|
||||||
self.admin_app = self.loadapp('keystoneclient_compat_master',
|
self.admin_app = self.loadapp('keystoneclient_compat_master',
|
||||||
|
|
|
@ -5,12 +5,16 @@ import sys
|
||||||
|
|
||||||
from nose import exc
|
from nose import exc
|
||||||
|
|
||||||
|
from keystonelight import config
|
||||||
from keystonelight import logging
|
from keystonelight import logging
|
||||||
from keystonelight import models
|
from keystonelight import models
|
||||||
from keystonelight import test
|
from keystonelight import test
|
||||||
from keystonelight import utils
|
from keystonelight import utils
|
||||||
|
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
IDENTITY_API_REPO = 'git://github.com/openstack/identity-api.git'
|
IDENTITY_API_REPO = 'git://github.com/openstack/identity-api.git'
|
||||||
KEYSTONE_REPO = 'git://github.com/openstack/keystone.git'
|
KEYSTONE_REPO = 'git://github.com/openstack/keystone.git'
|
||||||
NOVACLIENT_REPO = 'git://github.com/rackspace/python-novaclient.git'
|
NOVACLIENT_REPO = 'git://github.com/rackspace/python-novaclient.git'
|
||||||
|
@ -46,16 +50,16 @@ class CompatTestCase(test.TestCase):
|
||||||
os.path.join(self.sampledir, 'auth.json')))
|
os.path.join(self.sampledir, 'auth.json')))
|
||||||
|
|
||||||
# validate_token call
|
# validate_token call
|
||||||
self.tenant_345 = self.identity_backend.create_tenant(
|
self.tenant_345 = self.identity_api.create_tenant(
|
||||||
'345',
|
'345',
|
||||||
models.Tenant(id='345', name='My Project'))
|
models.Tenant(id='345', name='My Project'))
|
||||||
self.user_123 = self.identity_backend.create_user(
|
self.user_123 = self.identity_api.create_user(
|
||||||
'123',
|
'123',
|
||||||
models.User(id='123',
|
models.User(id='123',
|
||||||
name='jqsmith',
|
name='jqsmith',
|
||||||
tenants=[self.tenant_345['id']],
|
tenants=[self.tenant_345['id']],
|
||||||
password='password'))
|
password='password'))
|
||||||
self.extras_123 = self.identity_backend.create_extras(
|
self.extras_123 = self.identity_api.create_extras(
|
||||||
self.user_123['id'], self.tenant_345['id'],
|
self.user_123['id'], self.tenant_345['id'],
|
||||||
dict(roles=[{'id': '234',
|
dict(roles=[{'id': '234',
|
||||||
'name': 'compute:admin'},
|
'name': 'compute:admin'},
|
||||||
|
@ -63,7 +67,7 @@ class CompatTestCase(test.TestCase):
|
||||||
'name': 'object-store:admin',
|
'name': 'object-store:admin',
|
||||||
'tenantId': '1'}],
|
'tenantId': '1'}],
|
||||||
roles_links=[]))
|
roles_links=[]))
|
||||||
self.token_123 = self.token_backend.create_token(
|
self.token_123 = self.token_api.create_token(
|
||||||
'ab48a9efdfedb23ty3494',
|
'ab48a9efdfedb23ty3494',
|
||||||
models.Token(id='ab48a9efdfedb23ty3494',
|
models.Token(id='ab48a9efdfedb23ty3494',
|
||||||
expires='2010-11-01T03:32:15-05:00',
|
expires='2010-11-01T03:32:15-05:00',
|
||||||
|
@ -79,32 +83,32 @@ class CompatTestCase(test.TestCase):
|
||||||
#catalog = json.load(open(
|
#catalog = json.load(open(
|
||||||
# os.path.join(os.path.dirname(__file__),
|
# os.path.join(os.path.dirname(__file__),
|
||||||
# 'keystone_compat_diablo_sample_catalog.json')))
|
# 'keystone_compat_diablo_sample_catalog.json')))
|
||||||
#self.catalog_backend.create_catalog(self.user_123['id'],
|
#self.catalog_api.create_catalog(self.user_123['id'],
|
||||||
# self.tenant_345['id'],
|
# self.tenant_345['id'],
|
||||||
# catalog)
|
# catalog)
|
||||||
|
|
||||||
# tenants_for_token call
|
# tenants_for_token call
|
||||||
self.user_foo = self.identity_backend.create_user(
|
self.user_foo = self.identity_api.create_user(
|
||||||
'foo',
|
'foo',
|
||||||
models.User(id='foo', name='FOO', tenants=['1234', '3456']))
|
models.User(id='foo', name='FOO', tenants=['1234', '3456']))
|
||||||
self.tenant_1234 = self.identity_backend.create_tenant(
|
self.tenant_1234 = self.identity_api.create_tenant(
|
||||||
'1234',
|
'1234',
|
||||||
models.Tenant(id='1234',
|
models.Tenant(id='1234',
|
||||||
name='ACME Corp',
|
name='ACME Corp',
|
||||||
description='A description ...',
|
description='A description ...',
|
||||||
enabled=True))
|
enabled=True))
|
||||||
self.tenant_3456 = self.identity_backend.create_tenant(
|
self.tenant_3456 = self.identity_api.create_tenant(
|
||||||
'3456',
|
'3456',
|
||||||
models.Tenant(id='3456',
|
models.Tenant(id='3456',
|
||||||
name='Iron Works',
|
name='Iron Works',
|
||||||
description='A description ...',
|
description='A description ...',
|
||||||
enabled=True))
|
enabled=True))
|
||||||
|
|
||||||
self.token_foo_unscoped = self.token_backend.create_token(
|
self.token_foo_unscoped = self.token_api.create_token(
|
||||||
'foo_unscoped',
|
'foo_unscoped',
|
||||||
models.Token(id='foo_unscoped',
|
models.Token(id='foo_unscoped',
|
||||||
user=self.user_foo))
|
user=self.user_foo))
|
||||||
self.token_foo_scoped = self.token_backend.create_token(
|
self.token_foo_scoped = self.token_api.create_token(
|
||||||
'foo_scoped',
|
'foo_scoped',
|
||||||
models.Token(id='foo_scoped',
|
models.Token(id='foo_scoped',
|
||||||
user=self.user_foo,
|
user=self.user_foo,
|
||||||
|
@ -113,18 +117,13 @@ class CompatTestCase(test.TestCase):
|
||||||
|
|
||||||
class DiabloCompatTestCase(CompatTestCase):
|
class DiabloCompatTestCase(CompatTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
CONF(config_files=['keystone_compat_diablo.conf'])
|
||||||
|
|
||||||
revdir = test.checkout_vendor(KEYSTONE_REPO, 'stable/diablo')
|
revdir = test.checkout_vendor(KEYSTONE_REPO, 'stable/diablo')
|
||||||
self.sampledir = os.path.join(revdir, KEYSTONE_SAMPLE_DIR)
|
self.sampledir = os.path.join(revdir, KEYSTONE_SAMPLE_DIR)
|
||||||
self.app = self.loadapp('keystone_compat_diablo')
|
self.app = self.loadapp('keystone_compat_diablo')
|
||||||
self.options = self.appconfig('keystone_compat_diablo')
|
|
||||||
|
|
||||||
self.identity_backend = utils.import_object(
|
|
||||||
self.options['identity_driver'], options=self.options)
|
|
||||||
self.token_backend = utils.import_object(
|
|
||||||
self.options['token_driver'], options=self.options)
|
|
||||||
self.catalog_backend = utils.import_object(
|
|
||||||
self.options['catalog_driver'], options=self.options)
|
|
||||||
|
|
||||||
|
self.load_backends()
|
||||||
super(DiabloCompatTestCase, self).setUp()
|
super(DiabloCompatTestCase, self).setUp()
|
||||||
|
|
||||||
def test_authenticate_scoped(self):
|
def test_authenticate_scoped(self):
|
||||||
|
|
|
@ -3,6 +3,7 @@ import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from keystonelight import config
|
||||||
from keystonelight import logging
|
from keystonelight import logging
|
||||||
from keystonelight import models
|
from keystonelight import models
|
||||||
from keystonelight import test
|
from keystonelight import test
|
||||||
|
@ -11,6 +12,7 @@ from keystonelight import utils
|
||||||
import default_fixtures
|
import default_fixtures
|
||||||
|
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
NOVACLIENT_REPO = 'git://github.com/openstack/python-novaclient.git'
|
NOVACLIENT_REPO = 'git://github.com/openstack/python-novaclient.git'
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,8 +32,8 @@ class NovaClientCompatMasterTestCase(CompatTestCase):
|
||||||
reload(ks_client)
|
reload(ks_client)
|
||||||
reload(base_client)
|
reload(base_client)
|
||||||
|
|
||||||
|
CONF(config_files=['keystoneclient_compat_master.conf'])
|
||||||
self.app = self.loadapp('keystoneclient_compat_master')
|
self.app = self.loadapp('keystoneclient_compat_master')
|
||||||
self.options = self.appconfig('keystoneclient_compat_master')
|
|
||||||
self.load_backends()
|
self.load_backends()
|
||||||
self.load_fixtures(default_fixtures)
|
self.load_fixtures(default_fixtures)
|
||||||
self.server = self.serveapp('keystoneclient_compat_master')
|
self.server = self.serveapp('keystoneclient_compat_master')
|
||||||
|
@ -41,7 +43,7 @@ class NovaClientCompatMasterTestCase(CompatTestCase):
|
||||||
from novaclient import client as base_client
|
from novaclient import client as base_client
|
||||||
|
|
||||||
port = self.server.socket_info['socket'][1]
|
port = self.server.socket_info['socket'][1]
|
||||||
self.options['public_port'] = port
|
CONF.public_port = port
|
||||||
|
|
||||||
# NOTE(termie): novaclient wants a "/" TypeErrorat the end, keystoneclient does not
|
# NOTE(termie): novaclient wants a "/" TypeErrorat the end, keystoneclient does not
|
||||||
# NOTE(termie): projectid is apparently sent as tenantName, so... that's
|
# NOTE(termie): projectid is apparently sent as tenantName, so... that's
|
||||||
|
|
Loading…
Reference in New Issue