outposts: allow externally managed SSH Config for outposts (#2917)

This commit is contained in:
Jens L 2022-05-21 12:10:08 +02:00 committed by GitHub
parent d9d42020cc
commit 2dee8034d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 5 deletions

View file

@ -15,7 +15,7 @@ from yaml import safe_dump
from authentik import __version__
from authentik.outposts.controllers.base import BaseClient, BaseController, ControllerException
from authentik.outposts.docker_ssh import DockerInlineSSH
from authentik.outposts.docker_ssh import DockerInlineSSH, SSHManagedExternallyException
from authentik.outposts.docker_tls import DockerInlineTLS
from authentik.outposts.managed import MANAGED_OUTPOST
from authentik.outposts.models import (
@ -35,6 +35,7 @@ class DockerClient(UpstreamDockerClient, BaseClient):
def __init__(self, connection: DockerServiceConnection):
self.tls = None
self.ssh = None
self.logger = get_logger()
if connection.local:
# Same result as DockerClient.from_env
super().__init__(**kwargs_from_env())
@ -42,8 +43,12 @@ class DockerClient(UpstreamDockerClient, BaseClient):
parsed_url = urlparse(connection.url)
tls_config = False
if parsed_url.scheme == "ssh":
self.ssh = DockerInlineSSH(parsed_url.hostname, connection.tls_authentication)
self.ssh.write()
try:
self.ssh = DockerInlineSSH(parsed_url.hostname, connection.tls_authentication)
self.ssh.write()
except SSHManagedExternallyException as exc:
# SSH config is managed externally
self.logger.info(f"SSH Managed externally: {exc}")
else:
self.tls = DockerInlineTLS(
verification_kp=connection.tls_verification,
@ -57,7 +62,6 @@ class DockerClient(UpstreamDockerClient, BaseClient):
)
except SSHException as exc:
raise ServiceConnectionInvalid from exc
self.logger = get_logger()
# Ensure the client actually works
self.containers.list()

View file

@ -16,6 +16,10 @@ def opener(path, flags):
return os.open(path, flags, 0o700)
class SSHManagedExternallyException(DockerException):
"""Raised when the ssh config file is managed externally."""
class DockerInlineSSH:
"""Create paramiko ssh config from CertificateKeyPair"""
@ -29,9 +33,15 @@ class DockerInlineSSH:
def __init__(self, host: str, keypair: CertificateKeyPair) -> None:
self.host = host
self.keypair = keypair
self.config_path = Path("~/.ssh/config").expanduser()
if self.config_path.exists() and HEADER not in self.config_path.read_text(encoding="utf-8"):
# SSH Config file already exists and there's no header from us, meaning that it's
# been externally mapped into the container for more complex configs
raise SSHManagedExternallyException(
"SSH Config exists and does not contain authentik header"
)
if not self.keypair:
raise DockerException("keypair must be set for SSH connections")
self.config_path = Path("~/.ssh/config").expanduser()
self.header = f"{HEADER} - {self.host}\n"
def write_config(self, key_path: str) -> bool: