feat(telemetry): add portable local telemetry plane
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$Version = "1.38.4",
|
||||
[string]$ExpectedSha256 = "6c7878ec319471ac85b82443baec2f3fa5dbcf1b6e2da5d5cd2cbb60fff2bb45",
|
||||
[string]$ConfigurationTemplate = "$PSScriptRoot\mission-core-windows.conf.tmpl"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$serviceName = "telegraf"
|
||||
$installRoot = "C:\Program Files\NDC\Mission Core\Telegraf"
|
||||
$configurationRoot = "C:\ProgramData\NDC\MissionCore\telemetry-agent"
|
||||
$configurationPath = Join-Path $configurationRoot "telegraf.conf"
|
||||
$archiveUrl = "https://dl.influxdata.com/telegraf/releases/telegraf-$($Version)_windows_amd64.zip"
|
||||
$payload = [Console]::In.ReadToEnd() | ConvertFrom-Json
|
||||
|
||||
foreach ($name in @(
|
||||
"MISSIONCORE_CONTOUR_ID",
|
||||
"MISSIONCORE_AGENT_ID",
|
||||
"MISSIONCORE_NODE_ID",
|
||||
"MISSIONCORE_MQTT_HOST",
|
||||
"MISSIONCORE_MQTT_PORT",
|
||||
"MISSIONCORE_MQTT_USERNAME",
|
||||
"MISSIONCORE_MQTT_PASSWORD"
|
||||
)) {
|
||||
$value = $payload.$name
|
||||
if (-not $value) {
|
||||
throw "Provisioning payload is missing $name"
|
||||
}
|
||||
Set-Item -Path "Env:$name" -Value ([string]$value)
|
||||
}
|
||||
|
||||
if (Get-Service -Name $serviceName -ErrorAction SilentlyContinue) {
|
||||
throw "Service '$serviceName' already exists; refusing an implicit replacement"
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $ConfigurationTemplate -PathType Leaf)) {
|
||||
throw "Configuration template not found: $ConfigurationTemplate"
|
||||
}
|
||||
|
||||
$temporaryRoot = Join-Path $env:TEMP "ndc-mission-core-telegraf-$([Guid]::NewGuid().ToString('N'))"
|
||||
$archivePath = Join-Path $temporaryRoot "telegraf.zip"
|
||||
$expandedRoot = Join-Path $temporaryRoot "expanded"
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $temporaryRoot, $expandedRoot -Force | Out-Null
|
||||
Invoke-WebRequest -UseBasicParsing -Uri $archiveUrl -OutFile $archivePath
|
||||
$actualSha256 = (Get-FileHash -LiteralPath $archivePath -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
if ($actualSha256 -ne $ExpectedSha256.ToLowerInvariant()) {
|
||||
throw "Telegraf archive SHA256 mismatch"
|
||||
}
|
||||
Expand-Archive -LiteralPath $archivePath -DestinationPath $expandedRoot
|
||||
$sourceExecutable = Get-ChildItem -Path $expandedRoot -Filter "telegraf.exe" -Recurse |
|
||||
Select-Object -First 1
|
||||
if (-not $sourceExecutable) {
|
||||
throw "telegraf.exe is missing from the verified archive"
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Path $installRoot, $configurationRoot -Force | Out-Null
|
||||
Copy-Item -LiteralPath $sourceExecutable.FullName -Destination (Join-Path $installRoot "telegraf.exe")
|
||||
Copy-Item -LiteralPath $ConfigurationTemplate -Destination $configurationPath
|
||||
& icacls.exe $configurationRoot /inheritance:r /grant:r `
|
||||
"*S-1-5-18:(OI)(CI)F" "*S-1-5-32-544:(OI)(CI)F" | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to restrict the telemetry agent configuration directory"
|
||||
}
|
||||
|
||||
$executable = Join-Path $installRoot "telegraf.exe"
|
||||
$validationOutput = Join-Path $temporaryRoot "validation.out.log"
|
||||
$validationError = Join-Path $temporaryRoot "validation.error.log"
|
||||
$validation = Start-Process -FilePath $executable `
|
||||
-ArgumentList @("--config", $configurationPath, "--test") `
|
||||
-NoNewWindow -Wait -PassThru `
|
||||
-RedirectStandardOutput $validationOutput `
|
||||
-RedirectStandardError $validationError
|
||||
if ($validation.ExitCode -ne 0) {
|
||||
$validationDetail = Get-Content -LiteralPath $validationError -Tail 8 |
|
||||
Out-String
|
||||
throw "Telegraf configuration validation failed: $validationDetail"
|
||||
}
|
||||
|
||||
& $executable --service install --config $configurationPath
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Telegraf service installation failed"
|
||||
}
|
||||
$serviceEnvironment = @(
|
||||
"MISSIONCORE_CONTOUR_ID=$($payload.MISSIONCORE_CONTOUR_ID)",
|
||||
"MISSIONCORE_AGENT_ID=$($payload.MISSIONCORE_AGENT_ID)",
|
||||
"MISSIONCORE_NODE_ID=$($payload.MISSIONCORE_NODE_ID)",
|
||||
"MISSIONCORE_MQTT_HOST=$($payload.MISSIONCORE_MQTT_HOST)",
|
||||
"MISSIONCORE_MQTT_PORT=$($payload.MISSIONCORE_MQTT_PORT)",
|
||||
"MISSIONCORE_MQTT_USERNAME=$($payload.MISSIONCORE_MQTT_USERNAME)",
|
||||
"MISSIONCORE_MQTT_PASSWORD=$($payload.MISSIONCORE_MQTT_PASSWORD)"
|
||||
)
|
||||
$serviceRegistryPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$serviceName"
|
||||
Set-ItemProperty -Path $serviceRegistryPath -Name Environment `
|
||||
-Type MultiString -Value $serviceEnvironment
|
||||
Set-ItemProperty -Path $serviceRegistryPath -Name DisplayName `
|
||||
-Value "NDC Mission Core Telemetry Agent"
|
||||
& sc.exe config $serviceName DisplayName= "NDC Mission Core Telemetry Agent" | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to apply the NDC service display name"
|
||||
}
|
||||
Set-Service -Name $serviceName -StartupType Automatic
|
||||
Start-Service -Name $serviceName
|
||||
$service = Get-Service -Name $serviceName
|
||||
$service.WaitForStatus([ServiceProcess.ServiceControllerStatus]::Running, [TimeSpan]::FromSeconds(20))
|
||||
|
||||
[ordered]@{
|
||||
SchemaVersion = "missioncore.telemetry-agent-install-result/v1"
|
||||
Agent = "Telegraf"
|
||||
Version = $Version
|
||||
ServiceName = $service.Name
|
||||
DisplayName = $service.DisplayName
|
||||
Status = $service.Status.ToString()
|
||||
StartType = $service.StartType.ToString()
|
||||
Configuration = $configurationPath
|
||||
Sha256 = $actualSha256
|
||||
} | ConvertTo-Json -Compress
|
||||
}
|
||||
finally {
|
||||
Remove-Item -LiteralPath $temporaryRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
Reference in New Issue
Block a user