save start and end directly in timestamp from default_timer()
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
f64ce142e4
commit
4e44354680
|
@ -1,4 +1,5 @@
|
|||
"""Tasks API"""
|
||||
from datetime import datetime, timezone
|
||||
from importlib import import_module
|
||||
|
||||
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.utils import OpenApiResponse, extend_schema
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.fields import (
|
||||
CharField,
|
||||
ChoiceField,
|
||||
DateTimeField,
|
||||
ListField,
|
||||
SerializerMethodField,
|
||||
)
|
||||
from rest_framework.fields import CharField, ChoiceField, ListField, SerializerMethodField
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
|
@ -32,8 +27,8 @@ class SystemTaskSerializer(ModelSerializer):
|
|||
full_name = SerializerMethodField()
|
||||
uid = CharField(required=False)
|
||||
description = CharField()
|
||||
start_timestamp = DateTimeField()
|
||||
finish_timestamp = DateTimeField()
|
||||
start_timestamp = SerializerMethodField()
|
||||
finish_timestamp = SerializerMethodField()
|
||||
duration = SerializerMethodField()
|
||||
|
||||
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 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"""
|
||||
return max(instance.finish_timestamp.timestamp() - instance.start_timestamp.timestamp(), 0)
|
||||
return max(instance.finish_timestamp - instance.start_timestamp, 0)
|
||||
|
||||
class Meta:
|
||||
model = SystemTask
|
||||
|
@ -74,7 +75,7 @@ class SystemTaskViewSet(ReadOnlyModelViewSet):
|
|||
ordering = ["name", "uid", "status"]
|
||||
search_fields = ["name", "description", "uid", "status"]
|
||||
|
||||
@permission_required(None, ["authentik_events.rerun_task"])
|
||||
@permission_required(None, ["authentik_events.run_task"])
|
||||
@extend_schema(
|
||||
request=OpenApiTypes.NONE,
|
||||
responses={
|
||||
|
@ -84,21 +85,21 @@ class SystemTaskViewSet(ReadOnlyModelViewSet):
|
|||
},
|
||||
)
|
||||
@action(detail=True, methods=["post"])
|
||||
def retry(self, request: Request, pk=None) -> Response:
|
||||
"""Retry task"""
|
||||
task = self.get_object()
|
||||
def run(self, request: Request, pk=None) -> Response:
|
||||
"""Run task"""
|
||||
task: SystemTask = self.get_object()
|
||||
try:
|
||||
task_module = import_module(task.task_call_module)
|
||||
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)
|
||||
messages.success(
|
||||
self.request,
|
||||
_("Successfully re-scheduled Task %(name)s!" % {"name": task.task_name}),
|
||||
_("Successfully started task %(name)s." % {"name": task.name}),
|
||||
)
|
||||
return Response(status=204)
|
||||
except (ImportError, AttributeError): # pragma: no cover
|
||||
LOGGER.warning("Failed to run task, remove state", task=task)
|
||||
except (ImportError, AttributeError) as exc: # pragma: no cover
|
||||
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
|
||||
task.delete()
|
||||
return Response(status=500)
|
||||
|
|
|
@ -21,7 +21,7 @@ from authentik.core.models import (
|
|||
UserSourceConnection,
|
||||
)
|
||||
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.flows.models import FlowToken, Stage
|
||||
from authentik.lib.sentry import before_send
|
||||
|
@ -56,6 +56,7 @@ IGNORED_MODELS = (
|
|||
SCIMGroup,
|
||||
Reputation,
|
||||
ConnectionToken,
|
||||
SystemTask,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -29,8 +29,8 @@ class Migration(migrations.Migration):
|
|||
),
|
||||
("name", models.TextField()),
|
||||
("uid", models.TextField(null=True)),
|
||||
("start_timestamp", models.DateTimeField(auto_now_add=True)),
|
||||
("finish_timestamp", models.DateTimeField(auto_now=True)),
|
||||
("start_timestamp", models.FloatField()),
|
||||
("finish_timestamp", models.FloatField()),
|
||||
(
|
||||
"status",
|
||||
models.TextField(
|
||||
|
@ -52,7 +52,7 @@ class Migration(migrations.Migration):
|
|||
options={
|
||||
"verbose_name": "System Task",
|
||||
"verbose_name_plural": "System Tasks",
|
||||
"permissions": [("rerun_task", "Rerun task")],
|
||||
"permissions": [("run_task", "Run task")],
|
||||
"default_permissions": ["view"],
|
||||
"unique_together": {("name", "uid")},
|
||||
},
|
||||
|
|
|
@ -601,8 +601,8 @@ class SystemTask(SerializerModel, ExpiringModel):
|
|||
name = models.TextField()
|
||||
uid = models.TextField(null=True)
|
||||
|
||||
start_timestamp = models.DateTimeField(auto_now_add=True)
|
||||
finish_timestamp = models.DateTimeField(auto_now=True)
|
||||
start_timestamp = models.FloatField()
|
||||
finish_timestamp = models.FloatField()
|
||||
|
||||
status = models.TextField(choices=TaskStatus.choices)
|
||||
|
||||
|
@ -636,6 +636,6 @@ class SystemTask(SerializerModel, ExpiringModel):
|
|||
unique_together = (("name", "uid"),)
|
||||
# Remove "add", "change" and "delete" permissions as those are not used
|
||||
default_permissions = ["view"]
|
||||
permissions = [("rerun_task", _("Rerun task"))]
|
||||
permissions = [("run_task", _("Run task"))]
|
||||
verbose_name = _("System Task")
|
||||
verbose_name_plural = _("System Tasks")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""Monitored tasks"""
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from datetime import timedelta
|
||||
from timeit import default_timer
|
||||
from typing import Any, Optional
|
||||
|
||||
|
@ -69,10 +69,8 @@ class MonitoredTask(Task):
|
|||
uid=self._uid,
|
||||
defaults={
|
||||
"description": self.__doc__,
|
||||
"start_timestamp": datetime.fromtimestamp(
|
||||
self._start or default_timer(), tz=timezone.utc
|
||||
),
|
||||
"finish_timestamp": datetime.fromtimestamp(default_timer(), tz=timezone.utc),
|
||||
"start_timestamp": self._start or default_timer(),
|
||||
"finish_timestamp": default_timer(),
|
||||
"task_call_module": self.__module__,
|
||||
"task_call_func": self.__name__,
|
||||
"task_call_args": args,
|
||||
|
@ -95,10 +93,8 @@ class MonitoredTask(Task):
|
|||
uid=self._uid,
|
||||
defaults={
|
||||
"description": self.__doc__,
|
||||
"start_timestamp": datetime.fromtimestamp(
|
||||
self._start or default_timer(), tz=timezone.utc
|
||||
),
|
||||
"finish_timestamp": datetime.fromtimestamp(default_timer(), tz=timezone.utc),
|
||||
"start_timestamp": self._start or default_timer(),
|
||||
"finish_timestamp": default_timer(),
|
||||
"task_call_module": self.__module__,
|
||||
"task_call_func": self.__name__,
|
||||
"task_call_args": args,
|
||||
|
|
|
@ -3252,16 +3252,6 @@
|
|||
"minLength": 1,
|
||||
"title": "Description"
|
||||
},
|
||||
"start_timestamp": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"title": "Start timestamp"
|
||||
},
|
||||
"finish_timestamp": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"title": "Finish timestamp"
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
|
11
schema.yml
11
schema.yml
|
@ -6944,10 +6944,10 @@ paths:
|
|||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/events/system_tasks/{uuid}/retry/:
|
||||
/events/system_tasks/{uuid}/run/:
|
||||
post:
|
||||
operationId: events_system_tasks_retry_create
|
||||
description: Retry task
|
||||
operationId: events_system_tasks_run_create
|
||||
description: Run task
|
||||
parameters:
|
||||
- in: path
|
||||
name: uuid
|
||||
|
@ -42719,11 +42719,14 @@ components:
|
|||
start_timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
finish_timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
duration:
|
||||
type: integer
|
||||
type: number
|
||||
format: double
|
||||
description: Get the duration a task took to run
|
||||
readOnly: true
|
||||
status:
|
||||
|
|
|
@ -113,7 +113,7 @@ export class SystemTaskListPage extends TablePage<SystemTask> {
|
|||
class="pf-m-plain"
|
||||
.apiRequest=${() => {
|
||||
return new EventsApi(DEFAULT_CONFIG)
|
||||
.eventsSystemTasksRetryCreate({
|
||||
.eventsSystemTasksRunCreate({
|
||||
uuid: item.uuid,
|
||||
})
|
||||
.then(() => {
|
||||
|
|
Reference in a new issue