flows: add API to clear cache
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
b6d797fc78
commit
6961089425
|
@ -1,20 +0,0 @@
|
||||||
{% extends base_template|default:"generic/form.html" %}
|
|
||||||
|
|
||||||
{% load authentik_utils %}
|
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block above_form %}
|
|
||||||
<h1>
|
|
||||||
{% trans form.title %}
|
|
||||||
</h1>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block beneath_form %}
|
|
||||||
<p>
|
|
||||||
{% trans form.body %}
|
|
||||||
</p>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block action %}
|
|
||||||
{% trans 'Confirm' %}
|
|
||||||
{% endblock %}
|
|
|
@ -10,7 +10,6 @@ from authentik.admin.views import (
|
||||||
groups,
|
groups,
|
||||||
outposts,
|
outposts,
|
||||||
outposts_service_connections,
|
outposts_service_connections,
|
||||||
overview,
|
|
||||||
policies,
|
policies,
|
||||||
policies_bindings,
|
policies_bindings,
|
||||||
property_mappings,
|
property_mappings,
|
||||||
|
@ -25,16 +24,6 @@ from authentik.admin.views import (
|
||||||
from authentik.providers.saml.views.metadata import MetadataImportView
|
from authentik.providers.saml.views.metadata import MetadataImportView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path(
|
|
||||||
"overview/cache/flow/",
|
|
||||||
overview.FlowCacheClearView.as_view(),
|
|
||||||
name="overview-clear-flow-cache",
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
"overview/cache/policy/",
|
|
||||||
overview.PolicyCacheClearView.as_view(),
|
|
||||||
name="overview-clear-policy-cache",
|
|
||||||
),
|
|
||||||
# Applications
|
# Applications
|
||||||
path(
|
path(
|
||||||
"applications/create/",
|
"applications/create/",
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
"""authentik administration overview"""
|
|
||||||
from django.contrib.messages.views import SuccessMessageMixin
|
|
||||||
from django.core.cache import cache
|
|
||||||
from django.http.request import HttpRequest
|
|
||||||
from django.http.response import HttpResponse
|
|
||||||
from django.utils.translation import gettext as _
|
|
||||||
from django.views.generic import FormView
|
|
||||||
from structlog.stdlib import get_logger
|
|
||||||
|
|
||||||
from authentik.admin.forms.overview import FlowCacheClearForm, PolicyCacheClearForm
|
|
||||||
from authentik.admin.mixins import AdminRequiredMixin
|
|
||||||
from authentik.core.api.applications import user_app_cache_key
|
|
||||||
|
|
||||||
LOGGER = get_logger()
|
|
||||||
|
|
||||||
|
|
||||||
class PolicyCacheClearView(AdminRequiredMixin, SuccessMessageMixin, FormView):
|
|
||||||
"""View to clear Policy cache"""
|
|
||||||
|
|
||||||
form_class = PolicyCacheClearForm
|
|
||||||
success_url = "/"
|
|
||||||
template_name = "generic/form_non_model.html"
|
|
||||||
success_message = _("Successfully cleared Policy cache")
|
|
||||||
|
|
||||||
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
|
||||||
keys = cache.keys("policy_*")
|
|
||||||
cache.delete_many(keys)
|
|
||||||
LOGGER.debug("Cleared Policy cache", keys=len(keys))
|
|
||||||
# Also delete user application cache
|
|
||||||
keys = cache.keys(user_app_cache_key("*"))
|
|
||||||
cache.delete_many(keys)
|
|
||||||
return super().post(request, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class FlowCacheClearView(AdminRequiredMixin, SuccessMessageMixin, FormView):
|
|
||||||
"""View to clear Flow cache"""
|
|
||||||
|
|
||||||
form_class = FlowCacheClearForm
|
|
||||||
success_url = "/"
|
|
||||||
template_name = "generic/form_non_model.html"
|
|
||||||
success_message = _("Successfully cleared Flow cache")
|
|
||||||
|
|
||||||
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
|
||||||
keys = cache.keys("flow_*")
|
|
||||||
cache.delete_many(keys)
|
|
||||||
LOGGER.debug("Cleared flow cache", keys=len(keys))
|
|
||||||
return super().post(request, *args, **kwargs)
|
|
|
@ -3,10 +3,10 @@ from dataclasses import dataclass
|
||||||
|
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.db.models import Model
|
from django.db.models import Model
|
||||||
from django.http.response import JsonResponse
|
from django.http.response import HttpResponseBadRequest, JsonResponse
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from drf_yasg2 import openapi
|
from drf_yasg2 import openapi
|
||||||
from drf_yasg2.utils import swagger_auto_schema
|
from drf_yasg2.utils import no_body, swagger_auto_schema, unset
|
||||||
from guardian.shortcuts import get_objects_for_user
|
from guardian.shortcuts import get_objects_for_user
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.exceptions import PermissionDenied
|
from rest_framework.exceptions import PermissionDenied
|
||||||
|
@ -19,6 +19,7 @@ from rest_framework.serializers import (
|
||||||
SerializerMethodField,
|
SerializerMethodField,
|
||||||
)
|
)
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
from authentik.core.api.utils import CacheSerializer
|
from authentik.core.api.utils import CacheSerializer
|
||||||
from authentik.flows.models import Flow
|
from authentik.flows.models import Flow
|
||||||
|
@ -26,6 +27,8 @@ from authentik.flows.planner import cache_key
|
||||||
from authentik.flows.transfer.common import DataclassEncoder
|
from authentik.flows.transfer.common import DataclassEncoder
|
||||||
from authentik.flows.transfer.exporter import FlowExporter
|
from authentik.flows.transfer.exporter import FlowExporter
|
||||||
|
|
||||||
|
LOGGER = get_logger()
|
||||||
|
|
||||||
|
|
||||||
class FlowSerializer(ModelSerializer):
|
class FlowSerializer(ModelSerializer):
|
||||||
"""Flow Serializer"""
|
"""Flow Serializer"""
|
||||||
|
@ -88,10 +91,24 @@ class FlowViewSet(ModelViewSet):
|
||||||
|
|
||||||
@swagger_auto_schema(responses={200: CacheSerializer(many=False)})
|
@swagger_auto_schema(responses={200: CacheSerializer(many=False)})
|
||||||
@action(detail=False)
|
@action(detail=False)
|
||||||
def cached(self, request: Request) -> Response:
|
def cache_info(self, request: Request) -> Response:
|
||||||
"""Info about cached flows"""
|
"""Info about cached flows"""
|
||||||
return Response(data={"count": len(cache.keys("flow_*"))})
|
return Response(data={"count": len(cache.keys("flow_*"))})
|
||||||
|
|
||||||
|
@swagger_auto_schema(
|
||||||
|
request_body=no_body,
|
||||||
|
responses={204: "Successfully cleared cache", 400: "Bad request"},
|
||||||
|
)
|
||||||
|
@action(detail=False, methods=["POST"])
|
||||||
|
def cache_clear(self, request: Request) -> Response:
|
||||||
|
"""Clear flow cache"""
|
||||||
|
if not request.user.is_superuser:
|
||||||
|
return HttpResponseBadRequest()
|
||||||
|
keys = cache.keys("flow_*")
|
||||||
|
cache.delete_many(keys)
|
||||||
|
LOGGER.debug("Cleared flow cache", keys=len(keys))
|
||||||
|
return Response(status=204)
|
||||||
|
|
||||||
@swagger_auto_schema(
|
@swagger_auto_schema(
|
||||||
responses={
|
responses={
|
||||||
"200": openapi.Response(
|
"200": openapi.Response(
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
"""policy API Views"""
|
"""policy API Views"""
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
from django.http.response import HttpResponseBadRequest
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from drf_yasg2.utils import swagger_auto_schema
|
from drf_yasg2.utils import no_body, swagger_auto_schema
|
||||||
from rest_framework import mixins
|
from rest_framework import mixins
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
|
@ -13,7 +14,9 @@ from rest_framework.serializers import (
|
||||||
SerializerMethodField,
|
SerializerMethodField,
|
||||||
)
|
)
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||||
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
|
from authentik.core.api.applications import user_app_cache_key
|
||||||
from authentik.core.api.utils import (
|
from authentik.core.api.utils import (
|
||||||
CacheSerializer,
|
CacheSerializer,
|
||||||
MetaNameSerializer,
|
MetaNameSerializer,
|
||||||
|
@ -23,6 +26,8 @@ from authentik.lib.templatetags.authentik_utils import verbose_name
|
||||||
from authentik.lib.utils.reflection import all_subclasses
|
from authentik.lib.utils.reflection import all_subclasses
|
||||||
from authentik.policies.models import Policy, PolicyBinding, PolicyBindingModel
|
from authentik.policies.models import Policy, PolicyBinding, PolicyBindingModel
|
||||||
|
|
||||||
|
LOGGER = get_logger()
|
||||||
|
|
||||||
|
|
||||||
class PolicyBindingModelForeignKey(PrimaryKeyRelatedField):
|
class PolicyBindingModelForeignKey(PrimaryKeyRelatedField):
|
||||||
"""rest_framework PrimaryKeyRelatedField which resolves
|
"""rest_framework PrimaryKeyRelatedField which resolves
|
||||||
|
@ -139,10 +144,27 @@ class PolicyViewSet(
|
||||||
|
|
||||||
@swagger_auto_schema(responses={200: CacheSerializer(many=False)})
|
@swagger_auto_schema(responses={200: CacheSerializer(many=False)})
|
||||||
@action(detail=False)
|
@action(detail=False)
|
||||||
def cached(self, request: Request) -> Response:
|
def cache_info(self, request: Request) -> Response:
|
||||||
"""Info about cached policies"""
|
"""Info about cached policies"""
|
||||||
return Response(data={"count": len(cache.keys("policy_*"))})
|
return Response(data={"count": len(cache.keys("policy_*"))})
|
||||||
|
|
||||||
|
@swagger_auto_schema(
|
||||||
|
request_body=no_body,
|
||||||
|
responses={204: "Successfully cleared cache", 400: "Bad request"},
|
||||||
|
)
|
||||||
|
@action(detail=False, methods=["POST"])
|
||||||
|
def cache_clear(self, request: Request) -> Response:
|
||||||
|
"""Clear policy cache"""
|
||||||
|
if not request.user.is_superuser:
|
||||||
|
return HttpResponseBadRequest()
|
||||||
|
keys = cache.keys("policy_*")
|
||||||
|
cache.delete_many(keys)
|
||||||
|
LOGGER.debug("Cleared Policy cache", keys=len(keys))
|
||||||
|
# Also delete user application cache
|
||||||
|
keys = cache.keys(user_app_cache_key("*"))
|
||||||
|
cache.delete_many(keys)
|
||||||
|
return Response(status=204)
|
||||||
|
|
||||||
|
|
||||||
class PolicyBindingSerializer(ModelSerializer):
|
class PolicyBindingSerializer(ModelSerializer):
|
||||||
"""PolicyBinding Serializer"""
|
"""PolicyBinding Serializer"""
|
||||||
|
|
34
swagger.yaml
34
swagger.yaml
|
@ -2878,9 +2878,22 @@ paths:
|
||||||
tags:
|
tags:
|
||||||
- flows
|
- flows
|
||||||
parameters: []
|
parameters: []
|
||||||
/flows/instances/cached/:
|
/flows/instances/cache_clear/:
|
||||||
|
post:
|
||||||
|
operationId: flows_instances_cache_clear
|
||||||
|
description: Clear flow cache
|
||||||
|
parameters: []
|
||||||
|
responses:
|
||||||
|
'204':
|
||||||
|
description: Successfully cleared cache
|
||||||
|
'400':
|
||||||
|
description: Bad request
|
||||||
|
tags:
|
||||||
|
- flows
|
||||||
|
parameters: []
|
||||||
|
/flows/instances/cache_info/:
|
||||||
get:
|
get:
|
||||||
operationId: flows_instances_cached
|
operationId: flows_instances_cache_info
|
||||||
description: Info about cached flows
|
description: Info about cached flows
|
||||||
parameters:
|
parameters:
|
||||||
- name: flow_uuid
|
- name: flow_uuid
|
||||||
|
@ -4116,9 +4129,22 @@ paths:
|
||||||
tags:
|
tags:
|
||||||
- policies
|
- policies
|
||||||
parameters: []
|
parameters: []
|
||||||
/policies/all/cached/:
|
/policies/all/cache_clear/:
|
||||||
|
post:
|
||||||
|
operationId: policies_all_cache_clear
|
||||||
|
description: Clear policy cache
|
||||||
|
parameters: []
|
||||||
|
responses:
|
||||||
|
'204':
|
||||||
|
description: Successfully cleared cache
|
||||||
|
'400':
|
||||||
|
description: Bad request
|
||||||
|
tags:
|
||||||
|
- policies
|
||||||
|
parameters: []
|
||||||
|
/policies/all/cache_info/:
|
||||||
get:
|
get:
|
||||||
operationId: policies_all_cached
|
operationId: policies_all_cache_info
|
||||||
description: Info about cached policies
|
description: Info about cached policies
|
||||||
parameters:
|
parameters:
|
||||||
- name: bindings__isnull
|
- name: bindings__isnull
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||||
export class FlowCacheStatusCard extends AdminStatusCard<number> {
|
export class FlowCacheStatusCard extends AdminStatusCard<number> {
|
||||||
|
|
||||||
getPrimaryValue(): Promise<number> {
|
getPrimaryValue(): Promise<number> {
|
||||||
return new FlowsApi(DEFAULT_CONFIG).flowsInstancesCached({}).then((value) => {
|
return new FlowsApi(DEFAULT_CONFIG).flowsInstancesCacheInfo({}).then((value) => {
|
||||||
return value.count || 0;
|
return value.count || 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||||
export class PolicyCacheStatusCard extends AdminStatusCard<number> {
|
export class PolicyCacheStatusCard extends AdminStatusCard<number> {
|
||||||
|
|
||||||
getPrimaryValue(): Promise<number> {
|
getPrimaryValue(): Promise<number> {
|
||||||
return new PoliciesApi(DEFAULT_CONFIG).policiesAllCached({}).then((value) => {
|
return new PoliciesApi(DEFAULT_CONFIG).policiesAllCacheInfo({}).then((value) => {
|
||||||
return value.count || 0;
|
return value.count || 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue