mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
cmd/tailscale,ipn: surface TKA-filtered peers in lock status command
Signed-off-by: Tom DNetto <tom@tailscale.com>
This commit is contained in:
parent
731be07777
commit
9a80b8fb10
@ -213,6 +213,26 @@ func runNetworkLockStatus(ctx context.Context, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if st.Enabled && len(st.FilteredPeers) > 0 {
|
||||
fmt.Println()
|
||||
fmt.Println("The following peers are locked out by tailnet lock & do not have connectivity:")
|
||||
for _, p := range st.FilteredPeers {
|
||||
var line strings.Builder
|
||||
line.WriteString("\t")
|
||||
line.WriteString(p.Name)
|
||||
line.WriteString("\t")
|
||||
for i, addr := range p.TailscaleIPs {
|
||||
line.WriteString(addr.String())
|
||||
if i < len(p.TailscaleIPs)-1 {
|
||||
line.WriteString(", ")
|
||||
}
|
||||
}
|
||||
line.WriteString("\t")
|
||||
line.WriteString(string(p.StableID))
|
||||
fmt.Println(line.String())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
@ -21,6 +22,7 @@
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/tka"
|
||||
"tailscale.com/types/key"
|
||||
@ -41,6 +43,7 @@ type tkaState struct {
|
||||
profile ipn.ProfileID
|
||||
authority *tka.Authority
|
||||
storage *tka.FS
|
||||
filtered []ipnstate.TKAFilteredPeer
|
||||
}
|
||||
|
||||
// tkaFilterNetmapLocked checks the signatures on each node key, dropping
|
||||
@ -75,12 +78,30 @@ func (b *LocalBackend) tkaFilterNetmapLocked(nm *netmap.NetworkMap) {
|
||||
// nm.Peers is ordered, so deletion must be order-preserving.
|
||||
if len(toDelete) > 0 {
|
||||
peers := make([]*tailcfg.Node, 0, len(nm.Peers))
|
||||
filtered := make([]ipnstate.TKAFilteredPeer, 0, len(toDelete))
|
||||
for i, p := range nm.Peers {
|
||||
if !toDelete[i] {
|
||||
peers = append(peers, p)
|
||||
} else {
|
||||
// Record information about the node we filtered out.
|
||||
fp := ipnstate.TKAFilteredPeer{
|
||||
Name: p.Name,
|
||||
ID: p.ID,
|
||||
StableID: p.StableID,
|
||||
TailscaleIPs: make([]netip.Addr, len(p.Addresses)),
|
||||
}
|
||||
for i, addr := range p.Addresses {
|
||||
if addr.IsSingleIP() && tsaddr.IsTailscaleIP(addr.Addr()) {
|
||||
fp.TailscaleIPs[i] = addr.Addr()
|
||||
}
|
||||
}
|
||||
filtered = append(filtered, fp)
|
||||
}
|
||||
}
|
||||
nm.Peers = peers
|
||||
b.tka.filtered = filtered
|
||||
} else {
|
||||
b.tka.filtered = nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,6 +420,11 @@ func (b *LocalBackend) NetworkLockStatus() *ipnstate.NetworkLockStatus {
|
||||
}
|
||||
}
|
||||
|
||||
filtered := make([]*ipnstate.TKAFilteredPeer, len(b.tka.filtered))
|
||||
for i := 0; i < len(filtered); i++ {
|
||||
filtered[i] = b.tka.filtered[i].Clone()
|
||||
}
|
||||
|
||||
return &ipnstate.NetworkLockStatus{
|
||||
Enabled: true,
|
||||
Head: &head,
|
||||
@ -406,6 +432,7 @@ func (b *LocalBackend) NetworkLockStatus() *ipnstate.NetworkLockStatus {
|
||||
NodeKey: nodeKey,
|
||||
NodeKeySigned: selfAuthorized,
|
||||
TrustedKeys: outKeys,
|
||||
FilteredPeers: filtered,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
||||
//go:generate go run tailscale.com/cmd/cloner -clonefunc=false -type=TKAFilteredPeer
|
||||
|
||||
// Status represents the entire state of the IPN network.
|
||||
type Status struct {
|
||||
// Version is the daemon's long version (see version.Long).
|
||||
@ -74,6 +76,16 @@ type TKAKey struct {
|
||||
Votes uint
|
||||
}
|
||||
|
||||
// TKAFilteredPeer describes a peer which was removed from the netmap
|
||||
// (i.e. no connectivity) because it failed tailnet lock
|
||||
// checks.
|
||||
type TKAFilteredPeer struct {
|
||||
Name string // DNS
|
||||
ID tailcfg.NodeID
|
||||
StableID tailcfg.StableNodeID
|
||||
TailscaleIPs []netip.Addr // Tailscale IP(s) assigned to this node
|
||||
}
|
||||
|
||||
// NetworkLockStatus represents whether network-lock is enabled,
|
||||
// along with details about the locally-known state of the tailnet
|
||||
// key authority.
|
||||
@ -99,6 +111,11 @@ type NetworkLockStatus struct {
|
||||
// TrustedKeys describes the keys currently trusted to make changes
|
||||
// to network-lock.
|
||||
TrustedKeys []TKAKey
|
||||
|
||||
// FilteredPeers describes peers which were removed from the netmap
|
||||
// (i.e. no connectivity) because they failed tailnet lock
|
||||
// checks.
|
||||
FilteredPeers []*TKAFilteredPeer
|
||||
}
|
||||
|
||||
// NetworkLockUpdate describes a change to network-lock state.
|
||||
|
33
ipn/ipnstate/ipnstate_clone.go
Normal file
33
ipn/ipnstate/ipnstate_clone.go
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
|
||||
|
||||
package ipnstate
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
|
||||
"tailscale.com/tailcfg"
|
||||
)
|
||||
|
||||
// Clone makes a deep copy of TKAFilteredPeer.
|
||||
// The result aliases no memory with the original.
|
||||
func (src *TKAFilteredPeer) Clone() *TKAFilteredPeer {
|
||||
if src == nil {
|
||||
return nil
|
||||
}
|
||||
dst := new(TKAFilteredPeer)
|
||||
*dst = *src
|
||||
dst.TailscaleIPs = append(src.TailscaleIPs[:0:0], src.TailscaleIPs...)
|
||||
return dst
|
||||
}
|
||||
|
||||
// A compilation failure here means this code must be regenerated, with the command at the top of this file.
|
||||
var _TKAFilteredPeerCloneNeedsRegeneration = TKAFilteredPeer(struct {
|
||||
Name string
|
||||
ID tailcfg.NodeID
|
||||
StableID tailcfg.StableNodeID
|
||||
TailscaleIPs []netip.Addr
|
||||
}{})
|
Loading…
Reference in New Issue
Block a user