cmd/derpprobe: support 'local' derpmap to get derp map via LocalAPI

To make it easier for people to monitor their custom DERP fleet.

Updates tailscale/corp#20654

Change-Id: Id8af22936a6d893cc7b6186d298ab794a2672524
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/12389/head
Brad Fitzpatrick 4 weeks ago committed by Brad Fitzpatrick
parent 6e106712f6
commit 8a11a43c28

@ -20,7 +20,7 @@ import (
) )
var ( var (
derpMapURL = flag.String("derp-map", "https://login.tailscale.com/derpmap/default", "URL to DERP map (https:// or file://)") derpMapURL = flag.String("derp-map", "https://login.tailscale.com/derpmap/default", "URL to DERP map (https:// or file://) or 'local' to use the local tailscaled's DERP map")
versionFlag = flag.Bool("version", false, "print version and exit") versionFlag = flag.Bool("version", false, "print version and exit")
listen = flag.String("listen", ":8030", "HTTP listen address") listen = flag.String("listen", ":8030", "HTTP listen address")
probeOnce = flag.Bool("once", false, "probe once and print results, then exit; ignores the listen flag") probeOnce = flag.Bool("once", false, "probe once and print results, then exit; ignores the listen flag")

@ -21,6 +21,7 @@ import (
"time" "time"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"tailscale.com/client/tailscale"
"tailscale.com/derp" "tailscale.com/derp"
"tailscale.com/derp/derphttp" "tailscale.com/derp/derphttp"
"tailscale.com/net/netmon" "tailscale.com/net/netmon"
@ -35,7 +36,7 @@ import (
// based on the current DERPMap. // based on the current DERPMap.
type derpProber struct { type derpProber struct {
p *Prober p *Prober
derpMapURL string derpMapURL string // or "local"
udpInterval time.Duration udpInterval time.Duration
meshInterval time.Duration meshInterval time.Duration
tlsInterval time.Duration tlsInterval time.Duration
@ -97,6 +98,9 @@ func WithTLSProbing(interval time.Duration) DERPOpt {
} }
// DERP creates a new derpProber. // DERP creates a new derpProber.
//
// If derpMapURL is "local", the DERPMap is fetched via
// the local machine's tailscaled.
func DERP(p *Prober, derpMapURL string, opts ...DERPOpt) (*derpProber, error) { func DERP(p *Prober, derpMapURL string, opts ...DERPOpt) (*derpProber, error) {
d := &derpProber{ d := &derpProber{
p: p, p: p,
@ -268,8 +272,18 @@ func (d *derpProber) getNodePair(n1, n2 string) (ret1, ret2 *tailcfg.DERPNode, _
return ret1, ret2, nil return ret1, ret2, nil
} }
var tsLocalClient tailscale.LocalClient
// updateMap refreshes the locally-cached DERP map. // updateMap refreshes the locally-cached DERP map.
func (d *derpProber) updateMap(ctx context.Context) error { func (d *derpProber) updateMap(ctx context.Context) error {
var dm *tailcfg.DERPMap
if d.derpMapURL == "local" {
var err error
dm, err = tsLocalClient.CurrentDERPMap(ctx)
if err != nil {
return err
}
} else {
req, err := http.NewRequestWithContext(ctx, "GET", d.derpMapURL, nil) req, err := http.NewRequestWithContext(ctx, "GET", d.derpMapURL, nil)
if err != nil { if err != nil {
return nil return nil
@ -290,10 +304,11 @@ func (d *derpProber) updateMap(ctx context.Context) error {
if res.StatusCode != 200 { if res.StatusCode != 200 {
return fmt.Errorf("fetching %s: %s", d.derpMapURL, res.Status) return fmt.Errorf("fetching %s: %s", d.derpMapURL, res.Status)
} }
dm := new(tailcfg.DERPMap) dm = new(tailcfg.DERPMap)
if err := json.NewDecoder(res.Body).Decode(dm); err != nil { if err := json.NewDecoder(res.Body).Decode(dm); err != nil {
return fmt.Errorf("decoding %s JSON: %v", d.derpMapURL, err) return fmt.Errorf("decoding %s JSON: %v", d.derpMapURL, err)
} }
}
d.Lock() d.Lock()
defer d.Unlock() defer d.Unlock()

Loading…
Cancel
Save