139 lines
4.4 KiB
PowerShell
139 lines
4.4 KiB
PowerShell
param(
|
|
[string]$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path,
|
|
[string]$PostgresDataDir = "D:\PostgreSQLData",
|
|
[string]$PostgresServiceName = "postgresql-x64-17",
|
|
[string]$FirewallRuleName = "InSAR PostgreSQL 5432 LandSAR Cluster",
|
|
[int]$PostgresPort = 5432
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
function Read-DotEnvValue {
|
|
param(
|
|
[string]$Path,
|
|
[string]$Name
|
|
)
|
|
if (-not (Test-Path -LiteralPath $Path)) {
|
|
return ""
|
|
}
|
|
$line = Get-Content -LiteralPath $Path |
|
|
Where-Object { $_ -match "^\s*$([regex]::Escape($Name))\s*=" } |
|
|
Select-Object -Last 1
|
|
if (-not $line) {
|
|
return ""
|
|
}
|
|
$value = ($line -split "=", 2)[1].Trim()
|
|
if (($value.StartsWith('"') -and $value.EndsWith('"')) -or ($value.StartsWith("'") -and $value.EndsWith("'"))) {
|
|
$value = $value.Substring(1, $value.Length - 2)
|
|
}
|
|
return $value
|
|
}
|
|
|
|
function Normalize-WorkerAddress {
|
|
param([string]$Raw)
|
|
$value = $Raw.Trim()
|
|
if (-not $value) {
|
|
return $null
|
|
}
|
|
if ($value -match "/") {
|
|
$parts = $value -split "/", 2
|
|
$ip = $parts[0]
|
|
$prefix = [int]$parts[1]
|
|
if ($prefix -lt 0 -or $prefix -gt 32) {
|
|
throw "Invalid CIDR prefix: $value"
|
|
}
|
|
} else {
|
|
$ip = $value
|
|
$prefix = 32
|
|
}
|
|
$parsed = $null
|
|
if (-not [System.Net.IPAddress]::TryParse($ip, [ref]$parsed)) {
|
|
throw "Invalid IP address: $value"
|
|
}
|
|
if ($parsed.AddressFamily -ne [System.Net.Sockets.AddressFamily]::InterNetwork) {
|
|
throw "Only IPv4 addresses are supported for LandSAR cluster workers: $value"
|
|
}
|
|
return "$ip/$prefix"
|
|
}
|
|
|
|
$envPath = Join-Path $RepoRoot ".env"
|
|
$allowedRaw = Read-DotEnvValue -Path $envPath -Name "LANDSAR_CLUSTER_ALLOWED_WORKER_IPS"
|
|
if (-not $allowedRaw) {
|
|
throw "LANDSAR_CLUSTER_ALLOWED_WORKER_IPS is empty. Set it in .env, for example: LANDSAR_CLUSTER_ALLOWED_WORKER_IPS=192.168.1.6"
|
|
}
|
|
|
|
$allowed = @()
|
|
foreach ($part in ($allowedRaw -split "[,;]")) {
|
|
$normalized = Normalize-WorkerAddress $part
|
|
if ($normalized -and ($allowed -notcontains $normalized)) {
|
|
$allowed += $normalized
|
|
}
|
|
}
|
|
if (-not $allowed) {
|
|
throw "No valid LandSAR cluster worker IPs found in LANDSAR_CLUSTER_ALLOWED_WORKER_IPS."
|
|
}
|
|
|
|
$hbaPath = Join-Path $PostgresDataDir "pg_hba.conf"
|
|
if (-not (Test-Path -LiteralPath $hbaPath)) {
|
|
throw "pg_hba.conf not found: $hbaPath"
|
|
}
|
|
|
|
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
|
Copy-Item -LiteralPath $hbaPath -Destination "$hbaPath.bak_$timestamp"
|
|
|
|
$begin = "# BEGIN InSAR LandSAR cluster workers"
|
|
$end = "# END InSAR LandSAR cluster workers"
|
|
$content = Get-Content -LiteralPath $hbaPath
|
|
$newContent = New-Object System.Collections.Generic.List[string]
|
|
$inside = $false
|
|
foreach ($line in $content) {
|
|
if ($line -eq $begin) {
|
|
$inside = $true
|
|
continue
|
|
}
|
|
if ($line -eq $end) {
|
|
$inside = $false
|
|
continue
|
|
}
|
|
if (-not $inside) {
|
|
$newContent.Add($line)
|
|
}
|
|
}
|
|
|
|
$newContent.Add("")
|
|
$newContent.Add($begin)
|
|
foreach ($address in $allowed) {
|
|
$newContent.Add(("host insar_management all {0,-20} scram-sha-256" -f $address))
|
|
}
|
|
$newContent.Add($end)
|
|
Set-Content -LiteralPath $hbaPath -Value $newContent -Encoding ASCII
|
|
|
|
$pgCtl = "C:\Program Files\PostgreSQL\17\bin\pg_ctl.exe"
|
|
if (Test-Path -LiteralPath $pgCtl) {
|
|
& $pgCtl reload -D $PostgresDataDir | Out-Host
|
|
} else {
|
|
Restart-Service -Name $PostgresServiceName
|
|
}
|
|
|
|
$remoteAddresses = $allowed | ForEach-Object { ($_ -split "/", 2)[0] }
|
|
$rule = Get-NetFirewallRule -DisplayName $FirewallRuleName -ErrorAction SilentlyContinue
|
|
if (-not $rule) {
|
|
New-NetFirewallRule `
|
|
-DisplayName $FirewallRuleName `
|
|
-Direction Inbound `
|
|
-Action Allow `
|
|
-Protocol TCP `
|
|
-LocalPort $PostgresPort `
|
|
-RemoteAddress $remoteAddresses `
|
|
-Profile Any | Out-Null
|
|
} else {
|
|
$rule | Set-NetFirewallRule -Enabled True -Direction Inbound -Action Allow -Profile Any
|
|
$rule | Get-NetFirewallAddressFilter | Set-NetFirewallAddressFilter -RemoteAddress $remoteAddresses
|
|
$rule | Get-NetFirewallPortFilter | Set-NetFirewallPortFilter -Protocol TCP -LocalPort $PostgresPort
|
|
}
|
|
|
|
Write-Host "LandSAR cluster network access synced."
|
|
Write-Host ("Allowed workers: " + ($allowed -join ", "))
|
|
Write-Host "PostgreSQL hba: $hbaPath"
|
|
Write-Host "Firewall rule: $FirewallRuleName"
|