519 lines
19 KiB
Makefile
519 lines
19 KiB
Makefile
set fallback := true
|
|
|
|
export LANGFUSE_NAMESPACE := env("LANGFUSE_NAMESPACE", "langfuse")
|
|
export LANGFUSE_CHART_VERSION := env("LANGFUSE_CHART_VERSION", "1.5.12")
|
|
export LANGFUSE_HOST := env("LANGFUSE_HOST", "")
|
|
export LANGFUSE_OIDC_CLIENT_ID := env("LANGFUSE_OIDC_CLIENT_ID", "langfuse")
|
|
export EXTERNAL_SECRETS_NAMESPACE := env("EXTERNAL_SECRETS_NAMESPACE", "external-secrets")
|
|
export K8S_VAULT_NAMESPACE := env("K8S_VAULT_NAMESPACE", "vault")
|
|
export KEYCLOAK_REALM := env("KEYCLOAK_REALM", "buunstack")
|
|
export KEYCLOAK_HOST := env("KEYCLOAK_HOST", "")
|
|
export MINIO_HOST := env("MINIO_HOST", "")
|
|
export MINIO_USER := "langfuse"
|
|
|
|
[private]
|
|
default:
|
|
@just --list --unsorted --list-submodules
|
|
|
|
# Add Helm repository
|
|
add-helm-repo:
|
|
helm repo add langfuse https://langfuse.github.io/langfuse-k8s
|
|
helm repo update
|
|
|
|
# Remove Helm repository
|
|
remove-helm-repo:
|
|
helm repo remove langfuse
|
|
|
|
# Create Langfuse namespace
|
|
create-namespace:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if ! kubectl get namespace ${LANGFUSE_NAMESPACE} &>/dev/null; then
|
|
kubectl create namespace ${LANGFUSE_NAMESPACE}
|
|
fi
|
|
kubectl label namespace ${LANGFUSE_NAMESPACE} \
|
|
pod-security.kubernetes.io/enforce=restricted \
|
|
pod-security.kubernetes.io/enforce-version=latest \
|
|
pod-security.kubernetes.io/warn=restricted \
|
|
pod-security.kubernetes.io/warn-version=latest \
|
|
--overwrite
|
|
|
|
# Delete Langfuse namespace
|
|
delete-namespace:
|
|
kubectl delete namespace ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
|
|
# Install Langfuse
|
|
install:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
just create-namespace
|
|
just create-keycloak-user
|
|
|
|
# Create PostgreSQL user and database with auto-generated password
|
|
if ! just postgres::user-exists langfuse &>/dev/null; then
|
|
PG_PASSWORD=$(just utils::random-password)
|
|
just postgres::create-user-and-db langfuse langfuse "${PG_PASSWORD}"
|
|
# Store password in Vault for later retrieval
|
|
just vault::put postgres/user/langfuse username=langfuse password="${PG_PASSWORD}"
|
|
else
|
|
echo "PostgreSQL user langfuse already exists, skipping creation"
|
|
if ! just postgres::db-exists langfuse &>/dev/null; then
|
|
just postgres::create-db langfuse
|
|
fi
|
|
fi
|
|
|
|
# Check if ClickHouse is installed (required)
|
|
if ! helm list -n clickhouse 2>/dev/null | grep -q clickhouse; then
|
|
echo "Error: ClickHouse is not installed. Please install ClickHouse first:"
|
|
echo " just clickhouse::install"
|
|
exit 1
|
|
fi
|
|
just create-clickhouse-user
|
|
just create-clickhouse-secret
|
|
|
|
# Check if MinIO is installed (required)
|
|
if ! helm list -n minio 2>/dev/null | grep -q minio; then
|
|
echo "Error: MinIO is not installed. Please install MinIO first:"
|
|
echo " just minio::install"
|
|
exit 1
|
|
fi
|
|
if ! just minio::user-exists langfuse &>/dev/null; then
|
|
just minio::create-user langfuse langfuse
|
|
else
|
|
echo "MinIO user langfuse already exists, skipping creation"
|
|
fi
|
|
just create-salt
|
|
just create-nextauth-secret
|
|
just create-redis-password
|
|
just create-keycloak-client
|
|
just create-secrets
|
|
|
|
just add-helm-repo
|
|
export MINIO_HOST=$(kubectl get ingress -n minio minio -o jsonpath='{.spec.rules[0].host}' 2>/dev/null || echo "")
|
|
LANGFUSE_SALT=$(just salt) \
|
|
NEXTAUTH_SECRET=$(just nextauth-secret) \
|
|
gomplate -f langfuse-values.gomplate.yaml -o langfuse-values.yaml
|
|
helm upgrade --install langfuse langfuse/langfuse \
|
|
--version ${LANGFUSE_CHART_VERSION} -n ${LANGFUSE_NAMESPACE} --wait \
|
|
-f langfuse-values.yaml
|
|
|
|
# Uninstall Langfuse
|
|
uninstall:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
helm uninstall langfuse -n ${LANGFUSE_NAMESPACE} --wait --ignore-not-found
|
|
kubectl delete namespace ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
|
|
# Clean up Keycloak client and Vault secrets to avoid stale credentials
|
|
just delete-keycloak-client || true
|
|
|
|
echo "Langfuse uninstalled successfully"
|
|
echo ""
|
|
echo "Note: The following resources were NOT deleted:"
|
|
echo " - PostgreSQL user and database (langfuse)"
|
|
echo " - ClickHouse user and database (langfuse)"
|
|
echo " - MinIO user and bucket (langfuse)"
|
|
echo " - Keycloak user (langfuse)"
|
|
echo ""
|
|
echo "To delete these resources, run:"
|
|
echo " just langfuse::delete-postgres-user-and-db"
|
|
echo " just langfuse::delete-clickhouse-user"
|
|
echo " just langfuse::delete-minio-user"
|
|
echo " just langfuse::delete-keycloak-user"
|
|
|
|
# Create all secrets (PostgreSQL, Keycloak, MinIO, Redis)
|
|
create-secrets:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Get PostgreSQL credentials
|
|
pg_host="postgres-cluster-rw.postgres"
|
|
pg_port="5432"
|
|
pg_user="langfuse"
|
|
pg_password=$(just vault::get postgres/user/langfuse password)
|
|
pg_database="langfuse"
|
|
database_url="postgresql://${pg_user}:${pg_password}@${pg_host}:${pg_port}/${pg_database}"
|
|
|
|
# Get OAuth client secret
|
|
# Prioritize temporary secret (freshly created) over Vault (potentially stale)
|
|
if kubectl get secret langfuse-oauth-temp -n ${LANGFUSE_NAMESPACE} &>/dev/null; then
|
|
oauth_client_id=$(kubectl get secret langfuse-oauth-temp -n ${LANGFUSE_NAMESPACE} \
|
|
-o jsonpath='{.data.client_id}' | base64 -d)
|
|
oauth_client_secret=$(kubectl get secret langfuse-oauth-temp -n ${LANGFUSE_NAMESPACE} \
|
|
-o jsonpath='{.data.client_secret}' | base64 -d)
|
|
elif helm status vault -n ${K8S_VAULT_NAMESPACE} &>/dev/null && \
|
|
just vault::get keycloak/client/langfuse client_secret &>/dev/null; then
|
|
oauth_client_id=$(just vault::get keycloak/client/langfuse client_id)
|
|
oauth_client_secret=$(just vault::get keycloak/client/langfuse client_secret)
|
|
else
|
|
echo "Error: Cannot retrieve OAuth client secret. Please run 'just langfuse::create-keycloak-client' first."
|
|
exit 1
|
|
fi
|
|
|
|
# Get Redis password
|
|
redis_password=$(just vault::get langfuse/redis secret)
|
|
|
|
if helm status external-secrets -n ${EXTERNAL_SECRETS_NAMESPACE} &>/dev/null; then
|
|
echo "External Secrets Operator detected. Storing secrets in Vault..."
|
|
|
|
# Store PostgreSQL credentials in Vault
|
|
just vault::put langfuse/postgres \
|
|
username="${pg_user}" \
|
|
password="${pg_password}" \
|
|
url="${database_url}"
|
|
|
|
# Store OAuth credentials in Vault
|
|
just vault::put keycloak/client/langfuse \
|
|
client_id="${oauth_client_id}" \
|
|
client_secret="${oauth_client_secret}"
|
|
|
|
# Redis password is already in Vault (created by create-redis-password)
|
|
|
|
# MinIO credentials are already in Vault (created by create-minio-service-account)
|
|
|
|
# Delete existing secrets and ExternalSecrets
|
|
kubectl delete secret postgres-auth -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
kubectl delete externalsecret postgres-auth-external-secret -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
kubectl delete secret keycloak-auth -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
kubectl delete externalsecret keycloak-auth-external-secret -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
kubectl delete secret redis-auth -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
kubectl delete externalsecret redis-auth-external-secret -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
|
|
# Create ExternalSecrets
|
|
gomplate -f postgres-auth-external-secret.gomplate.yaml | kubectl apply -f -
|
|
kubectl apply -n ${LANGFUSE_NAMESPACE} -f keycloak-auth-external-secret.yaml
|
|
kubectl apply -n ${LANGFUSE_NAMESPACE} -f redis-auth-external-secret.yaml
|
|
kubectl delete secret minio-auth -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
kubectl delete externalsecret minio-auth-external-secret -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
kubectl apply -n ${LANGFUSE_NAMESPACE} -f minio-auth-external-secret.yaml
|
|
|
|
echo "Waiting for ExternalSecrets to sync..."
|
|
kubectl wait --for=condition=Ready externalsecret/postgres-auth-external-secret \
|
|
-n ${LANGFUSE_NAMESPACE} --timeout=60s
|
|
kubectl wait --for=condition=Ready externalsecret/keycloak-auth-external-secret \
|
|
-n ${LANGFUSE_NAMESPACE} --timeout=60s
|
|
kubectl wait --for=condition=Ready externalsecret/redis-auth-external-secret \
|
|
-n ${LANGFUSE_NAMESPACE} --timeout=60s
|
|
kubectl wait --for=condition=Ready externalsecret/minio-auth-external-secret \
|
|
-n ${LANGFUSE_NAMESPACE} --timeout=60s
|
|
|
|
echo "ExternalSecrets created successfully"
|
|
else
|
|
echo "External Secrets Operator not found. Creating Kubernetes Secrets directly..."
|
|
|
|
# Create PostgreSQL Secret
|
|
kubectl delete secret postgres-auth -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
kubectl create secret generic postgres-auth -n ${LANGFUSE_NAMESPACE} \
|
|
--from-literal=username="${pg_user}" \
|
|
--from-literal=password="${pg_password}" \
|
|
--from-literal=url="${database_url}"
|
|
|
|
# Create Keycloak OAuth Secret
|
|
kubectl delete secret keycloak-auth -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
kubectl create secret generic keycloak-auth -n ${LANGFUSE_NAMESPACE} \
|
|
--from-literal=client_id="${oauth_client_id}" \
|
|
--from-literal=client_secret="${oauth_client_secret}"
|
|
|
|
# Create Redis Secret
|
|
kubectl delete secret redis-auth -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
kubectl create secret generic redis-auth -n ${LANGFUSE_NAMESPACE} \
|
|
--from-literal=secret="${redis_password}"
|
|
|
|
# Create MinIO Secret
|
|
minio_access_key=$(just vault::get langfuse/minio access_key)
|
|
minio_secret_key=$(just vault::get langfuse/minio secret_key)
|
|
kubectl delete secret minio-auth -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
kubectl create secret generic minio-auth -n ${LANGFUSE_NAMESPACE} \
|
|
--from-literal=access_key="${minio_access_key}" \
|
|
--from-literal=secret_key="${minio_secret_key}"
|
|
|
|
# Store credentials in Vault if available (backup for admin credentials)
|
|
if helm status vault -n ${K8S_VAULT_NAMESPACE} &>/dev/null; then
|
|
just vault::put langfuse/postgres \
|
|
username="${pg_user}" \
|
|
password="${pg_password}" \
|
|
url="${database_url}"
|
|
just vault::put keycloak/client/langfuse \
|
|
client_id="${oauth_client_id}" \
|
|
client_secret="${oauth_client_secret}"
|
|
fi
|
|
|
|
echo "Kubernetes Secrets created successfully"
|
|
fi
|
|
|
|
# Clean up temporary OAuth secret
|
|
kubectl delete secret langfuse-oauth-temp -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
|
|
# Print Postgres password (from Kubernetes Secret)
|
|
postgres-password:
|
|
@kubectl get secret postgres-auth -n ${LANGFUSE_NAMESPACE} \
|
|
-o jsonpath='{.data.password}' | base64 -d
|
|
@echo
|
|
|
|
# Print Postgres password (from Vault)
|
|
postgres-password-from-vault:
|
|
@just vault::get postgres/user/langfuse password
|
|
|
|
# Delete PostgreSQL user and database
|
|
delete-postgres-user-and-db:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if just postgres::user-exists langfuse &>/dev/null; then
|
|
just postgres::delete-user-and-db langfuse langfuse
|
|
else
|
|
echo "PostgreSQL user langfuse does not exist, skipping deletion"
|
|
fi
|
|
if just vault::exist postgres/user/langfuse &>/dev/null; then
|
|
just vault::delete postgres/user/langfuse
|
|
fi
|
|
|
|
# Create ClickHouse user and database (for external ClickHouse)
|
|
create-clickhouse-user:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Create database if it doesn't exist
|
|
if ! just clickhouse::db-exists langfuse &>/dev/null; then
|
|
just clickhouse::create-db langfuse
|
|
echo "ClickHouse database 'langfuse' created"
|
|
else
|
|
echo "ClickHouse database 'langfuse' already exists"
|
|
fi
|
|
|
|
# Create user if it doesn't exist
|
|
if just clickhouse::user-exists langfuse &>/dev/null; then
|
|
echo "ClickHouse user langfuse already exists"
|
|
# Ensure privileges are granted even if user already exists
|
|
just clickhouse::grant langfuse langfuse
|
|
exit
|
|
fi
|
|
|
|
PASSWORD=$(just utils::random-password)
|
|
just vault::put clickhouse/user/langfuse username=langfuse password="${PASSWORD}"
|
|
|
|
# Create user and grant privileges
|
|
just clickhouse::create-user langfuse "${PASSWORD}"
|
|
just clickhouse::grant langfuse langfuse
|
|
|
|
# Delete ClickHouse user and database (for external ClickHouse)
|
|
delete-clickhouse-user:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if ! just clickhouse::user-exists langfuse &>/dev/null; then
|
|
echo "ClickHouse user langfuse does not exist, skipping deletion"
|
|
exit
|
|
fi
|
|
just clickhouse::delete-user langfuse
|
|
if just clickhouse::db-exists langfuse &>/dev/null; then
|
|
just clickhouse::delete-db langfuse
|
|
fi
|
|
just vault::delete clickhouse/user/langfuse
|
|
|
|
# Create ClickHouse auth secret
|
|
create-clickhouse-secret:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if kubectl get secret clickhouse-auth -n ${LANGFUSE_NAMESPACE} &>/dev/null; then
|
|
echo "ClickHouse auth secret already exists"
|
|
exit
|
|
fi
|
|
|
|
# for external ClickHouse
|
|
PASSWORD=$(just vault::get clickhouse/user/langfuse password)
|
|
|
|
# for internal ClickHouse
|
|
# PASSWORD=$(just utils::random-password)
|
|
# just vault::put clickhouse/user/langfuse username=langfuse password="${PASSWORD}"
|
|
|
|
kubectl create secret generic clickhouse-auth -n ${LANGFUSE_NAMESPACE} \
|
|
--from-literal=password="${PASSWORD}"
|
|
|
|
# Delete ClickHouse auth secret
|
|
delete-clickhouse-secret:
|
|
kubectl delete secret clickhouse-auth -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
|
|
# Print ClickHouse password
|
|
clickhouse-password:
|
|
@kubectl get secret clickhouse-auth -n ${LANGFUSE_NAMESPACE} \
|
|
-o jsonpath='{.data.password}' | base64 -d
|
|
@echo
|
|
|
|
check-clickhouse-privilege:
|
|
kubectl exec -it clickhouse-pod -n clickhouse -- \
|
|
clickhouse-client --user=langfuse --password=$(just clickhouse-password) \
|
|
--query "SHOW GRANTS FOR langfuse"
|
|
|
|
# Delete MinIO user and bucket
|
|
delete-minio-user:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if ! just minio::user-exists langfuse &>/dev/null; then
|
|
echo "MinIO user langfuse does not exist, skipping deletion"
|
|
exit
|
|
fi
|
|
just minio::delete-user langfuse
|
|
if just vault::exist langfuse/minio &>/dev/null; then
|
|
just vault::delete langfuse/minio
|
|
fi
|
|
|
|
# Create Keycloak user
|
|
create-keycloak-user:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if just keycloak::user-exists langfuse &>/dev/null; then
|
|
echo "Keycloak user langfuse already exists, skipping creation"
|
|
exit
|
|
fi
|
|
PASSWORD=$(just utils::random-password)
|
|
just vault::put keycloak/user/langfuse username=langfuse password="${PASSWORD}"
|
|
just keycloak::create-system-user langfuse "${PASSWORD}"
|
|
|
|
# Delete keycloak user
|
|
delete-keycloak-user:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if ! just keycloak::user-exists langfuse &>/dev/null; then
|
|
echo "Keycloak user langfuse does not exist, skipping deletion"
|
|
exit
|
|
fi
|
|
just keycloak::delete-user langfuse
|
|
just vault::delete keycloak/user/langfuse
|
|
|
|
# Create Langfuse salt
|
|
create-salt:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if just vault::exist langfuse/salt &>/dev/null; then
|
|
echo "Salt for Langfuse already exists, skipping creation"
|
|
exit
|
|
fi
|
|
SALT=$(just utils::random-password)
|
|
just vault::put langfuse/salt value="${SALT}"
|
|
|
|
# Delete Langfuse salt
|
|
delete-salt:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if ! just vault::exist langfuse/salt &>/dev/null; then
|
|
echo "Salt for Langfuse does not exist, skipping deletion"
|
|
exit
|
|
fi
|
|
just vault::delete langfuse/salt
|
|
|
|
# Print Langfuse salt
|
|
salt:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if ! just vault::exist langfuse/salt &>/dev/null; then
|
|
echo "Salt for Langfuse does not exist" >&2
|
|
exit 1
|
|
fi
|
|
just vault::get langfuse/salt value
|
|
|
|
# Create NextAuth secret
|
|
create-nextauth-secret:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if just vault::exist langfuse/nextauth &>/dev/null; then
|
|
echo "Langfuse NextAuth secret already exists, skipping creation"
|
|
exit
|
|
fi
|
|
SECRET=$(just utils::random-password)
|
|
just vault::put langfuse/nextauth secret="${SECRET}"
|
|
|
|
# Delete NextAuth secret
|
|
delete-nextauth-secret:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if ! just vault::exist langfuse/nextauth &>/dev/null; then
|
|
echo "Langfuse NextAuth secret does not exist, skipping deletion"
|
|
exit
|
|
fi
|
|
just vault::delete langfuse/nextauth
|
|
|
|
# Print NextAuth secret
|
|
nextauth-secret:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if ! just vault::exist langfuse/nextauth &>/dev/null; then
|
|
echo "Langfuse NextAuth secret does not exist" >&2
|
|
exit 1
|
|
fi
|
|
just vault::get langfuse/nextauth secret
|
|
|
|
# Create Redis password
|
|
create-redis-password:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if just vault::exist langfuse/redis &>/dev/null; then
|
|
echo "Redis password already exists, skipping creation"
|
|
exit
|
|
fi
|
|
SECRET=$(just utils::random-password)
|
|
just vault::put langfuse/redis secret="${SECRET}"
|
|
|
|
# Delete Redis password
|
|
delete-redis-password:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if ! just vault::exist langfuse/redis &>/dev/null; then
|
|
echo "Redis password does not exist, skipping deletion"
|
|
exit
|
|
fi
|
|
just vault::delete langfuse/redis
|
|
|
|
# Print Redis password
|
|
redis-password:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
if ! just vault::exist langfuse/redis &>/dev/null; then
|
|
echo "Redis password does not exist" >&2
|
|
exit 1
|
|
fi
|
|
just vault::get langfuse/redis secret
|
|
echo
|
|
|
|
# Create Keycloak client for Langfuse
|
|
create-keycloak-client:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
while [ -z "${LANGFUSE_HOST}" ]; do
|
|
LANGFUSE_HOST=$(
|
|
gum input --prompt="Langfuse host (FQDN): " --width=100 \
|
|
--placeholder="e.g., langfuse.example.com"
|
|
)
|
|
done
|
|
|
|
echo "Creating Keycloak client for Langfuse..."
|
|
|
|
just keycloak::delete-client ${KEYCLOAK_REALM} ${LANGFUSE_OIDC_CLIENT_ID} || true
|
|
|
|
CLIENT_SECRET=$(just utils::random-password)
|
|
|
|
just keycloak::create-client \
|
|
realm=${KEYCLOAK_REALM} \
|
|
client_id=${LANGFUSE_OIDC_CLIENT_ID} \
|
|
redirect_url="https://${LANGFUSE_HOST}/api/auth/callback/keycloak" \
|
|
client_secret="${CLIENT_SECRET}"
|
|
|
|
kubectl delete secret langfuse-oauth-temp -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
kubectl create secret generic langfuse-oauth-temp -n ${LANGFUSE_NAMESPACE} \
|
|
--from-literal=client_id="${LANGFUSE_OIDC_CLIENT_ID}" \
|
|
--from-literal=client_secret="${CLIENT_SECRET}"
|
|
|
|
echo "Keycloak client created successfully"
|
|
echo "Client ID: ${LANGFUSE_OIDC_CLIENT_ID}"
|
|
echo "Redirect URI: https://${LANGFUSE_HOST}/api/auth/callback/keycloak"
|
|
|
|
# Delete Keycloak client for Langfuse
|
|
delete-keycloak-client:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
echo "Deleting Keycloak client for Langfuse..."
|
|
just keycloak::delete-client ${KEYCLOAK_REALM} ${LANGFUSE_OIDC_CLIENT_ID} || true
|
|
kubectl delete secret langfuse-oauth-temp -n ${LANGFUSE_NAMESPACE} --ignore-not-found
|
|
if just vault::exist keycloak/client/langfuse &>/dev/null; then
|
|
just vault::delete keycloak/client/langfuse
|
|
fi
|