Skip to content

Bulk User and Provider Setup

This document provides information about setting up multiple providers, users, and models using automated scripts. The script automates the process of configuring your AI Controller with the necessary components for immediate use.

Setup Script Overview

The setup script handles the following tasks:

  • License Configuration: Registers your AI Controller license
  • Provider Setup: Adds AI providers with their respective models and API keys
  • User Account Creation: Creates user accounts with appropriate roles and permissions
  • Verification: Checks that all components were properly configured

Using the Setup Script

The setup script is available in both Bash (for Linux/Mac) and PowerShell (for Windows) formats. Choose the appropriate script for your operating system.

#!/bin/bash

# Debug and verify flags
DEBUG=0
VERIFY_ONLY=0

# Parse command line arguments
while getopts "dv" opt; do
  case $opt in
    d)
      DEBUG=1
      echo "Debug mode enabled"
      ;;
    v)
      VERIFY_ONLY=1
      echo "Verification mode enabled"
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      echo "Usage: $0 [-d] [-v]" >&2
      echo "  -d: Debug mode" >&2
      echo "  -v: Verification only mode" >&2
      exit 1
      ;;
  esac
done

# Debug print function
debug_print() {
    if [ $DEBUG -eq 1 ]; then
        echo "[DEBUG] $1"
    fi
}

# Base URL from the docker setup
BASE_URL="http://localhost:8080"

# Read the configuration data
CONFIG_DATA=$(cat config.json)
debug_print "Read configuration data: ${CONFIG_DATA}"

# Function to handle errors
check_response() {
    if [ $1 -ne 0 ]; then
        echo "Error: $2 failed with status code $1"
        exit 1
    fi
}

# Set curl verbose flag based on debug mode
CURL_OPTS="-s -k"
if [ $DEBUG -eq 1 ]; then
    CURL_OPTS="-v -s -k"
fi

echo "Logging in to AIC server..."

# Extract access token from AICUserCookie
LOGIN_RESPONSE=$(curl $CURL_OPTS -i -X POST \
    -H "Content-Type: application/vnd.api+json" \
    -d '{"data":{"attributes":{"grantType":"password","userName":"admin","password":"admin"}}}' \
    "${BASE_URL}/login/")

debug_print "Login response: ${LOGIN_RESPONSE}"

# Extract AICUserCookie from the login response
ACCESS_TOKEN=$(echo "$LOGIN_RESPONSE" | grep -i "Set-Cookie" | grep "AICUserCookie" | cut -d"=" -f2 | cut -d";" -f1)

check_response $? "Login"
debug_print "Access token obtained: ${ACCESS_TOKEN}"
echo "Successfully logged in"

