cmd/tailscale: add derp and endpoints status (#703)

cmd/tailscale: add local node's information to status output (by default)

RELNOTE=yes

Updates #477

Signed-off-by: Halulu <lzjluzijie@gmail.com>
reviewable/pr717/r1
halulu 4 years ago committed by GitHub
parent f915ab6552
commit f27a57911b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -33,6 +33,7 @@ var statusCmd = &ffcli.Command{
fs.BoolVar(&statusArgs.json, "json", false, "output in JSON format (WARNING: format subject to change)") fs.BoolVar(&statusArgs.json, "json", false, "output in JSON format (WARNING: format subject to change)")
fs.BoolVar(&statusArgs.web, "web", false, "run webserver with HTML showing status") fs.BoolVar(&statusArgs.web, "web", false, "run webserver with HTML showing status")
fs.BoolVar(&statusArgs.active, "active", false, "filter output to only peers with active sessions (not applicable to web mode)") fs.BoolVar(&statusArgs.active, "active", false, "filter output to only peers with active sessions (not applicable to web mode)")
fs.BoolVar(&statusArgs.self, "self", true, "show status of local machine")
fs.StringVar(&statusArgs.listen, "listen", "127.0.0.1:8384", "listen address; use port 0 for automatic") fs.StringVar(&statusArgs.listen, "listen", "127.0.0.1:8384", "listen address; use port 0 for automatic")
fs.BoolVar(&statusArgs.browser, "browser", true, "Open a browser in web mode") fs.BoolVar(&statusArgs.browser, "browser", true, "Open a browser in web mode")
return fs return fs
@ -45,6 +46,7 @@ var statusArgs struct {
listen string // in web mode, webserver address to listen on, empty means auto listen string // in web mode, webserver address to listen on, empty means auto
browser bool // in web mode, whether to open browser browser bool // in web mode, whether to open browser
active bool // in CLI mode, filter output to only peers with active sessions active bool // in CLI mode, filter output to only peers with active sessions
self bool // in CLI mode, show status of local machine
} }
func runStatus(ctx context.Context, args []string) error { func runStatus(ctx context.Context, args []string) error {
@ -127,14 +129,10 @@ func runStatus(ctx context.Context, args []string) error {
var buf bytes.Buffer var buf bytes.Buffer
f := func(format string, a ...interface{}) { fmt.Fprintf(&buf, format, a...) } f := func(format string, a ...interface{}) { fmt.Fprintf(&buf, format, a...) }
for _, peer := range st.Peers() { printPS := func(ps *ipnstate.PeerStatus) {
ps := st.Peer[peer]
active := peerActive(ps) active := peerActive(ps)
if statusArgs.active && !active {
continue
}
f("%s %-7s %-15s %-18s tx=%8d rx=%8d ", f("%s %-7s %-15s %-18s tx=%8d rx=%8d ",
peer.ShortString(), ps.PublicKey.ShortString(),
ps.OS, ps.OS,
ps.TailAddr, ps.TailAddr,
ps.SimpleHostName(), ps.SimpleHostName(),
@ -160,6 +158,18 @@ func runStatus(ctx context.Context, args []string) error {
} }
f("\n") f("\n")
} }
if statusArgs.self && st.Self != nil {
printPS(st.Self)
}
for _, peer := range st.Peers() {
ps := st.Peer[peer]
active := peerActive(ps)
if statusArgs.active && !active {
continue
}
printPS(ps)
}
os.Stdout.Write(buf.Bytes()) os.Stdout.Write(buf.Bytes())
return nil return nil
} }

@ -27,8 +27,10 @@ import (
type Status struct { type Status struct {
BackendState string BackendState string
TailscaleIPs []netaddr.IP // Tailscale IP(s) assigned to this node TailscaleIPs []netaddr.IP // Tailscale IP(s) assigned to this node
Peer map[key.Public]*PeerStatus Self *PeerStatus
User map[tailcfg.UserID]tailcfg.UserProfile
Peer map[key.Public]*PeerStatus
User map[tailcfg.UserID]tailcfg.UserProfile
} }
func (s *Status) Peers() []key.Public { func (s *Status) Peers() []key.Public {
@ -95,6 +97,13 @@ func (sb *StatusBuilder) Status() *Status {
return &sb.st return &sb.st
} }
// SetSelfStatus sets the status of the local machine.
func (sb *StatusBuilder) SetSelfStatus(ss *PeerStatus) {
sb.mu.Lock()
defer sb.mu.Unlock()
sb.st.Self = ss
}
// AddUser adds a user profile to the status. // AddUser adds a user profile to the status.
func (sb *StatusBuilder) AddUser(id tailcfg.UserID, up tailcfg.UserProfile) { func (sb *StatusBuilder) AddUser(id tailcfg.UserID, up tailcfg.UserProfile) {
sb.mu.Lock() sb.mu.Lock()

@ -3034,6 +3034,21 @@ func (c *Conn) UpdateStatus(sb *ipnstate.StatusBuilder) {
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()
ss := &ipnstate.PeerStatus{
PublicKey: c.privateKey.Public(),
Addrs: c.lastEndpoints,
}
if c.netMap != nil {
ss.HostName = c.netMap.Hostinfo.Hostname
ss.OS = c.netMap.Hostinfo.OS
}
if c.derpMap != nil {
derpRegion, ok := c.derpMap.Regions[c.myDerp]
if ok {
ss.Relay = derpRegion.RegionCode
}
}
if c.netMap != nil { if c.netMap != nil {
for _, addr := range c.netMap.Addresses { for _, addr := range c.netMap.Addresses {
if (addr.IP.Is4() && addr.Mask != 32) || (addr.IP.Is6() && addr.Mask != 128) { if (addr.IP.Is4() && addr.Mask != 32) || (addr.IP.Is6() && addr.Mask != 128) {
@ -3041,9 +3056,11 @@ func (c *Conn) UpdateStatus(sb *ipnstate.StatusBuilder) {
} }
if ip, ok := netaddr.FromStdIP(addr.IP.IP()); ok { if ip, ok := netaddr.FromStdIP(addr.IP.IP()); ok {
sb.AddTailscaleIP(ip) sb.AddTailscaleIP(ip)
ss.TailAddr = ip.String()
} }
} }
} }
sb.SetSelfStatus(ss)
for dk, n := range c.nodeOfDisco { for dk, n := range c.nodeOfDisco {
ps := &ipnstate.PeerStatus{InMagicSock: true} ps := &ipnstate.PeerStatus{InMagicSock: true}

Loading…
Cancel
Save