Status api view
This commit is contained in:
parent
23ceb2a5ec
commit
e482aa4e92
@ -59,7 +59,8 @@ ARG GS_VERSION=10.02.1
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
# Ignore warning from Whitenoise
|
||||
PYTHONWARNINGS="ignore:::django.http.response:517"
|
||||
PYTHONWARNINGS="ignore:::django.http.response:517" \
|
||||
PNGX_CONTAINERIZED=1
|
||||
|
||||
#
|
||||
# Begin installation and configuration
|
||||
|
34
src/documents/tests/test_api_status.py
Normal file
34
src/documents/tests/test_api_status.py
Normal file
@ -0,0 +1,34 @@
|
||||
from django.contrib.auth.models import User
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from paperless import version
|
||||
|
||||
|
||||
class TestSystemStatusView(APITestCase):
|
||||
ENDPOINT = "/api/status/"
|
||||
|
||||
def test_system_status_insufficient_permissions(self):
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
def test_system_status(self):
|
||||
user = User.objects.create_superuser(
|
||||
username="temp_admin",
|
||||
)
|
||||
self.client.force_login(user)
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["pngx_version"], version.__full_version_str__)
|
||||
self.assertIsNotNone(response.data["server_os"])
|
||||
self.assertEqual(response.data["install_type"], "bare-metal")
|
||||
self.assertIsNotNone(response.data["storage"]["total"])
|
||||
self.assertIsNotNone(response.data["storage"]["available"])
|
||||
self.assertEqual(response.data["database"]["type"], "sqlite")
|
||||
self.assertIsNotNone(response.data["database"]["url"])
|
||||
self.assertEqual(response.data["database"]["status"], "OK")
|
||||
self.assertIsNone(response.data["database"]["error"])
|
||||
self.assertIsNotNone(response.data["database"]["migration_status"])
|
||||
self.assertEqual(response.data["redis"]["url"], "redis://localhost:6379")
|
||||
self.assertEqual(response.data["redis"]["status"], "ERROR")
|
||||
self.assertIsNotNone(response.data["redis"]["error"])
|
@ -2,6 +2,7 @@ import itertools
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import tempfile
|
||||
import urllib
|
||||
@ -15,6 +16,9 @@ from urllib.parse import quote
|
||||
import pathvalidate
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import connections
|
||||
from django.db.migrations.loader import MigrationLoader
|
||||
from django.db.migrations.recorder import MigrationRecorder
|
||||
from django.db.models import Case
|
||||
from django.db.models import Count
|
||||
from django.db.models import IntegerField
|
||||
@ -40,6 +44,7 @@ from django.views.generic import TemplateView
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from langdetect import detect
|
||||
from packaging import version as packaging_version
|
||||
from redis import Redis
|
||||
from rest_framework import parsers
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.exceptions import NotFound
|
||||
@ -1539,3 +1544,74 @@ class CustomFieldViewSet(ModelViewSet):
|
||||
model = CustomField
|
||||
|
||||
queryset = CustomField.objects.all().order_by("-created")
|
||||
|
||||
|
||||
class SystemStatusView(GenericAPIView, PassUserMixin):
|
||||
permission_classes = (IsAuthenticated,)
|
||||
|
||||
def get(self, request, format=None):
|
||||
if not request.user.has_perm("admin.view_logentry"):
|
||||
return HttpResponseForbidden("Insufficient permissions")
|
||||
|
||||
current_version = version.__full_version_str__
|
||||
|
||||
media_stats = os.statvfs(settings.MEDIA_ROOT)
|
||||
|
||||
db_conn = connections["default"]
|
||||
db_url = db_conn.settings_dict["NAME"]
|
||||
loader = MigrationLoader(connection=db_conn)
|
||||
all_migrations = [f"{app}.{name}" for app, name in loader.graph.nodes]
|
||||
applied_migrations = [
|
||||
f"{m.app}.{m.name}"
|
||||
for m in MigrationRecorder.Migration.objects.all().order_by("id")
|
||||
]
|
||||
db_error = None
|
||||
try:
|
||||
db_conn.cursor()
|
||||
db_status = "OK"
|
||||
except Exception as e:
|
||||
db_status = "ERROR"
|
||||
db_error = str(e)
|
||||
|
||||
redis_url = settings._CELERY_REDIS_URL
|
||||
redis_error = None
|
||||
with Redis.from_url(url=redis_url) as client:
|
||||
try:
|
||||
client.ping()
|
||||
redis_status = "OK"
|
||||
except Exception as e:
|
||||
redis_status = "ERROR"
|
||||
redis_error = str(e)
|
||||
|
||||
return Response(
|
||||
{
|
||||
"pngx_version": current_version,
|
||||
"server_os": platform.platform(),
|
||||
"install_type": (
|
||||
"containerized"
|
||||
if os.environ.get("PNGX_CONTAINERIZED") == "1"
|
||||
else "bare-metal"
|
||||
),
|
||||
"storage": {
|
||||
"total": media_stats.f_frsize * media_stats.f_blocks,
|
||||
"available": media_stats.f_frsize * media_stats.f_bavail,
|
||||
},
|
||||
"database": {
|
||||
"type": db_conn.vendor,
|
||||
"url": db_url,
|
||||
"status": db_status,
|
||||
"error": db_error,
|
||||
"migration_status": {
|
||||
"latest_migration": applied_migrations[-1],
|
||||
"unapplied_migrations": [
|
||||
m for m in all_migrations if m not in applied_migrations
|
||||
],
|
||||
},
|
||||
},
|
||||
"redis": {
|
||||
"url": redis_url,
|
||||
"status": redis_status,
|
||||
"error": redis_error,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
@ -32,6 +32,7 @@ from documents.views import SharedLinkView
|
||||
from documents.views import ShareLinkViewSet
|
||||
from documents.views import StatisticsView
|
||||
from documents.views import StoragePathViewSet
|
||||
from documents.views import SystemStatusView
|
||||
from documents.views import TagViewSet
|
||||
from documents.views import TasksViewSet
|
||||
from documents.views import UiSettingsView
|
||||
@ -147,6 +148,11 @@ urlpatterns = [
|
||||
ProfileView.as_view(),
|
||||
name="profile_view",
|
||||
),
|
||||
re_path(
|
||||
"^status/",
|
||||
SystemStatusView.as_view(),
|
||||
name="system_status",
|
||||
),
|
||||
*api_router.urls,
|
||||
],
|
||||
),
|
||||
|
Loading…
x
Reference in New Issue
Block a user