This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
authentik/authentik/outposts/signals.py
2021-05-10 17:11:31 +02:00

72 lines
2.7 KiB
Python

"""authentik outpost signals"""
from django.core.cache import cache
from django.db.models import Model
from django.db.models.signals import post_save, pre_delete, pre_save
from django.dispatch import receiver
from structlog.stdlib import get_logger
from authentik.core.models import Provider
from authentik.crypto.models import CertificateKeyPair
from authentik.lib.utils.reflection import class_to_path
from authentik.outposts.models import Outpost, OutpostServiceConnection
from authentik.outposts.tasks import (
CACHE_KEY_OUTPOST_DOWN,
outpost_controller,
outpost_post_save,
)
LOGGER = get_logger()
UPDATE_TRIGGERING_MODELS = (
Outpost,
OutpostServiceConnection,
Provider,
CertificateKeyPair,
)
@receiver(pre_save, sender=Outpost)
# pylint: disable=unused-argument
def pre_save_outpost(sender, instance: Outpost, **_):
"""Pre-save checks for an outpost, if the name or config.kubernetes_namespace changes,
we call down and then wait for the up after save"""
old_instances = Outpost.objects.filter(pk=instance.pk)
if not old_instances.exists():
return
old_instance = old_instances.first()
dirty = False
# Name changes the deployment name, need to recreate
dirty += old_instance.name != instance.name
# namespace requires re-create
dirty += (
old_instance.config.kubernetes_namespace != instance.config.kubernetes_namespace
)
if bool(dirty):
LOGGER.info("Outpost needs re-deployment due to changes", instance=instance)
cache.set(CACHE_KEY_OUTPOST_DOWN % instance.pk.hex, old_instance)
outpost_controller.delay(instance.pk.hex, action="down", from_cache=True)
@receiver(post_save)
# pylint: disable=unused-argument
def post_save_update(sender, instance: Model, **_):
"""If an Outpost is saved, Ensure that token is created/updated
If an OutpostModel, or a model that is somehow connected to an OutpostModel is saved,
we send a message down the relevant OutpostModels WS connection to trigger an update"""
if instance.__module__ == "django.db.migrations.recorder":
return
if instance.__module__ == "__fake__":
return
if not isinstance(instance, UPDATE_TRIGGERING_MODELS):
return
outpost_post_save.delay(class_to_path(instance.__class__), instance.pk)
@receiver(pre_delete, sender=Outpost)
# pylint: disable=unused-argument
def pre_delete_cleanup(sender, instance: Outpost, **_):
"""Ensure that Outpost's user is deleted (which will delete the token through cascade)"""
instance.user.delete()
cache.set(CACHE_KEY_OUTPOST_DOWN % instance.pk.hex, instance)
outpost_controller.delay(instance.pk.hex, action="down", from_cache=True)