save start and end directly in timestamp from default_timer()

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens Langhammer 2024-01-13 22:46:31 +01:00
parent f64ce142e4
commit 4e44354680
No known key found for this signature in database
8 changed files with 42 additions and 51 deletions

View File

@ -1,4 +1,5 @@
"""Tasks API""" """Tasks API"""
from datetime import datetime, timezone
from importlib import import_module from importlib import import_module
from django.contrib import messages from django.contrib import messages
@ -6,13 +7,7 @@ from django.utils.translation import gettext_lazy as _
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiResponse, extend_schema from drf_spectacular.utils import OpenApiResponse, extend_schema
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.fields import ( from rest_framework.fields import CharField, ChoiceField, ListField, SerializerMethodField
CharField,
ChoiceField,
DateTimeField,
ListField,
SerializerMethodField,
)
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 from rest_framework.serializers import ModelSerializer
@ -32,8 +27,8 @@ class SystemTaskSerializer(ModelSerializer):
full_name = SerializerMethodField() full_name = SerializerMethodField()
uid = CharField(required=False) uid = CharField(required=False)
description = CharField() description = CharField()
start_timestamp = DateTimeField() start_timestamp = SerializerMethodField()
finish_timestamp = DateTimeField() finish_timestamp = SerializerMethodField()
duration = SerializerMethodField() duration = SerializerMethodField()
status = ChoiceField(choices=[(x.value, x.name) for x in TaskStatus]) status = ChoiceField(choices=[(x.value, x.name) for x in TaskStatus])
@ -45,9 +40,15 @@ class SystemTaskSerializer(ModelSerializer):
return f"{instance.name}:{instance.uid}" return f"{instance.name}:{instance.uid}"
return instance.name return instance.name
def get_duration(self, instance: SystemTask) -> int: def get_start_timestamp(self, instance: SystemTask) -> datetime:
return datetime.fromtimestamp(instance.start_timestamp, tz=timezone.utc)
def get_finish_timestamp(self, instance: SystemTask) -> datetime:
return datetime.fromtimestamp(instance.finish_timestamp, tz=timezone.utc)
def get_duration(self, instance: SystemTask) -> float:
"""Get the duration a task took to run""" """Get the duration a task took to run"""
return max(instance.finish_timestamp.timestamp() - instance.start_timestamp.timestamp(), 0) return max(instance.finish_timestamp - instance.start_timestamp, 0)
class Meta: class Meta:
model = SystemTask model = SystemTask
@ -74,7 +75,7 @@ class SystemTaskViewSet(ReadOnlyModelViewSet):
ordering = ["name", "uid", "status"] ordering = ["name", "uid", "status"]
search_fields = ["name", "description", "uid", "status"] search_fields = ["name", "description", "uid", "status"]
@permission_required(None, ["authentik_events.rerun_task"]) @permission_required(None, ["authentik_events.run_task"])
@extend_schema( @extend_schema(
request=OpenApiTypes.NONE, request=OpenApiTypes.NONE,
responses={ responses={
@ -84,21 +85,21 @@ class SystemTaskViewSet(ReadOnlyModelViewSet):
}, },
) )
@action(detail=True, methods=["post"]) @action(detail=True, methods=["post"])
def retry(self, request: Request, pk=None) -> Response: def run(self, request: Request, pk=None) -> Response:
"""Retry task""" """Run task"""
task = self.get_object() task: SystemTask = self.get_object()
try: try:
task_module = import_module(task.task_call_module) task_module = import_module(task.task_call_module)
task_func = getattr(task_module, task.task_call_func) task_func = getattr(task_module, task.task_call_func)
LOGGER.debug("Running task", task=task_func) LOGGER.info("Running task", task=task_func)
task_func.delay(*task.task_call_args, **task.task_call_kwargs) task_func.delay(*task.task_call_args, **task.task_call_kwargs)
messages.success( messages.success(
self.request, self.request,
_("Successfully re-scheduled Task %(name)s!" % {"name": task.task_name}), _("Successfully started task %(name)s." % {"name": task.name}),
) )
return Response(status=204) return Response(status=204)
except (ImportError, AttributeError): # pragma: no cover except (ImportError, AttributeError) as exc: # pragma: no cover
LOGGER.warning("Failed to run task, remove state", task=task) LOGGER.warning("Failed to run task, remove state", task=task.name, exc=exc)
# if we get an import error, the module path has probably changed # if we get an import error, the module path has probably changed
task.delete() task.delete()
return Response(status=500) return Response(status=500)

View File

@ -21,7 +21,7 @@ from authentik.core.models import (
UserSourceConnection, UserSourceConnection,
) )
from authentik.enterprise.providers.rac.models import ConnectionToken from authentik.enterprise.providers.rac.models import ConnectionToken
from authentik.events.models import Event, EventAction, Notification from authentik.events.models import Event, EventAction, Notification, SystemTask
from authentik.events.utils import model_to_dict from authentik.events.utils import model_to_dict
from authentik.flows.models import FlowToken, Stage from authentik.flows.models import FlowToken, Stage
from authentik.lib.sentry import before_send from authentik.lib.sentry import before_send
@ -56,6 +56,7 @@ IGNORED_MODELS = (
SCIMGroup, SCIMGroup,
Reputation, Reputation,
ConnectionToken, ConnectionToken,
SystemTask,
) )

View File

