mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-27 02:37:38 +00:00
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>
This commit is contained in:
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,31 +272,42 @@ 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 {
|
||||||
req, err := http.NewRequestWithContext(ctx, "GET", d.derpMapURL, nil)
|
var dm *tailcfg.DERPMap
|
||||||
if err != nil {
|
if d.derpMapURL == "local" {
|
||||||
return nil
|
var err error
|
||||||
}
|
dm, err = tsLocalClient.CurrentDERPMap(ctx)
|
||||||
res, err := httpOrFileClient.Do(req)
|
if err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
d.Lock()
|
}
|
||||||
defer d.Unlock()
|
} else {
|
||||||
if d.lastDERPMap != nil && time.Since(d.lastDERPMapAt) < 10*time.Minute {
|
req, err := http.NewRequestWithContext(ctx, "GET", d.derpMapURL, nil)
|
||||||
log.Printf("Error while fetching DERP map, using cached one: %s", err)
|
if err != nil {
|
||||||
// Assume that control is restarting and use
|
|
||||||
// the same one for a bit.
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return err
|
res, err := httpOrFileClient.Do(req)
|
||||||
}
|
if err != nil {
|
||||||
defer res.Body.Close()
|
d.Lock()
|
||||||
if res.StatusCode != 200 {
|
defer d.Unlock()
|
||||||
return fmt.Errorf("fetching %s: %s", d.derpMapURL, res.Status)
|
if d.lastDERPMap != nil && time.Since(d.lastDERPMapAt) < 10*time.Minute {
|
||||||
}
|
log.Printf("Error while fetching DERP map, using cached one: %s", err)
|
||||||
dm := new(tailcfg.DERPMap)
|
// Assume that control is restarting and use
|
||||||
if err := json.NewDecoder(res.Body).Decode(dm); err != nil {
|
// the same one for a bit.
|
||||||
return fmt.Errorf("decoding %s JSON: %v", d.derpMapURL, err)
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
if res.StatusCode != 200 {
|
||||||
|
return fmt.Errorf("fetching %s: %s", d.derpMapURL, res.Status)
|
||||||
|
}
|
||||||
|
dm = new(tailcfg.DERPMap)
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(dm); err != nil {
|
||||||
|
return fmt.Errorf("decoding %s JSON: %v", d.derpMapURL, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Lock()
|
d.Lock()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user