# Setup function
perform_setup() {
    # Check and setup License
    if echo "${CONFIG_DATA}" | jq -e '.license' > /dev/null; then
        echo "Setting up license..."
        LICENSE_KEY=$(echo "${CONFIG_DATA}" | jq -r '.license.licenseKey')
        LICENSE_REQUEST='{"data":{"attributes":{"licenceKey":"'${LICENSE_KEY}'"}}}' 

        debug_print "License request payload: ${LICENSE_REQUEST}"

        LICENSE_RESPONSE=$(curl $CURL_OPTS -i -X PATCH \
            -H "Content-Type: application/vnd.api+json" \
            -H "Cookie: AICUserCookie=${ACCESS_TOKEN}" \
            --data "${LICENSE_REQUEST}" \
            "${BASE_URL}/licensing/")

        check_response $? "License addition"
        echo "✓ License setup completed"

        # Short pause to allow the license to be processed
        sleep 10
    else
        echo "⚠ No license configuration found, skipping license setup"
    fi

    # Check and setup Providers
    if echo "${CONFIG_DATA}" | jq -e '.providers' > /dev/null; then
        echo "Adding providers and their models..."
        for provider in $(echo "${CONFIG_DATA}" | jq -c '.providers[]'); do
            name=$(echo $provider | jq -r '.name')
            debug_print "Processing provider: ${name}"

            provider_request='{"data":{"attributes":'$(echo $provider)'}}'
            debug_print "Provider request payload: ${provider_request}"

            provider_response=$(curl $CURL_OPTS -i -X POST \
                -H "Content-Type: application/vnd.api+json" \
                -H "Cookie: AICUserCookie=${ACCESS_TOKEN}" \
                --data "${provider_request}" \
                "${BASE_URL}/providers/")

            response_code=$(echo "$provider_response" | head -n 1 | awk '{print $2}')
            if [ "$response_code" != "201" ]; then
                echo "❌ Failed to add provider: ${name}"
                echo "Response: ${provider_response}"
                exit 1
            fi

            echo "✓ Added provider: ${name}"
        done
    else
        echo "⚠ No providers configuration found, skipping providers setup"
    fi

    # Check and setup Users
    if echo "${CONFIG_DATA}" | jq -e '.users' > /dev/null; then
        echo "Adding users..."
        added_count=0
        skipped_count=0

        echo "${CONFIG_DATA}" | jq -c '.users[]' | while read -r user; do
            username=$(echo $user | jq -r '.userName')
            debug_print "Processing user: ${username}"

            user_request='{"data":{"attributes":'$(echo $user)'}}'
            debug_print "User request payload: ${user_request}"

            user_response=$(curl $CURL_OPTS -i -X POST \
                -H "Content-Type: application/vnd.api+json" \
                -H "Cookie: AICUserCookie=${ACCESS_TOKEN}" \
                --data "${user_request}" \
                "${BASE_URL}/users/")

            response_code=$(echo "$user_response" | head -n 1 | awk '{print $2}')
            debug_print "Response code: ${response_code}"

            if [ "$response_code" = "201" ]; then
                echo "✓ Added user: ${username}"
                added_count=$((added_count + 1))
            elif [ "$response_code" = "409" ]; then
                echo "⚠ Skipped existing user: ${username}"
                skipped_count=$((skipped_count + 1))
            else
                echo "❌ Failed to add user: ${username}"
                echo "Response: ${user_response}"
                exit 1
            fi
        done
    else
        echo "⚠ No users configuration found, skipping users setup"
    fi
}

# Verification function
perform_verification() {
    echo -e "\nVerifying setup..."

    # License verification
    if echo "${CONFIG_DATA}" | jq -e '.license' > /dev/null; then
        echo "Verifying license..."
        LICENSE_STATUS=$(curl $CURL_OPTS -X GET \
            -H "Content-Type: application/vnd.api+json" \
            -H "Cookie: AICUserCookie=${ACCESS_TOKEN}" \
            "${BASE_URL}/licensing/")

        if echo "$LICENSE_STATUS" | grep -q '"valid":true'; then
            echo "✓ License verification successful"
        else
            echo "✗ License verification failed"
            exit 1
        fi
    fi

    # Providers verification
    if echo "${CONFIG_DATA}" | jq -e '.providers' > /dev/null; then
        echo "Verifying providers..."
        PROVIDERS_RESPONSE=$(curl $CURL_OPTS -X GET \
            -H "Content-Type: application/vnd.api+json" \
            -H "Cookie: AICUserCookie=${ACCESS_TOKEN}" \
            "${BASE_URL}/providers/")

        expected_providers=$(echo "${CONFIG_DATA}" | jq '.providers | length')
        actual_providers=$(echo "${PROVIDERS_RESPONSE}" | jq '. | length')

        if [ "$actual_providers" -eq "$expected_providers" ]; then
            echo "✓ Providers verification successful"
        else
            echo "✗ Providers verification failed (expected: ${expected_providers}, actual: ${actual_providers})"
            exit 1
        fi
    fi

    # Users verification
    if echo "${CONFIG_DATA}" | jq -e '.users' > /dev/null; then
        echo "Verifying users..."
        USERS_RESPONSE=$(curl $CURL_OPTS -X GET \
            -H "Content-Type: application/vnd.api+json" \
            -H "Cookie: AICUserCookie=${ACCESS_TOKEN}" \
            "${BASE_URL}/users/")

        actual_users=$(echo "${USERS_RESPONSE}" | jq '. | length')
        expected_users=$(echo "${CONFIG_DATA}" | jq '.users | length')

        if [ "$actual_users" -ge "$expected_users" ]; then
            echo "✓ Users verification successful"
        else
            echo "✗ Users verification failed (expected at least: ${expected_users}, actual: ${actual_users})"
            exit 1
        fi
    fi

    echo -e "\nVerification completed successfully!"
}

