events: rework log messages returned from API and their rendering (#8770)
* events: initial log rework Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add migration code Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
		@ -19,8 +19,6 @@ from guardian.models import UserObjectPermission
 | 
			
		||||
from rest_framework.exceptions import ValidationError
 | 
			
		||||
from rest_framework.serializers import BaseSerializer, Serializer
 | 
			
		||||
from structlog.stdlib import BoundLogger, get_logger
 | 
			
		||||
from structlog.testing import capture_logs
 | 
			
		||||
from structlog.types import EventDict
 | 
			
		||||
from yaml import load
 | 
			
		||||
 | 
			
		||||
from authentik.blueprints.v1.common import (
 | 
			
		||||
@ -42,6 +40,7 @@ from authentik.core.models import (
 | 
			
		||||
from authentik.enterprise.license import LicenseKey
 | 
			
		||||
from authentik.enterprise.models import LicenseUsage
 | 
			
		||||
from authentik.enterprise.providers.rac.models import ConnectionToken
 | 
			
		||||
from authentik.events.logs import LogEvent, capture_logs
 | 
			
		||||
from authentik.events.models import SystemTask
 | 
			
		||||
from authentik.events.utils import cleanse_dict
 | 
			
		||||
from authentik.flows.models import FlowToken, Stage
 | 
			
		||||
@ -161,7 +160,7 @@ class Importer:
 | 
			
		||||
 | 
			
		||||
        def updater(value) -> Any:
 | 
			
		||||
            if value in self.__pk_map:
 | 
			
		||||
                self.logger.debug("updating reference in entry", value=value)
 | 
			
		||||
                self.logger.debug("Updating reference in entry", value=value)
 | 
			
		||||
                return self.__pk_map[value]
 | 
			
		||||
            return value
 | 
			
		||||
 | 
			
		||||
@ -250,7 +249,7 @@ class Importer:
 | 
			
		||||
        model_instance = existing_models.first()
 | 
			
		||||
        if not isinstance(model(), BaseMetaModel) and model_instance:
 | 
			
		||||
            self.logger.debug(
 | 
			
		||||
                "initialise serializer with instance",
 | 
			
		||||
                "Initialise serializer with instance",
 | 
			
		||||
                model=model,
 | 
			
		||||
                instance=model_instance,
 | 
			
		||||
                pk=model_instance.pk,
 | 
			
		||||
@ -260,14 +259,14 @@ class Importer:
 | 
			
		||||
        elif model_instance and entry.state == BlueprintEntryDesiredState.MUST_CREATED:
 | 
			
		||||
            raise EntryInvalidError.from_entry(
 | 
			
		||||
                (
 | 
			
		||||
                    f"state is set to {BlueprintEntryDesiredState.MUST_CREATED} "
 | 
			
		||||
                    f"State is set to {BlueprintEntryDesiredState.MUST_CREATED} "
 | 
			
		||||
                    "and object exists already",
 | 
			
		||||
                ),
 | 
			
		||||
                entry,
 | 
			
		||||
            )
 | 
			
		||||
        else:
 | 
			
		||||
            self.logger.debug(
 | 
			
		||||
                "initialised new serializer instance",
 | 
			
		||||
                "Initialised new serializer instance",
 | 
			
		||||
                model=model,
 | 
			
		||||
                **cleanse_dict(updated_identifiers),
 | 
			
		||||
            )
 | 
			
		||||
@ -324,7 +323,7 @@ class Importer:
 | 
			
		||||
                model: type[SerializerModel] = registry.get_model(model_app_label, model_name)
 | 
			
		||||
            except LookupError:
 | 
			
		||||
                self.logger.warning(
 | 
			
		||||
                    "app or model does not exist", app=model_app_label, model=model_name
 | 
			
		||||
                    "App or Model does not exist", app=model_app_label, model=model_name
 | 
			
		||||
                )
 | 
			
		||||
                return False
 | 
			
		||||
            # Validate each single entry
 | 
			
		||||
@ -336,7 +335,7 @@ class Importer:
 | 
			
		||||
                if entry.get_state(self._import) == BlueprintEntryDesiredState.ABSENT:
 | 
			
		||||
                    serializer = exc.serializer
 | 
			
		||||
                else:
 | 
			
		||||
                    self.logger.warning(f"entry invalid: {exc}", entry=entry, error=exc)
 | 
			
		||||
                    self.logger.warning(f"Entry invalid: {exc}", entry=entry, error=exc)
 | 
			
		||||
                    if raise_errors:
 | 
			
		||||
                        raise exc
 | 
			
		||||
                    return False
 | 
			
		||||
@ -356,14 +355,14 @@ class Importer:
 | 
			
		||||
                    and state == BlueprintEntryDesiredState.CREATED
 | 
			
		||||
                ):
 | 
			
		||||
                    self.logger.debug(
 | 
			
		||||
                        "instance exists, skipping",
 | 
			
		||||
                        "Instance exists, skipping",
 | 
			
		||||
                        model=model,
 | 
			
		||||
                        instance=instance,
 | 
			
		||||
                        pk=instance.pk,
 | 
			
		||||
                    )
 | 
			
		||||
                else:
 | 
			
		||||
                    instance = serializer.save()
 | 
			
		||||
                    self.logger.debug("updated model", model=instance)
 | 
			
		||||
                    self.logger.debug("Updated model", model=instance)
 | 
			
		||||
                if "pk" in entry.identifiers:
 | 
			
		||||
                    self.__pk_map[entry.identifiers["pk"]] = instance.pk
 | 
			
		||||
                entry._state = BlueprintEntryState(instance)
 | 
			
		||||
@ -371,12 +370,12 @@ class Importer:
 | 
			
		||||
                instance: Model | None = serializer.instance
 | 
			
		||||
                if instance.pk:
 | 
			
		||||
                    instance.delete()
 | 
			
		||||
                    self.logger.debug("deleted model", mode=instance)
 | 
			
		||||
                    self.logger.debug("Deleted model", mode=instance)
 | 
			
		||||
                    continue
 | 
			
		||||
                self.logger.debug("entry to delete with no instance, skipping")
 | 
			
		||||
                self.logger.debug("Entry to delete with no instance, skipping")
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    def validate(self, raise_validation_errors=False) -> tuple[bool, list[EventDict]]:
 | 
			
		||||
    def validate(self, raise_validation_errors=False) -> tuple[bool, list[LogEvent]]:
 | 
			
		||||
        """Validate loaded blueprint export, ensure all models are allowed
 | 
			
		||||
        and serializers have no errors"""
 | 
			
		||||
        self.logger.debug("Starting blueprint import validation")
 | 
			
		||||
@ -390,9 +389,7 @@ class Importer:
 | 
			
		||||
        ):
 | 
			
		||||
            successful = self._apply_models(raise_errors=raise_validation_errors)
 | 
			
		||||
            if not successful:
 | 
			
		||||
                self.logger.debug("Blueprint validation failed")
 | 
			
		||||
        for log in logs:
 | 
			
		||||
            getattr(self.logger, log.get("log_level"))(**log)
 | 
			
		||||
                self.logger.warning("Blueprint validation failed")
 | 
			
		||||
        self.logger.debug("Finished blueprint import validation")
 | 
			
		||||
        self._import = orig_import
 | 
			
		||||
        return successful, logs
 | 
			
		||||
 | 
			
		||||
@ -30,6 +30,7 @@ from authentik.blueprints.v1.common import BlueprintLoader, BlueprintMetadata, E
 | 
			
		||||
from authentik.blueprints.v1.importer import Importer
 | 
			
		||||
from authentik.blueprints.v1.labels import LABEL_AUTHENTIK_INSTANTIATE
 | 
			
		||||
from authentik.blueprints.v1.oci import OCI_PREFIX
 | 
			
		||||
from authentik.events.logs import capture_logs
 | 
			
		||||
from authentik.events.models import TaskStatus
 | 
			
		||||
from authentik.events.system_tasks import SystemTask, prefill_task
 | 
			
		||||
from authentik.events.utils import sanitize_dict
 | 
			
		||||
@ -211,14 +212,15 @@ def apply_blueprint(self: SystemTask, instance_pk: str):
 | 
			
		||||
        if not valid:
 | 
			
		||||
            instance.status = BlueprintInstanceStatus.ERROR
 | 
			
		||||
            instance.save()
 | 
			
		||||
            self.set_status(TaskStatus.ERROR, *[x["event"] for x in logs])
 | 
			
		||||
            return
 | 
			
		||||
        applied = importer.apply()
 | 
			
		||||
        if not applied:
 | 
			
		||||
            instance.status = BlueprintInstanceStatus.ERROR
 | 
			
		||||
            instance.save()
 | 
			
		||||
            self.set_status(TaskStatus.ERROR, "Failed to apply")
 | 
			
		||||
            self.set_status(TaskStatus.ERROR, *logs)
 | 
			
		||||
            return
 | 
			
		||||
        with capture_logs() as logs:
 | 
			
		||||
            applied = importer.apply()
 | 
			
		||||
            if not applied:
 | 
			
		||||
                instance.status = BlueprintInstanceStatus.ERROR
 | 
			
		||||
                instance.save()
 | 
			
		||||
                self.set_status(TaskStatus.ERROR, *logs)
 | 
			
		||||
                return
 | 
			
		||||
        instance.status = BlueprintInstanceStatus.SUCCESSFUL
 | 
			
		||||
        instance.last_applied_hash = file_hash
 | 
			
		||||
        instance.last_applied = now()
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user