# Generated by Django 3.2.8 on 2021-10-10 16:18 import uuid import django.db.models.deletion from django.apps.registry import Apps from django.core.exceptions import FieldError from django.db import migrations, models from django.db.backends.base.schema import BaseDatabaseSchemaEditor import authentik.lib.models import authentik.outposts.models def fix_missing_token_identifier(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): User = apps.get_model("authentik_core", "User") Token = apps.get_model("authentik_core", "Token") from authentik.outposts.models import Outpost for outpost in Outpost.objects.using(schema_editor.connection.alias).all().only("pk"): user_identifier = outpost.user_identifier users = User.objects.filter(username=user_identifier) if not users.exists(): continue tokens = Token.objects.filter(user=users.first()) for token in tokens: if token.identifier != outpost.token_identifier: token.identifier = outpost.token_identifier token.save() def migrate_to_service_connection(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): db_alias = schema_editor.connection.alias Outpost = apps.get_model("authentik_outposts", "Outpost") DockerServiceConnection = apps.get_model("authentik_outposts", "DockerServiceConnection") KubernetesServiceConnection = apps.get_model( "authentik_outposts", "KubernetesServiceConnection" ) docker = DockerServiceConnection.objects.filter(local=True).first() k8s = KubernetesServiceConnection.objects.filter(local=True).first() try: for outpost in Outpost.objects.using(db_alias).all().exclude(deployment_type="custom"): if outpost.deployment_type == "kubernetes": outpost.service_connection = k8s elif outpost.deployment_type == "docker": outpost.service_connection = docker outpost.save() except FieldError: # This is triggered during e2e tests when this function is called on an already-upgraded # schema pass def remove_pb_prefix_users(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): alias = schema_editor.connection.alias User = apps.get_model("authentik_core", "User") Outpost = apps.get_model("authentik_outposts", "Outpost") for outpost in Outpost.objects.using(alias).all(): matching = User.objects.using(alias).filter(username=f"pb-outpost-{outpost.uuid.hex}") if matching.exists(): matching.delete() def update_config_prefix(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): alias = schema_editor.connection.alias Outpost = apps.get_model("authentik_outposts", "Outpost") for outpost in Outpost.objects.using(alias).all(): config = outpost._config for key in list(config): if "passbook" in key: new_key = key.replace("passbook", "authentik") config[new_key] = config[key] del config[key] outpost._config = config outpost.save() class Migration(migrations.Migration): replaces = [ ("authentik_outposts", "0001_initial"), ("authentik_outposts", "0002_auto_20200826_1306"), ("authentik_outposts", "0003_auto_20200827_2108"), ("authentik_outposts", "0004_auto_20200830_1056"), ("authentik_outposts", "0005_auto_20200909_1733"), ("authentik_outposts", "0006_auto_20201003_2239"), ("authentik_outposts", "0007_remove_outpost_channels"), ("authentik_outposts", "0008_auto_20201014_1547"), ("authentik_outposts", "0009_fix_missing_token_identifier"), ("authentik_outposts", "0010_service_connection"), ("authentik_outposts", "0011_docker_tls_auth"), ("authentik_outposts", "0012_service_connection_non_unique"), ("authentik_outposts", "0013_auto_20201203_2009"), ("authentik_outposts", "0014_auto_20201213_1407"), ("authentik_outposts", "0015_auto_20201224_1206"), ("authentik_outposts", "0016_alter_outpost_type"), ("authentik_outposts", "0017_outpost_managed"), ] initial = True dependencies = [ ("authentik_core", "0014_auto_20201018_1158"), ("authentik_core", "0016_auto_20201202_2234"), ("authentik_crypto", "0002_create_self_signed_kp"), ("authentik_core", "0008_auto_20200824_1532"), ] operations = [ migrations.CreateModel( name="Outpost", fields=[ ( "uuid", models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False ), ), ("name", models.TextField()), ("providers", models.ManyToManyField(to="authentik_core.Provider")), ( "_config", models.JSONField(default=authentik.outposts.models.default_outpost_config), ), ("type", models.TextField(choices=[("proxy", "Proxy")], default="proxy")), ( "deployment_type", models.TextField( choices=[ ("kubernetes", "Kubernetes"), ("docker", "Docker"), ("custom", "Custom"), ], default="custom", help_text="Select between authentik-managed deployment types or a custom deployment.", ), ), ], ), migrations.RunPython( code=fix_missing_token_identifier, ), migrations.CreateModel( name="OutpostServiceConnection", fields=[ ( "uuid", models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False ), ), ("name", models.TextField()), ( "local", models.BooleanField( default=False, help_text="If enabled, use the local connection. Required Docker socket/Kubernetes Integration", unique=True, ), ), ], ), migrations.CreateModel( name="DockerServiceConnection", fields=[ ( "outpostserviceconnection_ptr", models.OneToOneField( auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to="authentik_outposts.outpostserviceconnection", ), ), ("url", models.TextField()), ("tls", models.BooleanField()), ], bases=("authentik_outposts.outpostserviceconnection",), ), migrations.CreateModel( name="KubernetesServiceConnection", fields=[ ( "outpostserviceconnection_ptr", models.OneToOneField( auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to="authentik_outposts.outpostserviceconnection", ), ), ("kubeconfig", models.JSONField()), ], bases=("authentik_outposts.outpostserviceconnection",), ), migrations.AddField( model_name="outpost", name="service_connection", field=models.ForeignKey( blank=True, default=None, help_text="Select Service-Connection authentik should use to manage this outpost. Leave empty if authentik should not handle the deployment.", null=True, on_delete=django.db.models.deletion.SET_DEFAULT, to="authentik_outposts.outpostserviceconnection", ), ), migrations.RunPython( code=migrate_to_service_connection, ), migrations.RemoveField( model_name="outpost", name="deployment_type", ), migrations.AlterModelOptions( name="dockerserviceconnection", options={ "verbose_name": "Docker Service-Connection", "verbose_name_plural": "Docker Service-Connections", }, ), migrations.AlterModelOptions( name="kubernetesserviceconnection", options={ "verbose_name": "Kubernetes Service-Connection", "verbose_name_plural": "Kubernetes Service-Connections", }, ), migrations.AlterField( model_name="outpost", name="service_connection", field=authentik.lib.models.InheritanceForeignKey( blank=True, default=None, help_text="Select Service-Connection authentik should use to manage this outpost. Leave empty if authentik should not handle the deployment.", null=True, on_delete=django.db.models.deletion.SET_DEFAULT, to="authentik_outposts.outpostserviceconnection", ), ), migrations.AlterModelOptions( name="outpostserviceconnection", options={ "verbose_name": "Outpost Service-Connection", "verbose_name_plural": "Outpost Service-Connections", }, ), migrations.AlterField( model_name="kubernetesserviceconnection", name="kubeconfig", field=models.JSONField( default=None, help_text="Paste your kubeconfig here. authentik will automatically use the currently selected context.", ), preserve_default=False, ), migrations.RemoveField( model_name="dockerserviceconnection", name="tls", ), migrations.AddField( model_name="dockerserviceconnection", name="tls_authentication", field=models.ForeignKey( blank=True, default=None, help_text="Certificate/Key used for authentication. Can be left empty for no authentication.", null=True, on_delete=django.db.models.deletion.SET_DEFAULT, related_name="+", to="authentik_crypto.certificatekeypair", ), ), migrations.AddField( model_name="dockerserviceconnection", name="tls_verification", field=models.ForeignKey( blank=True, default=None, help_text="CA which the endpoint's Certificate is verified against. Can be left empty for no validation.", null=True, on_delete=django.db.models.deletion.SET_DEFAULT, related_name="+", to="authentik_crypto.certificatekeypair", ), ), migrations.AlterField( model_name="outpostserviceconnection", name="local", field=models.BooleanField( default=False, help_text="If enabled, use the local connection. Required Docker socket/Kubernetes Integration", ), ), migrations.RunPython( code=remove_pb_prefix_users, ), migrations.RunPython( code=update_config_prefix, ), migrations.AlterField( model_name="dockerserviceconnection", name="url", field=models.TextField( help_text="Can be in the format of 'unix://' when connecting to a local docker daemon, or 'https://:2376' when connecting to a remote system." ), ), migrations.AlterField( model_name="kubernetesserviceconnection", name="kubeconfig", field=models.JSONField( blank=True, help_text="Paste your kubeconfig here. authentik will automatically use the currently selected context.", ), ), migrations.AlterField( model_name="outpost", name="type", field=models.TextField(choices=[("proxy", "Proxy"), ("ldap", "Ldap")], default="proxy"), ), migrations.AddField( model_name="outpost", name="managed", field=models.TextField( default=None, help_text="Objects which are managed by authentik. These objects are created and updated automatically. This is flag only indicates that an object can be overwritten by migrations. You can still modify the objects via the API, but expect changes to be overwritten in a later update.", null=True, unique=True, verbose_name="Managed by authentik", ), ), ]