tests/integration: add tests for Docker outpost using TLS connection

This commit is contained in:
Jens Langhammer 2020-12-13 21:28:13 +01:00
parent 426cb33fab
commit 07082cb3aa
5 changed files with 112 additions and 7 deletions

View File

@ -6,9 +6,9 @@ As authentik is currently in a pre-stable, only the latest "stable" version is s
| Version | Supported | | Version | Supported |
| -------- | ------------------ | | -------- | ------------------ |
| 0.10.x | :white_check_mark: |
| 0.11.x | :white_check_mark: | | 0.11.x | :white_check_mark: |
| 0.12.x | :white_check_mark: | | 0.12.x | :white_check_mark: |
| 0.13.x | :white_check_mark: |
## Reporting a Vulnerability ## Reporting a Vulnerability

View File

@ -11,9 +11,6 @@ from authentik.core.models import Token, TokenIntents
class TestAPIAuth(TestCase): class TestAPIAuth(TestCase):
"""Test API Authentication""" """Test API Authentication"""
def setUp(self) -> None:
super().setUp()
def test_valid(self): def test_valid(self):
"""Test valid token""" """Test valid token"""
token = Token.objects.create( token = Token.objects.create(

View File

@ -1,7 +1,7 @@
# Generated by Django 3.1.4 on 2020-12-13 14:07 # Generated by Django 3.1.4 on 2020-12-13 14:07
from django.apps.registry import Apps from django.apps.registry import Apps
from django.db import migrations from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor from django.db.backends.base.schema import BaseDatabaseSchemaEditor
@ -26,4 +26,13 @@ class Migration(migrations.Migration):
("authentik_outposts", "0013_auto_20201203_2009"), ("authentik_outposts", "0013_auto_20201203_2009"),
] ]
operations = [migrations.RunPython(update_config_prefix)] operations = [
migrations.RunPython(update_config_prefix),
migrations.AlterField(
model_name="dockerserviceconnection",
name="url",
field=models.TextField(
help_text="Can be in the format of 'unix://<path>' when connecting to a local docker daemon, or 'https://<hostname>:2376' when connecting to a remote system."
),
),
]

View File

@ -140,7 +140,14 @@ class OutpostServiceConnection(models.Model):
class DockerServiceConnection(OutpostServiceConnection): class DockerServiceConnection(OutpostServiceConnection):
"""Service Connection to a Docker endpoint""" """Service Connection to a Docker endpoint"""
url = models.TextField() url = models.TextField(
help_text=_(
(
"Can be in the format of 'unix://<path>' when connecting to a local docker daemon, "
"or 'https://<hostname>:2376' when connecting to a remote system."
)
)
)
tls_verification = models.ForeignKey( tls_verification = models.ForeignKey(
CertificateKeyPair, CertificateKeyPair,
null=True, null=True,

View File

@ -0,0 +1,92 @@
"""outpost tests"""
from shutil import rmtree
from tempfile import mkdtemp
from time import sleep
from django.test import TestCase
from docker import DockerClient, from_env
from docker.models.containers import Container
from docker.types.healthcheck import Healthcheck
from authentik.crypto.models import CertificateKeyPair
from authentik.flows.models import Flow
from authentik.outposts.apps import AuthentikOutpostConfig
from authentik.outposts.controllers.docker import DockerController
from authentik.outposts.models import DockerServiceConnection, Outpost, OutpostType
from authentik.providers.proxy.models import ProxyProvider
class OutpostDockerTests(TestCase):
"""Test Docker Controllers"""
def _start_container(self, ssl_folder: str) -> Container:
client: DockerClient = from_env()
container = client.containers.run(
image="docker.beryju.org/proxy/library/docker:dind",
detach=True,
network_mode="host",
remove=True,
privileged=True,
healthcheck=Healthcheck(
test=["CMD", "docker", "info"],
interval=5 * 100 * 1000000,
start_period=5 * 100 * 1000000,
),
environment={"DOCKER_TLS_CERTDIR": "/ssl"},
volumes={
f"{ssl_folder}/": {
"bind": "/ssl",
}
},
)
while True:
container.reload()
status = container.attrs.get("State", {}).get("Health", {}).get("Status")
if status == "healthy":
return container
sleep(1)
def setUp(self):
super().setUp()
self.ssl_folder = mkdtemp()
self.container = self._start_container(self.ssl_folder)
# Ensure that local connection have been created
AuthentikOutpostConfig.init_local_connection()
self.provider: ProxyProvider = ProxyProvider.objects.create(
name="test",
internal_host="http://localhost",
external_host="http://localhost",
authorization_flow=Flow.objects.first(),
)
authentication_kp = CertificateKeyPair.objects.create(
name="docker-authentication",
certificate_data=open(f"{self.ssl_folder}/client/cert.pem").read(),
key_data=open(f"{self.ssl_folder}/client/key.pem").read(),
)
verification_kp = CertificateKeyPair.objects.create(
name="docker-verification",
certificate_data=open(f"{self.ssl_folder}/client/ca.pem").read(),
)
self.service_connection = DockerServiceConnection.objects.create(
url="https://localhost:2376",
tls_verification=verification_kp,
tls_authentication=authentication_kp,
)
self.outpost: Outpost = Outpost.objects.create(
name="test",
type=OutpostType.PROXY,
service_connection=self.service_connection,
)
self.outpost.providers.add(self.provider)
self.outpost.save()
def tearDown(self) -> None:
super().tearDown()
self.container.kill()
rmtree(self.ssl_folder)
def test_docker_controller(self):
"""test that deployment requires update"""
controller = DockerController(self.outpost, self.service_connection)
controller.up()
controller.down()