flnxi-Wu/scripts/generate-shared-test-env.ps1
2026-05-30 19:33:59 +08:00

212 lines
6.5 KiB
PowerShell
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

param(
[string]$OutputPath,
[string]$ServerIp = "192.168.42.134",
[int]$AppPort = 4320,
[int]$MinioApiPort = 39200,
[int]$MinioConsolePort = 39201,
[int]$AgentPort = 3080,
[int]$AgentGoPort = 9091,
[string]$ComposeProjectName = "flnxi_sucai_test",
[string]$ContainerPrefix = "flnxi-sucai-test",
[string]$AppImage,
[string]$LicenseServerUrl,
[string]$LicenseProjectCode = "flnxi-sucai",
[string]$LicenseRequestSigningSecret,
[string]$InitAdminEmail = "admin@test.flnxi.local"
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
if ([string]::IsNullOrWhiteSpace($LicenseServerUrl)) {
throw "必须显式传入 -LicenseServerUrl,避免把过期或错误的许可证地址写进测试环境。"
}
if ([string]::IsNullOrWhiteSpace($AppImage)) {
throw "必须显式传入 -AppImage,测试环境也要固定完整镜像版本,不能依赖 latest。"
}
function New-RandomString {
param(
[int]$Length = 32,
[string]$Alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
)
$bytes = New-Object byte[] ($Length * 2)
[System.Security.Cryptography.RandomNumberGenerator]::Fill($bytes)
$builder = New-Object System.Text.StringBuilder
foreach ($byte in $bytes) {
if ($builder.Length -ge $Length) {
break
}
[void]$builder.Append($Alphabet[$byte % $Alphabet.Length])
}
return $builder.ToString()
}
function Get-LicensePublicKey {
param([string]$ProjectRoot)
$candidateFiles = @(
(Join-Path $ProjectRoot "license-server\.env"),
(Join-Path $ProjectRoot ".env.production"),
(Join-Path $ProjectRoot ".env"),
(Join-Path $ProjectRoot ".env.local")
)
foreach ($file in $candidateFiles) {
if (-not (Test-Path $file)) {
continue
}
$content = Get-Content -Raw $file
$licenseMatch = [regex]::Match($content, '(?m)^LICENSE_PUBLIC_KEY=(.+)$')
if ($licenseMatch.Success) {
return $licenseMatch.Groups[1].Value.Trim().Trim('"')
}
$rsaMatch = [regex]::Match($content, '(?m)^RSA_PUBLIC_KEY=(.+)$')
if ($rsaMatch.Success) {
return $rsaMatch.Groups[1].Value.Trim().Trim('"')
}
$privateMatch = [regex]::Match($content, '(?m)^RSA_PRIVATE_KEY=(.+)$')
if ($privateMatch.Success) {
$privateKey = $privateMatch.Groups[1].Value.Trim().Trim('"')
$pem = $privateKey.Replace('\n', [Environment]::NewLine)
try {
$rsa = [System.Security.Cryptography.RSA]::Create()
try {
$rsa.ImportFromPem($pem.ToCharArray())
$publicPem = $rsa.ExportSubjectPublicKeyInfoPem()
return ([regex]::Replace($publicPem, "(\r\n|\n|\r)", '\n')).Trim()
} finally {
$rsa.Dispose()
}
} catch {
throw "检测到 RSA_PRIVATE_KEY,但自动推导公钥失败:$($_.Exception.Message)"
}
}
}
throw "未找到可用的 LICENSE_PUBLIC_KEY / RSA_PUBLIC_KEY,无法生成测试环境 .env。"
}
if ([string]::IsNullOrWhiteSpace($OutputPath)) {
throw "必须提供 -OutputPath。"
}
$projectRoot = Split-Path -Parent $PSScriptRoot
$licensePublicKey = Get-LicensePublicKey -ProjectRoot $projectRoot
$postgresUser = "flnxi_test"
$postgresDb = "flnxi_sucai_test"
$postgresPassword = New-RandomString -Length 24
$minioRootUser = "flnxitest"
$minioRootPassword = New-RandomString -Length 24
$nextAuthSecret = New-RandomString -Length 48
$localEncryptionKey = New-RandomString -Length 48
$systemInitToken = New-RandomString -Length 40
if ([string]::IsNullOrWhiteSpace($LicenseRequestSigningSecret)) {
$LicenseRequestSigningSecret = New-RandomString -Length 48
}
$s3Bucket = "flnxi-sucai-test"
$appUrl = "http://${ServerIp}:${AppPort}"
$s3PublicDomain = "http://${ServerIp}:${MinioApiPort}/${s3Bucket}"
$envContent = @"
# FLNXI 素材库共享测试机环境变量
# 用途:192.168.42.134 测试机
# 生成时间:$(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
NODE_ENV=production
# Shared-machine isolation
COMPOSE_PROJECT_NAME=$ComposeProjectName
APP_CONTAINER_NAME=${ContainerPrefix}-app
POSTGRES_CONTAINER_NAME=${ContainerPrefix}-postgres
MINIO_CONTAINER_NAME=${ContainerPrefix}-minio
MINIO_INIT_CONTAINER_NAME=${ContainerPrefix}-minio-init
POSTGRES_VOLUME_NAME=${ContainerPrefix}-postgres-data
MINIO_VOLUME_NAME=${ContainerPrefix}-minio-data
APP_NETWORK_NAME=${ContainerPrefix}-network
APP_PORT=$AppPort
MINIO_API_PORT=$MinioApiPort
MINIO_CONSOLE_PORT=$MinioConsolePort
AGENT_PORT=$AgentPort
AGENT_GO_PORT=$AgentGoPort
# Versioned application image
APP_IMAGE=$AppImage
# Public URLs
SERVER_IP=$ServerIp
APP_PUBLIC_URL=$appUrl
NEXTAUTH_URL=$appUrl
NEXTAUTH_SECRET=$nextAuthSecret
# License
LICENSE_SERVER_URL=$LicenseServerUrl
LICENSE_PROJECT_CODE=$LicenseProjectCode
LICENSE_REQUEST_SIGNING_SECRET=$LicenseRequestSigningSecret
LICENSE_PUBLIC_KEY="$licensePublicKey"
LOCAL_ENCRYPTION_KEY=$localEncryptionKey
# Database
POSTGRES_USER=$postgresUser
POSTGRES_PASSWORD=$postgresPassword
POSTGRES_DB=$postgresDb
DATABASE_URL=postgresql://${postgresUser}:${postgresPassword}@postgres:5432/${postgresDb}
DATABASE_DRIVER=node
# Object storage
STORAGE_PROVIDER=s3
S3_ENDPOINT=http://minio:9000
S3_BUCKET=$s3Bucket
S3_ACCESS_KEY_ID=$minioRootUser
S3_SECRET_ACCESS_KEY=$minioRootPassword
S3_REGION=us-east-1
S3_PUBLIC_DOMAIN=$s3PublicDomain
S3_ENABLE_PATH_STYLE=1
S3_FILE_PATH=materials/
S3_ENV_PREFIX=test
MINIO_ROOT_USER=$minioRootUser
MINIO_ROOT_PASSWORD=$minioRootPassword
# Access control and URL rewriting
PUBLIC_DOMAINS=$ServerIp
NEXT_PUBLIC_PUBLIC_DOMAINS=$ServerIp
ALLOWED_ORIGINS=$appUrl
IMAGE_REMOTE_HOSTS=$ServerIp
# Initial system bootstrap
SYSTEM_INIT_TOKEN=$systemInitToken
INIT_ADMIN_EMAIL=$InitAdminEmail
INIT_ADMIN_PASSWORD=
# Optional features disabled by default on shared test server
DINGTALK_CLIENT_ID=
DINGTALK_CLIENT_SECRET=
NEXT_PUBLIC_DINGTALK_CALLBACK_URL=
GEMINI_API_KEY=
GEMINI_API_BASE_URL=https://api.huandutech.com/v1
GEMINI_MODEL=gemini-2.0-flash-exp
NEXT_PUBLIC_DEFAULT_HEADER_LOGO_URL=
NEXT_PUBLIC_DEFAULT_LOGIN_LOGO_URL=
NEXT_PUBLIC_INTRANET_URL=$appUrl
NEXT_PUBLIC_PORTAL_BASE_URL=$appUrl
UPLOAD_DIR=./uploads
"@
$parent = Split-Path -Parent $OutputPath
if ($parent -and -not (Test-Path $parent)) {
New-Item -ItemType Directory -Path $parent -Force | Out-Null
}
[System.IO.File]::WriteAllText($OutputPath, $envContent, [System.Text.UTF8Encoding]::new($false))
Write-Host "共享测试机环境文件已生成: $OutputPath"