Remove pastedeploy

This patchset removes the lingering code that supported paste.deploy
that is obsolted by the loader wrapped around keystone's use of Flask.

 * The keystone-paste.ini file has been removed.

 * All options have been removed (without deprecation) as they are no
   longer referenced.

 * The TokenAuthMiddleware code (with deprecation warning) has been
   removed as it was only provided to ensure compatibility with paste.ini
   files that were not updated (ensuring not breaking a deployer that
   did not update paste.ini file to remove it from the pipeline).

 * Paste deploy entrypoints have been removed.

Change-Id: I35064a440ef718f50c7e644e8b2d56a99c3ec74f
This commit is contained in:
Morgan Fainberg 2018-06-06 10:56:49 -07:00
parent a11d6ca0eb
commit 8bf335bb01
19 changed files with 46 additions and 468 deletions

View File

@ -9,6 +9,5 @@ found below:
.. toctree::
keystone-conf.rst
keystone-paste-ini.rst
logging-conf.rst
policy-yaml.rst

View File

@ -1,8 +0,0 @@
==================
keystone-paste.ini
==================
Use the ``keystone-paste.ini`` file to configure the Web Service Gateway
Interface (WSGI) middleware pipeline for the Identity service:
.. literalinclude:: ../../../../etc/keystone-paste.ini

View File

@ -1,3 +1,8 @@
# !!! WARNING: THIS FILE IS NO LONGER USED. KEYSTONE IS LOADED DIRECTLY AND
# !!! WILL IGNORE THIS FILE. THIS FILE WILL BE REMOVED IN THE STEIN
# !!! RELEASE. IT IS BEING MAINTAINED TO EASE THE TRANSITION OF THE
# !!! DEPLOYMENT TOOLING IN THE WILD.
# Keystone PasteDeploy configuration file.
[filter:debug]

View File

