outposts: include protocol in outpost deployment ports

This commit is contained in:
Jens Langhammer 2020-12-28 17:18:01 +01:00
parent 1a292feebb
commit 22ce142cb8
9 changed files with 55 additions and 25 deletions

View File

@ -1,5 +1,5 @@
"""Base Controller"""
from typing import Dict, List
from dataclasses import dataclass
from structlog import get_logger
from structlog.testing import capture_logs
@ -7,15 +7,26 @@ from structlog.testing import capture_logs
from authentik.lib.sentry import SentryIgnoredException
from authentik.outposts.models import Outpost, OutpostServiceConnection
FIELD_MANAGER = "goauthentik.io"
class ControllerException(SentryIgnoredException):
"""Exception raised when anything fails during controller run"""
@dataclass
class DeploymentPort:
"""Info about deployment's single port."""
port: int
name: str
protocol: str
class BaseController:
"""Base Outpost deployment controller"""
deployment_ports: Dict[str, int]
deployment_ports: list[DeploymentPort]
outpost: Outpost
connection: OutpostServiceConnection
@ -24,14 +35,14 @@ class BaseController:
self.outpost = outpost
self.connection = connection
self.logger = get_logger()
self.deployment_ports = {}
self.deployment_ports = []
# pylint: disable=invalid-name
def up(self):
"""Called by scheduled task to reconcile deployment/service/etc"""
raise NotImplementedError
def up_with_logs(self) -> List[str]:
def up_with_logs(self) -> list[str]:
"""Call .up() but capture all log output and return it."""
with capture_logs() as logs:
self.up()

View File

@ -68,7 +68,10 @@ class DockerController(BaseController):
"image": image_name,
"name": f"authentik-proxy-{self.outpost.uuid.hex}",
"detach": True,
"ports": {x: x for _, x in self.deployment_ports.items()},
"ports": {
f"{port.port}/{port.protocol.lower()}": port.port
for port in self.deployment_ports
},
"environment": self._get_env(),
"labels": self._get_labels(),
}
@ -139,7 +142,10 @@ class DockerController(BaseController):
def get_static_deployment(self) -> str:
"""Generate docker-compose yaml for proxy, version 3.5"""
ports = [f"{x}:{x}" for _, x in self.deployment_ports.items()]
ports = [
f"{port.port}:{port.port}/{port.protocol.lower()}"
for port in self.deployment_ports
]
image_prefix = CONFIG.y("outposts.docker_image_base")
compose = {
"version": "3.5",

View File

@ -18,11 +18,11 @@ from kubernetes.client import (
from authentik import __version__
from authentik.lib.config import CONFIG
from authentik.outposts.controllers.base import FIELD_MANAGER
from authentik.outposts.controllers.k8s.base import (
KubernetesObjectReconciler,
NeedsUpdate,
)
from authentik.outposts.controllers.kubernetes import FIELD_MANAGER
from authentik.outposts.models import Outpost
if TYPE_CHECKING:
@ -65,8 +65,14 @@ class DeploymentReconciler(KubernetesObjectReconciler[V1Deployment]):
"""Get deployment object for outpost"""
# Generate V1ContainerPort objects
container_ports = []
for port_name, port in self.controller.deployment_ports.items():
container_ports.append(V1ContainerPort(container_port=port, name=port_name))
for port in self.controller.deployment_ports:
container_ports.append(
V1ContainerPort(
container_port=port.port,
name=port.name,
protocol=port.protocol.upper(),
)
)
meta = self.get_object_meta(name=self.name)
secret_name = f"authentik-outpost-{self.controller.outpost.uuid.hex}-api"
image_prefix = CONFIG.y("outposts.docker_image_base")

View File

@ -4,11 +4,11 @@ from typing import TYPE_CHECKING
from kubernetes.client import CoreV1Api, V1Secret
from authentik.outposts.controllers.base import FIELD_MANAGER
from authentik.outposts.controllers.k8s.base import (
KubernetesObjectReconciler,
NeedsUpdate,
)
from authentik.outposts.controllers.kubernetes import FIELD_MANAGER
if TYPE_CHECKING:
from authentik.outposts.controllers.kubernetes import KubernetesController

View File

@ -3,12 +3,12 @@ from typing import TYPE_CHECKING
from kubernetes.client import CoreV1Api, V1Service, V1ServicePort, V1ServiceSpec
from authentik.outposts.controllers.base import FIELD_MANAGER
from authentik.outposts.controllers.k8s.base import (
KubernetesObjectReconciler,
NeedsUpdate,
)
from authentik.outposts.controllers.k8s.deployment import DeploymentReconciler
from authentik.outposts.controllers.kubernetes import FIELD_MANAGER
if TYPE_CHECKING:
from authentik.outposts.controllers.kubernetes import KubernetesController
@ -37,8 +37,15 @@ class ServiceReconciler(KubernetesObjectReconciler[V1Service]):
"""Get deployment object for outpost"""
meta = self.get_object_meta(name=self.name)
ports = []
for port_name, port in self.controller.deployment_ports.items():
ports.append(V1ServicePort(name=port_name, port=port))
for port in self.controller.deployment_ports:
ports.append(
V1ServicePort(
name=port.name,
port=port.port,
protocol=port.protocol.upper(),
target_port=port.port,
)
)
selector_labels = DeploymentReconciler(self.controller).get_pod_meta()
return V1Service(
metadata=meta,

View File

@ -14,8 +14,6 @@ from authentik.outposts.controllers.k8s.secret import SecretReconciler
from authentik.outposts.controllers.k8s.service import ServiceReconciler
from authentik.outposts.models import KubernetesServiceConnection, Outpost
FIELD_MANAGER = "goauthentik.io"
class KubernetesController(BaseController):
"""Manage deployment of outpost in kubernetes"""

View File

@ -2,6 +2,7 @@
from typing import Dict
from urllib.parse import urlparse
from authentik.outposts.controllers.base import DeploymentPort
from authentik.outposts.controllers.docker import DockerController
from authentik.outposts.models import DockerServiceConnection, Outpost
from authentik.providers.proxy.models import ProxyProvider
@ -12,10 +13,10 @@ class ProxyDockerController(DockerController):
def __init__(self, outpost: Outpost, connection: DockerServiceConnection):
super().__init__(outpost, connection)
self.deployment_ports = {
"http": 4180,
"https": 4443,
}
self.deployment_ports = [
DeploymentPort(4180, "http", "tcp"),
DeploymentPort(4443, "https", "tcp"),
]
def _get_labels(self) -> Dict[str, str]:
hosts = []

View File

@ -15,11 +15,11 @@ from kubernetes.client.models.networking_v1beta1_ingress_rule import (
NetworkingV1beta1IngressRule,
)
from authentik.outposts.controllers.base import FIELD_MANAGER
from authentik.outposts.controllers.k8s.base import (
KubernetesObjectReconciler,
NeedsUpdate,
)
from authentik.outposts.controllers.kubernetes import FIELD_MANAGER
from authentik.providers.proxy.models import ProxyProvider
if TYPE_CHECKING:
@ -106,7 +106,7 @@ class IngressReconciler(KubernetesObjectReconciler[NetworkingV1beta1Ingress]):
NetworkingV1beta1HTTPIngressPath(
backend=NetworkingV1beta1IngressBackend(
service_name=self.name,
service_port=self.controller.deployment_ports["http"],
service_port="http",
),
path="/",
)

View File

@ -1,4 +1,5 @@
"""Proxy Provider Kubernetes Contoller"""
from authentik.outposts.controllers.base import DeploymentPort
from authentik.outposts.controllers.kubernetes import KubernetesController
from authentik.outposts.models import KubernetesServiceConnection, Outpost
from authentik.providers.proxy.controllers.k8s.ingress import IngressReconciler
@ -9,9 +10,9 @@ class ProxyKubernetesController(KubernetesController):
def __init__(self, outpost: Outpost, connection: KubernetesServiceConnection):
super().__init__(outpost, connection)
self.deployment_ports = {
"http": 4180,
"https": 4443,
}
self.deployment_ports = [
DeploymentPort(4180, "http", "tcp"),
DeploymentPort(4443, "https", "tcp"),
]
self.reconcilers["ingress"] = IngressReconciler
self.reconcile_order.append("ingress")