From 5887927e9b34ff6d2138112bfbe22f2f76d44a8c Mon Sep 17 00:00:00 2001 From: Julian Sommer <115516918+juliansommer@users.noreply.github.com> Date: Tue, 19 May 2026 10:05:51 +1000 Subject: [PATCH] fix(daemon): republish vpc.add-nat on instance recovery (#232) --- spinifex/daemon/vm_adapters.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/spinifex/daemon/vm_adapters.go b/spinifex/daemon/vm_adapters.go index 6c5eca68c..5596ac5b6 100644 --- a/spinifex/daemon/vm_adapters.go +++ b/spinifex/daemon/vm_adapters.go @@ -412,6 +412,29 @@ func (d *Daemon) onInstanceUpHook() func(*vm.VM) error { } } } + + // Republish vpc.add-nat so vpcd re-establishes the dnat_and_snat + // rule on host-reboot recovery. The OVN NB entry doesn't always + // survive the reboot, and vpcd's reconcile loop only re-creates + // EIP-allocated NATs (reconcile.go:391) — direct-add NATs from + // LaunchInstance / LaunchSystemInstance are otherwise unrecoverable. + // Idempotent: vpcd's handler deletes-then-adds (topology.go:1297), + // so this is a no-op on fresh launches where the initial publish + // already fired. + if d.natsConn != nil && instance.PublicIP != "" && instance.ENIId != "" && instance.Instance != nil { + vpcID := "" + privateIP := "" + if instance.Instance.VpcId != nil { + vpcID = *instance.Instance.VpcId + } + if instance.Instance.PrivateIpAddress != nil { + privateIP = *instance.Instance.PrivateIpAddress + } + if vpcID != "" && privateIP != "" { + portName := "port-" + instance.ENIId + utils.PublishNATEvent(d.natsConn, "vpc.add-nat", vpcID, instance.PublicIP, privateIP, portName, instance.ENIMac) + } + } return nil } }