The dry run
A dry run answers “what would this failover do, and would it be allowed?” without doing any of it. It reads every check a failover makes, fences nothing and moves nothing (spec §45). The console runs one before every failover and switchover. Its Execute button stays disabled until a dry run for exactly what is on screen has come back; a dry run older than 60 seconds disables it again, and a BLOCKED one leaves no Execute button at all.
Through the API, it is the failover request with ?dry_run=true:
api -data '{"target_site":"dc2"}' POST "/api/v1/availability-plans/erp-db/failover?dry_run=true"Reading it
From the demo lab, with erp-db active at dc1, shortened:
{
"quorum": "PASS",
"current_state_allows_acquire": "PASS",
"dependencies": "PASS (none configured)",
"target_readiness": "PASS",
"target_readiness_lag_seconds": 0.49,
"fence_plan": "PASS",
"fence_bindings": ["bmc-dc1"],
"fence_success": "ALL",
"shield_bindings": ["shield-dc2"],
"unfence_bindings": ["pve-dc2-erp"],
"network_only_fencing": "NO",
"out_of_band_warnings": ["pve-dc1-erp: no network_domain declared (§15)"],
"service_plan": "vip-erp-db",
"config_consistency": "CONSISTENT",
"dependents": [{"plan": "web-portal", "owner": "dc1", "follows": false,
"detail": "stays at dc1, where erp-db will no longer be ACTIVE: it does not follow erp-db"}],
"promotion": "ALLOWED"
}| Field | What it says |
|---|---|
promotion | ALLOWED, or BLOCKED with the reasons that block it. The answer that matters |
quorum | Whether this orchestrator can commit through a majority now |
current_state_allows_acquire | Whether the plan’s state allows a failover: a plan already failing over does not |
dependencies | Whether the plans this one depends on are where they must be |
target_readiness, target_readiness_lag_seconds | Whether the target’s copy is recent enough to promote, and how far behind it is |
fence_plan, fence_bindings, fence_success | What would be fenced, and whether ALL required targets must verify or ANY per site |
shield_bindings | The shields the target would raise (returning sites) |
unfence_bindings | What would be unfenced at the target to start it |
network_only_fencing | YES when the plan relies on network fences alone, a weaker guarantee |
out_of_band_warnings | Fences whose path may share a network with what they fence |
service_plan | What moves the service: here, a FortiGate VIP |
config_consistency | Whether every orchestrator runs the same configuration |
dependents | Plans that depend on this one, and whether they would follow it |
secrets | For each binding and each orchestrator, whether its credential resolves, and through which store and site |
A dry run is advice about the moment it was taken. The failover checks everything again when it runs, and blocks if anything has changed.
Forced operations
A dry run can carry what a forced failover would carry, and shows what it would do with it, still changing nothing:
api -data '{"target_site":"dc2","attest_fenced":{"targets":["bmc-dc1"],"statement":"dc1 lost power at 03:12; the facility confirms both hosts are off"}}' \
POST "/api/v1/availability-plans/erp-db/failover?dry_run=true"Its attestation lists each target the statement would cover, whether that target answers now, and whether it is eligible: a target can be attested only once a failover has tried it and seen it fail, at least min_failing_seconds before (60 in the demo lab). Until then the dry run says so, and is BLOCKED. accept_data_loss gets a data_loss section the same way, with the lag measured now against the bound you give (fencing).