# Main execution logic
if [ $VERIFY_ONLY -eq 1 ]; then
    perform_verification
else
    perform_setup
    perform_verification
fi
# Debug and verify flags
param(
    [switch]$Debug,
    [switch]$VerifyOnly
)

# Debug print function
function Debug-Print {
    param([string]$Message)
    if ($Debug) {
        Write-Host "[DEBUG] $Message" -ForegroundColor Cyan
    }
}

# Base URL from the docker setup
$BASE_URL = "http://localhost:8080"

# Read the configuration data
$CONFIG_DATA = Get-Content -Raw -Path "config.json" | ConvertFrom-Json
Debug-Print "Read configuration data: $($CONFIG_DATA | ConvertTo-Json -Compress)"

# Function to handle errors
function Check-Response {
    param(
        [int]$StatusCode,
        [string]$Operation
    )
    if ($StatusCode -lt 200 -or $StatusCode -ge 300) {
        Write-Host "Error: $Operation failed with status code $StatusCode" -ForegroundColor Red
        exit 1
    }
}

# Invoke REST API with proper parameters
function Invoke-AicApi {
    param(
        [string]$Method,
        [string]$Uri,
        [object]$Body = $null,
        [string]$ContentType = "application/vnd.api+json",
        [string]$Cookie = ""
    )

    $headers = @{
        "Content-Type" = $ContentType
    }

    if ($Cookie) {
        $headers["Cookie"] = "AICUserCookie=$Cookie"
    }

    $params = @{
        Method = $Method
        Uri = $Uri
        Headers = $headers
        UseBasicParsing = $true
    }

    if ($Body) {
        $params["Body"] = ($Body | ConvertTo-Json -Depth 10 -Compress)
    }

    if ($Debug) {
        Write-Host "Request: $Method $Uri" -ForegroundColor Gray
        if ($Body) {
            Write-Host "Request Body: $($params.Body)" -ForegroundColor Gray
        }
    }

    try {
        $response = Invoke-WebRequest @params
        return $response
    }
    catch {
        $statusCode = $_.Exception.Response.StatusCode.value__
        $statusDescription = $_.Exception.Response.StatusDescription

        if ($Debug) {
            Write-Host "Response Status: $statusCode $statusDescription" -ForegroundColor Red
            if ($_.ErrorDetails.Message) {
                Write-Host "Response Body: $($_.ErrorDetails.Message)" -ForegroundColor Red
            }
        }

        return [PSCustomObject]@{
            StatusCode = $statusCode
            Content = $_.ErrorDetails.Message
            Headers = $_.Exception.Response.Headers
        }
    }
}

Write-Host "Logging in to AIC server..." -ForegroundColor Green

# Login to get access token
$loginBody = @{
    data = @{
        attributes = @{
            grantType = "password"
            userName = "admin"
            password = "admin"
        }
    }
}

$loginResponse = Invoke-AicApi -Method "POST" -Uri "$BASE_URL/login/" -Body $loginBody
Debug-Print "Login response status: $($loginResponse.StatusCode)"

# Extract AICUserCookie from the login response
$cookieHeader = $loginResponse.Headers["Set-Cookie"]
$ACCESS_TOKEN = ($cookieHeader -split ";" | Where-Object { $_ -match "AICUserCookie=" }) -replace "AICUserCookie=", ""

Check-Response -StatusCode $loginResponse.StatusCode -Operation "Login"
Debug-Print "Access token obtained: $ACCESS_TOKEN"
Write-Host "Successfully logged in" -ForegroundColor Green

