From 3d3a0cd9e3238584ff44f1fe6f1cf5313f3d494b Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Mon, 18 Jan 2021 09:34:48 +0100 Subject: [PATCH] events: create event when system task fails --- authentik/admin/api/tasks.py | 2 +- authentik/admin/tasks.py | 2 +- authentik/admin/views/tasks.py | 2 +- authentik/core/tasks.py | 2 +- authentik/events/models.py | 6 +++++- .../{lib/tasks.py => events/monitored_tasks.py} | 16 ++++++++++++++++ authentik/events/tasks.py | 2 +- authentik/events/tests/test_notifications.py | 2 +- authentik/outposts/tasks.py | 2 +- authentik/policies/reputation/tasks.py | 2 +- authentik/sources/ldap/tasks.py | 2 +- authentik/sources/saml/tasks.py | 2 +- authentik/stages/email/tasks.py | 2 +- swagger.yaml | 4 ++++ 14 files changed, 36 insertions(+), 12 deletions(-) rename authentik/{lib/tasks.py => events/monitored_tasks.py} (89%) diff --git a/authentik/admin/api/tasks.py b/authentik/admin/api/tasks.py index 3c4075084..ddeed8fb9 100644 --- a/authentik/admin/api/tasks.py +++ b/authentik/admin/api/tasks.py @@ -14,7 +14,7 @@ from rest_framework.response import Response from rest_framework.serializers import Serializer from rest_framework.viewsets import ViewSet -from authentik.lib.tasks import TaskInfo +from authentik.events.monitored_tasks import TaskInfo class TaskSerializer(Serializer): diff --git a/authentik/admin/tasks.py b/authentik/admin/tasks.py index e4c7efed6..336cfa37a 100644 --- a/authentik/admin/tasks.py +++ b/authentik/admin/tasks.py @@ -6,7 +6,7 @@ from structlog.stdlib import get_logger from authentik import __version__ from authentik.events.models import Event, EventAction -from authentik.lib.tasks import MonitoredTask, TaskResult, TaskResultStatus +from authentik.events.monitored_tasks import MonitoredTask, TaskResult, TaskResultStatus from authentik.root.celery import CELERY_APP LOGGER = get_logger() diff --git a/authentik/admin/views/tasks.py b/authentik/admin/views/tasks.py index 44b96c8e9..40dfa74c1 100644 --- a/authentik/admin/views/tasks.py +++ b/authentik/admin/views/tasks.py @@ -4,7 +4,7 @@ from typing import Any, Dict from django.views.generic.base import TemplateView from authentik.admin.mixins import AdminRequiredMixin -from authentik.lib.tasks import TaskInfo, TaskResultStatus +from authentik.events.monitored_tasks import TaskInfo, TaskResultStatus class TaskListView(AdminRequiredMixin, TemplateView): diff --git a/authentik/core/tasks.py b/authentik/core/tasks.py index 168255b24..aaf2c3aef 100644 --- a/authentik/core/tasks.py +++ b/authentik/core/tasks.py @@ -11,7 +11,7 @@ from django.utils.timezone import now from structlog.stdlib import get_logger from authentik.core.models import ExpiringModel -from authentik.lib.tasks import MonitoredTask, TaskResult, TaskResultStatus +from authentik.events.monitored_tasks import MonitoredTask, TaskResult, TaskResultStatus from authentik.root.celery import CELERY_APP LOGGER = get_logger() diff --git a/authentik/events/models.py b/authentik/events/models.py index 2e5875f46..b28a71423 100644 --- a/authentik/events/models.py +++ b/authentik/events/models.py @@ -22,7 +22,6 @@ from authentik.events.utils import cleanse_dict, get_user, sanitize_dict from authentik.lib.sentry import SentryIgnoredException from authentik.lib.utils.http import get_client_ip from authentik.policies.models import PolicyBindingModel -from authentik.stages.email.tasks import send_mail from authentik.stages.email.utils import TemplateEmailMessage LOGGER = get_logger("authentik.events") @@ -57,6 +56,9 @@ class EventAction(models.TextChoices): POLICY_EXCEPTION = "policy_exception" PROPERTY_MAPPING_EXCEPTION = "property_mapping_exception" + SYSTEM_TASK_EXECUTION = "system_task_execution" + SYSTEM_TASK_EXCEPTION = "system_task_exception" + CONFIGURATION_ERROR = "configuration_error" MODEL_CREATED = "model_created" @@ -280,6 +282,8 @@ class NotificationTransport(models.Model): ) # Email is sent directly here, as the call to send() should have been from a task. try: + from authentik.stages.email.tasks import send_mail + # pyright: reportGeneralTypeIssues=false return send_mail(mail.__dict__) # pylint: disable=no-value-for-parameter except (SMTPException, ConnectionError, OSError) as exc: diff --git a/authentik/lib/tasks.py b/authentik/events/monitored_tasks.py similarity index 89% rename from authentik/lib/tasks.py rename to authentik/events/monitored_tasks.py index 132d03a5e..b6d66bece 100644 --- a/authentik/lib/tasks.py +++ b/authentik/events/monitored_tasks.py @@ -8,6 +8,8 @@ from typing import Any, Dict, List, Optional from celery import Task from django.core.cache import cache +from authentik.events.models import Event, EventAction + class TaskResultStatus(Enum): """Possible states of tasks""" @@ -122,6 +124,13 @@ class MonitoredTask(Task): task_call_args=args, task_call_kwargs=kwargs, ).save(self.result_timeout_hours) + Event.new( + EventAction.SYSTEM_TASK_EXECUTION, + message=( + f"Task {self.__name__} finished successfully: " + "\n".join(self._result.messages) + ), + ).save() return super().after_return(status, retval, task_id, args, kwargs, einfo=einfo) # pylint: disable=too-many-arguments @@ -138,6 +147,13 @@ class MonitoredTask(Task): task_call_args=args, task_call_kwargs=kwargs, ).save(self.result_timeout_hours) + Event.new( + EventAction.SYSTEM_TASK_EXCEPTION, + message=( + f"Task {self.__name__} encountered an error: " + "\n".join(self._result.messages) + ), + ).save() return super().on_failure(exc, task_id, args, kwargs, einfo=einfo) def run(self, *args, **kwargs): diff --git a/authentik/events/tasks.py b/authentik/events/tasks.py index ad13c610b..1f30f73a3 100644 --- a/authentik/events/tasks.py +++ b/authentik/events/tasks.py @@ -9,7 +9,7 @@ from authentik.events.models import ( NotificationTransport, NotificationTransportError, ) -from authentik.lib.tasks import MonitoredTask, TaskResult, TaskResultStatus +from authentik.events.monitored_tasks import MonitoredTask, TaskResult, TaskResultStatus from authentik.policies.engine import PolicyEngine, PolicyEngineMode from authentik.policies.models import PolicyBinding from authentik.root.celery import CELERY_APP diff --git a/authentik/events/tests/test_notifications.py b/authentik/events/tests/test_notifications.py index eccf3e182..98c23b5fb 100644 --- a/authentik/events/tests/test_notifications.py +++ b/authentik/events/tests/test_notifications.py @@ -87,4 +87,4 @@ class TestEventsNotifications(TestCase): "authentik.events.models.NotificationTransport.send", execute_mock ): Event.new(EventAction.CUSTOM_PREFIX).save() - self.assertEqual(passes.call_count, 0) + self.assertEqual(passes.call_count, 1) diff --git a/authentik/outposts/tasks.py b/authentik/outposts/tasks.py index 8ce64c77a..b187216f3 100644 --- a/authentik/outposts/tasks.py +++ b/authentik/outposts/tasks.py @@ -8,7 +8,7 @@ from django.db.models.base import Model from django.utils.text import slugify from structlog.stdlib import get_logger -from authentik.lib.tasks import MonitoredTask, TaskResult, TaskResultStatus +from authentik.events.monitored_tasks import MonitoredTask, TaskResult, TaskResultStatus from authentik.lib.utils.reflection import path_to_class from authentik.outposts.controllers.base import ControllerException from authentik.outposts.models import ( diff --git a/authentik/policies/reputation/tasks.py b/authentik/policies/reputation/tasks.py index 17781ca1c..a6fcf2b38 100644 --- a/authentik/policies/reputation/tasks.py +++ b/authentik/policies/reputation/tasks.py @@ -3,7 +3,7 @@ from django.core.cache import cache from structlog.stdlib import get_logger from authentik.core.models import User -from authentik.lib.tasks import MonitoredTask, TaskResult, TaskResultStatus +from authentik.events.monitored_tasks import MonitoredTask, TaskResult, TaskResultStatus from authentik.policies.reputation.models import IPReputation, UserReputation from authentik.policies.reputation.signals import ( CACHE_KEY_IP_PREFIX, diff --git a/authentik/sources/ldap/tasks.py b/authentik/sources/ldap/tasks.py index fcb47c756..29ac1696f 100644 --- a/authentik/sources/ldap/tasks.py +++ b/authentik/sources/ldap/tasks.py @@ -5,7 +5,7 @@ from django.core.cache import cache from django.utils.text import slugify from ldap3.core.exceptions import LDAPException -from authentik.lib.tasks import MonitoredTask, TaskResult, TaskResultStatus +from authentik.events.monitored_tasks import MonitoredTask, TaskResult, TaskResultStatus from authentik.root.celery import CELERY_APP from authentik.sources.ldap.models import LDAPSource from authentik.sources.ldap.sync import LDAPSynchronizer diff --git a/authentik/sources/saml/tasks.py b/authentik/sources/saml/tasks.py index 55dff9c5b..4ebbddba9 100644 --- a/authentik/sources/saml/tasks.py +++ b/authentik/sources/saml/tasks.py @@ -3,7 +3,7 @@ from django.utils.timezone import now from structlog.stdlib import get_logger from authentik.core.models import User -from authentik.lib.tasks import MonitoredTask, TaskResult, TaskResultStatus +from authentik.events.monitored_tasks import MonitoredTask, TaskResult, TaskResultStatus from authentik.lib.utils.time import timedelta_from_string from authentik.root.celery import CELERY_APP from authentik.sources.saml.models import SAMLSource diff --git a/authentik/stages/email/tasks.py b/authentik/stages/email/tasks.py index 84cb73134..38fafdeeb 100644 --- a/authentik/stages/email/tasks.py +++ b/authentik/stages/email/tasks.py @@ -9,7 +9,7 @@ from django.core.mail.utils import DNS_NAME from django.utils.text import slugify from structlog.stdlib import get_logger -from authentik.lib.tasks import MonitoredTask, TaskResult, TaskResultStatus +from authentik.events.monitored_tasks import MonitoredTask, TaskResult, TaskResultStatus from authentik.root.celery import CELERY_APP from authentik.stages.email.models import EmailStage diff --git a/swagger.yaml b/swagger.yaml index 8e0539760..548a5e4cd 100755 --- a/swagger.yaml +++ b/swagger.yaml @@ -7584,6 +7584,8 @@ definitions: - policy_execution - policy_exception - property_mapping_exception + - system_task_execution + - system_task_exception - configuration_error - model_created - model_updated @@ -8300,6 +8302,8 @@ definitions: - policy_execution - policy_exception - property_mapping_exception + - system_task_execution + - system_task_exception - configuration_error - model_created - model_updated