Check project_id/tenant_id in API call

When project_id/tenant_id is present in an API call, Neutron
checks first if this project exists. If not, a HTTPNotFound
will be thrown.

This patch is tested in neutron-tempest-plugin:
https://review.opendev.org/#/c/754390/

Closes-Bug: #1896588

Change-Id: I6276490d4df69ec0f2c9a1492b9b03d1130c7c05
This commit is contained in:
Rodolfo Alonso Hernandez 2020-09-21 15:55:26 +00:00
parent 164f12349f
commit 2df49fa879
2 changed files with 32 additions and 0 deletions

View File

@ -24,6 +24,10 @@ paste.filter_factory = oslo_middleware:CatchErrors.factory
paste.filter_factory = oslo_middleware.cors:filter_factory
oslo_config_project = neutron
[filter:project_id]
paste.filter_factory = neutron.api.extensions:ProjectIdMiddleware.factory
oslo_config_project = neutron
[filter:http_proxy_to_wsgi]
paste.filter_factory = oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory

View File

@ -17,9 +17,11 @@ import collections
import imp
import os
from keystoneauth1 import loading as ks_loading
from neutron_lib.api import extensions as api_extensions
from neutron_lib import exceptions
from neutron_lib.plugins import directory
from openstack import connection
from oslo_config import cfg
from oslo_log import log as logging
from oslo_middleware import base
@ -39,6 +41,7 @@ LOG = logging.getLogger(__name__)
EXTENSION_SUPPORTED_CHECK_MAP = {}
_PLUGIN_AGNOSTIC_EXTENSIONS = set()
_NOVA_CONNECTION = None
def register_custom_supported_check(alias, f, plugin_agnostic=False):
@ -640,3 +643,28 @@ def append_api_extensions_path(paths):
paths = list(set([cfg.CONF.api_extensions_path] + paths))
cfg.CONF.set_override('api_extensions_path',
':'.join([p for p in paths if p]))
class ProjectIdMiddleware(base.ConfigurableMiddleware):
@webob.dec.wsgify
def __call__(self, req):
# NOTE(ralonsoh): this method uses Nova Keystone user to retrieve the
# project because (1) it is allowed to retrieve the projects and (2)
# Neutron avoids adding another user section in the configuration
# (Nova user will be always used).
global _NOVA_CONNECTION
project = req.params.get('project_id') or req.params.get('tenant_id')
if project:
if not _NOVA_CONNECTION:
auth = ks_loading.load_auth_from_conf_options(cfg.CONF, 'nova')
keystone_session = ks_loading.load_session_from_conf_options(
cfg.CONF, 'nova', auth=auth)
_NOVA_CONNECTION = connection.Connection(
session=keystone_session, oslo_conf=cfg.CONF,
connect_retries=cfg.CONF.http_retries)
if not _NOVA_CONNECTION.get_project(project):
return webob.exc.HTTPNotFound(
comment='Project %s does not exist' % project)
return req.get_response(self.application)