schedule form and helpers
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
This commit is contained in:
		@ -1,15 +1,21 @@
 | 
			
		||||
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 extend_schema
 | 
			
		||||
from rest_framework.decorators import action
 | 
			
		||||
from rest_framework.mixins import (
 | 
			
		||||
    ListModelMixin,
 | 
			
		||||
    RetrieveModelMixin,
 | 
			
		||||
    UpdateModelMixin,
 | 
			
		||||
)
 | 
			
		||||
from rest_framework.request import Request
 | 
			
		||||
from rest_framework.response import Response
 | 
			
		||||
from rest_framework.serializers import SerializerMethodField
 | 
			
		||||
from rest_framework.viewsets import GenericViewSet
 | 
			
		||||
 | 
			
		||||
from authentik.core.api.utils import ModelSerializer
 | 
			
		||||
from authentik.rbac.decorators import permission_required
 | 
			
		||||
from authentik.tasks.schedules.models import Schedule
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -23,6 +29,7 @@ class ScheduleSerializer(ModelSerializer):
 | 
			
		||||
            "uid",
 | 
			
		||||
            "actor_name",
 | 
			
		||||
            "crontab",
 | 
			
		||||
            "paused",
 | 
			
		||||
            "next_run",
 | 
			
		||||
            "description",
 | 
			
		||||
        ]
 | 
			
		||||
@ -52,3 +59,12 @@ class ScheduleViewSet(
 | 
			
		||||
        "uid",
 | 
			
		||||
    )
 | 
			
		||||
    ordering = ("next_run", "uid")
 | 
			
		||||
 | 
			
		||||
    @permission_required("authentik_tasks_schedules.send_schedule")
 | 
			
		||||
    @extend_schema(request=OpenApiTypes.NONE)
 | 
			
		||||
    @action(detail=True, pagination_class=None, filter_backends=[], methods=["POST"])
 | 
			
		||||
    def send(self, request: Request, pk=None) -> Response:
 | 
			
		||||
        """Trigger this schedule now"""
 | 
			
		||||
        schedule: Schedule = self.get_object()
 | 
			
		||||
        schedule.send()
 | 
			
		||||
        return Response({})
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,22 @@
 | 
			
		||||
# Generated by Django 5.0.13 on 2025-04-03 14:28
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("authentik_tasks_schedules", "0003_schedule_options"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterModelOptions(
 | 
			
		||||
            name="schedule",
 | 
			
		||||
            options={
 | 
			
		||||
                "default_permissions": ("change", "view"),
 | 
			
		||||
                "permissions": [("send_schedule", "Manually trigger a schedule")],
 | 
			
		||||
                "verbose_name": "Schedule",
 | 
			
		||||
                "verbose_name_plural": "Schedules",
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
							
								
								
									
										18
									
								
								authentik/tasks/schedules/migrations/0005_schedule_paused.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								authentik/tasks/schedules/migrations/0005_schedule_paused.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
# Generated by Django 5.0.13 on 2025-04-03 14:33
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("authentik_tasks_schedules", "0004_alter_schedule_options"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="schedule",
 | 
			
		||||
            name="paused",
 | 
			
		||||
            field=models.BooleanField(default=False, help_text="Pause this schedule"),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -40,6 +40,7 @@ class Schedule(SerializerModel):
 | 
			
		||||
    rel_obj = GenericForeignKey("rel_obj_content_type", "rel_obj_id")
 | 
			
		||||
 | 
			
		||||
    crontab = models.TextField(validators=[validate_crontab], help_text=_("When to schedule tasks"))
 | 
			
		||||
    paused = models.BooleanField(default=False, help_text=_("Pause this schedule"))
 | 
			
		||||
 | 
			
		||||
    next_run = models.DateTimeField(auto_now_add=True, editable=False)
 | 
			
		||||
 | 
			
		||||
@ -50,6 +51,9 @@ class Schedule(SerializerModel):
 | 
			
		||||
            "change",
 | 
			
		||||
            "view",
 | 
			
		||||
        )
 | 
			
		||||
        permissions = [
 | 
			
		||||
            ("send_schedule", _("Manually trigger a schedule")),
 | 
			
		||||
        ]
 | 
			
		||||
        indexes = (models.Index(fields=("rel_obj_content_type", "rel_obj_id")),)
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,9 @@ class Scheduler:
 | 
			
		||||
                    tenant=tenant.schema_name,
 | 
			
		||||
                )
 | 
			
		||||
            with transaction.atomic(using=router.db_for_write(Schedule)):
 | 
			
		||||
                for schedule in Schedule.objects.select_for_update().filter(next_run__lt=now()):
 | 
			
		||||
                for schedule in Schedule.objects.select_for_update().filter(
 | 
			
		||||
                    next_run__lt=now(), paused=False
 | 
			
		||||
                ):
 | 
			
		||||
                    self.process_schedule(schedule)
 | 
			
		||||
 | 
			
		||||
    def run(self):
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user