@ -64,8 +64,7 @@ class Catalog(base.CatalogDriverBase):
and is stored in a similar looking hierarchy. Where a value can contain
values to be interpolated by standard python string interpolation that look
like (the % is replaced by a $ due to paste attempting to interpolate on
its own:
like (the % is replaced by a $):
http://localhost:$(public_port)s/

View File

@ -136,27 +136,7 @@ class BaseApplication(object):
@classmethod
def factory(cls, global_config, **local_config):
"""Used for paste app factories in paste.deploy config files.
Any local configuration (that is, values under the [app:APPNAME]
section of the paste config) will be passed into the `__init__` method
as kwargs.
A hypothetical configuration would look like:
[app:wadl]
latest_version = 1.3
paste.app_factory = keystone.fancy_api:Wadl.factory
which would result in a call to the `Wadl` class as
import keystone.fancy_api
keystone.fancy_api.Wadl(latest_version='1.3')
You could of course re-implement the `factory` method in subclasses,
but using the kwarg passing it shouldn't be necessary.
"""
"""Used for loading in middleware (holdover from paste.deploy)."""
return cls(**local_config)
def __call__(self, environ, start_response):
@ -194,6 +174,11 @@ class BaseApplication(object):
See the end of http://pythonpaste.org/webob/modules/dec.html
for more info.
NOTE: this is now strictly used in conversion from old wsgi
implementation to flask. Once the flask implementation is complete,
the __call__ will not be needed as the flask app will handle
dispatching and __call__.
"""
raise NotImplementedError('You must implement __call__')
@ -566,27 +551,7 @@ class ExtensionRouter(Router):
@classmethod
def factory(cls, global_config, **local_config):
"""Used for paste app factories in paste.deploy config files.
Any local configuration (that is, values under the [filter:APPNAME]
section of the paste config) will be passed into the `__init__` method
as kwargs.
A hypothetical configuration would look like:
[filter:analytics]
redis_host = 127.0.0.1
paste.filter_factory = keystone.analytics:Analytics.factory
which would result in a call to the `Analytics` class as
import keystone.analytics
keystone.analytics.Analytics(app, redis_host='127.0.0.1')
You could of course re-implement the `factory` method in subclasses,
but using the kwarg passing it shouldn't be necessary.
"""
"""Used for loading in middleware (holdover from paste.deploy)."""
def _factory(app):
conf = global_config.copy()
conf.update(local_config)

View File

@ -36,7 +36,6 @@ from keystone.conf import identity_mapping
from keystone.conf import ldap
from keystone.conf import memcache
from keystone.conf import oauth1
from keystone.conf import paste_deploy
from keystone.conf import policy
from keystone.conf import resource
from keystone.conf import revoke
@ -72,7 +71,6 @@ conf_modules = [
ldap,
memcache,
oauth1,
paste_deploy,
policy,
resource,
revoke,

View File

@ -1,40 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from keystone.conf import utils
config_file = cfg.StrOpt(
'config_file',
default='keystone-paste.ini',
help=utils.fmt("""
Name of (or absolute path to) the Paste Deploy configuration file that composes
middleware and the keystone application itself into actual WSGI entry points.
See http://pythonpaste.org/deploy/ for additional documentation on the file's
format.
"""))
GROUP_NAME = __name__.split('.')[-1]
ALL_OPTS = [
config_file,
]
def register_opts(conf):
conf.register_opts(ALL_OPTS, group=GROUP_NAME)
def list_opts():
return {GROUP_NAME: ALL_OPTS}

View File

@ -249,27 +249,7 @@ class AuthContextMiddleware(provider_api.ProviderAPIMixin,
@classmethod
def factory(cls, global_config, **local_config):
"""Used for paste app factories in paste.deploy config files.
Any local configuration (that is, values under the [filter:APPNAME]
section of the paste config) will be passed into the `__init__` method
as kwargs.
A hypothetical configuration would look like:
[filter:analytics]
redis_host = 127.0.0.1
paste.filter_factory = keystone.analytics:Analytics.factory
which would result in a call to the `Analytics` class as
import keystone.analytics
keystone.analytics.Analytics(app, redis_host='127.0.0.1')
You could of course re-implement the `factory` method in subclasses,
but using the kwarg passing it shouldn't be necessary.
"""
"""Used for loading in middleware (holdover from paste.deploy)."""
def _factory(app):
conf = global_config.copy()
conf.update(local_config)

View File

@ -13,7 +13,6 @@
# under the License.
from oslo_log import log
from oslo_log import versionutils
from oslo_serialization import jsonutils
from keystone.common import wsgi
@ -23,25 +22,6 @@ from keystone import exception
LOG = log.getLogger(__name__)
class TokenAuthMiddleware(wsgi.Middleware):
@versionutils.deprecated(
as_of=versionutils.deprecated.ROCKY,
what='TokenAuthMiddleware in the paste-ini pipeline.',
remove_in=+2)
def __init__(self, *args, **kwargs):
super(TokenAuthMiddleware, self).__init__(*args, **kwargs)
LOG.warning('The token_auth middleware functionality has been '
'merged into the main auth middleware '
'(keystone.middleware.auth.AuthContextMiddleware). '
'The [filter:token_auth] block will need to be'
'removed from your paste ini file. Failure to'
'remove these elements from your paste ini file will '
'result in keystone to no longer start/run when the '
'`token_auth` is removed in the Stein release.')
class JsonBodyMiddleware(wsgi.Middleware):
"""Middleware to allow method arguments to be passed as serialized JSON.

View File

@ -11,3 +11,10 @@
# under the License.
from keystone.server.flask.core import * # noqa
from keystone.server.flask import application # noqa
__all__ = ('application', 'core', 'fail_gracefully', 'initialize_application',
'setup_app_middleware')
fail_gracefully = application.fail_gracefully

View File

@ -1,5 +1,3 @@
# Copyright 2013 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
@ -12,124 +10,21 @@
# License for the specific language governing permissions and limitations
# under the License.
import os
import oslo_i18n
from oslo_log import log
# NOTE(dstanek): i18n.enable_lazy() must be called before
# keystone.i18n._() is called to ensure it has the desired lazy lookup
# behavior. This includes cases, like keystone.exceptions, where
# keystone.i18n._() is called at import time.
oslo_i18n.enable_lazy()
from keystone.common import profiler
import keystone.conf
from keystone import exception
from keystone.server import common
from keystone.server import flask as keystone_flask
from keystone.version import service as keystone_service
CONF = keystone.conf.CONF
def initialize_application(name,
post_log_configured_function=lambda: None,
config_files=None):
possible_topdir = os.path.normpath(os.path.join(
os.path.abspath(__file__),
os.pardir,
os.pardir,
os.pardir))
dev_conf = os.path.join(possible_topdir,
'etc',
'keystone.conf')
if not config_files:
config_files = None
if os.path.exists(dev_conf):
config_files = [dev_conf]
common.configure(config_files=config_files)
# Log the options used when starting if we're in debug mode...
if CONF.debug:
CONF.log_opt_values(log.getLogger(CONF.prog), log.DEBUG)
post_log_configured_function()
def loadapp():
return keystone_service.loadapp(
'config:%s' % find_paste_config(), name)
_unused, application = common.setup_backends(
startup_application_fn=loadapp)
# setup OSprofiler notifier and enable the profiling if that is configured
# in Keystone configuration file.
profiler.setup(name)
return application
def find_paste_config():
"""Find Keystone's paste.deploy configuration file.
Keystone's paste.deploy configuration file is specified in the
``[paste_deploy]`` section of the main Keystone configuration file,
``keystone.conf``.
For example::
[paste_deploy]
config_file = keystone-paste.ini
:returns: The selected configuration filename
:raises: exception.ConfigFileNotFound
"""
if CONF.paste_deploy.config_file:
paste_config = CONF.paste_deploy.config_file
paste_config_value = paste_config
if not os.path.isabs(paste_config):
paste_config = CONF.find_file(paste_config)
elif CONF.config_file:
paste_config = CONF.config_file[0]
paste_config_value = paste_config
else:
# this provides backwards compatibility for keystone.conf files that
# still have the entire paste configuration included, rather than just
# a [paste_deploy] configuration section referring to an external file
paste_config = CONF.find_file('keystone.conf')
paste_config_value = 'keystone.conf'
if not paste_config or not os.path.exists(paste_config):
raise exception.ConfigFileNotFound(config_file=paste_config_value)
return paste_config
def _get_config_files(env=None):
if env is None:
env = os.environ
dirname = env.get('OS_KEYSTONE_CONFIG_DIR', '').strip()
files = [s.strip() for s in
env.get('OS_KEYSTONE_CONFIG_FILES', '').split(';') if s.strip()]
if dirname:
if not files:
files = ['keystone.conf']
files = [os.path.join(dirname, fname) for fname in files]
return files
from keystone.server.flask import core as flask_core
# NOTE(morgan): While "_get_config_files" is present in the keystone_flask
# module, since it is considered "private", we are going to directly
# import core and call it directly, eventually keystone_flask will not
# export all the symbols from keystone.flask.core only specific ones that
# are meant for public consumption
def initialize_admin_application():
return keystone_flask.initialize_application(
name='admin', config_files=_get_config_files())
name='admin', config_files=flask_core._get_config_files())
def initialize_public_application():
return keystone_flask.initialize_application(
name='public', config_files=_get_config_files())
name='public', config_files=flask_core._get_config_files())

View File

@ -25,10 +25,10 @@ from keystone.common import utils as common_utils
import keystone.conf
from keystone.credential.providers import fernet as credential_fernet
from keystone import exception
from keystone.server import flask as server_flask
from keystone.tests import unit
from keystone.tests.unit import ksfixtures
from keystone.tests.unit import utils
from keystone.version import service
CONF = keystone.conf.CONF
@ -250,7 +250,7 @@ class UtilsTestCase(unit.BaseTestCase):
class ServiceHelperTests(unit.BaseTestCase):
@service.fail_gracefully
@server_flask.fail_gracefully
def _do_test(self):
raise Exception("Test Exc")

View File

@ -34,7 +34,6 @@ from oslo_context import fixture as oslo_ctx_fixture
from oslo_log import fixture as log_fixture
from oslo_log import log
from oslo_utils import timeutils
from paste.deploy import loadwsgi
import six
from sqlalchemy import exc
import testtools
@ -112,26 +111,6 @@ class dirs(object):
return os.path.join(TESTCONF, *p)
class EggLoader(loadwsgi.EggLoader):
_basket = {}
def find_egg_entry_point(self, object_type, name=None):
egg_key = '%s:%s' % (object_type, name)
egg_ep = self._basket.get(egg_key)
if not egg_ep:
egg_ep = super(EggLoader, self).find_egg_entry_point(
object_type, name=name)
self._basket[egg_key] = egg_ep
return egg_ep
# NOTE(dstanek): class paths were removed from the keystone-paste.ini in
# favor of using entry points. This caused tests to slow to a crawl
# since we reload the application object for each RESTful test. This
# monkey-patching adds caching to paste deploy's egg lookup.
loadwsgi.EggLoader = EggLoader
@atexit.register
def remove_test_databases():
db = dirs.tmp('test.db')
@ -798,15 +777,6 @@ class TestCase(BaseTestCase):
self.addCleanup(self.cleanup_instance(*fixtures_to_cleanup))
def _paste_config(self, config):
if not config.startswith('config:'):
test_path = os.path.join(TESTSDIR, config)
etc_path = os.path.join(ROOTDIR, 'etc', config)
for path in [test_path, etc_path]:
if os.path.exists('%s-paste.ini' % path):
return 'config:%s-paste.ini' % path
return config
def loadapp(self, name='public'):
return service.loadapp(name=name)

