Luke Kosewski fa4ad9d5d5 Add watchIPNBus-compatible notification for node going away.
Without this signal, tsnet consumers (e.g. Aperture) cannot distinguish
a deleted node from a transient control-plane outage. Such a node will
sit in BackendState=Running and indefinitely wile mapRoutine has been
silently 404'ing on /machine/map every 30 seconds for 5 years.

With NodeNotFoundWarnable exposed on the IPN bus, the entire
consumer-side reaction collapses to a few lines in its existing notify
watcher:

  for {
      notify, err := watcher.Next()
      if err != nil {
          return
      }
      if notify.Health != nil {
          _, deleted := notify.Health.Warnings[health.NodeNotFoundWarnable.Code]
          if deleted && !nodeDeleted {
              nodeDeleted = true
              // surface to the operator (UI badge, alert, action, etc.)
          }
      }
  }

A subsequent successful registration with a fresh node key clears the
warnable on its own, so re-authentication flows recover without any
extra plumbing on the consumer side. And no persistence is required: if
a consumer process crashes while the node is in this state, mapRoutine
re-hits the 404 within ~30s of restart and the warnable trips again.

Updates #19326

Signed-off-by: Luke Kosewski <lkosewsk@tailscale.com>
2026-04-30 15:59:19 -07:00
..