151 lines
4.4 KiB
PowerShell
151 lines
4.4 KiB
PowerShell
param(
|
|
[string]$Instruction = "",
|
|
[string]$Mode = "",
|
|
[switch]$ControlledApply,
|
|
[switch]$RunNow,
|
|
[string]$Source = "agent99-submit-request",
|
|
[string]$RequestedBy = "",
|
|
[string]$ExternalId = "",
|
|
[string]$ReplyChatId = "",
|
|
[string]$AgentRoot = "C:\Wooo\Agent99"
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
if (-not $Instruction) {
|
|
$Instruction = Read-Host "Agent99 request"
|
|
}
|
|
|
|
if (-not $Instruction) {
|
|
throw "Instruction is required."
|
|
}
|
|
|
|
$allowedModes = @("Status", "Recover", "StartVMs", "PublicSmoke", "HarborRepair", "AwoooRepair", "Perf", "LoadShed", "SelfCheck", "BackupCheck")
|
|
|
|
function Test-AgentContainsChar {
|
|
param(
|
|
[string]$Text,
|
|
[int[]]$Codes
|
|
)
|
|
foreach ($code in $Codes) {
|
|
if ($Text.IndexOf([string][char]$code) -ge 0) {
|
|
return $true
|
|
}
|
|
}
|
|
return $false
|
|
}
|
|
|
|
function Resolve-AgentRequestMode {
|
|
param(
|
|
[string]$Text,
|
|
[string]$ExplicitMode
|
|
)
|
|
|
|
if ($ExplicitMode) {
|
|
if ($ExplicitMode -notin $allowedModes) {
|
|
throw "Mode is not allowlisted: $ExplicitMode"
|
|
}
|
|
return $ExplicitMode
|
|
}
|
|
|
|
$lower = $Text.ToLowerInvariant()
|
|
$mentionsPublic = ($lower -match "public|smoke|website|site|route|url|http|502" -or (Test-AgentContainsChar $Text @(0x7DB2, 0x7AD9)))
|
|
$wantsRecovery = ($lower -match "recover|reboot|restore|restart|startup|repair|fix|502" -or (Test-AgentContainsChar $Text @(0x6062, 0x5FA9, 0x91CD, 0x555F, 0x4FEE)))
|
|
|
|
if ($mentionsPublic -and $wantsRecovery) {
|
|
return "Recover"
|
|
}
|
|
|
|
if ($mentionsPublic) {
|
|
return "PublicSmoke"
|
|
}
|
|
|
|
if ($wantsRecovery) {
|
|
return "Recover"
|
|
}
|
|
|
|
if ($lower -match "vm|vmware|startvm|start vm|start vms" -or (Test-AgentContainsChar $Text @(0x865B, 0x64EC, 0x4E3B, 0x6A5F))) {
|
|
return "StartVMs"
|
|
}
|
|
|
|
if ($lower -match "cpu|load|memory|ram|disk|perf|performance|pressure" -or (Test-AgentContainsChar $Text @(0x6548, 0x80FD, 0x78C1, 0x789F, 0x8CA0, 0x8F09))) {
|
|
return "Perf"
|
|
}
|
|
|
|
if ($lower -match "backup|snapshot|restore drill|cron" -or (Test-AgentContainsChar $Text @(0x5099, 0x4EFD))) {
|
|
return "BackupCheck"
|
|
}
|
|
|
|
if ($lower -match "self|agent|health|selfcheck" -or (Test-AgentContainsChar $Text @(0x81EA, 0x6AA2, 0x5065, 0x5EB7))) {
|
|
return "SelfCheck"
|
|
}
|
|
|
|
if ($lower -match "harbor|registry") {
|
|
return "HarborRepair"
|
|
}
|
|
|
|
if ($lower -match "awoooi|k3s|pod|pods") {
|
|
return "AwoooRepair"
|
|
}
|
|
|
|
return "Status"
|
|
}
|
|
|
|
$modeName = Resolve-AgentRequestMode $Instruction $Mode
|
|
$queueDir = Join-Path $AgentRoot "queue"
|
|
$requestDir = Join-Path $AgentRoot "requests"
|
|
$evidenceDir = Join-Path $AgentRoot "evidence"
|
|
New-Item -ItemType Directory -Force -Path $queueDir, $requestDir, $evidenceDir | Out-Null
|
|
|
|
$id = "request-" + (Get-Date -Format "yyyyMMdd-HHmmss") + "-" + ([guid]::NewGuid().ToString("N").Substring(0, 8))
|
|
$request = [pscustomobject]@{
|
|
id = $id
|
|
instruction = $Instruction
|
|
resolvedMode = $modeName
|
|
controlledApply = [bool]$ControlledApply
|
|
requestedBy = if ($RequestedBy) { $RequestedBy } else { $env:USERNAME }
|
|
source = $Source
|
|
externalId = $ExternalId
|
|
createdAt = (Get-Date -Format o)
|
|
}
|
|
|
|
$requestPath = Join-Path $requestDir "$id.json"
|
|
$queuePath = Join-Path $queueDir "$id.json"
|
|
$request | ConvertTo-Json -Depth 8 | Set-Content -Path $requestPath -Encoding UTF8
|
|
[pscustomobject]@{
|
|
id = $id
|
|
mode = $modeName
|
|
controlledApply = [bool]$ControlledApply
|
|
requestedBy = if ($RequestedBy) { $RequestedBy } else { $env:USERNAME }
|
|
source = $Source
|
|
externalId = $ExternalId
|
|
reason = "operator_instruction"
|
|
instruction = $Instruction
|
|
requestPath = $requestPath
|
|
replyChatId = $ReplyChatId
|
|
createdAt = (Get-Date -Format o)
|
|
} | ConvertTo-Json -Depth 8 | Set-Content -Path $queuePath -Encoding UTF8
|
|
|
|
$result = [pscustomobject]@{
|
|
ok = $true
|
|
id = $id
|
|
instruction = $Instruction
|
|
resolvedMode = $modeName
|
|
controlledApply = [bool]$ControlledApply
|
|
requestPath = $requestPath
|
|
queuePath = $queuePath
|
|
runNow = [bool]$RunNow
|
|
controlExitCode = $null
|
|
}
|
|
|
|
if ($RunNow) {
|
|
$launcher = Join-Path $AgentRoot "agent99-run.ps1"
|
|
$process = Start-Process -FilePath "powershell.exe" -ArgumentList @("-NoProfile", "-ExecutionPolicy", "Bypass", "-File", $launcher, "-Mode", "ControlTick") -Wait -PassThru -WindowStyle Hidden
|
|
$process.Refresh()
|
|
$result.controlExitCode = $process.ExitCode
|
|
}
|
|
|
|
$submitEvidence = Join-Path $evidenceDir "agent99-submit-$id.json"
|
|
$result | ConvertTo-Json -Depth 8 | Set-Content -Path $submitEvidence -Encoding UTF8
|
|
$result | ConvertTo-Json -Depth 8
|