View File

@ -13,13 +13,10 @@
# under the License.
import os
import uuid
from oslo_config import generator
import keystone.conf
from keystone import exception
from keystone.server import wsgi
from keystone.tests import unit
@ -31,10 +28,6 @@ class ConfigTestCase(unit.TestCase):
def config_files(self):
config_files = super(ConfigTestCase, self).config_files()
# NOTE(lbragstad): This needs some investigation, but CONF.find_file()
# apparently needs the sample configuration file in order to find the
# paste file. This should really be replaced by just setting the
# default configuration directory on the config object instead.
sample_file = 'keystone.conf.sample'
args = ['--namespace', 'keystone', '--output-file',
unit.dirs.etc(sample_file)]
@ -43,18 +36,6 @@ class ConfigTestCase(unit.TestCase):
self.addCleanup(os.remove, unit.dirs.etc(sample_file))
return config_files
def test_default_paste_config_location_succeeds(self):
paste_file_location = unit.dirs.etc(CONF.paste_deploy.config_file)
self.assertEqual(paste_file_location, wsgi.find_paste_config())
def test_invalid_paste_file_location_fails(self):
self.config_fixture.config(
group='paste_deploy', config_file=uuid.uuid4().hex
)
self.assertRaises(
exception.ConfigFileNotFound, wsgi.find_paste_config
)
def test_config_default(self):
self.assertIsNone(CONF.auth.password)
self.assertIsNone(CONF.auth.token)

View File

@ -26,7 +26,6 @@ class TestEntryPoints(test.TestCase):
'json_body',
'request_id',
'sizelimit',
'token_auth',
'url_normalize',
]

View File

