Merge branch 'master' into outpost-ldap

This commit is contained in:
Jens Langhammer
2021-04-24 22:22:01 +02:00
105 changed files with 1092 additions and 813 deletions

View File

@ -1,17 +1,8 @@
"""authentik outposts app config"""
from importlib import import_module
from os import R_OK, access
from os.path import expanduser
from pathlib import Path
from socket import gethostname
from urllib.parse import urlparse
import yaml
from django.apps import AppConfig
from django.db import ProgrammingError
from docker.constants import DEFAULT_UNIX_SOCKET
from kubernetes.config.incluster_config import SERVICE_TOKEN_FILENAME
from kubernetes.config.kube_config import KUBE_CONFIG_DEFAULT_LOCATION
from structlog.stdlib import get_logger
LOGGER = get_logger()
@ -27,49 +18,8 @@ class AuthentikOutpostConfig(AppConfig):
def ready(self):
import_module("authentik.outposts.signals")
try:
AuthentikOutpostConfig.init_local_connection()
from authentik.outposts.tasks import outpost_local_connection
outpost_local_connection.delay()
except ProgrammingError:
pass
@staticmethod
def init_local_connection():
"""Check if local kubernetes or docker connections should be created"""
from authentik.outposts.models import (
DockerServiceConnection,
KubernetesServiceConnection,
)
# Explicitly check against token filename, as thats
# only present when the integration is enabled
if Path(SERVICE_TOKEN_FILENAME).exists():
LOGGER.debug("Detected in-cluster Kubernetes Config")
if not KubernetesServiceConnection.objects.filter(local=True).exists():
LOGGER.debug("Created Service Connection for in-cluster")
KubernetesServiceConnection.objects.create(
name="Local Kubernetes Cluster", local=True, kubeconfig={}
)
# For development, check for the existence of a kubeconfig file
kubeconfig_path = expanduser(KUBE_CONFIG_DEFAULT_LOCATION)
if Path(kubeconfig_path).exists():
LOGGER.debug("Detected kubeconfig")
kubeconfig_local_name = f"k8s-{gethostname()}"
if not KubernetesServiceConnection.objects.filter(
name=kubeconfig_local_name
).exists():
LOGGER.debug("Creating kubeconfig Service Connection")
with open(kubeconfig_path, "r") as _kubeconfig:
KubernetesServiceConnection.objects.create(
name=kubeconfig_local_name,
kubeconfig=yaml.safe_load(_kubeconfig),
)
unix_socket_path = urlparse(DEFAULT_UNIX_SOCKET).path
socket = Path(unix_socket_path)
if socket.exists() and access(socket, R_OK):
LOGGER.debug("Detected local docker socket")
if len(DockerServiceConnection.objects.filter(local=True)) == 0:
LOGGER.debug("Created Service Connection for docker")
DockerServiceConnection.objects.create(
name="Local Docker connection",
local=True,
url=unix_socket_path,
)

View File

@ -9,7 +9,7 @@ CELERY_BEAT_SCHEDULE = {
},
"outposts_service_connection_check": {
"task": "authentik.outposts.tasks.outpost_service_connection_monitor",
"schedule": crontab(minute=0, hour="*"),
"schedule": crontab(minute="*/60"),
"options": {"queue": "authentik_scheduled"},
},
"outpost_token_ensurer": {
@ -17,4 +17,9 @@ CELERY_BEAT_SCHEDULE = {
"schedule": crontab(minute="*/5"),
"options": {"queue": "authentik_scheduled"},
},
"outpost_local_connection": {
"task": "authentik.outposts.tasks.outpost_local_connection",
"schedule": crontab(minute="*/60"),
"options": {"queue": "authentik_scheduled"},
},
}

View File

@ -1,11 +1,20 @@
"""outpost tasks"""
from os import R_OK, access
from os.path import expanduser
from pathlib import Path
from socket import gethostname
from typing import Any
from urllib.parse import urlparse
import yaml
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from django.core.cache import cache
from django.db.models.base import Model
from django.utils.text import slugify
from docker.constants import DEFAULT_UNIX_SOCKET
from kubernetes.config.incluster_config import SERVICE_TOKEN_FILENAME
from kubernetes.config.kube_config import KUBE_CONFIG_DEFAULT_LOCATION
from structlog.stdlib import get_logger
from authentik.events.monitored_tasks import MonitoredTask, TaskResult, TaskResultStatus
@ -185,3 +194,42 @@ def _outpost_single_update(outpost: Outpost, layer=None):
for state in OutpostState.for_outpost(outpost):
LOGGER.debug("sending update", channel=state.uid, outpost=outpost)
async_to_sync(layer.send)(state.uid, {"type": "event.update"})
@CELERY_APP.task()
def outpost_local_connection():
"""Checks the local environment and create Service connections."""
# Explicitly check against token filename, as thats
# only present when the integration is enabled
if Path(SERVICE_TOKEN_FILENAME).exists():
LOGGER.debug("Detected in-cluster Kubernetes Config")
if not KubernetesServiceConnection.objects.filter(local=True).exists():
LOGGER.debug("Created Service Connection for in-cluster")
KubernetesServiceConnection.objects.create(
name="Local Kubernetes Cluster", local=True, kubeconfig={}
)
# For development, check for the existence of a kubeconfig file
kubeconfig_path = expanduser(KUBE_CONFIG_DEFAULT_LOCATION)
if Path(kubeconfig_path).exists():
LOGGER.debug("Detected kubeconfig")
kubeconfig_local_name = f"k8s-{gethostname()}"
if not KubernetesServiceConnection.objects.filter(
name=kubeconfig_local_name
).exists():
LOGGER.debug("Creating kubeconfig Service Connection")
with open(kubeconfig_path, "r") as _kubeconfig:
KubernetesServiceConnection.objects.create(
name=kubeconfig_local_name,
kubeconfig=yaml.safe_load(_kubeconfig),
)
unix_socket_path = urlparse(DEFAULT_UNIX_SOCKET).path
socket = Path(unix_socket_path)
if socket.exists() and access(socket, R_OK):
LOGGER.debug("Detected local docker socket")
if len(DockerServiceConnection.objects.filter(local=True)) == 0:
LOGGER.debug("Created Service Connection for docker")
DockerServiceConnection.objects.create(
name="Local Docker connection",
local=True,
url=unix_socket_path,
)