refactor(coderd/healthcheck): move derp report to derphealth package (#9506)

This change helps remove one indirect use of coderd/database in the slim
CLI.

No size change (yet).

Ref: #9380
This commit is contained in:
Mathias Fredriksson 2023-09-04 21:41:50 +03:00 committed by GitHub
parent a1025f92af
commit 39e3b049a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 242 additions and 228 deletions

View File

@ -9,7 +9,7 @@ import (
"golang.org/x/xerrors"
"github.com/coder/coder/v2/cli/clibase"
"github.com/coder/coder/v2/coderd/healthcheck"
"github.com/coder/coder/v2/coderd/healthcheck/derphealth"
"github.com/coder/coder/v2/codersdk"
)
@ -33,8 +33,8 @@ func (r *RootCmd) netcheck() *clibase.Cmd {
_, _ = fmt.Fprint(inv.Stderr, "Gathering a network report. This may take a few seconds...\n\n")
var report healthcheck.DERPReport
report.Run(ctx, &healthcheck.DERPReportOptions{
var report derphealth.Report
report.Run(ctx, &derphealth.ReportOptions{
DERPMap: connInfo.DERPMap,
})

View File

@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/cli/clitest"
"github.com/coder/coder/v2/coderd/healthcheck"
"github.com/coder/coder/v2/coderd/healthcheck/derphealth"
"github.com/coder/coder/v2/pty/ptytest"
)
@ -27,7 +27,7 @@ func TestNetcheck(t *testing.T) {
b := out.Bytes()
t.Log(string(b))
var report healthcheck.DERPReport
var report derphealth.Report
require.NoError(t, json.Unmarshal(b, &report))
assert.True(t, report.Healthy)

62
coderd/apidoc/docs.go generated
View File

@ -11400,30 +11400,7 @@ const docTemplate = `{
}
}
},
"healthcheck.AccessURLReport": {
"type": "object",
"properties": {
"access_url": {
"type": "string"
},
"error": {
"type": "string"
},
"healthy": {
"type": "boolean"
},
"healthz_response": {
"type": "string"
},
"reachable": {
"type": "boolean"
},
"status_code": {
"type": "integer"
}
}
},
"healthcheck.DERPNodeReport": {
"derphealth.NodeReport": {
"type": "object",
"properties": {
"can_exchange_messages": {
@ -11466,14 +11443,14 @@ const docTemplate = `{
"type": "integer"
},
"stun": {
"$ref": "#/definitions/healthcheck.DERPStunReport"
"$ref": "#/definitions/derphealth.StunReport"
},
"uses_websocket": {
"type": "boolean"
}
}
},
"healthcheck.DERPRegionReport": {
"derphealth.RegionReport": {
"type": "object",
"properties": {
"error": {
@ -11485,7 +11462,7 @@ const docTemplate = `{
"node_reports": {
"type": "array",
"items": {
"$ref": "#/definitions/healthcheck.DERPNodeReport"
"$ref": "#/definitions/derphealth.NodeReport"
}
},
"region": {
@ -11493,7 +11470,7 @@ const docTemplate = `{
}
}
},
"healthcheck.DERPReport": {
"derphealth.Report": {
"type": "object",
"properties": {
"error": {
@ -11517,12 +11494,12 @@ const docTemplate = `{
"regions": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/healthcheck.DERPRegionReport"
"$ref": "#/definitions/derphealth.RegionReport"
}
}
}
},
"healthcheck.DERPStunReport": {
"derphealth.StunReport": {
"type": "object",
"properties": {
"canSTUN": {
@ -11536,6 +11513,29 @@ const docTemplate = `{
}
}
},
"healthcheck.AccessURLReport": {
"type": "object",
"properties": {
"access_url": {
"type": "string"
},
"error": {
"type": "string"
},
"healthy": {
"type": "boolean"
},
"healthz_response": {
"type": "string"
},
"reachable": {
"type": "boolean"
},
"status_code": {
"type": "integer"
}
}
},
"healthcheck.DatabaseReport": {
"type": "object",
"properties": {
@ -11570,7 +11570,7 @@ const docTemplate = `{
"$ref": "#/definitions/healthcheck.DatabaseReport"
},
"derp": {
"$ref": "#/definitions/healthcheck.DERPReport"
"$ref": "#/definitions/derphealth.Report"
},
"failing_sections": {
"description": "FailingSections is a list of sections that have failed their healthcheck.",

View File

@ -10366,30 +10366,7 @@
}
}
},
"healthcheck.AccessURLReport": {
"type": "object",
"properties": {
"access_url": {
"type": "string"
},
"error": {
"type": "string"
},
"healthy": {
"type": "boolean"
},
"healthz_response": {
"type": "string"
},
"reachable": {
"type": "boolean"
},
"status_code": {
"type": "integer"
}
}
},
"healthcheck.DERPNodeReport": {
"derphealth.NodeReport": {
"type": "object",
"properties": {
"can_exchange_messages": {
@ -10432,14 +10409,14 @@
"type": "integer"
},
"stun": {
"$ref": "#/definitions/healthcheck.DERPStunReport"
"$ref": "#/definitions/derphealth.StunReport"
},
"uses_websocket": {
"type": "boolean"
}
}
},
"healthcheck.DERPRegionReport": {
"derphealth.RegionReport": {
"type": "object",
"properties": {
"error": {
@ -10451,7 +10428,7 @@
"node_reports": {
"type": "array",
"items": {
"$ref": "#/definitions/healthcheck.DERPNodeReport"
"$ref": "#/definitions/derphealth.NodeReport"
}
},
"region": {
@ -10459,7 +10436,7 @@
}
}
},
"healthcheck.DERPReport": {
"derphealth.Report": {
"type": "object",
"properties": {
"error": {
@ -10483,12 +10460,12 @@
"regions": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/healthcheck.DERPRegionReport"
"$ref": "#/definitions/derphealth.RegionReport"
}
}
}
},
"healthcheck.DERPStunReport": {
"derphealth.StunReport": {
"type": "object",
"properties": {
"canSTUN": {
@ -10502,6 +10479,29 @@
}
}
},
"healthcheck.AccessURLReport": {
"type": "object",
"properties": {
"access_url": {
"type": "string"
},
"error": {
"type": "string"
},
"healthy": {
"type": "boolean"
},
"healthz_response": {
"type": "string"
},
"reachable": {
"type": "boolean"
},
"status_code": {
"type": "integer"
}
}
},
"healthcheck.DatabaseReport": {
"type": "object",
"properties": {
@ -10536,7 +10536,7 @@
"$ref": "#/definitions/healthcheck.DatabaseReport"
},
"derp": {
"$ref": "#/definitions/healthcheck.DERPReport"
"$ref": "#/definitions/derphealth.Report"
},
"failing_sections": {
"description": "FailingSections is a list of sections that have failed their healthcheck.",

View File

@ -1,4 +1,4 @@
package healthcheck
package derphealth
import (
"context"
@ -24,11 +24,11 @@ import (
"github.com/coder/coder/v2/coderd/util/ptr"
)
// @typescript-generate DERPReport
type DERPReport struct {
// @typescript-generate Report
type Report struct {
Healthy bool `json:"healthy"`
Regions map[int]*DERPRegionReport `json:"regions"`
Regions map[int]*RegionReport `json:"regions"`
Netcheck *netcheck.Report `json:"netcheck"`
NetcheckErr *string `json:"netcheck_err"`
@ -37,18 +37,18 @@ type DERPReport struct {
Error *string `json:"error"`
}
// @typescript-generate DERPRegionReport
type DERPRegionReport struct {
// @typescript-generate RegionReport
type RegionReport struct {
mu sync.Mutex
Healthy bool `json:"healthy"`
Region *tailcfg.DERPRegion `json:"region"`
NodeReports []*DERPNodeReport `json:"node_reports"`
NodeReports []*NodeReport `json:"node_reports"`
Error *string `json:"error"`
}
// @typescript-generate DERPNodeReport
type DERPNodeReport struct {
// @typescript-generate NodeReport
type NodeReport struct {
mu sync.Mutex
clientCounter int
@ -64,23 +64,23 @@ type DERPNodeReport struct {
ClientErrs [][]string `json:"client_errs"`
Error *string `json:"error"`
STUN DERPStunReport `json:"stun"`
STUN StunReport `json:"stun"`
}
// @typescript-generate DERPStunReport
type DERPStunReport struct {
// @typescript-generate StunReport
type StunReport struct {
Enabled bool
CanSTUN bool
Error *string
}
type DERPReportOptions struct {
type ReportOptions struct {
DERPMap *tailcfg.DERPMap
}
func (r *DERPReport) Run(ctx context.Context, opts *DERPReportOptions) {
func (r *Report) Run(ctx context.Context, opts *ReportOptions) {
r.Healthy = true
r.Regions = map[int]*DERPRegionReport{}
r.Regions = map[int]*RegionReport{}
wg := &sync.WaitGroup{}
mu := sync.Mutex{}
@ -89,7 +89,7 @@ func (r *DERPReport) Run(ctx context.Context, opts *DERPReportOptions) {
for _, region := range opts.DERPMap.Regions {
var (
region = region
regionReport = DERPRegionReport{
regionReport = RegionReport{
Region: region,
}
)
@ -128,9 +128,9 @@ func (r *DERPReport) Run(ctx context.Context, opts *DERPReportOptions) {
wg.Wait()
}
func (r *DERPRegionReport) Run(ctx context.Context) {
func (r *RegionReport) Run(ctx context.Context) {
r.Healthy = true
r.NodeReports = []*DERPNodeReport{}
r.NodeReports = []*NodeReport{}
wg := &sync.WaitGroup{}
@ -138,7 +138,7 @@ func (r *DERPRegionReport) Run(ctx context.Context) {
for _, node := range r.Region.Nodes {
var (
node = node
nodeReport = DERPNodeReport{
nodeReport = NodeReport{
Node: node,
Healthy: true,
}
@ -166,7 +166,7 @@ func (r *DERPRegionReport) Run(ctx context.Context) {
wg.Wait()
}
func (r *DERPNodeReport) derpURL() *url.URL {
func (r *NodeReport) derpURL() *url.URL {
derpURL := &url.URL{
Scheme: "https",
Host: r.Node.HostName,
@ -185,7 +185,7 @@ func (r *DERPNodeReport) derpURL() *url.URL {
return derpURL
}
func (r *DERPNodeReport) Run(ctx context.Context) {
func (r *NodeReport) Run(ctx context.Context) {
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
@ -218,7 +218,7 @@ func (r *DERPNodeReport) Run(ctx context.Context) {
}
}
func (r *DERPNodeReport) doExchangeMessage(ctx context.Context) {
func (r *NodeReport) doExchangeMessage(ctx context.Context) {
if r.Node.STUNOnly {
return
}
@ -299,7 +299,7 @@ func (r *DERPNodeReport) doExchangeMessage(ctx context.Context) {
wg.Wait()
}
func (r *DERPNodeReport) doSTUNTest(ctx context.Context) {
func (r *NodeReport) doSTUNTest(ctx context.Context) {
if r.Node.STUNPort == -1 {
return
}
@ -331,7 +331,7 @@ func (r *DERPNodeReport) doSTUNTest(ctx context.Context) {
r.mu.Unlock()
}
func (r *DERPNodeReport) stunAddr(ctx context.Context) (string, int, error) {
func (r *NodeReport) stunAddr(ctx context.Context) (string, int, error) {
port := r.Node.STUNPort
if port == 0 {
port = 3478
@ -387,13 +387,13 @@ func (r *DERPNodeReport) stunAddr(ctx context.Context) (string, int, error) {
return "", 0, xerrors.New("no stun ips provided")
}
func (r *DERPNodeReport) writeClientErr(clientID int, err error) {
func (r *NodeReport) writeClientErr(clientID int, err error) {
r.mu.Lock()
r.ClientErrs[clientID] = append(r.ClientErrs[clientID], err.Error())
r.mu.Unlock()
}
func (r *DERPNodeReport) derpClient(ctx context.Context, derpURL *url.URL) (*derphttp.Client, int, error) {
func (r *NodeReport) derpClient(ctx context.Context, derpURL *url.URL) (*derphttp.Client, int, error) {
r.mu.Lock()
id := r.clientCounter
r.clientCounter++
@ -440,7 +440,7 @@ func (r *DERPNodeReport) derpClient(ctx context.Context, derpURL *url.URL) (*der
return client, id, nil
}
func (r *DERPNodeReport) recvData(client *derphttp.Client) (derp.ReceivedPacket, error) {
func (r *NodeReport) recvData(client *derphttp.Client) (derp.ReceivedPacket, error) {
for {
msg, err := client.Recv()
if err != nil {
@ -459,3 +459,11 @@ func (r *DERPNodeReport) recvData(client *derphttp.Client) (derp.ReceivedPacket,
}
}
}
func convertError(err error) *string {
if err != nil {
return ptr.Ref(err.Error())
}
return nil
}

View File

@ -1,4 +1,4 @@
package healthcheck_test
package derphealth_test
import (
"context"
@ -17,7 +17,7 @@ import (
"tailscale.com/tailcfg"
"tailscale.com/types/key"
"github.com/coder/coder/v2/coderd/healthcheck"
"github.com/coder/coder/v2/coderd/healthcheck/derphealth"
"github.com/coder/coder/v2/tailnet"
"github.com/coder/coder/v2/testutil"
)
@ -38,9 +38,9 @@ func TestDERP(t *testing.T) {
var (
ctx = context.Background()
report = healthcheck.DERPReport{}
report = derphealth.Report{}
derpURL, _ = url.Parse(srv.URL)
opts = &healthcheck.DERPReportOptions{
opts = &derphealth.ReportOptions{
DERPMap: &tailcfg.DERPMap{Regions: map[int]*tailcfg.DERPRegion{
1: {
EmbeddedRelay: true,
@ -95,8 +95,8 @@ func TestDERP(t *testing.T) {
var (
ctx = context.Background()
report = healthcheck.DERPReport{}
opts = &healthcheck.DERPReportOptions{
report = derphealth.Report{}
opts = &derphealth.ReportOptions{
DERPMap: tsDERPMap(ctx, t),
}
)
@ -145,9 +145,9 @@ func TestDERP(t *testing.T) {
var (
ctx = context.Background()
report = healthcheck.DERPReport{}
report = derphealth.Report{}
derpURL, _ = url.Parse(srv.URL)
opts = &healthcheck.DERPReportOptions{
opts = &derphealth.ReportOptions{
DERPMap: &tailcfg.DERPMap{Regions: map[int]*tailcfg.DERPRegion{
1: {
EmbeddedRelay: true,
@ -195,8 +195,8 @@ func TestDERP(t *testing.T) {
var (
ctx = context.Background()
report = healthcheck.DERPReport{}
opts = &healthcheck.DERPReportOptions{
report = derphealth.Report{}
opts = &derphealth.ReportOptions{
DERPMap: &tailcfg.DERPMap{Regions: map[int]*tailcfg.DERPRegion{
1: {
EmbeddedRelay: true,

View File

@ -12,6 +12,7 @@ import (
"github.com/coder/coder/v2/buildinfo"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/healthcheck/derphealth"
"github.com/coder/coder/v2/coderd/util/ptr"
)
@ -23,7 +24,7 @@ const (
)
type Checker interface {
DERP(ctx context.Context, opts *DERPReportOptions) DERPReport
DERP(ctx context.Context, opts *derphealth.ReportOptions) derphealth.Report
AccessURL(ctx context.Context, opts *AccessURLReportOptions) AccessURLReport
Websocket(ctx context.Context, opts *WebsocketReportOptions) WebsocketReport
Database(ctx context.Context, opts *DatabaseReportOptions) DatabaseReport
@ -38,10 +39,10 @@ type Report struct {
// FailingSections is a list of sections that have failed their healthcheck.
FailingSections []string `json:"failing_sections"`
DERP DERPReport `json:"derp"`
AccessURL AccessURLReport `json:"access_url"`
Websocket WebsocketReport `json:"websocket"`
Database DatabaseReport `json:"database"`
DERP derphealth.Report `json:"derp"`
AccessURL AccessURLReport `json:"access_url"`
Websocket WebsocketReport `json:"websocket"`
Database DatabaseReport `json:"database"`
// The Coder version of the server that the report was generated on.
CoderVersion string `json:"coder_version"`
@ -60,7 +61,7 @@ type ReportOptions struct {
type defaultChecker struct{}
func (defaultChecker) DERP(ctx context.Context, opts *DERPReportOptions) (report DERPReport) {
func (defaultChecker) DERP(ctx context.Context, opts *derphealth.ReportOptions) (report derphealth.Report) {
report.Run(ctx, opts)
return report
}
@ -99,7 +100,7 @@ func Run(ctx context.Context, opts *ReportOptions) *Report {
}
}()
report.DERP = opts.Checker.DERP(ctx, &DERPReportOptions{
report.DERP = opts.Checker.DERP(ctx, &derphealth.ReportOptions{
DERPMap: opts.DERPMap,
})
}()

View File

@ -7,16 +7,17 @@ import (
"github.com/stretchr/testify/assert"
"github.com/coder/coder/v2/coderd/healthcheck"
"github.com/coder/coder/v2/coderd/healthcheck/derphealth"
)
type testChecker struct {
DERPReport healthcheck.DERPReport
DERPReport derphealth.Report
AccessURLReport healthcheck.AccessURLReport
WebsocketReport healthcheck.WebsocketReport
DatabaseReport healthcheck.DatabaseReport
}
func (c *testChecker) DERP(context.Context, *healthcheck.DERPReportOptions) healthcheck.DERPReport {
func (c *testChecker) DERP(context.Context, *derphealth.ReportOptions) derphealth.Report {
return c.DERPReport
}
@ -43,7 +44,7 @@ func TestHealthcheck(t *testing.T) {
}{{
name: "OK",
checker: &testChecker{
DERPReport: healthcheck.DERPReport{
DERPReport: derphealth.Report{
Healthy: true,
},
AccessURLReport: healthcheck.AccessURLReport{
@ -61,7 +62,7 @@ func TestHealthcheck(t *testing.T) {
}, {
name: "DERPFail",
checker: &testChecker{
DERPReport: healthcheck.DERPReport{
DERPReport: derphealth.Report{
Healthy: false,
},
AccessURLReport: healthcheck.AccessURLReport{
@ -79,7 +80,7 @@ func TestHealthcheck(t *testing.T) {
}, {
name: "AccessURLFail",
checker: &testChecker{
DERPReport: healthcheck.DERPReport{
DERPReport: derphealth.Report{
Healthy: true,
},
AccessURLReport: healthcheck.AccessURLReport{
@ -97,7 +98,7 @@ func TestHealthcheck(t *testing.T) {
}, {
name: "WebsocketFail",
checker: &testChecker{
DERPReport: healthcheck.DERPReport{
DERPReport: derphealth.Report{
Healthy: true,
},
AccessURLReport: healthcheck.AccessURLReport{
@ -115,7 +116,7 @@ func TestHealthcheck(t *testing.T) {
}, {
name: "DatabaseFail",
checker: &testChecker{
DERPReport: healthcheck.DERPReport{
DERPReport: derphealth.Report{
Healthy: true,
},
AccessURLReport: healthcheck.AccessURLReport{

114
docs/api/schemas.md generated
View File

@ -6698,31 +6698,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
| `tokenBucketBytesPerSecond` | integer | false | | Tokenbucketbytespersecond is how many bytes per second the server says it will accept, including all framing bytes. |
| Zero means unspecified. There might be a limit, but the client need not try to respect it. |
## healthcheck.AccessURLReport
```json
{
"access_url": "string",
"error": "string",
"healthy": true,
"healthz_response": "string",
"reachable": true,
"status_code": 0
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
| ------------------ | ------- | -------- | ------------ | ----------- |
| `access_url` | string | false | | |
| `error` | string | false | | |
| `healthy` | boolean | false | | |
| `healthz_response` | string | false | | |
| `reachable` | boolean | false | | |
| `status_code` | integer | false | | |
## healthcheck.DERPNodeReport
## derphealth.NodeReport
```json
{
@ -6763,21 +6739,21 @@ If the schedule is empty, the user will be updated to use the default schedule.|
### Properties
| Name | Type | Required | Restrictions | Description |
| ----------------------- | -------------------------------------------------------- | -------- | ------------ | ----------- |
| `can_exchange_messages` | boolean | false | | |
| `client_errs` | array of array | false | | |
| `client_logs` | array of array | false | | |
| `error` | string | false | | |
| `healthy` | boolean | false | | |
| `node` | [tailcfg.DERPNode](#tailcfgderpnode) | false | | |
| `node_info` | [derp.ServerInfoMessage](#derpserverinfomessage) | false | | |
| `round_trip_ping` | string | false | | |
| `round_trip_ping_ms` | integer | false | | |
| `stun` | [healthcheck.DERPStunReport](#healthcheckderpstunreport) | false | | |
| `uses_websocket` | boolean | false | | |
| Name | Type | Required | Restrictions | Description |
| ----------------------- | ------------------------------------------------ | -------- | ------------ | ----------- |
| `can_exchange_messages` | boolean | false | | |
| `client_errs` | array of array | false | | |
| `client_logs` | array of array | false | | |
| `error` | string | false | | |
| `healthy` | boolean | false | | |
| `node` | [tailcfg.DERPNode](#tailcfgderpnode) | false | | |
| `node_info` | [derp.ServerInfoMessage](#derpserverinfomessage) | false | | |
| `round_trip_ping` | string | false | | |
| `round_trip_ping_ms` | integer | false | | |
| `stun` | [derphealth.StunReport](#derphealthstunreport) | false | | |
| `uses_websocket` | boolean | false | | |
## healthcheck.DERPRegionReport
## derphealth.RegionReport
```json
{
@ -6848,14 +6824,14 @@ If the schedule is empty, the user will be updated to use the default schedule.|
### Properties
| Name | Type | Required | Restrictions | Description |
| -------------- | ----------------------------------------------------------------- | -------- | ------------ | ----------- |
| `error` | string | false | | |
| `healthy` | boolean | false | | |
| `node_reports` | array of [healthcheck.DERPNodeReport](#healthcheckderpnodereport) | false | | |
| `region` | [tailcfg.DERPRegion](#tailcfgderpregion) | false | | |
| Name | Type | Required | Restrictions | Description |
| -------------- | ------------------------------------------------------- | -------- | ------------ | ----------- |
| `error` | string | false | | |
| `healthy` | boolean | false | | |
| `node_reports` | array of [derphealth.NodeReport](#derphealthnodereport) | false | | |
| `region` | [tailcfg.DERPRegion](#tailcfgderpregion) | false | | |
## healthcheck.DERPReport
## derphealth.Report
```json
{
@ -7028,17 +7004,17 @@ If the schedule is empty, the user will be updated to use the default schedule.|
### Properties
| Name | Type | Required | Restrictions | Description |
| ------------------ | ------------------------------------------------------------ | -------- | ------------ | ----------- |
| `error` | string | false | | |
| `healthy` | boolean | false | | |
| `netcheck` | [netcheck.Report](#netcheckreport) | false | | |
| `netcheck_err` | string | false | | |
| `netcheck_logs` | array of string | false | | |
| `regions` | object | false | | |
| » `[any property]` | [healthcheck.DERPRegionReport](#healthcheckderpregionreport) | false | | |
| Name | Type | Required | Restrictions | Description |
| ------------------ | -------------------------------------------------- | -------- | ------------ | ----------- |
| `error` | string | false | | |
| `healthy` | boolean | false | | |
| `netcheck` | [netcheck.Report](#netcheckreport) | false | | |
| `netcheck_err` | string | false | | |
| `netcheck_logs` | array of string | false | | |
| `regions` | object | false | | |
| » `[any property]` | [derphealth.RegionReport](#derphealthregionreport) | false | | |
## healthcheck.DERPStunReport
## derphealth.StunReport
```json
{
@ -7056,6 +7032,30 @@ If the schedule is empty, the user will be updated to use the default schedule.|
| `enabled` | boolean | false | | |
| `error` | string | false | | |
## healthcheck.AccessURLReport
```json
{
"access_url": "string",
"error": "string",
"healthy": true,
"healthz_response": "string",
"reachable": true,
"status_code": 0
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
| ------------------ | ------- | -------- | ------------ | ----------- |
| `access_url` | string | false | | |
| `error` | string | false | | |
| `healthy` | boolean | false | | |
| `healthz_response` | string | false | | |
| `reachable` | boolean | false | | |
| `status_code` | integer | false | | |
## healthcheck.DatabaseReport
```json
@ -7283,7 +7283,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
| `access_url` | [healthcheck.AccessURLReport](#healthcheckaccessurlreport) | false | | |
| `coder_version` | string | false | | The Coder version of the server that the report was generated on. |
| `database` | [healthcheck.DatabaseReport](#healthcheckdatabasereport) | false | | |
| `derp` | [healthcheck.DERPReport](#healthcheckderpreport) | false | | |
| `derp` | [derphealth.Report](#derphealthreport) | false | | |
| `failing_sections` | array of string | false | | Failing sections is a list of sections that have failed their healthcheck. |
| `healthy` | boolean | false | | Healthy is true if the report returns no errors. |
| `time` | string | false | | Time is the time the report was generated at. |

View File

@ -19,7 +19,7 @@ import (
"github.com/coder/coder/v2/cli/clibase"
"github.com/coder/coder/v2/coderd"
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/healthcheck"
"github.com/coder/coder/v2/coderd/healthcheck/derphealth"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/workspaceapps/apptest"
"github.com/coder/coder/v2/codersdk"
@ -295,8 +295,8 @@ resourceLoop:
}
ctx := testutil.Context(t, testutil.WaitLong)
report := healthcheck.DERPReport{}
report.Run(ctx, &healthcheck.DERPReportOptions{
report := derphealth.Report{}
report.Run(ctx, &derphealth.ReportOptions{
DERPMap: derpMap,
})

View File

@ -26,7 +26,7 @@ import (
)
var (
baseDirs = [...]string{"./codersdk", "./coderd/healthcheck"}
baseDirs = [...]string{"./codersdk", "./coderd/healthcheck", "./coderd/healthcheck/derphealth"}
indent = " "
)

View File

@ -1985,54 +1985,6 @@ export interface HealthcheckAccessURLReport {
readonly error?: string
}
// From healthcheck/derp.go
export interface HealthcheckDERPNodeReport {
readonly healthy: boolean
// Named type "tailscale.com/tailcfg.DERPNode" unknown, using "any"
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
readonly node?: any
// Named type "tailscale.com/derp.ServerInfoMessage" unknown, using "any"
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
readonly node_info: any
readonly can_exchange_messages: boolean
readonly round_trip_ping: string
readonly round_trip_ping_ms: number
readonly uses_websocket: boolean
readonly client_logs: string[][]
readonly client_errs: string[][]
readonly error?: string
readonly stun: HealthcheckDERPStunReport
}
// From healthcheck/derp.go
export interface HealthcheckDERPRegionReport {
readonly healthy: boolean
// Named type "tailscale.com/tailcfg.DERPRegion" unknown, using "any"
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
readonly region?: any
readonly node_reports: HealthcheckDERPNodeReport[]
readonly error?: string
}
// From healthcheck/derp.go
export interface HealthcheckDERPReport {
readonly healthy: boolean
readonly regions: Record<number, HealthcheckDERPRegionReport>
// Named type "tailscale.com/net/netcheck.Report" unknown, using "any"
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
readonly netcheck?: any
readonly netcheck_err?: string
readonly netcheck_logs: string[]
readonly error?: string
}
// From healthcheck/derp.go
export interface HealthcheckDERPStunReport {
readonly Enabled: boolean
readonly CanSTUN: boolean
readonly Error?: string
}
// From healthcheck/database.go
export interface HealthcheckDatabaseReport {
readonly healthy: boolean
@ -2047,7 +1999,9 @@ export interface HealthcheckReport {
readonly time: string
readonly healthy: boolean
readonly failing_sections: string[]
readonly derp: HealthcheckDERPReport
// Named type "github.com/coder/coder/v2/coderd/healthcheck/derphealth.Report" unknown, using "any"
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
readonly derp: any
readonly access_url: HealthcheckAccessURLReport
readonly websocket: HealthcheckWebsocketReport
readonly database: HealthcheckDatabaseReport
@ -2061,3 +2015,53 @@ export interface HealthcheckWebsocketReport {
readonly code: number
readonly error?: string
}
// The code below is generated from coderd/healthcheck/derphealth.
// From derphealth/derp.go
export interface DerphealthNodeReport {
readonly healthy: boolean
// Named type "tailscale.com/tailcfg.DERPNode" unknown, using "any"
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
readonly node?: any
// Named type "tailscale.com/derp.ServerInfoMessage" unknown, using "any"
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
readonly node_info: any
readonly can_exchange_messages: boolean
readonly round_trip_ping: string
readonly round_trip_ping_ms: number
readonly uses_websocket: boolean
readonly client_logs: string[][]
readonly client_errs: string[][]
readonly error?: string
readonly stun: DerphealthStunReport
}
// From derphealth/derp.go
export interface DerphealthRegionReport {
readonly healthy: boolean
// Named type "tailscale.com/tailcfg.DERPRegion" unknown, using "any"
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
readonly region?: any
readonly node_reports: DerphealthNodeReport[]
readonly error?: string
}
// From derphealth/derp.go
export interface DerphealthReport {
readonly healthy: boolean
readonly regions: Record<number, DerphealthRegionReport>
// Named type "tailscale.com/net/netcheck.Report" unknown, using "any"
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
readonly netcheck?: any
readonly netcheck_err?: string
readonly netcheck_logs: string[]
readonly error?: string
}
// From derphealth/derp.go
export interface DerphealthStunReport {
readonly Enabled: boolean
readonly CanSTUN: boolean
readonly Error?: string
}