Skip to content

Commit

Permalink
outposts: add support for provider-specific websocket messages
Browse files Browse the repository at this point in the history
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
  • Loading branch information
BeryJu committed Oct 8, 2023
1 parent b90ed6b commit be86903
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 2 deletions.
14 changes: 14 additions & 0 deletions authentik/outposts/channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class WebsocketMessageInstruction(IntEnum):
# Message sent by us to trigger an Update
TRIGGER_UPDATE = 2

# Provider specific message
PROVIDER_SPECIFIC = 3


@dataclass(slots=True)
class WebsocketMessage:
Expand Down Expand Up @@ -131,3 +134,14 @@ def event_update(self, event): # pragma: no cover
self.send_json(
asdict(WebsocketMessage(instruction=WebsocketMessageInstruction.TRIGGER_UPDATE))
)

def event_provider_specific(self, event):
"""Event handler which can be called by provider-specific
implementations to send specific messages to the outpost"""
self.send_json(
asdict(
WebsocketMessage(
instruction=WebsocketMessageInstruction.PROVIDER_SPECIFIC, args=event
)
)
)
4 changes: 2 additions & 2 deletions authentik/outposts/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from typing import Any, Optional
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
Expand All @@ -16,6 +15,7 @@
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 yaml import safe_load

from authentik.events.monitored_tasks import (
MonitoredTask,
Expand Down Expand Up @@ -279,7 +279,7 @@ def outpost_connection_discovery(self: MonitoredTask):
with kubeconfig_path.open("r", encoding="utf8") as _kubeconfig:
KubernetesServiceConnection.objects.create(
name=kubeconfig_local_name,
kubeconfig=yaml.safe_load(_kubeconfig),
kubeconfig=safe_load(_kubeconfig),
)
unix_socket_path = urlparse(DEFAULT_UNIX_SOCKET).path
socket = Path(unix_socket_path)
Expand Down
8 changes: 8 additions & 0 deletions internal/outpost/ak/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
log "github.com/sirupsen/logrus"
)

type WSHandler func(ctx context.Context, args map[string]interface{})

const ConfigLogLevel = "log_level"

// APIController main controller which connects to the authentik api via http and ws
Expand All @@ -42,6 +44,7 @@ type APIController struct {
lastWsReconnect time.Time
wsIsReconnecting bool
wsBackoffMultiplier int
wsHandlers []WSHandler
refreshHandlers []func()

instanceUUID uuid.UUID
Expand Down Expand Up @@ -106,6 +109,7 @@ func NewAPIController(akURL url.URL, token string) *APIController {
reloadOffset: time.Duration(rand.Intn(10)) * time.Second,
instanceUUID: uuid.New(),
Outpost: outpost,
wsHandlers: []WSHandler{},
wsBackoffMultiplier: 1,
refreshHandlers: make([]func(), 0),
}
Expand Down Expand Up @@ -156,6 +160,10 @@ func (a *APIController) AddRefreshHandler(handler func()) {
a.refreshHandlers = append(a.refreshHandlers, handler)
}

func (a *APIController) AddWSHandler(handler WSHandler) {
a.wsHandlers = append(a.wsHandlers, handler)
}

func (a *APIController) OnRefresh() error {
// Because we don't know the outpost UUID, we simply do a list and pick the first
// The service account this token belongs to should only have access to a single outpost
Expand Down
5 changes: 5 additions & 0 deletions internal/outpost/ak/api_ws.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ak

import (
"context"
"crypto/tls"
"fmt"
"net/http"
Expand Down Expand Up @@ -145,6 +146,10 @@ func (ac *APIController) startWSHandler() {
"build": constants.BUILD("tagged"),
}).SetToCurrentTime()
}
} else if wsMsg.Instruction == WebsocketInstructionProviderSpecific {
for _, h := range ac.wsHandlers {
h(context.Background(), wsMsg.Args)
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions internal/outpost/ak/api_ws_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const (
WebsocketInstructionHello websocketInstruction = 1
// WebsocketInstructionTriggerUpdate Code received to trigger a config update
WebsocketInstructionTriggerUpdate websocketInstruction = 2
// WebsocketInstructionProviderSpecific Code received to trigger some provider specific function
WebsocketInstructionProviderSpecific websocketInstruction = 3
)

type websocketMessage struct {
Expand Down

0 comments on commit be86903

Please sign in to comment.