@@ -11,11 +11,24 @@ import (
1111 "tailscale.com/tailcfg"
1212)
1313
14+ const (
15+ SectionDERP string = "DERP"
16+ SectionAccessURL string = "AccessURL"
17+ SectionWebsocket string = "Websocket"
18+ )
19+
20+ type Checker interface {
21+ DERP (ctx context.Context , opts * DERPReportOptions ) DERPReport
22+ AccessURL (ctx context.Context , opts * AccessURLOptions ) AccessURLReport
23+ Websocket (ctx context.Context , opts * WebsocketReportOptions ) WebsocketReport
24+ }
25+
1426type Report struct {
1527 // Time is the time the report was generated at.
1628 Time time.Time `json:"time"`
1729 // Healthy is true if the report returns no errors.
18- Healthy bool `json:"healthy"`
30+ Healthy bool `json:"healthy"`
31+ FailingSections []string `json:"failing_sections"`
1932
2033 DERP DERPReport `json:"derp"`
2134 AccessURL AccessURLReport `json:"access_url"`
@@ -28,12 +41,36 @@ type ReportOptions struct {
2841 AccessURL * url.URL
2942 Client * http.Client
3043 APIKey string
44+
45+ Checker Checker
46+ }
47+
48+ type defaultChecker struct {}
49+
50+ func (defaultChecker ) DERP (ctx context.Context , opts * DERPReportOptions ) (report DERPReport ) {
51+ report .Run (ctx , opts )
52+ return report
53+ }
54+
55+ func (defaultChecker ) AccessURL (ctx context.Context , opts * AccessURLOptions ) (report AccessURLReport ) {
56+ report .Run (ctx , opts )
57+ return report
3158}
3259
33- func Run (ctx context.Context , opts * ReportOptions ) (* Report , error ) {
34- var report Report
60+ func (defaultChecker ) Websocket (ctx context.Context , opts * WebsocketReportOptions ) (report WebsocketReport ) {
61+ report .Run (ctx , opts )
62+ return report
63+ }
3564
36- wg := & sync.WaitGroup {}
65+ func Run (ctx context.Context , opts * ReportOptions ) * Report {
66+ var (
67+ wg sync.WaitGroup
68+ report Report
69+ )
70+
71+ if opts .Checker == nil {
72+ opts .Checker = defaultChecker {}
73+ }
3774
3875 wg .Add (1 )
3976 go func () {
@@ -44,7 +81,7 @@ func Run(ctx context.Context, opts *ReportOptions) (*Report, error) {
4481 }
4582 }()
4683
47- report .DERP . Run (ctx , & DERPReportOptions {
84+ report .DERP = opts . Checker . DERP (ctx , & DERPReportOptions {
4885 DERPMap : opts .DERPMap ,
4986 })
5087 }()
@@ -58,7 +95,7 @@ func Run(ctx context.Context, opts *ReportOptions) (*Report, error) {
5895 }
5996 }()
6097
61- report .AccessURL . Run (ctx , & AccessURLOptions {
98+ report .AccessURL = opts . Checker . AccessURL (ctx , & AccessURLOptions {
6299 AccessURL : opts .AccessURL ,
63100 Client : opts .Client ,
64101 })
@@ -72,16 +109,25 @@ func Run(ctx context.Context, opts *ReportOptions) (*Report, error) {
72109 report .Websocket .Error = xerrors .Errorf ("%v" , err )
73110 }
74111 }()
75- report .Websocket .Run (ctx , & WebsocketReportOptions {
112+
113+ report .Websocket = opts .Checker .Websocket (ctx , & WebsocketReportOptions {
76114 APIKey : opts .APIKey ,
77115 AccessURL : opts .AccessURL ,
78116 })
79117 }()
80118
81119 wg .Wait ()
82120 report .Time = time .Now ()
83- report .Healthy = report .DERP .Healthy &&
84- report .AccessURL .Healthy &&
85- report .Websocket .Healthy
86- return & report , nil
121+ if ! report .DERP .Healthy {
122+ report .FailingSections = append (report .FailingSections , SectionDERP )
123+ }
124+ if ! report .AccessURL .Healthy {
125+ report .FailingSections = append (report .FailingSections , SectionAccessURL )
126+ }
127+ if ! report .Websocket .Healthy {
128+ report .FailingSections = append (report .FailingSections , SectionWebsocket )
129+ }
130+
131+ report .Healthy = len (report .FailingSections ) == 0
132+ return & report
87133}
0 commit comments