@ -28,7 +28,7 @@ import webob
from keystone.common import wsgi
from keystone import exception
from keystone.server import wsgi as server_wsgi
from keystone.server.flask import core as server_flask
from keystone.tests import unit
@ -297,7 +297,7 @@ class WSGIAppConfigTest(unit.TestCase):
custom_config_files = ['kst.conf', 'kst2.conf']
def test_config_files_have_default_values_when_envars_not_set(self):
config_files = server_wsgi._get_config_files()
config_files = server_flask._get_config_files()
config_files.sort()
expected_config_files = []
self.assertListEqual(config_files, expected_config_files)
@ -305,7 +305,7 @@ class WSGIAppConfigTest(unit.TestCase):
def test_config_files_have_default_values_with_empty_envars(self):
env = {'OS_KEYSTONE_CONFIG_FILES': '',
'OS_KEYSTONE_CONFIG_DIR': ''}
config_files = server_wsgi._get_config_files(env)
config_files = server_flask._get_config_files(env)
config_files.sort()
expected_config_files = []
self.assertListEqual(config_files, expected_config_files)
@ -313,20 +313,20 @@ class WSGIAppConfigTest(unit.TestCase):
def test_can_use_single_config_file_under_default_config_dir(self):
cfg = self.custom_config_files[0]
env = {'OS_KEYSTONE_CONFIG_FILES': cfg}
config_files = server_wsgi._get_config_files(env)
config_files = server_flask._get_config_files(env)
expected_config_files = [cfg]
self.assertListEqual(config_files, expected_config_files)
def test_can_use_multiple_config_files_under_default_config_dir(self):
env = {'OS_KEYSTONE_CONFIG_FILES': ';'.join(self.custom_config_files)}
config_files = server_wsgi._get_config_files(env)
config_files = server_flask._get_config_files(env)
config_files.sort()
expected_config_files = self.custom_config_files
self.assertListEqual(config_files, expected_config_files)
config_with_empty_strings = self.custom_config_files + ['', ' ']
env = {'OS_KEYSTONE_CONFIG_FILES': ';'.join(config_with_empty_strings)}
config_files = server_wsgi._get_config_files(env)
config_files = server_flask._get_config_files(env)
config_files.sort()
self.assertListEqual(config_files, expected_config_files)
@ -334,7 +334,7 @@ class WSGIAppConfigTest(unit.TestCase):
cfg = self.custom_config_files[0]
cfgpath = os.path.join(self.custom_config_dir, cfg)
env = {'OS_KEYSTONE_CONFIG_FILES': cfgpath}
config_files = server_wsgi._get_config_files(env)
config_files = server_flask._get_config_files(env)
self.assertListEqual(config_files, [cfgpath])
def test_can_use_multiple_absolute_path_config_files(self):
@ -342,18 +342,18 @@ class WSGIAppConfigTest(unit.TestCase):
for cfg in self.custom_config_files]
cfgpaths.sort()
env = {'OS_KEYSTONE_CONFIG_FILES': ';'.join(cfgpaths)}
config_files = server_wsgi._get_config_files(env)
config_files = server_flask._get_config_files(env)
config_files.sort()
self.assertListEqual(config_files, cfgpaths)
env = {'OS_KEYSTONE_CONFIG_FILES': ';'.join(cfgpaths + ['', ' '])}
config_files = server_wsgi._get_config_files(env)
config_files = server_flask._get_config_files(env)
config_files.sort()
self.assertListEqual(config_files, cfgpaths)
def test_can_use_default_config_files_with_custom_config_dir(self):
env = {'OS_KEYSTONE_CONFIG_DIR': self.custom_config_dir}
config_files = server_wsgi._get_config_files(env)
config_files = server_flask._get_config_files(env)
config_files.sort()
expected_config_files = [os.path.join(self.custom_config_dir,
self.default_config_file)]
@ -363,7 +363,7 @@ class WSGIAppConfigTest(unit.TestCase):
cfg = self.custom_config_files[0]
env = {'OS_KEYSTONE_CONFIG_DIR': self.custom_config_dir,
'OS_KEYSTONE_CONFIG_FILES': cfg}
config_files = server_wsgi._get_config_files(env)
config_files = server_flask._get_config_files(env)
config_files.sort()
expected_config_files = [os.path.join(self.custom_config_dir, cfg)]
self.assertListEqual(config_files, expected_config_files)
@ -371,7 +371,7 @@ class WSGIAppConfigTest(unit.TestCase):
def test_can_use_multiple_config_files_under_custom_config_dir(self):
env = {'OS_KEYSTONE_CONFIG_DIR': self.custom_config_dir,
'OS_KEYSTONE_CONFIG_FILES': ';'.join(self.custom_config_files)}
config_files = server_wsgi._get_config_files(env)
config_files = server_flask._get_config_files(env)
config_files.sort()
expected_config_files = [os.path.join(self.custom_config_dir, s)
for s in self.custom_config_files]
@ -381,7 +381,7 @@ class WSGIAppConfigTest(unit.TestCase):
config_with_empty_strings = self.custom_config_files + ['', ' ']
env = {'OS_KEYSTONE_CONFIG_DIR': self.custom_config_dir,
'OS_KEYSTONE_CONFIG_FILES': ';'.join(config_with_empty_strings)}
config_files = server_wsgi._get_config_files(env)
config_files = server_flask._get_config_files(env)
config_files.sort()
self.assertListEqual(config_files, expected_config_files)
@ -393,14 +393,14 @@ class WSGIAppConfigTest(unit.TestCase):
self.custom_config_files[1])
env = {'OS_KEYSTONE_CONFIG_DIR': self.custom_config_dir,
'OS_KEYSTONE_CONFIG_FILES': ';'.join([cfg0, cfgpath1])}
config_files = server_wsgi._get_config_files(env)
config_files = server_flask._get_config_files(env)
config_files.sort()
expected_config_files = [cfgpath0, cfgpath1]
expected_config_files.sort()
self.assertListEqual(config_files, expected_config_files)
env = {'OS_KEYSTONE_CONFIG_FILES': ';'.join([cfg0, cfgpath1])}
config_files = server_wsgi._get_config_files(env)
config_files = server_flask._get_config_files(env)
config_files.sort()
expected_config_files = [cfg0, cfgpath1]
expected_config_files.sort()

