Commit 37eb3a61 authored by Tanner Prestegard's avatar Tanner Prestegard Committed by GraceDB

Add maintenance mode functionality

parent 21d51acf
......@@ -21,6 +21,10 @@ def get_from_env(envvar, default_value=None, fail_if_not_found=True):
'Could not get environment variable {0}'.format(envvar))
return value
# Maintenance mode
MAINTENANCE_MODE = False
MAINTENANCE_MODE_MESSAGE = None
# Version ---------------------------------------------------------------------
PROJECT_VERSION = '2.6.3'
......@@ -307,6 +311,7 @@ AUTHENTICATION_BACKENDS = [
# List of middleware classes to use.
MIDDLEWARE = [
'core.middleware.maintenance.MaintenanceModeMiddleware',
'events.middleware.PerformanceMiddleware',
'core.middleware.accept.AcceptMiddleware',
'core.middleware.api.ClientVersionMiddleware',
......
......@@ -61,6 +61,18 @@ TWILIO_AUTH_TOKEN = os.environ.get('DJANGO_TWILIO_AUTH_TOKEN', None)
if TWILIO_AUTH_TOKEN is None:
raise ImproperlyConfigured('Could not get Twilio auth token from envvars.')
# Get maintenance mode settings from environment
maintenance_mode = get_from_env(
'DJANGO_MAINTENANCE_MODE_ACTIVE',
default_value=False,
fail_if_not_found=False
)
if (isinstance(maintenance_mode, str) and
maintenance_mode.lower() in ['true', 't', '1']):
MAINTENANCE_MODE = True
MAINTENANCE_MODE_MESSAGE = \
get_from_env('DJANGO_MAINTENANCE_MODE_MESSAGE', fail_if_not_found=False)
# Get email settings from environment
EMAIL_BACKEND = 'django_ses.SESBackend'
AWS_SES_ACCESS_KEY_ID = get_from_env('AWS_SES_ACCESS_KEY_ID')
......
from functools import wraps
def ignore_maintenance_mode(view):
@wraps(view)
def inner(request, *args, **kwargs):
return view(request, *args, **kwargs)
inner.__dict__['ignore_maintenance_mode'] = True
return inner
from django.conf import settings
from django.http import HttpResponse
from django.shortcuts import render
from django.urls import resolve
import logging
# Set up logger
logger = logging.getLogger(__name__)
class MaintenanceModeMiddleware(object):
accept_header_name = 'HTTP_ACCEPT'
default_message = 'The site is temporarily down for maintenance.'
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# Process request -----------------------------------------------------
if settings.MAINTENANCE_MODE is True:
# Check if the view specifies to ignore maintenance mode
ignore_maintenance = \
self.check_for_ignore_maintenance_mode(request)
if not ignore_maintenance:
# Get message to display
maintenance_message = self.get_message()
accept_header = request.META.get(self.accept_header_name, None)
if accept_header and 'text/html' in accept_header:
# Attempt to handle browsers
context = {'message': maintenance_message}
return render(request, 'maintenance.html', context=context,
status=503)
else:
# Anything else (likely client API requests)
return HttpResponse(maintenance_message, status=503)
# Otherwise, get response and return with no further processing -------
response = self.get_response(request)
return response
@staticmethod
def check_for_ignore_maintenance_mode(request):
resolver_match = resolve(request.path)
view_func = resolver_match.func
return view_func.__dict__.get('ignore_maintenance_mode', False)
def get_message(self):
message = settings.MAINTENANCE_MODE_MESSAGE
if message is None:
message = self.default_message
return message
{% extends "base.html" %}
{% block title %}Maintenance{% endblock %}
{% block heading %}{% endblock %}
{% block headcontents %}
{{ block.super }}
<style>
.maintenance-message {
background-color: red;
color: white;
text-align: center;
display: inline-block;
border-radius: 5px;
padding: 10px;
min-width: 400px;
max-width: 600px;
box-shadow: 0 0 20px rgba(0,0,0,.2);
}
.maintenance-message p {
font-weight: bold;
font-size: 2rem;
margin: 0;
}
</style>
{% endblock %}
{% block content %}
<div align="center" style="padding: 30px;">
<div class="maintenance-message">
<p>{{ message | safe }}</p>
</div>
</div>
{% endblock %}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment