feat: Authentik login + switchable GPU prod target

Add OIDC auth for Command Center and runtime GPU endpoint selection
pointed at atc-gpu-prod (10.0.10.106), matching what is currently deployed.
This commit is contained in:
mo
2026-07-21 23:20:24 +00:00
parent f36c8906bc
commit 9008fbd512
31 changed files with 4667 additions and 139 deletions
+58 -8
View File
@@ -6,6 +6,8 @@ import type {
CdcStats,
DataflowGraph,
FeedEntry,
GpuConfigPayload,
GpuConfigTestResult,
GpuStatus,
Movement,
PiiDataset,
@@ -21,7 +23,7 @@ async function fetchJson<T>(url: string, timeoutMs = 10000): Promise<T | null> {
const ctrl = new AbortController()
const timer = setTimeout(() => ctrl.abort(), timeoutMs)
try {
const r = await fetch(url, { signal: ctrl.signal })
const r = await fetch(url, { signal: ctrl.signal, credentials: 'same-origin' })
if (!r.ok) return null
return (await r.json()) as T
} catch {
@@ -62,6 +64,54 @@ export async function fetchGpu(): Promise<GpuStatus | null> {
return fetchJson<GpuStatus>('/api/gpu', 8000)
}
export async function fetchGpuConfig(): Promise<GpuConfigPayload | null> {
return fetchJson<GpuConfigPayload>('/api/gpu/config', 8000)
}
export async function saveGpuConfig(body: {
preset_id?: string
host?: string
gpu_ui_port?: number
llm_port?: number
}) {
const r = await fetch('/api/gpu/config', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
})
return r.json()
}
export async function testGpuConfig(body: {
preset_id?: string
host?: string
gpu_ui_port?: number
llm_port?: number
}): Promise<GpuConfigTestResult | null> {
const ctrl = new AbortController()
const timer = setTimeout(() => ctrl.abort(), 12000)
try {
const r = await fetch('/api/gpu/config/test', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
signal: ctrl.signal,
})
if (!r.ok) return null
return (await r.json()) as GpuConfigTestResult
} catch {
return null
} finally {
clearTimeout(timer)
}
}
export async function resetGpuConfig() {
const r = await fetch('/api/gpu/config', { method: 'DELETE' , credentials: 'same-origin' })
return r.json()
}
export async function fetchTerminals(): Promise<Record<string, TerminalLine[]>> {
const j = await fetchJson<{ terminals?: Record<string, TerminalLine[]> }>('/api/terminals', 8000)
return j?.terminals || {}
@@ -77,7 +127,7 @@ export async function fetchNodeDetail(nodeId: string) {
}
export function probeNode(nodeId: string) {
return fetch(`/api/nodes/${nodeId}/probe`, { method: 'POST' })
return fetch(`/api/nodes/${nodeId}/probe`, { method: 'POST' , credentials: 'same-origin' })
}
export function askNode(nodeId: string, message: string) {
@@ -207,19 +257,19 @@ export function triggerStreamingJob(jobId: string, conf?: Record<string, unknown
}
export function restartKafkaConnector(name: string) {
return fetch(`/api/pipeline/streaming/kafka/connectors/${encodeURIComponent(name)}/restart`, { method: 'POST' })
return fetch(`/api/pipeline/streaming/kafka/connectors/${encodeURIComponent(name)}/restart`, { method: 'POST' , credentials: 'same-origin' })
}
export function pauseKafkaConnector(name: string) {
return fetch(`/api/pipeline/streaming/kafka/connectors/${encodeURIComponent(name)}/pause`, { method: 'POST' })
return fetch(`/api/pipeline/streaming/kafka/connectors/${encodeURIComponent(name)}/pause`, { method: 'POST' , credentials: 'same-origin' })
}
export function resumeKafkaConnector(name: string) {
return fetch(`/api/pipeline/streaming/kafka/connectors/${encodeURIComponent(name)}/resume`, { method: 'POST' })
return fetch(`/api/pipeline/streaming/kafka/connectors/${encodeURIComponent(name)}/resume`, { method: 'POST' , credentials: 'same-origin' })
}
export function triggerStreamingPipeline(pipelineId: string) {
return fetch(`/api/pipeline/streaming/pipeline/${encodeURIComponent(pipelineId)}`, { method: 'POST' })
return fetch(`/api/pipeline/streaming/pipeline/${encodeURIComponent(pipelineId)}`, { method: 'POST' , credentials: 'same-origin' })
}
export function exportHdfsToKafka(body?: { path?: string; topic?: string; limit?: number }) {
@@ -231,7 +281,7 @@ export function exportHdfsToKafka(body?: { path?: string; topic?: string; limit?
}
export function setStreamingFlow(action: 'pause' | 'resume' | 'stop') {
return fetch(`/api/pipeline/streaming/flow/${action}`, { method: 'POST' })
return fetch(`/api/pipeline/streaming/flow/${action}`, { method: 'POST' , credentials: 'same-origin' })
}
// ── Spark Workbench ──────────────────────────────────────────────
@@ -271,7 +321,7 @@ export async function fetchSparkRun(runId: string) {
}
export function cancelSparkRun(runId: string) {
return fetch(`/api/spark/run/${runId}/cancel`, { method: 'POST' })
return fetch(`/api/spark/run/${runId}/cancel`, { method: 'POST' , credentials: 'same-origin' })
}
export async function fetchSparkLive() {