Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3a1a1f6
add provider as "test"
Mar 25, 2026
192c530
Revert "add provider as "test""
Mar 25, 2026
580f9df
Merge remote-tracking branch 'upstream/main'
Mar 25, 2026
75b4a49
Merge remote-tracking branch 'upstream/main'
Mar 25, 2026
cb63f60
Merge remote-tracking branch 'upstream/main'
Mar 26, 2026
8b3c6c1
Merge remote-tracking branch 'upstream/main'
Mar 26, 2026
5694f11
Merge remote-tracking branch 'upstream/main'
Mar 30, 2026
8b4443f
Merge remote-tracking branch 'upstream/main'
Mar 31, 2026
c0879ae
add configurable db to deploy.sh and update helper functions
Mar 31, 2026
1a6c570
update setups docs
Mar 31, 2026
fd2fe69
update warning msg
Mar 31, 2026
a192141
switch to returning 1 for testability
Apr 1, 2026
4959fb7
Merge remote-tracking branch 'upstream/main'
Apr 1, 2026
507f60d
Merge branch 'main' into yt-allow-custom-db-connection
Apr 1, 2026
37df8ac
address coderabbit review
Apr 1, 2026
02fbc53
address coderabbit review
Apr 1, 2026
0d34bd0
rework url-enconding into a simpler implementation with comments
Apr 1, 2026
a27b033
Merge remote-tracking branch 'upstream/main'
Apr 1, 2026
641d1e8
Merge branch 'main' into yt-allow-custom-db-connection
Apr 1, 2026
eddd370
Fixed the credential exposure issue by piping the connection URL via …
Apr 1, 2026
4c5fcae
workaround for the missing xxd tool
Apr 1, 2026
67695fd
Merge remote-tracking branch 'upstream/main'
Apr 1, 2026
9a14df6
Merge branch 'main' into yt-allow-custom-db-connection
Apr 1, 2026
45bd2cb
Merge remote-tracking branch 'upstream/main'
Apr 2, 2026
8ca1daa
Merge branch 'main' into yt-allow-custom-db-connection
Apr 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/content/install/maas-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ postgresql://USERNAME:PASSWORD@HOSTNAME:PORT/DATABASE?sslmode=require

The full `scripts/deploy.sh` script also creates PostgreSQL automatically when deploying MaaS.

!!! note "Using deploy.sh with an external database"
If you use `scripts/deploy.sh`, you can supply your own PostgreSQL connection string with the `--postgres-connection` flag. This skips the built-in POC PostgreSQL deployment and creates the `maas-db-config` Secret automatically:

```bash
./scripts/deploy.sh --postgres-connection 'postgresql://username:password@hostname:5432/database?sslmode=require'
```

!!! note "Restarting maas-api"
If you add or update the Secret after the DataScienceCluster already has modelsAsService in managed state, restart the maas-api deployment to pick up the config:

Expand Down
42 changes: 41 additions & 1 deletion scripts/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
# # Test custom MaaS API image
# MAAS_API_IMAGE=quay.io/myuser/maas-api:pr-123 ./scripts/deploy.sh
#
# # Use external PostgreSQL (production)
# ./scripts/deploy.sh --postgres-connection 'postgresql://user:pass@db.example.com:5432/maas?sslmode=require'
#
# For detailed documentation, see:
# https://opendatahub-io.github.io/models-as-a-service/latest/install/maas-setup/
################################################################################
Expand Down Expand Up @@ -94,6 +97,7 @@ MAAS_API_IMAGE="${MAAS_API_IMAGE:-}"
MAAS_CONTROLLER_IMAGE="${MAAS_CONTROLLER_IMAGE:-}"
KUSTOMIZE_FORCE_CONFLICTS="${KUSTOMIZE_FORCE_CONFLICTS:-false}"
EXTERNAL_OIDC="${EXTERNAL_OIDC:-false}"
POSTGRES_CONNECTION="${POSTGRES_CONNECTION:-}"

#──────────────────────────────────────────────────────────────
# HELP TEXT
Expand Down Expand Up @@ -130,6 +134,11 @@ OPTIONS:
Creates keycloak-system namespace and deploys Keycloak operator
See docs/samples/install/keycloak/ for configuration guide

--postgres-connection <connection-string>
Use an external PostgreSQL database instead of deploying a POC instance.
Format: postgresql://USER:PASSWORD@HOST:PORT/DATABASE?sslmode=require
When set, skips the built-in PostgreSQL deployment entirely.

--namespace <namespace>
Target namespace for deployment
Default: redhat-ods-applications (RHOAI) or opendatahub (ODH)
Expand Down Expand Up @@ -181,6 +190,7 @@ ENVIRONMENT VARIABLES:
OIDC_ISSUER_URL External OIDC issuer URL for maas-api AuthPolicy patching
LOG_LEVEL Logging verbosity (DEBUG, INFO, WARN, ERROR)
KUSTOMIZE_FORCE_CONFLICTS When true, pass --force-conflicts to kubectl apply in kustomize mode (default: false)
POSTGRES_CONNECTION External PostgreSQL connection string (same as --postgres-connection)

