ipn,control: adds node not found to ipn.Notify

Updates #18700

Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
This commit is contained in:
chaosinthecrd 2026-02-12 16:04:01 +00:00
parent 0bac4223d1
commit 5ba62d2832
No known key found for this signature in database
GPG Key ID: 52ED56820AF046EE
2 changed files with 14 additions and 0 deletions

View File

@ -157,6 +157,12 @@ type Notify struct {
// any changes to the user in the UI.
Health *health.State `json:",omitzero"`
// NodeRemoved, if non-nil, indicates that this node has been removed
// from the tailnet by the control plane. When set, the value is a
// message describing why the node was removed (e.g., "node not found",
// "node deleted by admin", etc.)
NodeRemoved *string `json:",omitzero"`
// SuggestedExitNode, if non-nil, is the node that the backend has determined to
// be the best exit node for the current network conditions.
SuggestedExitNode *tailcfg.StableNodeID `json:",omitzero"`
@ -203,6 +209,9 @@ func (n Notify) String() string {
if n.SuggestedExitNode != nil {
fmt.Fprintf(&sb, "SuggestedExitNode=%v ", *n.SuggestedExitNode)
}
if n.NodeRemoved != nil {
fmt.Fprintf(&sb, "nodeRemoved=%q ", *n.NodeRemoved)
}
s := sb.String()
if s == "Notify{" {

View File

@ -1583,6 +1583,11 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control
return
}
b.logf("Received error: %v", st.Err)
errMsg := st.Err.Error()
if strings.Contains(errMsg, "404") && strings.Contains(errMsg, "node not found") {
reason := "This node has been removed from the tailnet"
b.sendLocked(ipn.Notify{NodeRemoved: &reason})
}
var uerr controlclient.UserVisibleError
if errors.As(st.Err, &uerr) {
s := uerr.UserVisibleError()