# Setup function
function Perform-Setup {
    # Check and setup License
    if ($CONFIG_DATA.license) {
        Write-Host "Setting up license..." -ForegroundColor Green
        $licenseKey = $CONFIG_DATA.license.licenseKey
        $licenseBody = @{
            data = @{
                attributes = @{
                    licenceKey = $licenseKey
                }
            }
        }

        Debug-Print "License request payload: $($licenseBody | ConvertTo-Json -Compress)"

        $licenseResponse = Invoke-AicApi -Method "PATCH" -Uri "$BASE_URL/licensing/" -Body $licenseBody -Cookie $ACCESS_TOKEN
        Check-Response -StatusCode $licenseResponse.StatusCode -Operation "License addition"
        Write-Host "✓ License setup completed" -ForegroundColor Green

        # Short pause to allow the license to be processed
        Start-Sleep -Seconds 10
    }
    else {
        Write-Host "⚠ No license configuration found, skipping license setup" -ForegroundColor Yellow
    }

    # Check and setup Providers
    if ($CONFIG_DATA.providers) {
        Write-Host "Adding providers and their models..." -ForegroundColor Green
        foreach ($provider in $CONFIG_DATA.providers) {
            $name = $provider.name
            Debug-Print "Processing provider: $name"

            $providerBody = @{
                data = @{
                    attributes = $provider
                }
            }

            Debug-Print "Provider request payload: $($providerBody | ConvertTo-Json -Compress)"

            $providerResponse = Invoke-AicApi -Method "POST" -Uri "$BASE_URL/providers/" -Body $providerBody -Cookie $ACCESS_TOKEN

            if ($providerResponse.StatusCode -ne 201) {
                Write-Host "❌ Failed to add provider: $name" -ForegroundColor Red
                Write-Host "Response: $($providerResponse.Content)" -ForegroundColor Red
                exit 1
            }

            Write-Host "✓ Added provider: $name" -ForegroundColor Green
        }
    }
    else {
        Write-Host "⚠ No providers configuration found, skipping providers setup" -ForegroundColor Yellow
    }

    # Check and setup Users
    if ($CONFIG_DATA.users) {
        Write-Host "Adding users..." -ForegroundColor Green
        $addedCount = 0
        $skippedCount = 0

        foreach ($user in $CONFIG_DATA.users) {
            $username = $user.userName
            Debug-Print "Processing user: $username"

            $userBody = @{
                data = @{
                    attributes = $user
                }
            }

            Debug-Print "User request payload: $($userBody | ConvertTo-Json -Compress)"

            $userResponse = Invoke-AicApi -Method "POST" -Uri "$BASE_URL/users/" -Body $userBody -Cookie $ACCESS_TOKEN

            if ($userResponse.StatusCode -eq 201) {
                Write-Host "✓ Added user: $username" -ForegroundColor Green
                $addedCount++
            }
            elseif ($userResponse.StatusCode -eq 409) {
                Write-Host "⚠ Skipped existing user: $username" -ForegroundColor Yellow
                $skippedCount++
            }
            else {
                Write-Host "❌ Failed to add user: $username" -ForegroundColor Red
                Write-Host "Response: $($userResponse.Content)" -ForegroundColor Red
                exit 1
            }
        }

        Write-Host "User addition summary: $addedCount added, $skippedCount skipped" -ForegroundColor Green
    }
    else {
        Write-Host "⚠ No users configuration found, skipping users setup" -ForegroundColor Yellow
    }
}

