From 42f01afe267acf97f7aa10a900d3d5e4e3816e57 Mon Sep 17 00:00:00 2001 From: Charlotte Brandhorst-Satzkorn <46385858+catzkorn@users.noreply.github.com> Date: Wed, 3 Jul 2024 11:48:20 -0700 Subject: [PATCH] cmd/tailscale/cli: exit node filter should display all exit node options (#12699) This change expands the `exit-node list -filter` command to display all location based exit nodes for the filtered country. This allows users to switch to alternative servers when our recommended exit node is not working as intended. This change also makes the country filter matching case insensitive, e.g. both USA and usa will work. Updates #12698 Signed-off-by: Charlotte Brandhorst-Satzkorn --- cmd/tailscale/cli/exitnode.go | 12 +++++++++--- cmd/tailscale/cli/exitnode_test.go | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/cmd/tailscale/cli/exitnode.go b/cmd/tailscale/cli/exitnode.go index 09971010f..9490b4de9 100644 --- a/cmd/tailscale/cli/exitnode.go +++ b/cmd/tailscale/cli/exitnode.go @@ -137,6 +137,7 @@ func runExitNodeList(ctx context.Context, args []string) error { } fmt.Fprintln(w) fmt.Fprintln(w) + fmt.Fprintln(w, "# To view the complete list of exit nodes for a country, use `tailscale exit-node list --filter=` followed by the country name.") fmt.Fprintln(w, "# To use an exit node, use `tailscale set --exit-node=` followed by the hostname or IP.") if hasAnyExitNodeSuggestions(peers) { fmt.Fprintln(w, "# To have Tailscale suggest an exit node, use `tailscale exit-node suggest`.") @@ -231,7 +232,7 @@ func filterFormatAndSortExitNodes(peers []*ipnstate.PeerStatus, filterBy string) for _, ps := range peers { loc := cmp.Or(ps.Location, noLocation) - if filterBy != "" && loc.Country != filterBy { + if filterBy != "" && !strings.EqualFold(loc.Country, filterBy) { continue } @@ -271,9 +272,14 @@ func filterFormatAndSortExitNodes(peers []*ipnstate.PeerStatus, filterBy string) countryAnyPeer = append(countryAnyPeer, city.Peers...) var reducedCityPeers []*ipnstate.PeerStatus for i, peer := range city.Peers { + if filterBy != "" { + // If the peers are being filtered, we return all peers to the user. + reducedCityPeers = append(reducedCityPeers, city.Peers...) + break + } + // If the peers are not being filtered, we only return the highest priority peer and any peer that + // is currently the active exit node. if i == 0 || peer.ExitNode { - // We only return the highest priority peer and any peer that - // is currently the active exit node. reducedCityPeers = append(reducedCityPeers, peer) } } diff --git a/cmd/tailscale/cli/exitnode_test.go b/cmd/tailscale/cli/exitnode_test.go index d2329bda4..4f66fa756 100644 --- a/cmd/tailscale/cli/exitnode_test.go +++ b/cmd/tailscale/cli/exitnode_test.go @@ -219,7 +219,7 @@ func TestFilterFormatAndSortExitNodes(t *testing.T) { { Name: "Rainier", Peers: []*ipnstate.PeerStatus{ - ps[2], + ps[2], ps[3], }, }, },