From 28082326ddfb4b6b884256180f40c08fd1d53405 Mon Sep 17 00:00:00 2001 From: gong yong sheng Date: Tue, 7 Jun 2016 13:35:52 +0800 Subject: [PATCH] Use request_id from oslo middleware Change-Id: I40e499de91bbc0e137515571cfae0f50b5f07006 Partial-bug: #1552282 --- requirements.txt | 1 + tacker/auth.py | 2 +- .../openstack/common/middleware/__init__.py | 0 tacker/openstack/common/middleware/audit.py | 44 ------ tacker/openstack/common/middleware/base.py | 56 -------- .../common/middleware/catch_errors.py | 43 ------ .../common/middleware/correlation_id.py | 28 ---- tacker/openstack/common/middleware/debug.py | 60 --------- .../openstack/common/middleware/notifier.py | 126 ------------------ .../openstack/common/middleware/request_id.py | 41 ------ .../openstack/common/middleware/sizelimit.py | 81 ----------- tacker/tests/unit/test_auth.py | 2 +- 12 files changed, 3 insertions(+), 481 deletions(-) delete mode 100644 tacker/openstack/common/middleware/__init__.py delete mode 100644 tacker/openstack/common/middleware/audit.py delete mode 100644 tacker/openstack/common/middleware/base.py delete mode 100644 tacker/openstack/common/middleware/catch_errors.py delete mode 100644 tacker/openstack/common/middleware/correlation_id.py delete mode 100644 tacker/openstack/common/middleware/debug.py delete mode 100644 tacker/openstack/common/middleware/notifier.py delete mode 100644 tacker/openstack/common/middleware/request_id.py delete mode 100644 tacker/openstack/common/middleware/sizelimit.py diff --git a/requirements.txt b/requirements.txt index 2ec679639..33ca0849e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,6 +27,7 @@ oslo.concurrency>=3.8.0 # Apache-2.0 oslo.config>=3.10.0 # Apache-2.0 oslo.log>=1.14.0 # Apache-2.0 oslo.messaging>=4.5.0 # Apache-2.0 +oslo.middleware>=3.0.0 # Apache-2.0 oslo.rootwrap>=2.0.0 # Apache-2.0 oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0 python-novaclient!=2.33.0,>=2.29.0 # Apache-2.0 diff --git a/tacker/auth.py b/tacker/auth.py index 7fbb94a4c..d273aad40 100644 --- a/tacker/auth.py +++ b/tacker/auth.py @@ -14,11 +14,11 @@ from oslo_config import cfg from oslo_log import log as logging +from oslo_middleware import request_id import webob.dec import webob.exc from tacker import context -from tacker.openstack.common.middleware import request_id from tacker import wsgi LOG = logging.getLogger(__name__) diff --git a/tacker/openstack/common/middleware/__init__.py b/tacker/openstack/common/middleware/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tacker/openstack/common/middleware/audit.py b/tacker/openstack/common/middleware/audit.py deleted file mode 100644 index c7f4c0e76..000000000 --- a/tacker/openstack/common/middleware/audit.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (c) 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -""" -Attach open standard audit information to request.environ - -AuditMiddleware filter should be place after Keystone's auth_token middleware -in the pipeline so that it can utilise the information Keystone provides. - -""" -from pycadf.audit import api as cadf_api - -from tacker.openstack.common.middleware import notifier - - -class AuditMiddleware(notifier.RequestNotifier): - - def __init__(self, app, **conf): - super(AuditMiddleware, self).__init__(app, **conf) - self.cadf_audit = cadf_api.OpenStackAuditApi() - - @notifier.log_and_ignore_error - def process_request(self, request): - self.cadf_audit.append_audit_event(request) - super(AuditMiddleware, self).process_request(request) - - @notifier.log_and_ignore_error - def process_response(self, request, response, - exception=None, traceback=None): - self.cadf_audit.mod_audit_event(request, response) - super(AuditMiddleware, self).process_response(request, response, - exception, traceback) diff --git a/tacker/openstack/common/middleware/base.py b/tacker/openstack/common/middleware/base.py deleted file mode 100644 index 464a1ccd7..000000000 --- a/tacker/openstack/common/middleware/base.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2011 OpenStack Foundation. -# All Rights Reserved. -# -# 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. - -"""Base class(es) for WSGI Middleware.""" - -import webob.dec - - -class Middleware(object): - """Base WSGI middleware wrapper. - - These classes require an application to be initialized that will be called - next. By default the middleware will simply call its wrapped app, or you - can override __call__ to customize its behavior. - """ - - @classmethod - def factory(cls, global_conf, **local_conf): - """Factory method for paste.deploy.""" - return cls - - def __init__(self, application): - self.application = application - - def process_request(self, req): - """Called on each request. - - If this returns None, the next application down the stack will be - executed. If it returns a response then that response will be returned - and execution will stop here. - """ - return None - - def process_response(self, response): - """Do whatever you'd like to the response.""" - return response - - @webob.dec.wsgify - def __call__(self, req): - response = self.process_request(req) - if response: - return response - response = req.get_response(self.application) - return self.process_response(response) diff --git a/tacker/openstack/common/middleware/catch_errors.py b/tacker/openstack/common/middleware/catch_errors.py deleted file mode 100644 index 29e439007..000000000 --- a/tacker/openstack/common/middleware/catch_errors.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2013 NEC Corporation -# All Rights Reserved. -# -# 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. - -"""Middleware that provides high-level error handling. - -It catches all exceptions from subsequent applications in WSGI pipeline -to hide internal errors from API response. -""" - -from oslo_log import log as logging -import webob.dec -import webob.exc - -from tacker.openstack.common.gettextutils import _ # noqa -from tacker.openstack.common.middleware import base - - -LOG = logging.getLogger(__name__) - - -class CatchErrorsMiddleware(base.Middleware): - - @webob.dec.wsgify - def __call__(self, req): - try: - response = req.get_response(self.application) - except Exception: - LOG.exception(_('An error occurred during ' - 'processing the request: %s')) - response = webob.exc.HTTPInternalServerError() - return response diff --git a/tacker/openstack/common/middleware/correlation_id.py b/tacker/openstack/common/middleware/correlation_id.py deleted file mode 100644 index c91fc058f..000000000 --- a/tacker/openstack/common/middleware/correlation_id.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) 2013 Rackspace Hosting -# All Rights Reserved. -# -# 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. - -"""Middleware that attaches a correlation id to WSGI request""" - -import uuid - -from tacker.openstack.common.middleware import base - - -class CorrelationIdMiddleware(base.Middleware): - - def process_request(self, req): - correlation_id = (req.headers.get("X_CORRELATION_ID") or - str(uuid.uuid4())) - req.headers['X_CORRELATION_ID'] = correlation_id diff --git a/tacker/openstack/common/middleware/debug.py b/tacker/openstack/common/middleware/debug.py deleted file mode 100644 index cb7266940..000000000 --- a/tacker/openstack/common/middleware/debug.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2011 OpenStack Foundation. -# All Rights Reserved. -# -# 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. - -"""Debug middleware""" - -from __future__ import print_function - -import sys - -import six -import webob.dec - -from tacker.openstack.common.middleware import base - - -class Debug(base.Middleware): - """Helper class that returns debug information. - - Can be inserted into any WSGI application chain to get information about - the request and response. - """ - - @webob.dec.wsgify - def __call__(self, req): - print(("*" * 40) + " REQUEST ENVIRON") - for key, value in req.environ.items(): - print(key, "=", value) - print() - resp = req.get_response(self.application) - - print(("*" * 40) + " RESPONSE HEADERS") - for (key, value) in six.iteritems(resp.headers): - print(key, "=", value) - print() - - resp.app_iter = self.print_generator(resp.app_iter) - - return resp - - @staticmethod - def print_generator(app_iter): - """Prints the contents of a wrapper string iterator when iterated.""" - print(("*" * 40) + " BODY") - for part in app_iter: - sys.stdout.write(part) - sys.stdout.flush() - yield part - print() diff --git a/tacker/openstack/common/middleware/notifier.py b/tacker/openstack/common/middleware/notifier.py deleted file mode 100644 index 7fa341fc3..000000000 --- a/tacker/openstack/common/middleware/notifier.py +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright (c) 2013 eNovance -# -# 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. - -""" -Send notifications on request - -""" -import os.path -import sys -import traceback as tb - -from oslo_log import log as logging -import six -import webob.dec - -from tacker.openstack.common import context -from tacker.openstack.common.gettextutils import _LE -from tacker.openstack.common.middleware import base -from tacker.openstack.common.notifier import api - -LOG = logging.getLogger(__name__) - - -def log_and_ignore_error(fn): - def wrapped(*args, **kwargs): - try: - return fn(*args, **kwargs) - except Exception as e: - LOG.exception(_LE('An exception occurred processing ' - 'the API call: %s '), e) - return wrapped - - -class RequestNotifier(base.Middleware): - """Send notification on request.""" - - @classmethod - def factory(cls, global_conf, **local_conf): - """Factory method for paste.deploy.""" - conf = global_conf.copy() - conf.update(local_conf) - - def _factory(app): - return cls(app, **conf) - return _factory - - def __init__(self, app, **conf): - self.service_name = conf.get('service_name') - self.ignore_req_list = [x.upper().strip() for x in - conf.get('ignore_req_list', '').split(',')] - super(RequestNotifier, self).__init__(app) - - @staticmethod - def environ_to_dict(environ): - """Following PEP 333, server variables are lower case, so don't - include them. - - """ - return dict((k, v) for k, v in six.iteritems(environ) - if k.isupper() and k != 'HTTP_X_AUTH_TOKEN') - - @log_and_ignore_error - def process_request(self, request): - request.environ['HTTP_X_SERVICE_NAME'] = \ - self.service_name or request.host - payload = { - 'request': self.environ_to_dict(request.environ), - } - - api.notify(context.get_admin_context(), - api.publisher_id(os.path.basename(sys.argv[0])), - 'http.request', - api.INFO, - payload) - - @log_and_ignore_error - def process_response(self, request, response, - exception=None, traceback=None): - payload = { - 'request': self.environ_to_dict(request.environ), - } - - if response: - payload['response'] = { - 'status': response.status, - 'headers': response.headers, - } - - if exception: - payload['exception'] = { - 'value': repr(exception), - 'traceback': tb.format_tb(traceback) - } - - api.notify(context.get_admin_context(), - api.publisher_id(os.path.basename(sys.argv[0])), - 'http.response', - api.INFO, - payload) - - @webob.dec.wsgify - def __call__(self, req): - if req.method in self.ignore_req_list: - return req.get_response(self.application) - else: - self.process_request(req) - try: - response = req.get_response(self.application) - except Exception: - exc_type, value, traceback = sys.exc_info() - self.process_response(req, None, value, traceback) - raise - else: - self.process_response(req, response) - return response diff --git a/tacker/openstack/common/middleware/request_id.py b/tacker/openstack/common/middleware/request_id.py deleted file mode 100644 index 180522d56..000000000 --- a/tacker/openstack/common/middleware/request_id.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (c) 2013 NEC Corporation -# All Rights Reserved. -# -# 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. - -"""Middleware that ensures request ID. - -It ensures to assign request ID for each API request and set it to -request environment. The request ID is also added to API response. -""" - -import webob.dec - -from tacker.openstack.common import context -from tacker.openstack.common.middleware import base - - -ENV_REQUEST_ID = 'openstack.request_id' -HTTP_RESP_HEADER_REQUEST_ID = 'x-openstack-request-id' - - -class RequestIdMiddleware(base.Middleware): - - @webob.dec.wsgify - def __call__(self, req): - req_id = context.generate_request_id() - req.environ[ENV_REQUEST_ID] = req_id - response = req.get_response(self.application) - if HTTP_RESP_HEADER_REQUEST_ID not in response.headers: - response.headers.add(HTTP_RESP_HEADER_REQUEST_ID, req_id) - return response diff --git a/tacker/openstack/common/middleware/sizelimit.py b/tacker/openstack/common/middleware/sizelimit.py deleted file mode 100644 index 487d247f9..000000000 --- a/tacker/openstack/common/middleware/sizelimit.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright (c) 2012 Red Hat, Inc. -# -# 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. - -""" -Request Body limiting middleware. - -""" - -from oslo_config import cfg -import webob.dec -import webob.exc - -from tacker.openstack.common.gettextutils import _ -from tacker.openstack.common.middleware import base - - -#default request size is 112k -max_req_body_size = cfg.IntOpt('max_request_body_size', - deprecated_name='osapi_max_request_body_size', - default=114688, - help='the maximum body size ' - 'per each request(bytes)') - -CONF = cfg.CONF -CONF.register_opt(max_req_body_size) - - -class LimitingReader(object): - """Reader to limit the size of an incoming request.""" - def __init__(self, data, limit): - """Initiates LimitingReader object. - - :param data: Underlying data object - :param limit: maximum number of bytes the reader should allow - """ - self.data = data - self.limit = limit - self.bytes_read = 0 - - def __iter__(self): - for chunk in self.data: - self.bytes_read += len(chunk) - if self.bytes_read > self.limit: - msg = _("Request is too large.") - raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg) - else: - yield chunk - - def read(self, i=None): - result = self.data.read(i) - self.bytes_read += len(result) - if self.bytes_read > self.limit: - msg = _("Request is too large.") - raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg) - return result - - -class RequestBodySizeLimiter(base.Middleware): - """Limit the size of incoming requests.""" - - @webob.dec.wsgify - def __call__(self, req): - if req.content_length > CONF.max_request_body_size: - msg = _("Request is too large.") - raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg) - if req.content_length is None and req.is_body_readable: - limiter = LimitingReader(req.body_file, - CONF.max_request_body_size) - req.body_file = limiter - return self.application diff --git a/tacker/tests/unit/test_auth.py b/tacker/tests/unit/test_auth.py index 15e7b2517..2f278e513 100644 --- a/tacker/tests/unit/test_auth.py +++ b/tacker/tests/unit/test_auth.py @@ -13,10 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +from oslo_middleware import request_id import webob from tacker import auth -from tacker.openstack.common.middleware import request_id from tacker.tests import base