# Verification function
function Perform-Verification {
    Write-Host "`nVerifying setup..." -ForegroundColor Green

    # License verification
    if ($CONFIG_DATA.license) {
        Write-Host "Verifying license..." -ForegroundColor Green
        $licenseResponse = Invoke-AicApi -Method "GET" -Uri "$BASE_URL/licensing/" -Cookie $ACCESS_TOKEN
        $licenseStatus = $licenseResponse.Content | ConvertFrom-Json

        if ($licenseStatus.valid -eq $true) {
            Write-Host "✓ License verification successful" -ForegroundColor Green
        }
        else {
            Write-Host "✗ License verification failed" -ForegroundColor Red
            exit 1
        }
    }

    # Providers verification
    if ($CONFIG_DATA.providers) {
        Write-Host "Verifying providers..." -ForegroundColor Green
        $providersResponse = Invoke-AicApi -Method "GET" -Uri "$BASE_URL/providers/" -Cookie $ACCESS_TOKEN
        $providers = $providersResponse.Content | ConvertFrom-Json

        $expectedProviders = $CONFIG_DATA.providers.Count
        $actualProviders = $providers.Count

        if ($actualProviders -eq $expectedProviders) {
            Write-Host "✓ Providers verification successful" -ForegroundColor Green
        }
        else {
            Write-Host "✗ Providers verification failed (expected: $expectedProviders, actual: $actualProviders)" -ForegroundColor Red
            exit 1
        }
    }

    # Users verification
    if ($CONFIG_DATA.users) {
        Write-Host "Verifying users..." -ForegroundColor Green
        $usersResponse = Invoke-AicApi -Method "GET" -Uri "$BASE_URL/users/" -Cookie $ACCESS_TOKEN
        $users = $usersResponse.Content | ConvertFrom-Json

        $expectedUsers = $CONFIG_DATA.users.Count
        $actualUsers = $users.Count

        if ($actualUsers -ge $expectedUsers) {
            Write-Host "✓ Users verification successful" -ForegroundColor Green
        }
        else {
            Write-Host "✗ Users verification failed (expected at least: $expectedUsers, actual: $actualUsers)" -ForegroundColor Red
            exit 1
        }
    }

    Write-Host "`nVerification completed successfully!" -ForegroundColor Green
}

# Main execution logic
if ($VerifyOnly) {
    Perform-Verification
}
else {
    Perform-Setup
    Perform-Verification
}

Configuration File

The setup script requires a JSON configuration file that defines the providers, models, users, and license information. Create a file named config.json with the following structure:

{
  "license": {
    "licenseKey": "your-license-key-here"
  },
  "providers": [
    {
      "id": 1,
      "name": "openai",
      "url": "https://api.openai.com/v1/chat/completions",
      "authMethod": "Bearer",
      "apiKey": "your-api-key-here",
      "models": [
        "gpt-4o",
        "gpt-3.5-turbo",
        "dall-e-3"
      ]
    },
    {
      "id": 2,
      "name": "anthropic",
      "url": "https://api.anthropic.com/v1/messages",
      "authMethod": "Bearer",
      "apiKey": "your-api-key-here",
      "models": [
        "claude-3-opus-20240229",
        "claude-3-sonnet-20240229",
        "claude-3-haiku-20240307"
      ]
    }
  ],
  "users": [
    {
      "userName": "john.doe",
      "password": "SecurePassword123",
      "displayName": "John Doe",
      "email": "john.doe@example.com",
      "active": true,
      "isDeleted": false,
      "roles": [{"id": 2, "name": "User"}]
    },
    {
      "userName": "jane.smith",
      "password": "SecurePassword456",
      "displayName": "Jane Smith",
      "email": "jane.smith@example.com",
      "active": true,
      "isDeleted": false,
      "roles": [{"id": 1, "name": "Admin"}]
    }
  ]
}

Running the Script

Prerequisites

  • For the Bash script:

    • Linux or macOS system
    • curl and jq installed
    • Bash shell
  • For the PowerShell script:

    • Windows system
    • PowerShell 5.1 or later

Execution Steps

  1. Save the appropriate script (Bash or PowerShell) to your local system
  2. Create the config.json file with your configuration
  3. Place both files in the same directory

For Bash (Linux/Mac)

# Make the script executable
chmod +x setup.sh

# Run the script
./setup.sh

# For debug mode
./setup.sh -d

# For verification only
./setup.sh -v

For PowerShell (Windows)

# Run the script
.\setup.ps1

# For debug mode
.\setup.ps1 -Debug

# For verification only
.\setup.ps1 -VerifyOnly

Troubleshooting

If you encounter issues running the script:

  1. Check that your config.json file is properly formatted
  2. Ensure your AI Controller server is running and accessible at the specified URL
  3. Verify that the admin credentials are correct
  4. Run the script in debug mode to get more detailed error information

For further assistance, contact the AI Controller support team.


Updated: 2025-05-20