cmd/tailscale/cli: let ip take a peername

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/1706/head
Brad Fitzpatrick 4 years ago
parent 762180595d
commit 75b99555f3

@ -11,13 +11,16 @@ import (
"fmt" "fmt"
"github.com/peterbourgon/ff/v2/ffcli" "github.com/peterbourgon/ff/v2/ffcli"
"inet.af/netaddr"
"tailscale.com/client/tailscale" "tailscale.com/client/tailscale"
"tailscale.com/ipn/ipnstate"
) )
var ipCmd = &ffcli.Command{ var ipCmd = &ffcli.Command{
Name: "ip", Name: "ip",
ShortUsage: "ip [-4] [-6]", ShortUsage: "ip [-4] [-6] [peername]",
ShortHelp: "Show this machine's current Tailscale IP address(es)", ShortHelp: "Show current Tailscale IP address(es)",
LongHelp: "Shows the Tailscale IP address of the current machine without an argument. With an argument, it shows the IP of a named peer.",
Exec: runIP, Exec: runIP,
FlagSet: (func() *flag.FlagSet { FlagSet: (func() *flag.FlagSet {
fs := flag.NewFlagSet("ip", flag.ExitOnError) fs := flag.NewFlagSet("ip", flag.ExitOnError)
@ -33,9 +36,14 @@ var ipArgs struct {
} }
func runIP(ctx context.Context, args []string) error { func runIP(ctx context.Context, args []string) error {
if len(args) > 0 { if len(args) > 1 {
return errors.New("unknown arguments") return errors.New("unknown arguments")
} }
var of string
if len(args) == 1 {
of = args[0]
}
v4, v6 := ipArgs.want4, ipArgs.want6 v4, v6 := ipArgs.want4, ipArgs.want6
if v4 && v6 { if v4 && v6 {
return errors.New("tailscale up -4 and -6 are mutually exclusive") return errors.New("tailscale up -4 and -6 are mutually exclusive")
@ -47,11 +55,24 @@ func runIP(ctx context.Context, args []string) error {
if err != nil { if err != nil {
return err return err
} }
if len(st.TailscaleIPs) == 0 { ips := st.TailscaleIPs
if of != "" {
ip, err := tailscaleIPFromArg(ctx, of)
if err != nil {
return err
}
peer, ok := peerMatchingIP(st, ip)
if !ok {
return fmt.Errorf("no peer found with IP %v", ip)
}
ips = peer.TailscaleIPs
}
if len(ips) == 0 {
return fmt.Errorf("no current Tailscale IPs; state: %v", st.BackendState) return fmt.Errorf("no current Tailscale IPs; state: %v", st.BackendState)
} }
match := false match := false
for _, ip := range st.TailscaleIPs { for _, ip := range ips {
if ip.Is4() && v4 || ip.Is6() && v6 { if ip.Is4() && v4 || ip.Is6() && v6 {
match = true match = true
fmt.Println(ip) fmt.Println(ip)
@ -67,3 +88,18 @@ func runIP(ctx context.Context, args []string) error {
} }
return nil return nil
} }
func peerMatchingIP(st *ipnstate.Status, ipStr string) (ps *ipnstate.PeerStatus, ok bool) {
ip, err := netaddr.ParseIP(ipStr)
if err != nil {
return
}
for _, ps = range st.Peer {
for _, pip := range ps.TailscaleIPs {
if ip == pip {
return ps, true
}
}
}
return nil, false
}

Loading…
Cancel
Save