1f07da2e12
Earlier fix (commit 047125b) filtered the infisical CLI's
"A new release of infisical is available" upgrade banner from
captured output via regex matching. That worked but coupled the
filter to specific banner-pattern strings — a future banner shape
("Update available" / "New version detected" / a localized
message) would slip through and break NTLM Type1 auth again.
The principled fix is to stop capturing stderr at all.
PowerShell's call operator (`&`) keeps stdout and stderr on
separate streams unless explicitly merged; the previous code's
`2>&1` was the actual mistake. Without it, the banner stays in
the error stream (visible on the console for diagnostics) and
the captured `$value` contains only the script's stdout — which
for `Get-Secret.ps1` is just the secret value from `infisical
secrets get --plain`.
Verified: live re-run of F54 (lmx_write_complete_live) passes
post-change with `MX_TEST_DOMAIN='DESKTOP-6JL3KKO'` clean and
the banner visibly logged to console (stderr) above each [SET]
line. No regex coupling to a specific banner-pattern remains.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
133 lines
6.4 KiB
PowerShell
133 lines
6.4 KiB
PowerShell
# Setup-LiveProbeEnv.ps1 — populate the env vars the mxaccess Rust port's
|
|
# `live`-feature integration tests and probes expect, fetching credentials
|
|
# from the homelab Infisical instance via wwtools/secrets/Get-Secret.ps1.
|
|
#
|
|
# Usage:
|
|
# . .\tools\Setup-LiveProbeEnv.ps1 # dot-source — env vars persist in the calling session
|
|
# . .\tools\Setup-LiveProbeEnv.ps1 -SkipAsbSecret # no Infisical lookup for ASB shared secret (CI/dev fallback)
|
|
# .\tools\Setup-LiveProbeEnv.ps1 -DryRun # print what would be set without exporting
|
|
#
|
|
# Hard rules (per design/00-overview.md "Adjacent tooling" section):
|
|
# - Credentials are fetched via `wwtools\secrets\Get-Secret.ps1`, which logs
|
|
# into Infisical fresh on each call (DPAPI session storage doesn't survive
|
|
# non-interactive contexts).
|
|
# - We never inline plaintext secrets here. New AVEVA-specific secrets go
|
|
# into Infisical at `homelab/aveva/system-platform/<KEY>` (suggested path).
|
|
# - Sets `MX_LIVE=1` to enable the `live` feature gate in cargo tests.
|
|
#
|
|
# Env vars set:
|
|
# MX_LIVE — "1", enables the `live` cargo feature
|
|
# MX_NMX_HOST — NMX hostname (default: localhost)
|
|
# MX_GALAXY_DB — tiberius / SQL Server connection string with integrated security
|
|
# MX_GALAXY_NAME — Galaxy name (default: $env:MX_GALAXY_NAME or 'ZB' from wwtools/grdb)
|
|
# MX_TEST_USER — fetched from Infisical: homelab/infrastructure/windows-hosts/WW_VM_ADMIN_USER
|
|
# MX_TEST_DOMAIN — fetched from Infisical: ...WW_VM_ADMIN_DOMAIN
|
|
# MX_TEST_PASSWORD — fetched from Infisical: ...WW_VM_ADMIN_PWD
|
|
# MX_ASB_SHARED_SECRET — fetched from Infisical: homelab/aveva/system-platform/ASB_SHARED_SECRET
|
|
# (TODO: add this entry to Infisical — currently optional with -SkipAsbSecret)
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[string]$NmxHost = 'localhost',
|
|
[string]$GalaxyName = $(if ($env:MX_GALAXY_NAME) { $env:MX_GALAXY_NAME } else { 'ZB' }),
|
|
[string]$GalaxyServer = 'localhost',
|
|
[switch]$SkipAsbSecret,
|
|
[switch]$DryRun
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$GetSecret = 'C:\Users\dohertj2\Desktop\wwtools\secrets\Get-Secret.ps1'
|
|
if (-not (Test-Path $GetSecret)) {
|
|
throw "Get-Secret.ps1 not found at $GetSecret. wwtools must be installed at C:\Users\dohertj2\Desktop\wwtools per design/00-overview.md 'Adjacent tooling' section."
|
|
}
|
|
|
|
# Hydrate User-scope env vars into Process scope. Necessary in non-interactive
|
|
# contexts (Bash → pwsh, scheduled tasks, CI runners) where the User-scope
|
|
# block from HKCU\Environment is not auto-merged into the process env.
|
|
foreach ($name in @('INFISICAL_API_URL','INFISICAL_UNIVERSAL_AUTH_CLIENT_ID','INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET')) {
|
|
if (-not (Get-Item -Path "Env:$name" -ErrorAction SilentlyContinue)) {
|
|
$userValue = [Environment]::GetEnvironmentVariable($name, 'User')
|
|
if ($userValue) {
|
|
Set-Item -Path "Env:$name" -Value $userValue
|
|
}
|
|
}
|
|
}
|
|
|
|
function Set-LiveEnvVar {
|
|
param([string]$Name, [string]$Value, [switch]$Sensitive)
|
|
$display = if ($Sensitive) { '***redacted***' } else { $Value }
|
|
if ($DryRun) {
|
|
Write-Host "[DRY] $Name = $display" -ForegroundColor Yellow
|
|
} else {
|
|
Set-Item -Path "Env:$Name" -Value $Value
|
|
Write-Host "[SET] $Name = $display" -ForegroundColor Green
|
|
}
|
|
}
|
|
|
|
function Get-InfisicalSecret {
|
|
param([string]$Key, [string]$Env = 'infrastructure', [string]$Path = '/windows-hosts')
|
|
# Capture stdout only — the infisical CLI writes its
|
|
# "A new release of infisical is available" upgrade banner (and any
|
|
# transient diagnostic noise) to STDERR. We deliberately do NOT use
|
|
# `2>&1` here so that banner stays in the error stream (visible on
|
|
# the console for diagnostics) and never pollutes the secret value.
|
|
# An earlier version of this function used `2>&1` plus a regex-based
|
|
# banner filter; that approach was brittle to future banner shapes,
|
|
# so it was replaced with stream separation. If a real error needs
|
|
# to be surfaced, $LASTEXITCODE catches it below.
|
|
try {
|
|
$value = & $GetSecret -Key $Key -Env $Env -Path $Path
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Get-Secret exit code $LASTEXITCODE for $Env$Path/$Key"
|
|
}
|
|
if (-not $value) {
|
|
throw "Get-Secret returned empty stdout for $Env$Path/$Key"
|
|
}
|
|
return ($value | Out-String).Trim()
|
|
} catch {
|
|
throw "Failed to fetch $Env$Path/$Key from Infisical: $_"
|
|
}
|
|
}
|
|
|
|
Write-Host "mxaccess live-probe env setup" -ForegroundColor Cyan
|
|
Write-Host " source: wwtools/secrets/Get-Secret.ps1 -> https://infisical.dohertylan.com" -ForegroundColor DarkGray
|
|
Write-Host ""
|
|
|
|
# Non-secret env vars
|
|
Set-LiveEnvVar -Name 'MX_LIVE' -Value '1'
|
|
Set-LiveEnvVar -Name 'MX_NMX_HOST' -Value $NmxHost
|
|
Set-LiveEnvVar -Name 'MX_GALAXY_NAME' -Value $GalaxyName
|
|
$galaxyDb = "Server=$GalaxyServer;Database=$GalaxyName;Integrated Security=True;TrustServerCertificate=True"
|
|
Set-LiveEnvVar -Name 'MX_GALAXY_DB' -Value $galaxyDb
|
|
|
|
# Secret-backed env vars
|
|
Write-Host ""
|
|
Write-Host "Fetching credentials from Infisical..." -ForegroundColor Cyan
|
|
|
|
$user = Get-InfisicalSecret -Key 'WW_VM_ADMIN_USER'
|
|
Set-LiveEnvVar -Name 'MX_TEST_USER' -Value $user
|
|
|
|
$domain = Get-InfisicalSecret -Key 'WW_VM_ADMIN_DOMAIN'
|
|
Set-LiveEnvVar -Name 'MX_TEST_DOMAIN' -Value $domain
|
|
|
|
$password = Get-InfisicalSecret -Key 'WW_VM_ADMIN_PWD'
|
|
Set-LiveEnvVar -Name 'MX_TEST_PASSWORD' -Value $password -Sensitive
|
|
|
|
if ($SkipAsbSecret) {
|
|
Write-Host "[SKIP] MX_ASB_SHARED_SECRET (use AsbCredentials::shared_secret(&[u8]) constructor or set manually)" -ForegroundColor Yellow
|
|
} else {
|
|
try {
|
|
$asbSecret = Get-InfisicalSecret -Key 'ASB_SHARED_SECRET' -Env 'aveva' -Path '/system-platform'
|
|
Set-LiveEnvVar -Name 'MX_ASB_SHARED_SECRET' -Value $asbSecret -Sensitive
|
|
} catch {
|
|
Write-Warning "MX_ASB_SHARED_SECRET not yet in Infisical. Add it at homelab/aveva/system-platform/ASB_SHARED_SECRET, or rerun with -SkipAsbSecret. Underlying error: $_"
|
|
Set-LiveEnvVar -Name 'MX_ASB_SHARED_SECRET' -Value '' -Sensitive
|
|
}
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "Done. Live-probe env is ready." -ForegroundColor Green
|
|
Write-Host " Run cargo tests with the 'live' feature: cargo test -p mxaccess --features live -- --ignored" -ForegroundColor DarkGray
|
|
Write-Host " Run a probe example: cargo run -p mxaccess --example session-write" -ForegroundColor DarkGray
|