diff --git a/etc/api-paste.ini b/etc/api-paste.ini index 4fb3ddbae36..3e79feb9e69 100644 --- a/etc/api-paste.ini +++ b/etc/api-paste.ini @@ -5,8 +5,8 @@ use = egg:Paste#urlmap [composite:neutronapi_v2_0] use = call:neutron.auth:pipeline_factory -noauth = request_id catch_errors extensions neutronapiapp_v2_0 -keystone = request_id catch_errors authtoken keystonecontext extensions neutronapiapp_v2_0 +noauth = cors request_id catch_errors extensions neutronapiapp_v2_0 +keystone = cors request_id catch_errors authtoken keystonecontext extensions neutronapiapp_v2_0 [filter:request_id] paste.filter_factory = oslo_middleware:RequestId.factory @@ -14,6 +14,13 @@ paste.filter_factory = oslo_middleware:RequestId.factory [filter:catch_errors] paste.filter_factory = oslo_middleware:CatchErrors.factory +[filter:cors] +paste.filter_factory = oslo_middleware.cors:filter_factory +oslo_config_project = neutron +latent_allow_headers = X-Auth-Token, X-Openstack-Request-Id +latent_expose_headers = X-Auth-Token, X-Openstack-Request-Id +latent_allow_methods = GET, PUT, POST, DELETE, PATCH + [filter:keystonecontext] paste.filter_factory = neutron.auth:NeutronKeystoneContext.factory diff --git a/etc/oslo-config-generator/neutron.conf b/etc/oslo-config-generator/neutron.conf index f55a562ecc1..1d61c360b3e 100644 --- a/etc/oslo-config-generator/neutron.conf +++ b/etc/oslo-config-generator/neutron.conf @@ -13,6 +13,7 @@ namespace = oslo.db namespace = oslo.policy namespace = oslo.concurrency namespace = oslo.messaging +namespace = oslo.middleware.cors namespace = oslo.service.sslutils namespace = oslo.service.wsgi namespace = keystonemiddleware.auth_token diff --git a/neutron/pecan_wsgi/app.py b/neutron/pecan_wsgi/app.py index 77d4c44a249..7860da5a7a5 100644 --- a/neutron/pecan_wsgi/app.py +++ b/neutron/pecan_wsgi/app.py @@ -15,6 +15,7 @@ from keystonemiddleware import auth_token from oslo_config import cfg +from oslo_middleware import cors from oslo_middleware import request_id import pecan @@ -74,4 +75,17 @@ def _wrap_app(app): else: raise n_exc.InvalidConfigurationOption( opt_name='auth_strategy', opt_value=cfg.CONF.auth_strategy) + + # This should be the last middleware in the list (which results in + # it being the first in the middleware chain). This is to ensure + # that any errors thrown by other middleware, such as an auth + # middleware - are annotated with CORS headers, and thus accessible + # by the browser. + app = cors.CORS(app, cfg.CONF) + app.set_latent( + allow_headers=['X-Auth-Token', 'X-Openstack-Request-Id'], + allow_methods=['GET', 'PUT', 'POST', 'DELETE', 'PATCH'], + expose_headers=['X-Auth-Token', 'X-Openstack-Request-Id'] + ) + return app