View File

@ -12,33 +12,12 @@
# License for the specific language governing permissions and limitations
# under the License.
import functools
import sys
from oslo_log import log
import routes
from keystone.application_credential import routers as app_cred_routers
from keystone.assignment import routers as assignment_routers
from keystone.auth import routers as auth_routers
from keystone.catalog import routers as catalog_routers
from keystone.common import wsgi
import keystone.conf
from keystone.credential import routers as credential_routers
from keystone.endpoint_policy import routers as endpoint_policy_routers
from keystone.federation import routers as federation_routers
from keystone.identity import routers as identity_routers
from keystone.limit import routers as limit_routers
from keystone.oauth1 import routers as oauth1_routers
from keystone.policy import routers as policy_routers
from keystone.resource import routers as resource_routers
from keystone.revoke import routers as revoke_routers
from keystone.server import flask as keystone_flask
from keystone.server.flask import application
from keystone.token import _simple_cert as simple_cert_ext
from keystone.trust import routers as trust_routers
from keystone.version import controllers
from keystone.version import routers
CONF = keystone.conf.CONF
@ -52,107 +31,3 @@ def loadapp(name):
controllers.latest_app = keystone_flask.setup_app_middleware(
application.application_factory(name))
return controllers.latest_app
def fail_gracefully(f):
"""Log exceptions and aborts."""
@functools.wraps(f)
def wrapper(*args, **kw):
try:
return f(*args, **kw)
except Exception as e:
LOG.debug(e, exc_info=True)
# exception message is printed to all logs
LOG.critical(e)
sys.exit(1)
return wrapper
def warn_local_conf(f):
@functools.wraps(f)
def wrapper(*args, **local_conf):
if local_conf:
LOG.warning("'local conf' from PasteDeploy INI is being ignored.")
return f(*args, **local_conf)
return wrapper
@fail_gracefully
@warn_local_conf
def public_app_factory(global_conf, **local_conf):
controllers.register_version('v2.0')
# NOTE(lbragstad): Only wire up the v2.0 version controller. We should keep
# this here because we still support the ec2tokens API on the v2.0 path
# until T. Once that is removed, we can remove the rest of the v2.0 routers
# and whatnot. The ec2token controller is actually wired up by the paste
# pipeline.
return wsgi.ComposingRouter(routes.Mapper(), [routers.VersionV2('public')])
@fail_gracefully
@warn_local_conf
def admin_app_factory(global_conf, **local_conf):
controllers.register_version('v2.0')
# NOTE(lbragstad): Only wire up the v2.0 version controller. We should keep
# this here because we still support the ec2tokens API on the v2.0 path
# until T. Once that is removed, we can remove the rest of the v2.0 routers
# and whatnot. The ec2token controller is actually wired up by the paste
# pipeline.
return wsgi.ComposingRouter(routes.Mapper(), [routers.VersionV2('admin')])
@fail_gracefully
@warn_local_conf
def public_version_app_factory(global_conf, **local_conf):
return wsgi.ComposingRouter(routes.Mapper(),
[routers.Versions('public')])
@fail_gracefully
@warn_local_conf
def admin_version_app_factory(global_conf, **local_conf):
return wsgi.ComposingRouter(routes.Mapper(),
[routers.Versions('admin')])
@fail_gracefully
@warn_local_conf
def v3_app_factory(global_conf, **local_conf):
controllers.register_version('v3')
mapper = routes.Mapper()
sub_routers = []
_routers = []
# NOTE(dstanek): Routers should be ordered by their frequency of use in
# a live system. This is due to the routes implementation. The most
# frequently used routers should appear first.
all_api_routers = [auth_routers,
assignment_routers,
catalog_routers,
credential_routers,
identity_routers,
app_cred_routers,
limit_routers,
policy_routers,
resource_routers,
revoke_routers,
federation_routers,
oauth1_routers,
endpoint_policy_routers,
# TODO(morganfainberg): Remove the simple_cert router
# when PKI and PKIZ tokens are removed.
simple_cert_ext]
if CONF.trust.enabled:
all_api_routers.append(trust_routers)
for api_routers in all_api_routers:
routers_instance = api_routers.Routers()
_routers.append(routers_instance)
routers_instance.append_v3_routers(mapper, sub_routers)
# Add in the v3 version api
sub_routers.append(routers.VersionV3('public', _routers))
return wsgi.ComposingRouter(mapper, sub_routers)

