Files
nova/nova/api/openstack/placement/deploy.py
T
Chris Dent a598af9de6 Add rudimentary CORS support to placement API
If 'cors.allowed_origin' is set in the nova.conf, configure the
placement API to use oslo_middleware.CORS. Simple gabbi tests are
added which confirm the basic operation of the middleware, modeled
on the tests in nova/tests/functional/test_middleware.py, as well as
additional tests which confirm that when the middleware is not
configured it is not present in the system.

The cors config options are registered in deploy.py to ensure that
the group is allowed to exist in conf (even if it doesn't). Without
that, a deployment that tries to configure cors would not actually
cause the middleware to run.

Change-Id: I571bc675facaecb523dcf906f4bb44a51102b514
2017-01-16 12:04:24 +00:00

88 lines
3.3 KiB
Python

# 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.
"""Deployment handling for Placmenent API."""
from keystonemiddleware import auth_token
import oslo_middleware
from oslo_middleware import cors
from nova.api import openstack as common_api
from nova.api.openstack.placement import auth
from nova.api.openstack.placement import handler
from nova.api.openstack.placement import microversion
from nova.api.openstack.placement import requestlog
from nova import objects
# TODO(cdent): NAME points to the config project being used, so for
# now this is "nova" but we probably want "placement" eventually.
NAME = "nova"
# Make sure that objects are registered for this running of the
# placement API.
objects.register_all()
def deploy(conf, project_name):
"""Assemble the middleware pipeline leading to the placement app."""
if conf.api.auth_strategy == 'noauth2':
auth_middleware = auth.NoAuthMiddleware
else:
# Do not provide global conf to middleware here.
auth_middleware = auth_token.filter_factory(
{}, oslo_config_project=project_name)
# Pass in our CORS config, if any, manually as that's a)
# explicit, b) makes testing more straightfoward, c) let's
# us control the use of cors by the presence of its config.
conf.register_opts(cors.CORS_OPTS, 'cors')
if conf.cors.allowed_origin:
cors_middleware = oslo_middleware.CORS.factory(
{}, **conf.cors)
else:
cors_middleware = None
context_middleware = auth.PlacementKeystoneContext
req_id_middleware = oslo_middleware.RequestId
microversion_middleware = microversion.MicroversionMiddleware
fault_wrap = common_api.FaultWrapper
request_log = requestlog.RequestLog
application = handler.PlacementHandler()
# NOTE(cdent): The ordering here is important. The list is ordered
# from the inside out. For a single request req_id_middleware is called
# first and microversion_middleware last. Then the request is finally
# passed to the application (the PlacementHandler). At that point
# the response ascends the middleware in the reverse of the
# order the request went in. This order ensures that log messages
# all see the same contextual information including request id and
# authentication information.
for middleware in (microversion_middleware,
fault_wrap,
request_log,
context_middleware,
auth_middleware,
cors_middleware,
req_id_middleware,
):
if middleware:
application = middleware(application)
return application
def loadapp(config, project_name=NAME):
application = deploy(config, project_name)
return application