#!/usr/bin/env bash # deploy/onboarding/import-users.sh # # Bulk-imports users from a CSV file into Veylant IA. # # CSV format (with header): # email,first_name,last_name,department,role # # Usage: # export VEYLANT_URL=http://localhost:8090 # export VEYLANT_ADMIN_TOKEN= # ./import-users.sh deploy/onboarding/sample-users.csv # # Required env vars: # VEYLANT_URL - base URL of the proxy (no trailing slash) # VEYLANT_ADMIN_TOKEN - JWT with admin role set -euo pipefail VEYLANT_URL="${VEYLANT_URL:?VEYLANT_URL is required}" VEYLANT_ADMIN_TOKEN="${VEYLANT_ADMIN_TOKEN:?VEYLANT_ADMIN_TOKEN is required}" CSV_FILE="${1:?Usage: $0 }" [[ -f "$CSV_FILE" ]] || { echo "ERROR: file not found: $CSV_FILE" >&2; exit 1; } API="${VEYLANT_URL}/v1/admin" AUTH="Authorization: Bearer ${VEYLANT_ADMIN_TOKEN}" log() { echo "[import-users] $*"; } success=0 failed=0 skip=0 # Skip header line, process each row while IFS=',' read -r email first_name last_name department role; do # Skip empty lines and header [[ -z "$email" || "$email" == "email" ]] && { ((skip++)) || true; continue; } log "Importing ${email} (${role}, ${department})…" http_code=$(curl -s -o /dev/null -w "%{http_code}" \ -X POST "${API}/users" \ -H "${AUTH}" \ -H "Content-Type: application/json" \ -d "{ \"email\": \"${email}\", \"first_name\": \"${first_name}\", \"last_name\": \"${last_name}\", \"department\": \"${department}\", \"role\": \"${role}\" }") if [[ "$http_code" == "201" ]]; then log " → created (201)" ((success++)) || true elif [[ "$http_code" == "409" ]]; then log " → already exists, skipped (409)" ((skip++)) || true else log " → ERROR: HTTP ${http_code}" ((failed++)) || true fi done < "$CSV_FILE" log "" log "Import summary:" log " Created : ${success}" log " Skipped : ${skip}" log " Errors : ${failed}" if [[ "$failed" -gt 0 ]]; then log "WARNING: ${failed} user(s) failed to import. Check logs above." exit 1 fi