diff --git a/awx/main/middleware.py b/awx/main/middleware.py index 94ba7b4c08..8ae8d444e1 100644 --- a/awx/main/middleware.py +++ b/awx/main/middleware.py @@ -20,6 +20,7 @@ from django.shortcuts import get_object_or_404, redirect from django.apps import apps from django.utils.translation import ugettext_lazy as _ from django.core.urlresolvers import reverse +from django.urls import resolve from awx.main.models import ActivityStream from awx.main.utils.named_url_graph import generate_graph, GraphNode @@ -193,5 +194,6 @@ class MigrationRanCheckMiddleware(object): def process_request(self, request): executor = MigrationExecutor(connection) plan = executor.migration_plan(executor.loader.graph.leaf_nodes()) - if bool(plan) and 'migrations_notran' not in request.path: + if bool(plan) and \ + getattr(resolve(request.path), 'url_name', '') != 'migrations_notran': return redirect(reverse("ui:migrations_notran")) diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index b53f96f00b..709c3a20dd 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -239,6 +239,7 @@ TEMPLATES = [ ] MIDDLEWARE_CLASSES = ( # NOQA + 'awx.main.middleware.MigrationRanCheckMiddleware', 'awx.main.middleware.TimingMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', diff --git a/awx/settings/production.py b/awx/settings/production.py index 9df01dd720..d1d5baa3ad 100644 --- a/awx/settings/production.py +++ b/awx/settings/production.py @@ -89,8 +89,6 @@ settings_files = os.path.join(settings_dir, '*.py') settings_file = os.environ.get('AWX_SETTINGS_FILE', '/etc/tower/settings.py') -MIDDLEWARE_CLASSES = ('awx.main.middleware.MigrationRanCheckMiddleware',) + MIDDLEWARE_CLASSES - # Attempt to load settings from /etc/tower/settings.py first, followed by # /etc/tower/conf.d/*.py. try: diff --git a/awx/wsgi.py b/awx/wsgi.py index 4b2666a409..6033d6d54e 100644 --- a/awx/wsgi.py +++ b/awx/wsgi.py @@ -8,7 +8,12 @@ from awx import __version__ as tower_version from awx import prepare_env, MODE prepare_env() -from django.core.wsgi import get_wsgi_application # NOQA + +from django.core.wsgi import WSGIHandler # NOQA +import django # NOQA +from django.conf import settings # NOQA +from django.urls import resolve # NOQA + """ WSGI config for AWX project. @@ -29,5 +34,37 @@ if MODE == 'production': logger.error("Missing or incorrect metadata for Tower version. Ensure Tower was installed using the setup playbook.") raise Exception("Missing or incorrect metadata for Tower version. Ensure Tower was installed using the setup playbook.") + +if django.__version__ != '1.11.7': + raise RuntimeError("Django version other than 1.11.7 detected {}. \ + Inherit from WSGIHandler to support short-circuit Django Middelware. \ + This is known to work for Django 1.11.7 and may not work with other, \ + even minor, versions.".format(django.__version__)) + + +if settings.MIDDLEWARE: + raise RuntimeError("MIDDLEWARE setting detected. \ + The 'migration in progress' view feature short-circuits OLD Django \ + MIDDLEWARE_CLASSES behavior. With the new Django MIDDLEWARE beahvior \ + it's possible to short-ciruit the middleware onion through supported \ + middleware mechanisms. Further, from django.core.wsgi.get_wsgi_application() \ + should be called to get an instance of WSGIHandler().") + + +class AWXWSGIHandler(WSGIHandler): + def _legacy_get_response(self, request): + # short-circuit middleware + if getattr(resolve(request.path), 'url_name', '') == 'migrations_notran': + return self._get_response(request) + # fall through to middle-ware + else: + return super(AWXWSGIHandler, self)._legacy_get_response(request) + + # Return the default Django WSGI application. +def get_wsgi_application(): + django.setup(set_prefix=False) + return AWXWSGIHandler() + + application = get_wsgi_application()