diff --git a/passbook/admin/api/tasks.py b/passbook/admin/api/tasks.py new file mode 100644 index 000000000..ccb40db06 --- /dev/null +++ b/passbook/admin/api/tasks.py @@ -0,0 +1,61 @@ +"""Tasks API""" +from importlib import import_module + +from django.contrib import messages +from django.http.response import Http404 +from django.utils.translation import gettext_lazy as _ +from drf_yasg.utils import swagger_auto_schema +from rest_framework.decorators import action +from rest_framework.fields import CharField, DateTimeField, IntegerField, ListField +from rest_framework.permissions import IsAdminUser +from rest_framework.request import Request +from rest_framework.response import Response +from rest_framework.serializers import Serializer +from rest_framework.viewsets import ViewSet + +from passbook.lib.tasks import TaskInfo + + +class TaskSerializer(Serializer): + """Serialize TaskInfo and TaskResult""" + + task_name = CharField() + task_description = CharField() + task_finish_timestamp = DateTimeField(source="finish_timestamp") + + status = IntegerField(source="result.status.value") + messages = ListField(source="result.messages") + + def create(self, request: Request) -> Response: + raise NotImplementedError + + def update(self, request: Request) -> Response: + raise NotImplementedError + + +class TaskViewSet(ViewSet): + """Read-only view set that returns all background tasks""" + + permission_classes = [IsAdminUser] + + @swagger_auto_schema(responses={200: TaskSerializer(many=True)}) + def list(self, request: Request) -> Response: + """List current messages and pass into Serializer""" + return Response(TaskSerializer(TaskInfo.all().values(), many=True).data) + + @action(detail=True, methods=["post"]) + # pylint: disable=invalid-name + def retry(self, request: Request, pk=None) -> Response: + """Retry task""" + task = TaskInfo.by_name(pk) + if not task: + raise Http404 + task_module = import_module(task.task_call_module) + task_func = getattr(task_module, task.task_call_func) + task_func.delay(*task.task_call_args, **task.task_call_kwargs) + messages.success(self.request, _("Successfully re-scheduled Task!")) + return Response( + { + "successful": True, + } + ) diff --git a/passbook/admin/templates/administration/task/list.html b/passbook/admin/templates/administration/task/list.html index 716aed06a..69cf0f745 100644 --- a/passbook/admin/templates/administration/task/list.html +++ b/passbook/admin/templates/administration/task/list.html @@ -30,7 +30,7 @@ {% for key, task in object_list.items %} -
{{ key }}
+
{{ task.task_name }}
diff --git a/passbook/api/v2/urls.py b/passbook/api/v2/urls.py index 610c17280..09c93022e 100644 --- a/passbook/api/v2/urls.py +++ b/passbook/api/v2/urls.py @@ -7,6 +7,7 @@ from rest_framework.permissions import AllowAny from passbook.admin.api.overview import AdministrationOverviewViewSet from passbook.admin.api.overview_metrics import AdministrationMetricsViewSet +from passbook.admin.api.tasks import TaskViewSet from passbook.api.v2.messages import MessagesViewSet from passbook.audit.api import EventViewSet from passbook.core.api.applications import ApplicationViewSet @@ -57,6 +58,7 @@ router.register( "admin/overview", AdministrationOverviewViewSet, basename="admin_overview" ) router.register("admin/metrics", AdministrationMetricsViewSet, basename="admin_metrics") +router.register("admin/system_tasks", TaskViewSet, basename="admin_system_tasks") router.register("core/applications", ApplicationViewSet) router.register("core/groups", GroupViewSet) diff --git a/swagger.yaml b/swagger.yaml index 66f0eafd0..91201caff 100755 --- a/swagger.yaml +++ b/swagger.yaml @@ -49,6 +49,36 @@ paths: tags: - admin parameters: [] + /admin/system_tasks/: + get: + operationId: admin_system_tasks_list + description: List current messages and pass into Serializer + parameters: [] + responses: + '200': + description: '' + schema: + type: array + items: + $ref: '#/definitions/Task' + tags: + - admin + parameters: [] + /admin/system_tasks/{id}/retry/: + post: + operationId: admin_system_tasks_retry + description: Retry task + parameters: [] + responses: + '201': + description: '' + tags: + - admin + parameters: + - name: id + in: path + required: true + type: string /audit/events/: get: operationId: audit_events_list @@ -6016,6 +6046,34 @@ definitions: title: Cached flows type: integer readOnly: true + Task: + required: + - task_name + - task_description + - task_finish_timestamp + - status + - messages + type: object + properties: + task_name: + title: Task name + type: string + minLength: 1 + task_description: + title: Task description + type: string + minLength: 1 + task_finish_timestamp: + title: Task finish timestamp + type: string + format: date-time + status: + title: Status + type: integer + messages: + type: array + items: + type: string Event: required: - action