@ -1,4 +1,4 @@
# Generated by Django 5.0.1 on 2024-01-13 20:14 # Generated by Django 5.0.1 on 2024-01-13 21:42
import uuid import uuid
@ -29,8 +29,8 @@ class Migration(migrations.Migration):
), ),
("name", models.TextField()), ("name", models.TextField()),
("uid", models.TextField(null=True)), ("uid", models.TextField(null=True)),
("start_timestamp", models.DateTimeField(auto_now_add=True)), ("start_timestamp", models.FloatField()),
("finish_timestamp", models.DateTimeField(auto_now=True)), ("finish_timestamp", models.FloatField()),
( (
"status", "status",
models.TextField( models.TextField(
@ -52,7 +52,7 @@ class Migration(migrations.Migration):
options={ options={
"verbose_name": "System Task", "verbose_name": "System Task",
"verbose_name_plural": "System Tasks", "verbose_name_plural": "System Tasks",
"permissions": [("rerun_task", "Rerun task")], "permissions": [("run_task", "Run task")],
"default_permissions": ["view"], "default_permissions": ["view"],
"unique_together": {("name", "uid")}, "unique_together": {("name", "uid")},
}, },

View File

@ -601,8 +601,8 @@ class SystemTask(SerializerModel, ExpiringModel):
name = models.TextField() name = models.TextField()
uid = models.TextField(null=True) uid = models.TextField(null=True)
start_timestamp = models.DateTimeField(auto_now_add=True) start_timestamp = models.FloatField()
finish_timestamp = models.DateTimeField(auto_now=True) finish_timestamp = models.FloatField()
status = models.TextField(choices=TaskStatus.choices) status = models.TextField(choices=TaskStatus.choices)
@ -636,6 +636,6 @@ class SystemTask(SerializerModel, ExpiringModel):
unique_together = (("name", "uid"),) unique_together = (("name", "uid"),)
# Remove "add", "change" and "delete" permissions as those are not used # Remove "add", "change" and "delete" permissions as those are not used
default_permissions = ["view"] default_permissions = ["view"]
permissions = [("rerun_task", _("Rerun task"))] permissions = [("run_task", _("Run task"))]
verbose_name = _("System Task") verbose_name = _("System Task")
verbose_name_plural = _("System Tasks") verbose_name_plural = _("System Tasks")

View File

@ -1,5 +1,5 @@
"""Monitored tasks""" """Monitored tasks"""
from datetime import datetime, timedelta, timezone from datetime import timedelta
from timeit import default_timer from timeit import default_timer
from typing import Any, Optional from typing import Any, Optional
@ -69,10 +69,8 @@ class MonitoredTask(Task):
uid=self._uid, uid=self._uid,
defaults={ defaults={
"description": self.__doc__, "description": self.__doc__,
"start_timestamp": datetime.fromtimestamp( "start_timestamp": self._start or default_timer(),
self._start or default_timer(), tz=timezone.utc "finish_timestamp": default_timer(),
),
"finish_timestamp": datetime.fromtimestamp(default_timer(), tz=timezone.utc),
"task_call_module": self.__module__, "task_call_module": self.__module__,
"task_call_func": self.__name__, "task_call_func": self.__name__,
"task_call_args": args, "task_call_args": args,
@ -95,10 +93,8 @@ class MonitoredTask(Task):
uid=self._uid, uid=self._uid,
defaults={ defaults={
"description": self.__doc__, "description": self.__doc__,
"start_timestamp": datetime.fromtimestamp( "start_timestamp": self._start or default_timer(),
self._start or default_timer(), tz=timezone.utc "finish_timestamp": default_timer(),
),
"finish_timestamp": datetime.fromtimestamp(default_timer(), tz=timezone.utc),
"task_call_module": self.__module__, "task_call_module": self.__module__,
"task_call_func": self.__name__, "task_call_func": self.__name__,
"task_call_args": args, "task_call_args": args,

View File

@ -3252,16 +3252,6 @@
"minLength": 1, "minLength": 1,
"title": "Description" "title": "Description"
}, },
"start_timestamp": {
"type": "string",
"format": "date-time",
"title": "Start timestamp"
},
"finish_timestamp": {
"type": "string",
"format": "date-time",
"title": "Finish timestamp"
},
"status": { "status": {
"type": "string", "type": "string",
"enum": [ "enum": [

View File

@ -6944,10 +6944,10 @@ paths:
schema: schema:
$ref: '#/components/schemas/GenericError' $ref: '#/components/schemas/GenericError'
description: '' description: ''
/events/system_tasks/{uuid}/retry/: /events/system_tasks/{uuid}/run/:
post: post:
operationId: events_system_tasks_retry_create operationId: events_system_tasks_run_create
description: Retry task description: Run task
parameters: parameters:
- in: path - in: path
name: uuid name: uuid
@ -42719,11 +42719,14 @@ components:
start_timestamp: start_timestamp:
type: string type: string
format: date-time format: date-time
readOnly: true
finish_timestamp: finish_timestamp:
type: string type: string
format: date-time format: date-time
readOnly: true
duration: duration:
type: integer type: number
format: double
description: Get the duration a task took to run description: Get the duration a task took to run
readOnly: true readOnly: true
status: status:

View File

@ -113,7 +113,7 @@ export class SystemTaskListPage extends TablePage<SystemTask> {
class="pf-m-plain" class="pf-m-plain"
.apiRequest=${() => { .apiRequest=${() => {
return new EventsApi(DEFAULT_CONFIG) return new EventsApi(DEFAULT_CONFIG)
.eventsSystemTasksRetryCreate({ .eventsSystemTasksRunCreate({
uuid: item.uuid, uuid: item.uuid,
}) })
.then(() => { .then(() => {