Files
rdp-proxy/scripts/fabric/deploy-test-nodes.ps1
T
2026-04-28 22:29:50 +03:00

175 lines
6.3 KiB
PowerShell

param(
[string]$BackendBaseUrl = "http://192.168.200.61:8080/api/v1",
[string]$DockerContext = "test-ubuntu",
[string]$AdminEmail = "windows-smoke@example.local",
[string]$AdminPassword = "SmokePass!123",
[int]$Count = 3,
[string]$ImageTag = "rap-node-agent:control-panel-test"
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..\..")).ProviderPath
$stateRoot = Join-Path "C:\work" "rap-fabric-test-nodes"
New-Item -ItemType Directory -Force -Path $stateRoot | Out-Null
function Invoke-Docker {
param([string[]]$Arguments)
docker @Arguments
if ($LASTEXITCODE -ne 0) {
throw "docker $($Arguments -join ' ') failed with exit code $LASTEXITCODE"
}
}
function Invoke-Api {
param(
[string]$Method,
[string]$Path,
[object]$Body = $null
)
$uri = "$BackendBaseUrl$Path"
if ($null -eq $Body) {
return Invoke-RestMethod -Method $Method -Uri $uri -TimeoutSec 30
}
return Invoke-RestMethod -Method $Method -Uri $uri -ContentType "application/json" -Body ($Body | ConvertTo-Json -Depth 20) -TimeoutSec 30
}
Write-Host "Building node-agent image on Docker context $DockerContext..."
Invoke-Docker -Arguments @("--context", $DockerContext, "build", "-f", "$repoRoot\agents\rap-node-agent\Dockerfile", "-t", $ImageTag, "$repoRoot")
$login = Invoke-Api -Method Post -Path "/auth/login" -Body @{
email = $AdminEmail
password = $AdminPassword
device_fingerprint = "fabric-test-nodes-script"
device_label = "Fabric Test Nodes Script"
trust_device = $true
}
$actorUserID = $login.user.id
$clusters = Invoke-Api -Method Get -Path "/clusters/?actor_user_id=$actorUserID"
$cluster = @($clusters.clusters)[0]
if ($null -eq $cluster) {
throw "No cluster available for test node deployment."
}
$clusterID = $cluster.id
Write-Host "Using cluster $($cluster.name) $clusterID"
Invoke-Api -Method Put -Path "/fabric/testing-flags" -Body @{
actor_user_id = $actorUserID
scope_type = "platform"
scope_id = $null
cluster_id = $null
enabled = $true
telemetry_enabled = $true
synthetic_links_enabled = $true
history_retention_hours = 24
metadata = @{ source = "deploy-test-nodes.ps1"; runtime_mesh_enabled = $false }
} | Out-Null
$joinToken = Invoke-Api -Method Post -Path "/clusters/$clusterID/join-tokens" -Body @{
actor_user_id = $actorUserID
scope = @{ purpose = "fabric-test-nodes"; roles = @("core-mesh", "relay-node") }
expires_at = (Get-Date).ToUniversalTime().AddHours(2).ToString("o")
max_uses = $Count
}
$nodes = @()
for ($i = 1; $i -le $Count; $i++) {
$nodeName = "fabric-test-node-$i"
$fingerprint = "rap-node-fp_$([guid]::NewGuid().ToString('N'))"
$publicKey = "rap-node-pub_$([guid]::NewGuid().ToString('N'))"
$joinRequest = Invoke-Api -Method Post -Path "/clusters/$clusterID/join-requests" -Body @{
join_token = $joinToken.join_token.token
node_name = $nodeName
node_fingerprint = $fingerprint
public_key = $publicKey
reported_capabilities = @{
can_accept_node_ingress = $true
can_route_mesh = $true
can_run_rdp_worker = $false
testing_node = $true
}
reported_facts = @{
os = "linux"
runtime = "docker-test"
source = "deploy-test-nodes.ps1"
}
requested_roles = @("core-mesh", "relay-node")
}
$approved = Invoke-Api -Method Post -Path "/clusters/$clusterID/join-requests/$($joinRequest.join_request.id)/approve" -Body @{
actor_user_id = $actorUserID
node_key = $fingerprint
ownership_type = "platform_managed"
owner_organization_id = $null
}
$nodeID = $approved.node_bootstrap.node_id
$nodes += [pscustomobject]@{ name = $nodeName; id = $nodeID; fingerprint = $fingerprint; public_key = $publicKey }
$nodeStateDir = Join-Path $stateRoot $nodeName
New-Item -ItemType Directory -Force -Path $nodeStateDir | Out-Null
@{
node_id = $nodeID
cluster_id = $clusterID
node_name = $nodeName
node_fingerprint = $fingerprint
public_key = $publicKey
identity_status = "active"
created_at = (Get-Date).ToUniversalTime().ToString("o")
updated_at = (Get-Date).ToUniversalTime().ToString("o")
} | ConvertTo-Json -Depth 10 | Set-Content -Encoding UTF8 -Path (Join-Path $nodeStateDir "identity.json")
$containerName = "rap_fabric_test_node_$i"
docker --context $DockerContext rm -f $containerName 2>$null | Out-Null
Invoke-Docker -Arguments @(
"--context", $DockerContext,
"create",
"--name", $containerName,
"--network", "host",
"-e", "RAP_BACKEND_URL=$BackendBaseUrl",
"-e", "RAP_NODE_STATE_DIR=/tmp/state",
"-e", "RAP_HEARTBEAT_INTERVAL_SECONDS=5",
$ImageTag,
"-backend-url", $BackendBaseUrl,
"-state-dir", "/tmp/state",
"-heartbeat-interval", "5s"
) | Out-Null
Invoke-Docker -Arguments @("--context", $DockerContext, "cp", "$nodeStateDir\.", "$containerName`:/tmp/state")
Invoke-Docker -Arguments @("--context", $DockerContext, "start", $containerName) | Out-Null
Write-Host "Started $containerName for $nodeName $nodeID"
}
Start-Sleep -Seconds 12
for ($i = 0; $i -lt $nodes.Count; $i++) {
for ($j = 0; $j -lt $nodes.Count; $j++) {
if ($i -eq $j) { continue }
$latency = 2 + (($i + $j) % 7)
Invoke-Api -Method Post -Path "/clusters/$clusterID/mesh/links" -Body @{
source_node_id = $nodes[$i].id
target_node_id = $nodes[$j].id
link_status = "reachable"
latency_ms = $latency
quality_score = 95 - $latency
metadata = @{
source = "deploy-test-nodes.ps1"
synthetic = $true
runtime_mesh_enabled = $false
}
} | Out-Null
}
}
$summary = Invoke-Api -Method Get -Path "/cluster-admin-summaries?actor_user_id=$actorUserID"
$links = Invoke-Api -Method Get -Path "/clusters/$clusterID/mesh/links?actor_user_id=$actorUserID"
[pscustomobject]@{
cluster_id = $clusterID
nodes_started = $nodes.Count
cluster_summaries = $summary.cluster_summaries
mesh_link_count = @($links.mesh_links).Count
state_root = $stateRoot
} | ConvertTo-Json -Depth 20