Changeset 0.28.6 (#192)

This commit is contained in:
2026-03-15 01:33:38 +00:00
parent 6f0ad1355c
commit bffda043db
59 changed files with 3022 additions and 77 deletions

25
chart/templates/NOTES.txt Normal file
View File

@@ -0,0 +1,25 @@
Chat Switchboard {{ .Chart.AppVersion }} deployed.
{{- if .Values.ingress.enabled }}
Access the application at:
{{- if .Values.ingress.tls.enabled }}
https://{{ .Values.ingress.host }}{{ .Values.basePath }}
{{- else }}
http://{{ .Values.ingress.host }}{{ .Values.basePath }}
{{- end }}
{{- else }}
Port-forward to access:
kubectl port-forward svc/{{ .Release.Name }}-frontend 3000:{{ .Values.frontend.port }}
open http://localhost:3000{{ .Values.basePath }}
{{- end }}
{{- if .Values.admin.password }}
Admin credentials set via Helm values.
{{- else }}
⚠ No admin password set. Set admin.password in values or an existing secret.
{{- end }}
{{- if not .Values.encryptionKey }}
⚠ ENCRYPTION_KEY not set. BYOK provider keys cannot be encrypted.
Set encryptionKey in values for production use.
{{- end }}

View File

@@ -0,0 +1,64 @@
{{/*
Common labels
*/}}
{{- define "switchboard.labels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
{{- end }}
{{/*
Backend selector labels
*/}}
{{- define "switchboard.backend.labels" -}}
app.kubernetes.io/component: backend
{{ include "switchboard.labels" . }}
{{- end }}
{{/*
Frontend selector labels
*/}}
{{- define "switchboard.frontend.labels" -}}
app.kubernetes.io/component: frontend
{{ include "switchboard.labels" . }}
{{- end }}
{{/*
Secret name
*/}}
{{- define "switchboard.secretName" -}}
{{- if .Values.existingSecret -}}
{{ .Values.existingSecret }}
{{- else -}}
{{ .Release.Name }}-secrets
{{- end -}}
{{- end }}
{{/*
Backend image
*/}}
{{- define "switchboard.backend.image" -}}
{{ .Values.backend.image.repository }}:{{ .Values.backend.image.tag | default .Chart.AppVersion }}
{{- end }}
{{/*
Frontend image
*/}}
{{- define "switchboard.frontend.image" -}}
{{ .Values.frontend.image.repository }}:{{ .Values.frontend.image.tag | default .Chart.AppVersion }}
{{- end }}
{{/*
Database URL assembled from postgres.* if url is empty
*/}}
{{- define "switchboard.databaseURL" -}}
{{- if .Values.database.url -}}
{{ .Values.database.url }}
{{- else if eq .Values.database.driver "sqlite" -}}
{{ .Values.database.sqlitePath }}
{{- else -}}
postgres://{{ .Values.database.postgres.user }}:$(POSTGRES_PASSWORD)@{{ .Values.database.postgres.host }}:{{ .Values.database.postgres.port }}/{{ .Values.database.postgres.database }}?sslmode={{ .Values.database.postgres.sslmode }}
{{- end -}}
{{- end }}

View File

@@ -0,0 +1,49 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-config
labels:
{{- include "switchboard.labels" . | nindent 4 }}
data:
PORT: {{ .Values.backend.port | quote }}
BASE_PATH: {{ .Values.basePath | quote }}
ENVIRONMENT: {{ .Values.environment | quote }}
DB_DRIVER: {{ .Values.database.driver | quote }}
AUTH_MODE: {{ .Values.auth.mode | quote }}
STORAGE_BACKEND: {{ .Values.storage.backend | quote }}
STORAGE_PATH: {{ .Values.storage.path | quote }}
SESSION_EXPIRY_DAYS: {{ .Values.sessionExpiryDays | quote }}
WORKFLOW_STALE_HOURS: {{ .Values.workflowStaleHours | quote }}
PROVIDER_AUTO_DISABLE_THRESHOLD: {{ .Values.providerAutoDisableThreshold | quote }}
EXTRACTION_MODE: {{ .Values.extraction.mode | quote }}
EXTRACTION_CONCURRENCY: {{ .Values.extraction.concurrency | quote }}
WORKSPACE_INDEXING_ENABLED: {{ .Values.workspace.indexingEnabled | quote }}
WORKSPACE_INDEX_CONCURRENCY: {{ .Values.workspace.indexConcurrency | quote }}
CORS_ALLOWED_ORIGINS: {{ .Values.corsAllowedOrigins | quote }}
{{- if .Values.storage.s3.endpoint }}
S3_ENDPOINT: {{ .Values.storage.s3.endpoint | quote }}
S3_BUCKET: {{ .Values.storage.s3.bucket | quote }}
S3_REGION: {{ .Values.storage.s3.region | quote }}
S3_PREFIX: {{ .Values.storage.s3.prefix | quote }}
S3_FORCE_PATH_STYLE: {{ .Values.storage.s3.forcePathStyle | quote }}
{{- end }}
{{- if eq .Values.auth.mode "oidc" }}
OIDC_ISSUER_URL: {{ .Values.auth.oidc.issuerURL | quote }}
OIDC_EXTERNAL_ISSUER_URL: {{ .Values.auth.oidc.externalIssuerURL | quote }}
OIDC_CLIENT_ID: {{ .Values.auth.oidc.clientID | quote }}
OIDC_REDIRECT_URL: {{ .Values.auth.oidc.redirectURL | quote }}
OIDC_AUTO_ACTIVATE: {{ .Values.auth.oidc.autoActivate | quote }}
OIDC_DEFAULT_TEAM: {{ .Values.auth.oidc.defaultTeam | quote }}
OIDC_DEFAULT_ROLE: {{ .Values.auth.oidc.defaultRole | quote }}
OIDC_ROLES_CLAIM: {{ .Values.auth.oidc.rolesClaim | quote }}
OIDC_GROUPS_CLAIM: {{ .Values.auth.oidc.groupsClaim | quote }}
OIDC_ADMIN_ROLE: {{ .Values.auth.oidc.adminRole | quote }}
{{- end }}
{{- if eq .Values.auth.mode "mtls" }}
MTLS_HEADER_DN: {{ .Values.auth.mtls.headerDN | quote }}
MTLS_HEADER_VERIFY: {{ .Values.auth.mtls.headerVerify | quote }}
MTLS_HEADER_FINGERPRINT: {{ .Values.auth.mtls.headerFingerprint | quote }}
MTLS_AUTO_ACTIVATE: {{ .Values.auth.mtls.autoActivate | quote }}
MTLS_DEFAULT_TEAM: {{ .Values.auth.mtls.defaultTeam | quote }}
MTLS_DEFAULT_ROLE: {{ .Values.auth.mtls.defaultRole | quote }}
{{- end }}

View File

@@ -0,0 +1,65 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-backend
labels:
{{- include "switchboard.backend.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.backend.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: backend
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: backend
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: backend
image: {{ include "switchboard.backend.image" . }}
imagePullPolicy: {{ .Values.backend.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.backend.port }}
protocol: TCP
envFrom:
- configMapRef:
name: {{ .Release.Name }}-config
- secretRef:
name: {{ include "switchboard.secretName" . }}
env:
- name: DATABASE_URL
value: {{ include "switchboard.databaseURL" . | quote }}
resources:
{{- toYaml .Values.backend.resources | nindent 12 }}
{{- if .Values.persistence.enabled }}
volumeMounts:
- name: data
mountPath: /data
{{- end }}
livenessProbe:
httpGet:
path: {{ .Values.basePath }}/api/v1/health
port: http
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: {{ .Values.basePath }}/api/v1/health
port: http
initialDelaySeconds: 5
periodSeconds: 10
{{- if .Values.persistence.enabled }}
volumes:
- name: data
persistentVolumeClaim:
claimName: {{ .Release.Name }}-data
{{- end }}

View File

@@ -0,0 +1,50 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-frontend
labels:
{{- include "switchboard.frontend.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.frontend.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: frontend
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: frontend
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: frontend
image: {{ include "switchboard.frontend.image" . }}
imagePullPolicy: {{ .Values.frontend.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.frontend.port }}
protocol: TCP
env:
- name: BACKEND_URL
value: "http://{{ .Release.Name }}-backend:{{ .Values.backend.port }}"
- name: BASE_PATH
value: {{ .Values.basePath | quote }}
resources:
{{- toYaml .Values.frontend.resources | nindent 12 }}
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 5
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: http
periodSeconds: 10

View File

@@ -0,0 +1,51 @@
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}-ingress
labels:
{{- include "switchboard.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls.enabled }}
tls:
- hosts:
- {{ .Values.ingress.host }}
{{- if .Values.ingress.tls.secretName }}
secretName: {{ .Values.ingress.tls.secretName }}
{{- end }}
{{- end }}
rules:
- host: {{ .Values.ingress.host }}
http:
paths:
# API + WebSocket → backend
- path: {{ .Values.basePath }}/api
pathType: Prefix
backend:
service:
name: {{ .Release.Name }}-backend
port:
number: {{ .Values.backend.port }}
- path: {{ .Values.basePath }}/ws
pathType: Prefix
backend:
service:
name: {{ .Release.Name }}-backend
port:
number: {{ .Values.backend.port }}
# Everything else → frontend (nginx serves static + proxies API)
- path: {{ .Values.basePath | default "/" }}
pathType: Prefix
backend:
service:
name: {{ .Release.Name }}-frontend
port:
number: {{ .Values.frontend.port }}
{{- end }}

17
chart/templates/pvc.yaml Normal file
View File

@@ -0,0 +1,17 @@
{{- if .Values.persistence.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ .Release.Name }}-data
labels:
{{- include "switchboard.labels" . | nindent 4 }}
spec:
accessModes:
- {{ .Values.persistence.accessMode }}
{{- if .Values.persistence.storageClass }}
storageClassName: {{ .Values.persistence.storageClass | quote }}
{{- end }}
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- end }}

View File

@@ -0,0 +1,31 @@
{{- if not .Values.existingSecret }}
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-secrets
labels:
{{- include "switchboard.labels" . | nindent 4 }}
type: Opaque
stringData:
JWT_SECRET: {{ required "jwtSecret is required" .Values.jwtSecret | quote }}
{{- if .Values.encryptionKey }}
ENCRYPTION_KEY: {{ .Values.encryptionKey | quote }}
{{- end }}
{{- if .Values.database.postgres.password }}
POSTGRES_PASSWORD: {{ .Values.database.postgres.password | quote }}
{{- end }}
{{- if .Values.admin.password }}
SWITCHBOARD_ADMIN_USERNAME: {{ .Values.admin.username | quote }}
SWITCHBOARD_ADMIN_PASSWORD: {{ .Values.admin.password | quote }}
{{- end }}
{{- if .Values.admin.email }}
SWITCHBOARD_ADMIN_EMAIL: {{ .Values.admin.email | quote }}
{{- end }}
{{- if .Values.storage.s3.accessKey }}
S3_ACCESS_KEY: {{ .Values.storage.s3.accessKey | quote }}
S3_SECRET_KEY: {{ .Values.storage.s3.secretKey | quote }}
{{- end }}
{{- if and (eq .Values.auth.mode "oidc") .Values.auth.oidc.clientSecret }}
OIDC_CLIENT_SECRET: {{ .Values.auth.oidc.clientSecret | quote }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,35 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-backend
labels:
{{- include "switchboard.backend.labels" . | nindent 4 }}
spec:
type: ClusterIP
ports:
- port: {{ .Values.backend.port }}
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: backend
---
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-frontend
labels:
{{- include "switchboard.frontend.labels" . | nindent 4 }}
spec:
type: ClusterIP
ports:
- port: {{ .Values.frontend.port }}
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: frontend