Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove MaintenanceModeMiddleware #1767

Merged
merged 2 commits into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
"etna.core.middleware.MaintenanceModeMiddleware",
"wagtail.contrib.redirects.middleware.RedirectMiddleware",
"etna.core.middleware.InterpretCookiesMiddleware",
]
Expand Down Expand Up @@ -420,16 +419,6 @@
os.getenv("CACHE_CONTROL_STALE_WHILE_REVALIDATE", 30)
)

# -----------------------------------------------------------------------------
# Maintenance mode
# -----------------------------------------------------------------------------

MAINTENANCE_MODE = strtobool(os.getenv("MAINTENANCE_MODE", "False"))
# MAINTENENCE_MODE_ALLOW_IPS="IPA1,IPA2" where IPA is IP address
MAINTENENCE_MODE_ALLOW_IPS = os.getenv("MAINTENENCE_MODE_ALLOW_IPS", "").split(",")
# datetime is iso MAINTENENCE_MODE_ENDS = "2011-11-04T00:05:23+04:00"
MAINTENENCE_MODE_ENDS = os.getenv("MAINTENENCE_MODE_ENDS", "")

# -----------------------------------------------------------------------------
# Feature flags
# -----------------------------------------------------------------------------
Expand Down
44 changes: 1 addition & 43 deletions etna/core/middleware.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import json
import logging

from datetime import datetime
from urllib.parse import unquote

from django.conf import settings
from django.http import HttpRequest
from django.template.response import SimpleTemplateResponse, TemplateResponse

from pytz import timezone
from django.template.response import TemplateResponse

logger = logging.getLogger(__name__)

Expand All @@ -25,45 +22,6 @@ def get_client_ip(request) -> str:
return ip


class MaintenanceModeMiddleware:
def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
"""
Renders for a 503 if MAINTENANCE_MODE is set.
Maintenance mode should be bypassed when the user's public IP address is present in MAINTENENCE_MODE_ALLOW_IPS
"""
if settings.MAINTENANCE_MODE:
# check override maintenance mode
if get_client_ip(request) not in settings.MAINTENENCE_MODE_ALLOW_IPS:
kwargs = {"template": "503.html", "status": 503}
if maintenance_mode_ends := settings.MAINTENENCE_MODE_ENDS:
# Evaluate only if config is set
try:
end_datetime = datetime.fromisoformat(maintenance_mode_ends)
except ValueError:
end_datetime = None
logger.debug(
f"settings.MAINTENENCE_MODE_ENDS={maintenance_mode_ends} is not iso format to add to Retry-After header."
)

if end_datetime:
# GMT is assumed for naive datetimes, but timezone-aware
# datetimes must be converted to GMT
if end_datetime.utcoffset() is not None:
end_datetime = end_datetime.astimezone(timezone("GMT"))

kwargs["headers"] = {
"Retry-After": end_datetime.strftime(HTTP_HEADER_FORMAT)
}
return SimpleTemplateResponse(**kwargs).render()

response = self.get_response(request)

return response


class InterpretCookiesMiddleware:
exclude_paths = (
"/admin/",
Expand Down
47 changes: 1 addition & 46 deletions etna/core/tests/test_middleware.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,10 @@
from unittest.mock import patch
from urllib.parse import quote

from django.http import HttpRequest
from django.template.response import TemplateResponse
from django.test import SimpleTestCase, TestCase, override_settings
from django.test import SimpleTestCase, override_settings

from etna.core.middleware import InterpretCookiesMiddleware
from etna.core.test_utils import prevent_request_warnings


@override_settings(MAINTENANCE_MODE=True)
class TestMaintenanceMode(TestCase):
@prevent_request_warnings
def test_without_maintenance_mode_ends(self):
response = self.client.get("/")
self.assertEqual(response.status_code, 503)
self.assertNotIn("Retry-After", response.headers)

@prevent_request_warnings
@override_settings(MAINTENENCE_MODE_ENDS="2011-11-04T00:05:23+04:00")
def test_maintenance_mode_ends_with_timezone_info(self):
response = self.client.get("/")
self.assertEqual(response.status_code, 503)
self.assertEqual(
response.headers["Retry-After"], "Thu, 03 Nov 2011 20:05:23 GMT"
)

@prevent_request_warnings
@override_settings(MAINTENENCE_MODE_ENDS="2011-11-04T00:05:23")
def test_maintenance_mode_ends_without_timezone_info(self):
response = self.client.get("/")
self.assertEqual(response.status_code, 503)
self.assertEqual(
response.headers["Retry-After"], "Fri, 04 Nov 2011 00:05:23 GMT"
)

@override_settings(MAINTENENCE_MODE_ALLOW_IPS=["123.4.5.6"])
@patch("etna.core.middleware.get_client_ip", return_value="123.4.5.6")
def test_maintenance_mode_bypassed_when_ip_in_allow_list(self, *args):
response = self.client.get("/")

self.assertEqual(response.status_code, 200)

@prevent_request_warnings
@override_settings(MAINTENENCE_MODE_ALLOW_IPS=["123.4.5.6"])
@patch("etna.core.middleware.get_client_ip", return_value="789.0.1.2")
def test_maintenance_mode_enforced_when_ip_not_in_allowed_list(
self, mock_get_client_ip
):
response = self.client.get("/")
self.assertEqual(response.status_code, 503)


class TestInterpretCookiesMiddleware(SimpleTestCase):
Expand Down
Loading