admin: separate overview API into WorkerAPI and VersionAPI
This commit is contained in:
parent
885a2f0a58
commit
48438e28fd
|
@ -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)
|
|
@ -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)
|
|
|
@ -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))}}
|
||||||
|
)
|
|
@ -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")
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Reference in New Issue