cmd/tailscale/cli: add tailscale exit-node suggest --force-probe

Add a new `--force-probe` flag to `tailscale exit-node suggest` that
waits for a routecheck.Refresh to finish before suggesting an exit
node.

This flag is currently hidden from the help text, but this flag is a
hint to the user that exit-node suggestions are based on routecheck
reachability reports.

Updates #17366
Updates tailscale/corp#33033

Signed-off-by: Simon Law <sfllaw@tailscale.com>
This commit is contained in:
Simon Law
2026-07-02 20:26:27 -07:00
committed by Simon Law
parent 932260511e
commit ca91eafce5
4 changed files with 99 additions and 3 deletions
+14 -1
View File
@@ -16,6 +16,7 @@ import (
"github.com/kballard/go-shellquote"
"github.com/peterbourgon/ff/v3/ffcli"
"tailscale.com/envknob"
"tailscale.com/feature/buildfeatures"
"tailscale.com/ipn/ipnstate"
"tailscale.com/tailcfg"
"tailscale.com/util/slicesx"
@@ -43,6 +44,13 @@ func exitNodeCmd() *ffcli.Command {
ShortUsage: "tailscale exit-node suggest",
ShortHelp: "Suggest the best available exit node",
Exec: runExitNodeSuggest,
FlagSet: (func() *flag.FlagSet {
fs := newFlagSet("suggest")
if buildfeatures.HasRouteCheck {
fs.BoolVar(&exitNodeArgs.probe, "force-probe", false, hidden+"perform a routecheck probe before suggesting")
}
return fs
})(),
}},
(func() []*ffcli.Command {
if !envknob.UseWIPCode() {
@@ -68,6 +76,7 @@ func exitNodeCmd() *ffcli.Command {
var exitNodeArgs struct {
filter string
probe bool
}
func exitNodeSetUse(wantOn bool) func(ctx context.Context, args []string) error {
@@ -148,7 +157,11 @@ func runExitNodeList(ctx context.Context, args []string) error {
// runExitNodeSuggest returns a suggested exit node ID to connect to and shows the chosen exit node tailcfg.StableNodeID.
// If there are no derp based exit nodes to choose from or there is a failure in finding a suggestion, the command will return an error indicating so.
func runExitNodeSuggest(ctx context.Context, args []string) error {
res, err := localClient.SuggestExitNode(ctx)
suggestExitNode := localClient.SuggestExitNode
if exitNodeArgs.probe {
suggestExitNode = localClient.SuggestExitNodeWithProbe
}
res, err := suggestExitNode(ctx)
if err != nil {
return fmt.Errorf("suggest exit node: %w", err)
}