feat: clean control plane — remove all example tenant resources
- Removed cameleer3-server and cameleer3-server-ui from docker-compose (tenants provision their own server instances via the vendor console) - Removed viewer/camel user from bootstrap (tenant users created during provisioning) - Removed Phase 7 server OIDC configuration (provisioned servers get OIDC config from env vars, claim mappings via Logto Custom JWT) - Removed server-related env vars from bootstrap (SERVER_ENDPOINT, etc.) - Removed jardata volume from dev overlay Clean slate: docker compose up gives you Traefik + PostgreSQL + ClickHouse + Logto + SaaS platform + vendor seed. Everything else (servers, tenants, users) created through the vendor console. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -31,31 +31,6 @@ services:
|
||||
CAMELEER_NETWORK: cameleer-saas_cameleer
|
||||
CAMELEER_TRAEFIK_NETWORK: cameleer-traefik
|
||||
|
||||
cameleer3-server:
|
||||
ports:
|
||||
- "8081:8081"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- jardata:/data/jars
|
||||
group_add:
|
||||
- "0"
|
||||
environment:
|
||||
CAMELEER_RUNTIME_ENABLED: "true"
|
||||
CAMELEER_JAR_STORAGE_PATH: /data/jars
|
||||
CAMELEER_RUNTIME_BASE_IMAGE: gitea.siegeln.net/cameleer/cameleer-runtime-base:latest
|
||||
CAMELEER_DOCKER_NETWORK: cameleer-saas_cameleer
|
||||
CAMELEER_SERVER_URL: http://cameleer3-server:8081
|
||||
CAMELEER_ROUTING_DOMAIN: ${PUBLIC_HOST:-localhost}
|
||||
CAMELEER_ROUTING_MODE: path
|
||||
CAMELEER_JAR_DOCKER_VOLUME: cameleer-saas_jardata
|
||||
|
||||
cameleer3-server-ui:
|
||||
ports:
|
||||
- "8082:80"
|
||||
|
||||
clickhouse:
|
||||
ports:
|
||||
- "8123:8123"
|
||||
|
||||
volumes:
|
||||
jardata:
|
||||
|
||||
@@ -103,8 +103,6 @@ services:
|
||||
depends_on:
|
||||
logto:
|
||||
condition: service_healthy
|
||||
cameleer3-server:
|
||||
condition: service_healthy
|
||||
restart: "no"
|
||||
entrypoint: ["sh", "/scripts/logto-bootstrap.sh"]
|
||||
environment:
|
||||
@@ -119,12 +117,6 @@ services:
|
||||
PG_DB_SAAS: ${POSTGRES_DB:-cameleer_saas}
|
||||
SAAS_ADMIN_USER: ${SAAS_ADMIN_USER:-admin}
|
||||
SAAS_ADMIN_PASS: ${SAAS_ADMIN_PASS:-admin}
|
||||
TENANT_ADMIN_USER: ${TENANT_ADMIN_USER:-camel}
|
||||
TENANT_ADMIN_PASS: ${TENANT_ADMIN_PASS:-camel}
|
||||
CAMELEER_AUTH_TOKEN: ${CAMELEER_AUTH_TOKEN:-default-bootstrap-token}
|
||||
SERVER_ENDPOINT: http://cameleer3-server:8081
|
||||
SERVER_UI_USER: ${CAMELEER_UI_USER:-admin}
|
||||
SERVER_UI_PASS: ${CAMELEER_UI_PASSWORD:-admin}
|
||||
volumes:
|
||||
- ./docker/logto-bootstrap.sh:/scripts/logto-bootstrap.sh:ro
|
||||
- bootstrapdata:/data
|
||||
@@ -151,7 +143,6 @@ services:
|
||||
LOGTO_JWK_SET_URI: ${LOGTO_ENDPOINT:-http://logto:3001}/oidc/jwks
|
||||
LOGTO_M2M_CLIENT_ID: ${LOGTO_M2M_CLIENT_ID:-}
|
||||
LOGTO_M2M_CLIENT_SECRET: ${LOGTO_M2M_CLIENT_SECRET:-}
|
||||
CAMELEER3_SERVER_ENDPOINT: http://cameleer3-server:8081
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.saas.rule=PathPrefix(`/platform`)
|
||||
@@ -161,62 +152,6 @@ services:
|
||||
networks:
|
||||
- cameleer
|
||||
|
||||
cameleer3-server:
|
||||
image: ${CAMELEER3_SERVER_IMAGE:-gitea.siegeln.net/cameleer/cameleer3-server}:${VERSION:-latest}
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
clickhouse:
|
||||
condition: service_started
|
||||
environment:
|
||||
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/cameleer3
|
||||
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-cameleer}
|
||||
SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-cameleer_dev}
|
||||
CLICKHOUSE_URL: jdbc:clickhouse://clickhouse:8123/cameleer
|
||||
CAMELEER_AUTH_TOKEN: ${CAMELEER_AUTH_TOKEN:-default-bootstrap-token}
|
||||
CAMELEER_JWT_SECRET: ${CAMELEER_JWT_SECRET:-cameleer-dev-jwt-secret-change-in-production}
|
||||
CAMELEER_TENANT_ID: ${CAMELEER_TENANT_SLUG:-default}
|
||||
CAMELEER_OIDC_ISSUER_URI: ${PUBLIC_PROTOCOL:-https}://${PUBLIC_HOST:-localhost}/oidc
|
||||
CAMELEER_OIDC_JWK_SET_URI: ${LOGTO_ENDPOINT:-http://logto:3001}/oidc/jwks
|
||||
CAMELEER_OIDC_TLS_SKIP_VERIFY: "true" # dev only — disable in production with real certs
|
||||
CAMELEER_OIDC_AUDIENCE: ${CAMELEER_OIDC_AUDIENCE:-https://api.cameleer.local}
|
||||
CAMELEER_CORS_ALLOWED_ORIGINS: ${PUBLIC_PROTOCOL:-https}://${PUBLIC_HOST:-localhost}
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -sf http://localhost:8081/api/v1/health || exit 1"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 30
|
||||
start_period: 15s
|
||||
labels:
|
||||
- traefik.enable=false
|
||||
networks:
|
||||
cameleer:
|
||||
cameleer-traefik:
|
||||
aliases:
|
||||
- cameleer3-server
|
||||
|
||||
cameleer3-server-ui:
|
||||
image: ${CAMELEER3_SERVER_UI_IMAGE:-gitea.siegeln.net/cameleer/cameleer3-server-ui}:${VERSION:-latest}
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
cameleer3-server:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
CAMELEER_API_URL: http://cameleer3-server:8081
|
||||
BASE_PATH: /server
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.server-ui.rule=PathPrefix(`/server`)
|
||||
- traefik.http.routers.server-ui.entrypoints=websecure
|
||||
- traefik.http.routers.server-ui.tls=true
|
||||
- traefik.http.routers.server-ui.middlewares=server-ui-strip
|
||||
- traefik.http.middlewares.server-ui-strip.stripprefix.prefixes=/server
|
||||
- traefik.http.routers.server-ui.service=server-ui
|
||||
- traefik.http.services.server-ui.loadbalancer.server.port=80
|
||||
networks:
|
||||
- cameleer
|
||||
|
||||
clickhouse:
|
||||
image: clickhouse/clickhouse-server:latest
|
||||
restart: unless-stopped
|
||||
|
||||
@@ -504,104 +504,10 @@ fi
|
||||
fi # end: ADMIN_TOKEN check
|
||||
fi # end: M_ADMIN_SECRET check
|
||||
|
||||
# --- Viewer user (for testing read-only OIDC role in server) ---
|
||||
log "Checking for viewer user '$TENANT_ADMIN_USER'..."
|
||||
TENANT_USER_ID=$(api_get "/api/users?search=$TENANT_ADMIN_USER" | jq -r ".[] | select(.username == \"$TENANT_ADMIN_USER\") | .id")
|
||||
if [ -n "$TENANT_USER_ID" ]; then
|
||||
log "Viewer user exists: $TENANT_USER_ID"
|
||||
else
|
||||
log "Creating viewer user '$TENANT_ADMIN_USER'..."
|
||||
TENANT_RESPONSE=$(api_post "/api/users" "{
|
||||
\"username\": \"$TENANT_ADMIN_USER\",
|
||||
\"password\": \"$TENANT_ADMIN_PASS\",
|
||||
\"name\": \"Viewer\"
|
||||
}")
|
||||
TENANT_USER_ID=$(echo "$TENANT_RESPONSE" | jq -r '.id')
|
||||
log "Created viewer user: $TENANT_USER_ID"
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# PHASE 6: Create organization + add users
|
||||
# ============================================================
|
||||
|
||||
# No example organization created — the vendor creates tenants via the SaaS UI.
|
||||
# Users (admin, viewer) are created above but not added to any org.
|
||||
# No viewer user — tenant users are created by the vendor during tenant provisioning.
|
||||
# No example organization — tenants are created via the vendor console.
|
||||
# No server OIDC config — each provisioned server gets OIDC from env vars.
|
||||
ORG_ID=""
|
||||
log "Skipping example organization (tenants are created by the vendor)."
|
||||
|
||||
# ============================================================
|
||||
# PHASE 7: Configure cameleer3-server OIDC
|
||||
# ============================================================
|
||||
|
||||
SERVER_HEALTHY="no"
|
||||
for i in 1 2 3; do
|
||||
if curl -sf "${SERVER_ENDPOINT}/api/v1/health" >/dev/null 2>&1; then
|
||||
SERVER_HEALTHY="yes"
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
log "Phase 7 check: SERVER_HEALTHY=$SERVER_HEALTHY, TRAD_SECRET length=${#TRAD_SECRET}"
|
||||
|
||||
if [ "$SERVER_HEALTHY" = "yes" ] && [ -n "$TRAD_SECRET" ]; then
|
||||
log "Configuring cameleer3-server OIDC..."
|
||||
|
||||
# Login to server as admin
|
||||
SERVER_TOKEN_RESPONSE=$(curl -s -X POST "${SERVER_ENDPOINT}/api/v1/auth/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"username\": \"$SERVER_UI_USER\", \"password\": \"$SERVER_UI_PASS\"}")
|
||||
SERVER_TOKEN=$(echo "$SERVER_TOKEN_RESPONSE" | jq -r '.accessToken' 2>/dev/null)
|
||||
|
||||
if [ -n "$SERVER_TOKEN" ] && [ "$SERVER_TOKEN" != "null" ]; then
|
||||
# Configure OIDC
|
||||
OIDC_RESPONSE=$(curl -s -X PUT "${SERVER_ENDPOINT}/api/v1/admin/oidc" \
|
||||
-H "Authorization: Bearer $SERVER_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"enabled\": true,
|
||||
\"issuerUri\": \"$LOGTO_PUBLIC_ENDPOINT/oidc\",
|
||||
\"clientId\": \"$TRAD_ID\",
|
||||
\"clientSecret\": \"$TRAD_SECRET\",
|
||||
\"autoSignup\": true,
|
||||
\"defaultRoles\": [\"VIEWER\"],
|
||||
\"displayNameClaim\": \"name\",
|
||||
\"rolesClaim\": \"roles\",
|
||||
\"audience\": \"$API_RESOURCE_INDICATOR\",
|
||||
\"additionalScopes\": []
|
||||
}")
|
||||
log "OIDC config response: $(echo "$OIDC_RESPONSE" | head -c 200)"
|
||||
log "cameleer3-server OIDC configured."
|
||||
|
||||
# Seed claim mapping rules (roles → server RBAC)
|
||||
log "Seeding claim mapping rules..."
|
||||
EXISTING_MAPPINGS=$(curl -s -H "Authorization: Bearer $SERVER_TOKEN" \
|
||||
"${SERVER_ENDPOINT}/api/v1/admin/claim-mappings" 2>/dev/null || echo "[]")
|
||||
|
||||
seed_claim_mapping() {
|
||||
local match_value="$1"
|
||||
local target="$2"
|
||||
local priority="$3"
|
||||
local exists=$(echo "$EXISTING_MAPPINGS" | jq -r ".[] | select(.matchValue == \"$match_value\") | .id")
|
||||
if [ -n "$exists" ]; then
|
||||
log " Claim mapping '$match_value' → $target exists"
|
||||
else
|
||||
local resp=$(curl -s -X POST "${SERVER_ENDPOINT}/api/v1/admin/claim-mappings" \
|
||||
-H "Authorization: Bearer $SERVER_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"claim\":\"roles\",\"matchType\":\"contains\",\"matchValue\":\"$match_value\",\"action\":\"assignRole\",\"target\":\"$target\",\"priority\":$priority}")
|
||||
log " Created claim mapping '$match_value' → $target"
|
||||
fi
|
||||
}
|
||||
|
||||
seed_claim_mapping "server:admin" "ADMIN" 10
|
||||
seed_claim_mapping "server:operator" "OPERATOR" 20
|
||||
log "Claim mapping rules seeded."
|
||||
else
|
||||
log "WARNING: Could not login to cameleer3-server — skipping OIDC config"
|
||||
fi
|
||||
else
|
||||
log "WARNING: cameleer3-server not available or no Traditional app secret — skipping OIDC config"
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# PHASE 7b: Configure Logto Custom JWT for access tokens
|
||||
|
||||
Reference in New Issue
Block a user