175 lines
6.3 KiB
PowerShell
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
|