@@ -11,11 +11,24 @@ import (
11
11
"tailscale.com/tailcfg"
12
12
)
13
13
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
+
14
26
type Report struct {
15
27
// Time is the time the report was generated at.
16
28
Time time.Time `json:"time"`
17
29
// 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"`
19
32
20
33
DERP DERPReport `json:"derp"`
21
34
AccessURL AccessURLReport `json:"access_url"`
@@ -28,12 +41,36 @@ type ReportOptions struct {
28
41
AccessURL * url.URL
29
42
Client * http.Client
30
43
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
31
58
}
32
59
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
+ }
35
64
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
+ }
37
74
38
75
wg .Add (1 )
39
76
go func () {
@@ -44,7 +81,7 @@ func Run(ctx context.Context, opts *ReportOptions) (*Report, error) {
44
81
}
45
82
}()
46
83
47
- report .DERP . Run (ctx , & DERPReportOptions {
84
+ report .DERP = opts . Checker . DERP (ctx , & DERPReportOptions {
48
85
DERPMap : opts .DERPMap ,
49
86
})
50
87
}()
@@ -58,7 +95,7 @@ func Run(ctx context.Context, opts *ReportOptions) (*Report, error) {
58
95
}
59
96
}()
60
97
61
- report .AccessURL . Run (ctx , & AccessURLOptions {
98
+ report .AccessURL = opts . Checker . AccessURL (ctx , & AccessURLOptions {
62
99
AccessURL : opts .AccessURL ,
63
100
Client : opts .Client ,
64
101
})
@@ -72,16 +109,25 @@ func Run(ctx context.Context, opts *ReportOptions) (*Report, error) {
72
109
report .Websocket .Error = xerrors .Errorf ("%v" , err )
73
110
}
74
111
}()
75
- report .Websocket .Run (ctx , & WebsocketReportOptions {
112
+
113
+ report .Websocket = opts .Checker .Websocket (ctx , & WebsocketReportOptions {
76
114
APIKey : opts .APIKey ,
77
115
AccessURL : opts .AccessURL ,
78
116
})
79
117
}()
80
118
81
119
wg .Wait ()
82
120
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
87
133
}
0 commit comments