mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-27 11:41:14 +00:00
cmd/tailscale/cli,client,ipn: add appc-routes cli command
Allow the user to access information about routes an app connector has learned, such as how many routes for each domain. Fixes tailscale/corp#32624 Signed-off-by: Fran Bull <fran@tailscale.com>
This commit is contained in:
@@ -7124,6 +7124,15 @@ func (b *LocalBackend) readRouteInfoLocked() (*appc.RouteInfo, error) {
|
||||
return ri, nil
|
||||
}
|
||||
|
||||
// ReadRouteInfo returns the app connector route information that is
|
||||
// stored in prefs to be consistent across restarts. It should be up
|
||||
// to date with the RouteInfo in memory being used by appc.
|
||||
func (b *LocalBackend) ReadRouteInfo() (*appc.RouteInfo, error) {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
return b.readRouteInfoLocked()
|
||||
}
|
||||
|
||||
// seamlessRenewalEnabled reports whether seamless key renewals are enabled.
|
||||
//
|
||||
// As of 2025-09-11, this is the default behaviour unless nodes receive
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
"tailscale.com/appc"
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/clientupdate"
|
||||
"tailscale.com/envknob"
|
||||
@@ -73,6 +74,7 @@ var handler = map[string]LocalAPIHandler{
|
||||
// The other /localapi/v0/NAME handlers are exact matches and contain only NAME
|
||||
// without a trailing slash:
|
||||
"alpha-set-device-attrs": (*Handler).serveSetDeviceAttrs, // see tailscale/corp#24690
|
||||
"appc-route-info": (*Handler).serveGetAppcRouteInfo,
|
||||
"bugreport": (*Handler).serveBugReport,
|
||||
"check-ip-forwarding": (*Handler).serveCheckIPForwarding,
|
||||
"check-prefs": (*Handler).serveCheckPrefs,
|
||||
@@ -2111,3 +2113,21 @@ func (h *Handler) serveShutdown(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
eventbus.Publish[Shutdown](ec).Publish(Shutdown{})
|
||||
}
|
||||
|
||||
func (h *Handler) serveGetAppcRouteInfo(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != httpm.GET {
|
||||
http.Error(w, "only GET allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
res, err := h.b.ReadRouteInfo()
|
||||
if err != nil {
|
||||
if errors.Is(err, ipn.ErrStateNotExist) {
|
||||
res = &appc.RouteInfo{}
|
||||
} else {
|
||||
WriteErrorJSON(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(res)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user