Squashes the work that landed on GitHub via PRs #2 (v0.1.1), #3 (v0.1.2), and #4 (wiki sync) into a single commit on Gitea so both remotes converge. Content is identical to github/main; commit history is split for branching reasons (Gitea was merged via PR #1 long ago, GitHub used squash merges from then on, so the SHAs diverged). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Zerto post-failover script. Fires the on-prem Webhook Server which does
|
||||
the real work (DNS updates, service health checks, notifications).
|
||||
|
||||
.DESCRIPTION
|
||||
Designed to be dropped into a Zerto VPG's post-recovery script slot. The
|
||||
Zerto Virtual Manager's PowerShell runner has a limited module set and
|
||||
runs scripts synchronously, so this script:
|
||||
|
||||
- uses curl.exe (ships with Windows 10 1803+ / Server 2019+) instead
|
||||
of any module-dependent HTTP client;
|
||||
- calls an ASYNC webhook endpoint - the server returns 202 in
|
||||
milliseconds and runs the actual work in the background;
|
||||
- returns within seconds regardless of how long the post-failover
|
||||
actions take, so Zerto's failover sequence is never blocked.
|
||||
|
||||
Wire this into your VPG via the Zerto UI:
|
||||
VPG settings -> Recovery -> Scripts -> Post-Recovery Script
|
||||
Path: C:\path\to\zerto-post-failover.ps1
|
||||
Parameters: leave empty (we read from $env:ZertoVPGName)
|
||||
|
||||
.NOTES
|
||||
Configure $WebhookUrl and either:
|
||||
- paste the bearer token directly into $Bearer (simplest, but the
|
||||
token then lives in this file), or
|
||||
- point $BearerFile at a file readable only by the ZVM service
|
||||
account (better - same threat model as Zerto's own credential
|
||||
storage).
|
||||
#>
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# ----------------------------- CONFIGURE ---------------------------------
|
||||
$WebhookUrl = 'http://webhook.contoso.local:8080/hook/post-failover'
|
||||
$Bearer = '' # paste here, or use $BearerFile
|
||||
$BearerFile = 'C:\ProgramData\Zerto\webhook-token.txt' # one line: the token
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
if (-not $Bearer -and (Test-Path $BearerFile)) {
|
||||
$Bearer = (Get-Content -LiteralPath $BearerFile -TotalCount 1).Trim()
|
||||
}
|
||||
if (-not $Bearer) {
|
||||
throw "No bearer token. Set `$Bearer in this script or write the token to $BearerFile."
|
||||
}
|
||||
|
||||
# Compose the payload. Zerto exposes a few env vars; fall back gracefully.
|
||||
$payload = @{
|
||||
operation = 'failover'
|
||||
vpg = if ($env:ZertoVPGName) { $env:ZertoVPGName } else { 'unknown' }
|
||||
timestamp = (Get-Date).ToUniversalTime().ToString('o')
|
||||
} | ConvertTo-Json -Compress
|
||||
|
||||
# curl on Windows handles long / quoted JSON better via @file than via -d "...".
|
||||
$tempBody = Join-Path $env:TEMP ("zerto-webhook-{0}.json" -f ([guid]::NewGuid()))
|
||||
$payload | Out-File -FilePath $tempBody -Encoding utf8 -NoNewline
|
||||
|
||||
try {
|
||||
Write-Host "POST $WebhookUrl (vpg=$($env:ZertoVPGName))"
|
||||
& curl.exe `
|
||||
--silent --show-error --fail-with-body `
|
||||
--max-time 10 `
|
||||
-X POST `
|
||||
-H "Authorization: Bearer $Bearer" `
|
||||
-H "Content-Type: application/json" `
|
||||
-d "@$tempBody" `
|
||||
"$WebhookUrl"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
# curl prints its own error to stderr; surface a non-zero exit so Zerto's
|
||||
# script log records the failure but we don't block the failover.
|
||||
Write-Warning "Webhook call failed with curl exit $LASTEXITCODE; continuing."
|
||||
} else {
|
||||
Write-Host "Webhook accepted (run id is in the response above)."
|
||||
}
|
||||
}
|
||||
finally {
|
||||
Remove-Item $tempBody -ErrorAction SilentlyContinue
|
||||
}
|
||||
Reference in New Issue
Block a user