Repository: cisagov/manage.get.gov

Issue:
Investigate Health check restarting sandboxes 
### Issue Description

We noticed a few times in both staging and stable environments that the sandboxes appeared to restart even when no one was on them. We weren't able to track down useful information in logs to help assist besides a reference to a health check being performed. Then when EPP connection was added, we saw this same restarting happening often, in fact just trying to set nameservers alone could result in multiple resets. However, this was very sporadic and  without a disernable pattern besides "when epp calls are happening". It was determined that the system was failing the health check which does result in a restart. The solution was to increase the timeout on the health check, but that seems like a patch to the problem.

AC:

- [ ] investigate the health check that is currently happening and investigate if this could be resulting by some piece of our architecture (such as a port that is being used and is blocking the health check request)
- [ ] make follow on tickets as needed or document findings here before closing ticket

### Additional Context (optional)

Cloudfoundry has a customer support slack that should be used to get more info on the healthcheck.

To force the health check to occur with some frequency, lower the healthcheck timeout to 1 second.

### Issue Links

May be partially mitigated by #1151 


Discussion:
Hey @PaulKuykendall I meant in prod huddle today to keep it in 36 but it could be a next. Happy if we want to move this to 37 to better denote that, but definitely warrants not being in backlog

Resolving patch:
diff --git a/src/djangooidc/views.py b/src/djangooidc/views.py
--- a/src/djangooidc/views.py
+++ b/src/djangooidc/views.py
@@ -55,7 +55,6 @@ def error_page(request, error):
 
 def openid(request):
     """Redirect the user to an authentication provider (OP)."""
-
     # If the session reset because of a server restart, attempt to login again
     request.session["acr_value"] = CLIENT.get_default_acr_value()
 
diff --git a/src/registrar/config/urls.py b/src/registrar/config/urls.py
--- a/src/registrar/config/urls.py
+++ b/src/registrar/config/urls.py
@@ -74,7 +74,7 @@
         views.ApplicationWithdrawn.as_view(),
         name="application-withdrawn",
     ),
-    path("health/", views.health),
+    path("health", views.health, name="health"),
     path("openid/", include("djangooidc.urls")),
     path("request/", include((application_urls, APPLICATION_NAMESPACE))),
     path("api/v1/available/", available, name="available"),


Test patch:
diff --git a/src/registrar/tests/test_url_auth.py b/src/registrar/tests/test_url_auth.py
--- a/src/registrar/tests/test_url_auth.py
+++ b/src/registrar/tests/test_url_auth.py
@@ -114,6 +114,13 @@ class TestURLAuth(TestCase):
         "/api/v1/available/",
         "/api/v1/get-report/current-federal",
         "/api/v1/get-report/current-full",
+        "/health",
+    ]
+
+    # We will test that the following URLs are not protected by auth
+    # and that the url returns a 200 response
+    NO_AUTH_URLS = [
+        "/health",
     ]
 
     def assertURLIsProtectedByAuth(self, url):
@@ -147,9 +154,33 @@ def assertURLIsProtectedByAuth(self, url):
                 f"GET {url} returned HTTP {code}, but should redirect to login or deny access",
             )
 
+    def assertURLIsNotProtectedByAuth(self, url):
+        """
+        Make a GET request to the given URL, and ensure that it returns 200.
+        """
+
+        try:
+            with less_console_noise():
+                response = self.client.get(url)
+        except Exception as e:
+            # It'll be helpful to provide information on what URL was being
+            # accessed at the time the exception occurred.  Python 3 will
+            # also include a full traceback of the original exception, so
+            # we don't need to worry about hiding the original cause.
+            raise AssertionError(f'Accessing {url} raised "{e}"', e)
+
+        code = response.status_code
+        if code != 200:
+            raise AssertionError(
+                f"GET {url} returned HTTP {code}, but should return 200 OK",
+            )
+
     def test_login_required_all_urls(self):
         """All URLs redirect to the login view."""
         for viewname, url in iter_sample_urls(registrar.config.urls):
             if url not in self.IGNORE_URLS:
                 with self.subTest(viewname=viewname):
                     self.assertURLIsProtectedByAuth(url)
+            elif url in self.NO_AUTH_URLS:
+                with self.subTest(viewname=viewname):
+                    self.assertURLIsNotProtectedByAuth(url)
diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py
--- a/src/registrar/tests/test_views.py
+++ b/src/registrar/tests/test_views.py
@@ -23,7 +23,7 @@ def setUp(self):
         self.client = Client()
 
     def test_health_check_endpoint(self):
-        response = self.client.get("/health/")
+        response = self.client.get("/health")
         self.assertContains(response, "OK", status_code=200)
 
     def test_home_page(self):