restart front
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
This commit is contained in:
@ -1,3 +1,6 @@
|
||||
from django_filters.filters import BooleanFilter
|
||||
from django_filters.filterset import FilterSet
|
||||
from rest_framework.fields import ReadOnlyField
|
||||
from rest_framework.mixins import (
|
||||
ListModelMixin,
|
||||
RetrieveModelMixin,
|
||||
@ -11,6 +14,9 @@ from authentik.tenants.utils import get_current_tenant
|
||||
|
||||
|
||||
class TaskSerializer(ModelSerializer):
|
||||
rel_obj_app_label = ReadOnlyField(source="rel_obj_content_type.app_label")
|
||||
rel_obj_model = ReadOnlyField(source="rel_obj_content_type.model")
|
||||
|
||||
messages = LogEventSerializer(many=True, source="_messages")
|
||||
|
||||
class Meta:
|
||||
@ -21,7 +27,8 @@ class TaskSerializer(ModelSerializer):
|
||||
"actor_name",
|
||||
"state",
|
||||
"mtime",
|
||||
"rel_obj_content_type",
|
||||
"rel_obj_app_label",
|
||||
"rel_obj_model",
|
||||
"rel_obj_id",
|
||||
"uid",
|
||||
"messages",
|
||||
@ -29,6 +36,23 @@ class TaskSerializer(ModelSerializer):
|
||||
]
|
||||
|
||||
|
||||
class TaskFilter(FilterSet):
|
||||
rel_obj_id__isnull = BooleanFilter("rel_obj_id", "isnull")
|
||||
|
||||
class Meta:
|
||||
model = Task
|
||||
fields = (
|
||||
"queue_name",
|
||||
"actor_name",
|
||||
"state",
|
||||
"rel_obj_content_type__app_label",
|
||||
"rel_obj_content_type__model",
|
||||
"rel_obj_id",
|
||||
"rel_obj_id__isnull",
|
||||
"aggregated_status",
|
||||
)
|
||||
|
||||
|
||||
class TaskViewSet(
|
||||
RetrieveModelMixin,
|
||||
ListModelMixin,
|
||||
@ -41,16 +65,16 @@ class TaskViewSet(
|
||||
"queue_name",
|
||||
"actor_name",
|
||||
"state",
|
||||
"rel_obj_app_label",
|
||||
"rel_obj_model",
|
||||
"rel_obj_id",
|
||||
"_uid",
|
||||
"aggregated_status",
|
||||
)
|
||||
filterset_fields = (
|
||||
"queue_name",
|
||||
"actor_name",
|
||||
"state",
|
||||
"aggregated_status",
|
||||
)
|
||||
filterset_class = TaskFilter
|
||||
ordering = ("-mtime",)
|
||||
|
||||
def get_queryset(self):
|
||||
return Task.objects.filter(tenant=get_current_tenant())
|
||||
return Task.objects.select_related("rel_obj_content_type").filter(
|
||||
tenant=get_current_tenant()
|
||||
)
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
from django_filters.filters import BooleanFilter
|
||||
from django_filters.filterset import FilterSet
|
||||
from dramatiq.actor import Actor
|
||||
from dramatiq.broker import get_broker
|
||||
from dramatiq.errors import ActorNotFound
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
from drf_spectacular.utils import OpenApiResponse, extend_schema
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.fields import ReadOnlyField
|
||||
from rest_framework.mixins import (
|
||||
ListModelMixin,
|
||||
RetrieveModelMixin,
|
||||
@ -20,19 +23,25 @@ from authentik.tasks.schedules.models import Schedule
|
||||
|
||||
|
||||
class ScheduleSerializer(ModelSerializer):
|
||||
rel_obj_app_label = ReadOnlyField(source="rel_obj_content_type.app_label")
|
||||
rel_obj_model = ReadOnlyField(source="rel_obj_content_type.model")
|
||||
|
||||
description = SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Schedule
|
||||
fields = [
|
||||
fields = (
|
||||
"id",
|
||||
"uid",
|
||||
"actor_name",
|
||||
"rel_obj_app_label",
|
||||
"rel_obj_model",
|
||||
"rel_obj_id",
|
||||
"crontab",
|
||||
"paused",
|
||||
"next_run",
|
||||
"description",
|
||||
]
|
||||
)
|
||||
|
||||
def get_description(self, instance: Schedule) -> str | None:
|
||||
if instance.rel_obj:
|
||||
@ -43,22 +52,48 @@ class ScheduleSerializer(ModelSerializer):
|
||||
actor: Actor = get_broker().get_actor(instance.actor_name)
|
||||
except ActorNotFound:
|
||||
return "FIXME this shouldn't happen"
|
||||
if not actor.fn.__doc__:
|
||||
return "no doc"
|
||||
return actor.fn.__doc__.strip()
|
||||
|
||||
|
||||
class ScheduleFilter(FilterSet):
|
||||
rel_obj_id__isnull = BooleanFilter("rel_obj_id", "isnull")
|
||||
|
||||
class Meta:
|
||||
model = Schedule
|
||||
fields = (
|
||||
"actor_name",
|
||||
"rel_obj_content_type__app_label",
|
||||
"rel_obj_content_type__model",
|
||||
"rel_obj_id",
|
||||
"rel_obj_id__isnull",
|
||||
"paused",
|
||||
)
|
||||
|
||||
|
||||
class ScheduleViewSet(
|
||||
RetrieveModelMixin,
|
||||
UpdateModelMixin,
|
||||
ListModelMixin,
|
||||
GenericViewSet,
|
||||
):
|
||||
queryset = Schedule.objects.all()
|
||||
queryset = Schedule.objects.select_related("rel_obj_content_type").all()
|
||||
serializer_class = ScheduleSerializer
|
||||
search_fields = (
|
||||
"id",
|
||||
"uid",
|
||||
"actor_name",
|
||||
"rel_obj_content_type__app_label",
|
||||
"rel_obj_content_type__model",
|
||||
"rel_obj_id",
|
||||
"description",
|
||||
)
|
||||
filterset_class = ScheduleFilter
|
||||
ordering = (
|
||||
"next_run",
|
||||
"uid",
|
||||
)
|
||||
ordering = ("next_run", "uid")
|
||||
|
||||
@permission_required("authentik_tasks_schedules.send_schedule")
|
||||
@extend_schema(
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
# Generated by Django 5.1.10 on 2025-06-11 12:57
|
||||
|
||||
import pgtrigger.compiler
|
||||
import pgtrigger.migrations
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("authentik_tasks_schedules", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
pgtrigger.migrations.AddTrigger(
|
||||
model_name="schedule",
|
||||
trigger=pgtrigger.compiler.Trigger(
|
||||
name="set_next_run_on_paused",
|
||||
sql=pgtrigger.compiler.UpsertTriggerSql(
|
||||
condition='WHEN (NEW."paused" AND NOT OLD."paused")',
|
||||
func="\n NEW.next_run = to_timestamp(0);\n RETURN NEW;\n ",
|
||||
hash="7fe580a86de70723522cfcbac712785984000f92",
|
||||
operation="UPDATE",
|
||||
pgid="pgtrigger_set_next_run_on_paused_95c6d",
|
||||
table="authentik_tasks_schedules_schedule",
|
||||
when="BEFORE",
|
||||
),
|
||||
),
|
||||
),
|
||||
]
|
||||
@ -1,6 +1,7 @@
|
||||
import pickle # nosec
|
||||
from uuid import uuid4
|
||||
|
||||
import pgtrigger
|
||||
from cron_converter import Cron
|
||||
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
@ -55,6 +56,18 @@ class Schedule(SerializerModel):
|
||||
("send_schedule", _("Manually trigger a schedule")),
|
||||
]
|
||||
indexes = (models.Index(fields=("rel_obj_content_type", "rel_obj_id")),)
|
||||
triggers = (
|
||||
pgtrigger.Trigger(
|
||||
name="set_next_run_on_paused",
|
||||
operation=pgtrigger.Update,
|
||||
when=pgtrigger.Before,
|
||||
condition=pgtrigger.Q(new__paused=True) & pgtrigger.Q(old__paused=False),
|
||||
func="""
|
||||
NEW.next_run = to_timestamp(0);
|
||||
RETURN NEW;
|
||||
""",
|
||||
),
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.uid
|
||||
|
||||
Reference in New Issue
Block a user