admin: separate overview API into WorkerAPI and VersionAPI

This commit is contained in:
Jens Langhammer 2020-12-16 22:40:22 +01:00
parent 885a2f0a58
commit 48438e28fd
8 changed files with 70 additions and 33 deletions

View File

@ -1,4 +1,4 @@
"""authentik administration overview""" """authentik administration metrics"""
import time import time
from collections import Counter from collections import Counter
from datetime import timedelta from datetime import timedelta
@ -47,7 +47,7 @@ def get_events_per_1h(**filter_kwargs) -> List[Dict[str, int]]:
class AdministrationMetricsSerializer(Serializer): class AdministrationMetricsSerializer(Serializer):
"""Overview View""" """Login Metrics per 1h"""
logins_per_1h = SerializerMethodField() logins_per_1h = SerializerMethodField()
logins_failed_per_1h = SerializerMethodField() logins_failed_per_1h = SerializerMethodField()
@ -68,12 +68,12 @@ class AdministrationMetricsSerializer(Serializer):
class AdministrationMetricsViewSet(ViewSet): class AdministrationMetricsViewSet(ViewSet):
"""Return single instance of AdministrationMetricsSerializer""" """Login Metrics per 1h"""
permission_classes = [IsAdminUser] permission_classes = [IsAdminUser]
@swagger_auto_schema(responses={200: AdministrationMetricsSerializer(many=True)}) @swagger_auto_schema(responses={200: AdministrationMetricsSerializer(many=True)})
def list(self, request: Request) -> Response: def list(self, request: Request) -> Response:
"""Return single instance of AdministrationMetricsSerializer""" """Login Metrics per 1h"""
serializer = AdministrationMetricsSerializer(True) serializer = AdministrationMetricsSerializer(True)
return Response(serializer.data) return Response(serializer.data)

View File

@ -2,25 +2,26 @@
from django.core.cache import cache from django.core.cache import cache
from drf_yasg2.utils import swagger_auto_schema from drf_yasg2.utils import swagger_auto_schema
from rest_framework.fields import SerializerMethodField from rest_framework.fields import SerializerMethodField
from rest_framework.mixins import ListModelMixin
from rest_framework.permissions import IsAdminUser from rest_framework.permissions import IsAdminUser
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.serializers import Serializer from rest_framework.serializers import Serializer
from rest_framework.viewsets import ViewSet from rest_framework.viewsets import GenericViewSet
from packaging.version import parse
from authentik import __version__ from authentik import __version__
from authentik.admin.tasks import VERSION_CACHE_KEY, update_latest_version from authentik.admin.tasks import VERSION_CACHE_KEY, update_latest_version
from authentik.root.celery import CELERY_APP
class AdministrationOverviewSerializer(Serializer): class VersionSerializer(Serializer):
"""Overview View""" """Get running and latest version."""
version = SerializerMethodField() version_current = SerializerMethodField()
version_latest = SerializerMethodField() version_latest = SerializerMethodField()
worker_count = SerializerMethodField() outdated = SerializerMethodField()
def get_version(self, _) -> str: def get_version_current(self, _) -> str:
"""Get current version""" """Get current version"""
return __version__ return __version__
@ -32,9 +33,9 @@ class AdministrationOverviewSerializer(Serializer):
return __version__ return __version__
return version_in_cache return version_in_cache
def get_worker_count(self, _) -> int: def get_outdated(self, instance) -> str:
"""Ping workers""" """Check if we're running the latest version"""
return len(CELERY_APP.control.ping(timeout=0.5)) return parse(self.get_version_current(instance)) < parse(self.get_version_latest(instance))
def create(self, request: Request) -> Response: def create(self, request: Request) -> Response:
raise NotImplementedError raise NotImplementedError
@ -43,13 +44,12 @@ class AdministrationOverviewSerializer(Serializer):
raise NotImplementedError raise NotImplementedError
class AdministrationOverviewViewSet(ViewSet): class VersionViewSet(ListModelMixin, GenericViewSet):
"""General overview information about authentik.""" """Get running and latest version."""
permission_classes = [IsAdminUser] permission_classes = [IsAdminUser]
@swagger_auto_schema(responses={200: AdministrationOverviewSerializer(many=True)}) @swagger_auto_schema(responses={200: VersionSerializer(many=True)})
def list(self, request: Request) -> Response: def list(self, request: Request) -> Response:
"""General overview information about authentik.""" """Get running and latest version."""
serializer = AdministrationOverviewSerializer(True) return Response(VersionSerializer(True).data)
return Response(serializer.data)

View File

@ -0,0 +1,23 @@
"""authentik administration overview"""
from rest_framework.mixins import ListModelMixin
from rest_framework.permissions import IsAdminUser
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import Serializer
from rest_framework.viewsets import GenericViewSet
from authentik import __version__
from authentik.root.celery import CELERY_APP
class WorkerViewSet(ListModelMixin, GenericViewSet):
"""Get currently connected worker count."""
serializer_class = Serializer
permission_classes = [IsAdminUser]
def list(self, request: Request) -> Response:
"""Get currently connected worker count."""
return Response(
{"pagination": {"count": len(CELERY_APP.control.ping(timeout=0.5))}}
)

View File

@ -5,9 +5,10 @@ from drf_yasg2.views import get_schema_view
from rest_framework import routers from rest_framework import routers
from rest_framework.permissions import AllowAny from rest_framework.permissions import AllowAny
from authentik.admin.api.overview import AdministrationOverviewViewSet from authentik.admin.api.metrics import AdministrationMetricsViewSet
from authentik.admin.api.overview_metrics import AdministrationMetricsViewSet
from authentik.admin.api.tasks import TaskViewSet from authentik.admin.api.tasks import TaskViewSet
from authentik.admin.api.version import VersionViewSet
from authentik.admin.api.workers import WorkerViewSet
from authentik.api.v2.config import ConfigsViewSet from authentik.api.v2.config import ConfigsViewSet
from authentik.api.v2.messages import MessagesViewSet from authentik.api.v2.messages import MessagesViewSet
from authentik.audit.api import EventViewSet from authentik.audit.api import EventViewSet
@ -19,13 +20,22 @@ from authentik.core.api.sources import SourceViewSet
from authentik.core.api.tokens import TokenViewSet from authentik.core.api.tokens import TokenViewSet
from authentik.core.api.users import UserViewSet from authentik.core.api.users import UserViewSet
from authentik.crypto.api import CertificateKeyPairViewSet from authentik.crypto.api import CertificateKeyPairViewSet
from authentik.flows.api import FlowStageBindingViewSet, FlowViewSet, StageViewSet, FlowCacheViewSet from authentik.flows.api import (
FlowCacheViewSet,
FlowStageBindingViewSet,
FlowViewSet,
StageViewSet,
)
from authentik.outposts.api import ( from authentik.outposts.api import (
DockerServiceConnectionViewSet, DockerServiceConnectionViewSet,
KubernetesServiceConnectionViewSet, KubernetesServiceConnectionViewSet,
OutpostViewSet, OutpostViewSet,
) )
from authentik.policies.api import PolicyBindingViewSet, PolicyViewSet, PolicyCacheViewSet from authentik.policies.api import (
PolicyBindingViewSet,
PolicyCacheViewSet,
PolicyViewSet,
)
from authentik.policies.dummy.api import DummyPolicyViewSet from authentik.policies.dummy.api import DummyPolicyViewSet
from authentik.policies.expiry.api import PasswordExpiryPolicyViewSet from authentik.policies.expiry.api import PasswordExpiryPolicyViewSet
from authentik.policies.expression.api import ExpressionPolicyViewSet from authentik.policies.expression.api import ExpressionPolicyViewSet
@ -63,9 +73,8 @@ router = routers.DefaultRouter()
router.register("root/messages", MessagesViewSet, basename="messages") router.register("root/messages", MessagesViewSet, basename="messages")
router.register("root/config", ConfigsViewSet, basename="configs") router.register("root/config", ConfigsViewSet, basename="configs")
router.register( router.register("admin/version", VersionViewSet, basename="admin_version")
"admin/overview", AdministrationOverviewViewSet, basename="admin_overview" router.register("admin/workers", WorkerViewSet, basename="admin_workers")
)
router.register("admin/metrics", AdministrationMetricsViewSet, basename="admin_metrics") router.register("admin/metrics", AdministrationMetricsViewSet, basename="admin_metrics")
router.register("admin/system_tasks", TaskViewSet, basename="admin_system_tasks") router.register("admin/system_tasks", TaskViewSet, basename="admin_system_tasks")

View File

@ -11,7 +11,7 @@ from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from rest_framework_guardian.filters import ObjectPermissionsFilter from rest_framework_guardian.filters import ObjectPermissionsFilter
from authentik.admin.api.overview_metrics import get_events_per_1h from authentik.admin.api.metrics import get_events_per_1h
from authentik.audit.models import EventAction from authentik.audit.models import EventAction
from authentik.core.models import Application from authentik.core.models import Application
from authentik.policies.engine import PolicyEngine from authentik.policies.engine import PolicyEngine

View File

@ -39,7 +39,7 @@ class ProviderViewSet(ModelViewSet):
queryset = Provider.objects.all() queryset = Provider.objects.all()
serializer_class = ProviderSerializer serializer_class = ProviderSerializer
filterset_fields = { filterset_fields = {
'application': ['isnull'], "application": ["isnull"],
} }
def get_queryset(self): def get_queryset(self):

View File

@ -3,7 +3,11 @@ from django.core.cache import cache
from rest_framework.mixins import ListModelMixin from rest_framework.mixins import ListModelMixin
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer, Serializer, SerializerMethodField from rest_framework.serializers import (
ModelSerializer,
Serializer,
SerializerMethodField,
)
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
from authentik.flows.models import Flow, FlowStageBinding, Stage from authentik.flows.models import Flow, FlowStageBinding, Stage

View File

@ -7,7 +7,8 @@ from rest_framework.request import Request
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.serializers import ( from rest_framework.serializers import (
ModelSerializer, ModelSerializer,
PrimaryKeyRelatedField, Serializer, PrimaryKeyRelatedField,
Serializer,
SerializerMethodField, SerializerMethodField,
) )
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
@ -74,8 +75,8 @@ class PolicyViewSet(ReadOnlyModelViewSet):
queryset = Policy.objects.all() queryset = Policy.objects.all()
serializer_class = PolicySerializer serializer_class = PolicySerializer
filterset_fields = { filterset_fields = {
'bindings': ['isnull'], "bindings": ["isnull"],
'promptstage': ['isnull'], "promptstage": ["isnull"],
} }
def get_queryset(self): def get_queryset(self):