mirror of
https://github.com/juanfont/headscale.git
synced 2026-09-18 06:22:05 +09:00
@@ -39,6 +39,11 @@ type Change struct {
|
||||
PeerPatches []*tailcfg.PeerChange
|
||||
SendAllPeers bool
|
||||
|
||||
// DeletedNodes identifies nodes permanently removed from state. Unlike
|
||||
// PeersRemoved, this is an internal lifecycle signal: the batcher uses it
|
||||
// to tear down the deleted nodes' own map sessions.
|
||||
DeletedNodes []types.NodeID
|
||||
|
||||
// RequiresRuntimePeerComputation indicates that peer visibility
|
||||
// must be computed at runtime per-node. Used for policy changes
|
||||
// where each node may have different peer visibility.
|
||||
@@ -78,6 +83,7 @@ func (r Change) Merge(other Change) Change {
|
||||
|
||||
merged.PeersChanged = uniqueNodeIDs(slices.Concat(r.PeersChanged, other.PeersChanged))
|
||||
merged.PeersRemoved = uniqueNodeIDs(slices.Concat(r.PeersRemoved, other.PeersRemoved))
|
||||
merged.DeletedNodes = uniqueNodeIDs(slices.Concat(r.DeletedNodes, other.DeletedNodes))
|
||||
merged.PeerPatches = slices.Concat(r.PeerPatches, other.PeerPatches)
|
||||
|
||||
// Preserve [Change.OriginNode] for self-update detection.
|
||||
@@ -139,6 +145,7 @@ func (r Change) IsEmpty() bool {
|
||||
|
||||
return len(r.PeersChanged) == 0 &&
|
||||
len(r.PeersRemoved) == 0 &&
|
||||
len(r.DeletedNodes) == 0 &&
|
||||
len(r.PeerPatches) == 0
|
||||
}
|
||||
|
||||
@@ -147,7 +154,8 @@ func (r Change) IsSelfOnly() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if r.SendAllPeers || len(r.PeersChanged) > 0 || len(r.PeersRemoved) > 0 || len(r.PeerPatches) > 0 {
|
||||
if r.SendAllPeers || len(r.PeersChanged) > 0 || len(r.PeersRemoved) > 0 ||
|
||||
len(r.DeletedNodes) > 0 || len(r.PeerPatches) > 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -185,7 +193,8 @@ func (r Change) Type() string {
|
||||
return "patch"
|
||||
}
|
||||
|
||||
if len(r.PeersChanged) > 0 || len(r.PeersRemoved) > 0 || r.SendAllPeers {
|
||||
if len(r.PeersChanged) > 0 || len(r.PeersRemoved) > 0 ||
|
||||
len(r.DeletedNodes) > 0 || r.SendAllPeers {
|
||||
return "peers"
|
||||
}
|
||||
|
||||
@@ -438,7 +447,11 @@ func NodeAdded(id types.NodeID) Change {
|
||||
|
||||
// NodeRemoved returns a [Change] for when a node is removed.
|
||||
func NodeRemoved(id types.NodeID) Change {
|
||||
return PeersRemoved(id)
|
||||
return Change{
|
||||
Reason: "node removed",
|
||||
PeersRemoved: []types.NodeID{id},
|
||||
DeletedNodes: []types.NodeID{id},
|
||||
}
|
||||
}
|
||||
|
||||
// KeyExpiryFor returns a [Change] for when a node's key expiry changes.
|
||||
|
||||
@@ -88,6 +88,11 @@ func TestChange_IsEmpty(t *testing.T) {
|
||||
response: Change{PeersRemoved: []types.NodeID{1}},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "DeletedNodes not empty",
|
||||
response: Change{DeletedNodes: []types.NodeID{1}},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "PeerPatches not empty",
|
||||
response: Change{PeerPatches: []*tailcfg.PeerChange{{}}},
|
||||
@@ -149,6 +154,11 @@ func TestChange_IsSelfOnly(t *testing.T) {
|
||||
response: Change{TargetNode: 1, IncludeSelf: true, PeersRemoved: []types.NodeID{2}},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "self only with DeletedNodes is not self only",
|
||||
response: Change{TargetNode: 1, IncludeSelf: true, DeletedNodes: []types.NodeID{2}},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "self only with PeerPatches is not self only",
|
||||
response: Change{TargetNode: 1, IncludeSelf: true, PeerPatches: []*tailcfg.PeerChange{{}}},
|
||||
@@ -218,6 +228,12 @@ func TestChange_Merge(t *testing.T) {
|
||||
r2: Change{PeersRemoved: []types.NodeID{2, 3}},
|
||||
want: Change{PeersRemoved: []types.NodeID{1, 2, 3}},
|
||||
},
|
||||
{
|
||||
name: "deleted nodes deduplicated",
|
||||
r1: Change{DeletedNodes: []types.NodeID{1, 2}},
|
||||
r2: Change{DeletedNodes: []types.NodeID{2, 3}},
|
||||
want: Change{DeletedNodes: []types.NodeID{1, 2, 3}},
|
||||
},
|
||||
{
|
||||
name: "peer patches concatenated",
|
||||
r1: Change{PeerPatches: []*tailcfg.PeerChange{{NodeID: 1}}},
|
||||
@@ -471,6 +487,13 @@ func TestPeersRemoved(t *testing.T) {
|
||||
assert.Equal(t, []types.NodeID{1, 2, 3}, r.PeersRemoved)
|
||||
}
|
||||
|
||||
func TestNodeRemoved(t *testing.T) {
|
||||
r := NodeRemoved(42)
|
||||
assert.Equal(t, "node removed", r.Reason)
|
||||
assert.Equal(t, []types.NodeID{42}, r.PeersRemoved)
|
||||
assert.Equal(t, []types.NodeID{42}, r.DeletedNodes)
|
||||
}
|
||||
|
||||
func TestPeerPatched(t *testing.T) {
|
||||
patch := &tailcfg.PeerChange{NodeID: 1}
|
||||
r := PeerPatched("endpoint change", patch)
|
||||
|
||||
Reference in New Issue
Block a user