EXAMPLES:
# Deploy ODH (default, uses kuadrant policy engine)
Expand All @@ -205,6 +215,9 @@ EXAMPLES:
--operator-catalog quay.io/opendatahub/opendatahub-operator-catalog:pr-456 \\
--operator-image quay.io/opendatahub/opendatahub-operator:pr-456

# Use an external PostgreSQL database
./scripts/deploy.sh --postgres-connection 'postgresql://user:pass@rds.example.com:5432/maas?sslmode=require'

For more information, see: https://github.com/opendatahub-io/models-as-a-service
EOF
}
Expand Down Expand Up @@ -290,6 +303,11 @@ parse_arguments() {
OPERATOR_CHANNEL="$2"
shift 2
;;
--postgres-connection)
require_flag_value "$1" "${2:-}"
POSTGRES_CONNECTION="$2"
shift 2
;;
--external-oidc)
EXTERNAL_OIDC="true"
shift
Expand Down Expand Up @@ -663,8 +681,30 @@ deploy_via_kustomize() {
# POSTGRESQL DEPLOYMENT
#──────────────────────────────────────────────────────────────

validate_postgres_connection() {
local conn="$1"
if [[ ! "$conn" =~ ^postgres(ql)?:// ]]; then
log_error "Invalid PostgreSQL connection string format"
log_error "Expected: postgresql://USER:PASSWORD@HOST:PORT/DATABASE?sslmode=require"
exit 1
fi
}

deploy_postgresql() {
NAMESPACE="$NAMESPACE" "${SCRIPT_DIR}/setup-database.sh"
if [[ -n "$POSTGRES_CONNECTION" ]]; then
validate_postgres_connection "$POSTGRES_CONNECTION"
log_info "Using external PostgreSQL connection"
create_maas_db_config_secret "$NAMESPACE" "$POSTGRES_CONNECTION"
log_info "Created maas-db-config secret with external connection"
else
log_warn "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
log_warn " DEPLOYING POC POSTGRESQL — NOT INTENDED FOR PRODUCTION USE"
log_warn " Data is stored in ephemeral storage and will be lost on pod restart."
log_warn " For production, use --postgres-connection with an external database"
log_warn " (AWS RDS, Crunchy Operator, Azure Database, etc.)"
log_warn "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
NAMESPACE="$NAMESPACE" "${SCRIPT_DIR}/setup-database.sh"
fi
}

#──────────────────────────────────────────────────────────────
Expand Down
26 changes: 26 additions & 0 deletions scripts/deployment-helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1373,3 +1373,29 @@ wait_authorino_ready() {
echo " WARNING: Auth request verification timed out, continuing anyway"
return 0
}

# ==========================================
# Database Secret Helpers
# ==========================================

# create_maas_db_config_secret <namespace> <connection_url>
# Creates the maas-db-config Secret containing DB_CONNECTION_URL.
# This secret is read by maas-api at startup to connect to PostgreSQL.
#
# Usage:
# create_maas_db_config_secret "opendatahub" "postgresql://user:pass@host:5432/db?sslmode=require"
create_maas_db_config_secret() {
local namespace="$1"
local connection_url="$2"

kubectl apply -n "$namespace" -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: maas-db-config
labels:
app: maas-api
stringData:
DB_CONNECTION_URL: "${connection_url}"
EOF
}
28 changes: 18 additions & 10 deletions scripts/setup-database.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@

set -euo pipefail

# Source helpers
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=deployment-helpers.sh
source "${SCRIPT_DIR}/deployment-helpers.sh"

# Default namespace for ODH; use redhat-ods-applications for RHOAI
: "${NAMESPACE:=opendatahub}"

Expand All @@ -34,6 +39,15 @@ if ! kubectl get namespace "$NAMESPACE" >/dev/null 2>&1; then
kubectl create namespace "$NAMESPACE"
fi

echo ""
echo "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
echo "┃ ⚠️ NOT INTENDED FOR PRODUCTION USE ┃"
echo "┃ This deploys PostgreSQL with ephemeral storage (emptyDir). ┃"
echo "┃ Data WILL be lost on pod restart. ┃"
echo "┃ For production, use an external database: ┃"
echo "┃ deploy.sh --postgres-connection postgresql://... ┃"
echo "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
echo ""
echo "🔧 Deploying PostgreSQL for API key storage in namespace '$NAMESPACE'..."

# Check if PostgreSQL already exists
Expand Down Expand Up @@ -142,18 +156,12 @@ spec:
ports:
- port: 5432
targetPort: 5432
---
apiVersion: v1
kind: Secret
metadata:
name: maas-db-config
labels:
app: maas-api
purpose: poc
stringData:
DB_CONNECTION_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=disable"
EOF

# Create the maas-db-config secret used by maas-api
DB_CONNECTION_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=disable"
create_maas_db_config_secret "$NAMESPACE" "$DB_CONNECTION_URL"

echo " Waiting for PostgreSQL to be ready..."
if ! kubectl wait -n "$NAMESPACE" --for=condition=available deployment/postgres --timeout=120s; then
echo "❌ PostgreSQL deployment failed to become ready" >&2
Expand Down
Loading