api: add System info API

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-05-30 13:56:43 +02:00
parent 11607622a3
commit 0e8d9aa45d
4 changed files with 162 additions and 0 deletions

View File

@ -0,0 +1,90 @@
"""authentik administration overview"""
import os
import platform
from datetime import datetime
from sys import version as python_version
from typing import TypedDict
from django.utils.timezone import now
from drf_spectacular.utils import extend_schema
from gunicorn import version_info as gunicorn_version
from rest_framework.fields import SerializerMethodField
from rest_framework.permissions import IsAdminUser
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView
from authentik.core.api.utils import PassiveSerializer
class RuntimeDict(TypedDict):
"""Runtime information"""
python_version: str
gunicorn_version: str
environment: str
architecture: str
platform: str
uname: str
class SystemSerializer(PassiveSerializer):
"""Get system information."""
http_headers = SerializerMethodField()
http_host = SerializerMethodField()
http_is_secure = SerializerMethodField()
runtime = SerializerMethodField()
tenant = SerializerMethodField()
server_time = SerializerMethodField()
def get_http_headers(self, request: Request) -> dict[str, str]:
"""Get HTTP Request headers"""
headers = {}
for key, value in request.META.items():
if not isinstance(value, str):
continue
headers[key] = value
return headers
def get_http_host(self, request: Request) -> str:
"""Get HTTP host"""
return request._request.get_host()
def get_http_is_secure(self, request: Request) -> bool:
"""Get HTTP Secure flag"""
return request._request.is_secure()
def get_runtime(self, request: Request) -> RuntimeDict:
"""Get versions"""
return {
"python_version": python_version,
"gunicorn_version": ".".join(str(x) for x in gunicorn_version),
"environment": "kubernetes"
if "KUBERNETES_PORT" in os.environ
else "compose",
"architecture": platform.machine(),
"platform": platform.platform(),
"uname": " ".join(platform.uname()),
}
def get_tenant(self, request: Request) -> str:
"""Currently active tenant"""
return str(request._request.tenant)
def get_server_time(self, request: Request) -> datetime:
"""Current server time"""
return now()
class SystemView(APIView):
"""Get system information."""
permission_classes = [IsAdminUser]
pagination_class = None
filter_backends = []
@extend_schema(responses={200: SystemSerializer(many=False)})
def get(self, request: Request) -> Response:
"""Get system information."""
return Response(SystemSerializer(request).data)

View File

@ -95,3 +95,8 @@ class TestAdminAPI(TestCase):
"""Test apps API""" """Test apps API"""
response = self.client.get(reverse("authentik_api:apps-list")) response = self.client.get(reverse("authentik_api:apps-list"))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_system(self):
"""Test system API"""
response = self.client.get(reverse("authentik_api:admin_system"))
self.assertEqual(response.status_code, 200)

View File

@ -5,6 +5,7 @@ from rest_framework import routers
from authentik.admin.api.meta import AppsViewSet from authentik.admin.api.meta import AppsViewSet
from authentik.admin.api.metrics import AdministrationMetricsViewSet from authentik.admin.api.metrics import AdministrationMetricsViewSet
from authentik.admin.api.system import SystemView
from authentik.admin.api.tasks import TaskViewSet from authentik.admin.api.tasks import TaskViewSet
from authentik.admin.api.version import VersionView from authentik.admin.api.version import VersionView
from authentik.admin.api.workers import WorkerView from authentik.admin.api.workers import WorkerView
@ -225,6 +226,7 @@ urlpatterns = (
), ),
path("admin/version/", VersionView.as_view(), name="admin_version"), path("admin/version/", VersionView.as_view(), name="admin_version"),
path("admin/workers/", WorkerView.as_view(), name="admin_workers"), path("admin/workers/", WorkerView.as_view(), name="admin_workers"),
path("admin/system/", SystemView.as_view(), name="admin_system"),
path("root/config/", ConfigView.as_view(), name="config"), path("root/config/", ConfigView.as_view(), name="config"),
path( path(
"flows/executor/<slug:flow_slug>/", "flows/executor/<slug:flow_slug>/",

View File

@ -51,6 +51,26 @@ paths:
$ref: '#/components/schemas/ValidationError' $ref: '#/components/schemas/ValidationError'
'403': '403':
$ref: '#/components/schemas/GenericError' $ref: '#/components/schemas/GenericError'
/api/v2beta/admin/system/:
get:
operationId: admin_system_retrieve
description: Get system information.
tags:
- admin
security:
- authentik: []
- cookieAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/System'
description: ''
'400':
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
/api/v2beta/admin/system_tasks/: /api/v2beta/admin/system_tasks/:
get: get:
operationId: admin_system_tasks_list operationId: admin_system_tasks_list
@ -24808,6 +24828,51 @@ components:
- user_email - user_email
- user_upn - user_upn
type: string type: string
System:
type: object
description: Get system information.
properties:
http_headers:
type: object
additionalProperties:
type: string
readOnly: true
http_host:
type: string
readOnly: true
http_is_secure:
type: boolean
readOnly: true
runtime:
type: object
properties:
python_version:
type: string
gunicorn_version:
type: string
environment:
type: string
architecture:
type: string
platform:
type: string
uname:
type: string
readOnly: true
tenant:
type: string
readOnly: true
server_time:
type: string
format: date-time
readOnly: true
required:
- http_headers
- http_host
- http_is_secure
- runtime
- server_time
- tenant
TOTPDevice: TOTPDevice:
type: object type: object
description: Serializer for totp authenticator devices description: Serializer for totp authenticator devices