View File

@ -8,8 +8,6 @@ Babel!=2.4.0,>=2.3.4 # BSD
pbr!=2.1.0,>=2.0.0 # Apache-2.0
WebOb>=1.7.1 # MIT
PasteDeploy>=1.5.0 # MIT
Paste>=2.0.2 # MIT
Routes>=2.3.1 # MIT
Flask!=0.11,<1.0 # BSD
cryptography>=2.1 # BSD/Apache-2.0

View File

@ -194,28 +194,3 @@ keystone.server_middleware =
token_auth = keystone.middleware:TokenAuthMiddleware
json_body = keystone.middleware:JsonBodyMiddleware
debug = oslo_middleware:Debug
paste.filter_factory =
# TODO(morgan): Remove paste.filter_factory
healthcheck = oslo_middleware:Healthcheck.factory
cors = oslo_middleware:CORS.factory
sizelimit = oslo_middleware:RequestBodySizeLimiter.factory
http_proxy_to_wsgi = oslo_middleware:HTTPProxyToWSGI.factory
osprofiler = osprofiler.web:WsgiMiddleware.factory
url_normalize = keystone.middleware:NormalizingFilter.factory
request_id = oslo_middleware:RequestId.factory
build_auth_context = keystone.middleware:AuthContextMiddleware.factory
token_auth = keystone.middleware:TokenAuthMiddleware.factory
json_body = keystone.middleware:JsonBodyMiddleware.factory
debug = oslo_middleware:Debug.factory
ec2_extension = keystone.contrib.ec2:Ec2Extension.factory
ec2_extension_v3 = keystone.contrib.ec2:Ec2ExtensionV3.factory
s3_extension = keystone.contrib.s3:S3Extension.factory
paste.app_factory =
# TODO(morgan): Remove paste.app_factory
admin_service = keystone.version.service:admin_app_factory
admin_version_service = keystone.version.service:admin_version_app_factory
public_service = keystone.version.service:public_app_factory
public_version_service = keystone.version.service:public_version_app_factory
service_v3 = keystone.version.service:v3_app_factory