feat: do not fail DERP healthcheck if WebSocket is used (#10714)

This commit is contained in:
Marcin Tojek
2023-11-17 16:00:49 +01:00
committed by GitHub
parent 24aa223399
commit 8999d5785a
14 changed files with 285 additions and 80 deletions
+36
View File
@@ -12115,6 +12115,12 @@ const docTemplate = `{
},
"uses_websocket": {
"type": "boolean"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
@@ -12135,6 +12141,12 @@ const docTemplate = `{
},
"region": {
"$ref": "#/definitions/tailcfg.DERPRegion"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
@@ -12164,6 +12176,12 @@ const docTemplate = `{
"additionalProperties": {
"$ref": "#/definitions/derphealth.RegionReport"
}
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
@@ -12201,6 +12219,12 @@ const docTemplate = `{
},
"status_code": {
"type": "integer"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
@@ -12224,6 +12248,12 @@ const docTemplate = `{
},
"threshold_ms": {
"type": "integer"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
@@ -12277,6 +12307,12 @@ const docTemplate = `{
},
"healthy": {
"type": "boolean"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
+36
View File
@@ -11036,6 +11036,12 @@
},
"uses_websocket": {
"type": "boolean"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
@@ -11056,6 +11062,12 @@
},
"region": {
"$ref": "#/definitions/tailcfg.DERPRegion"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
@@ -11085,6 +11097,12 @@
"additionalProperties": {
"$ref": "#/definitions/derphealth.RegionReport"
}
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
@@ -11122,6 +11140,12 @@
},
"status_code": {
"type": "integer"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
@@ -11145,6 +11169,12 @@
},
"threshold_ms": {
"type": "integer"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
@@ -11198,6 +11228,12 @@
},
"healthy": {
"type": "boolean"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
+3 -1
View File
@@ -14,8 +14,10 @@ import (
// @typescript-generate AccessURLReport
type AccessURLReport struct {
Healthy bool `json:"healthy"`
Warnings []string `json:"warnings"`
AccessURL string `json:"access_url"`
Healthy bool `json:"healthy"`
Reachable bool `json:"reachable"`
StatusCode int `json:"status_code"`
HealthzResponse string `json:"healthz_response"`
+3 -1
View File
@@ -16,7 +16,9 @@ const (
// @typescript-generate DatabaseReport
type DatabaseReport struct {
Healthy bool `json:"healthy"`
Healthy bool `json:"healthy"`
Warnings []string `json:"warnings"`
Reachable bool `json:"reachable"`
Latency string `json:"latency"`
LatencyMS int64 `json:"latency_ms"`
+25 -9
View File
@@ -24,9 +24,14 @@ import (
"github.com/coder/coder/v2/coderd/util/ptr"
)
const (
warningNodeUsesWebsocket = `Node uses WebSockets because the "Upgrade: DERP" header may be blocked on the load balancer.`
)
// @typescript-generate Report
type Report struct {
Healthy bool `json:"healthy"`
Healthy bool `json:"healthy"`
Warnings []string `json:"warnings"`
Regions map[int]*RegionReport `json:"regions"`
@@ -39,8 +44,9 @@ type Report struct {
// @typescript-generate RegionReport
type RegionReport struct {
mu sync.Mutex
Healthy bool `json:"healthy"`
mu sync.Mutex
Healthy bool `json:"healthy"`
Warnings []string `json:"warnings"`
Region *tailcfg.DERPRegion `json:"region"`
NodeReports []*NodeReport `json:"node_reports"`
@@ -52,8 +58,10 @@ type NodeReport struct {
mu sync.Mutex
clientCounter int
Healthy bool `json:"healthy"`
Node *tailcfg.DERPNode `json:"node"`
Healthy bool `json:"healthy"`
Warnings []string `json:"warnings"`
Node *tailcfg.DERPNode `json:"node"`
ServerInfo derp.ServerInfoMessage `json:"node_info"`
CanExchangeMessages bool `json:"can_exchange_messages"`
@@ -108,6 +116,10 @@ func (r *Report) Run(ctx context.Context, opts *ReportOptions) {
if !regionReport.Healthy {
r.Healthy = false
}
for _, w := range regionReport.Warnings {
r.Warnings = append(r.Warnings, fmt.Sprintf("[%s] %s", regionReport.Region.RegionName, w))
}
mu.Unlock()
}()
}
@@ -159,6 +171,10 @@ func (r *RegionReport) Run(ctx context.Context) {
if !nodeReport.Healthy {
r.Healthy = false
}
for _, w := range nodeReport.Warnings {
r.Warnings = append(r.Warnings, fmt.Sprintf("[%s] %s", nodeReport.Node.Name, w))
}
r.mu.Unlock()
}()
}
@@ -208,14 +224,14 @@ func (r *NodeReport) Run(ctx context.Context) {
// We can't exchange messages with the node,
if (!r.CanExchangeMessages && !r.Node.STUNOnly) ||
// A node may use websockets because `Upgrade: DERP` may be blocked on
// the load balancer. This is unhealthy because websockets are slower
// than the regular DERP protocol.
r.UsesWebsocket ||
// The node was marked as STUN compatible but the STUN test failed.
r.STUN.Error != nil {
r.Healthy = false
}
if r.UsesWebsocket {
r.Warnings = append(r.Warnings, warningNodeUsesWebsocket)
}
}
func (r *NodeReport) doExchangeMessage(ctx context.Context) {
+6 -3
View File
@@ -170,11 +170,14 @@ func TestDERP(t *testing.T) {
report.Run(ctx, opts)
assert.False(t, report.Healthy)
assert.True(t, report.Healthy)
assert.NotEmpty(t, report.Warnings)
for _, region := range report.Regions {
assert.False(t, region.Healthy)
assert.True(t, region.Healthy)
assert.NotEmpty(t, region.Warnings)
for _, node := range region.NodeReports {
assert.False(t, node.Healthy)
assert.True(t, node.Healthy)
assert.NotEmpty(t, node.Warnings)
assert.True(t, node.CanExchangeMessages)
assert.NotEmpty(t, node.RoundTripPing)
assert.Len(t, node.ClientLogs, 2)
+20
View File
@@ -77,6 +77,25 @@ func TestHealthcheck(t *testing.T) {
},
healthy: false,
failingSections: []string{healthcheck.SectionDERP},
}, {
name: "DERPWarning",
checker: &testChecker{
DERPReport: derphealth.Report{
Healthy: true,
Warnings: []string{"foobar"},
},
AccessURLReport: healthcheck.AccessURLReport{
Healthy: true,
},
WebsocketReport: healthcheck.WebsocketReport{
Healthy: true,
},
DatabaseReport: healthcheck.DatabaseReport{
Healthy: true,
},
},
healthy: true,
failingSections: nil,
}, {
name: "AccessURLFail",
checker: &testChecker{
@@ -153,6 +172,7 @@ func TestHealthcheck(t *testing.T) {
assert.Equal(t, c.healthy, report.Healthy)
assert.Equal(t, c.failingSections, report.FailingSections)
assert.Equal(t, c.checker.DERPReport.Healthy, report.DERP.Healthy)
assert.Equal(t, c.checker.DERPReport.Warnings, report.DERP.Warnings)
assert.Equal(t, c.checker.AccessURLReport.Healthy, report.AccessURL.Healthy)
assert.Equal(t, c.checker.WebsocketReport.Healthy, report.Websocket.Healthy)
assert.NotZero(t, report.Time)
+6 -4
View File
@@ -21,10 +21,12 @@ type WebsocketReportOptions struct {
// @typescript-generate WebsocketReport
type WebsocketReport struct {
Healthy bool `json:"healthy"`
Body string `json:"body"`
Code int `json:"code"`
Error *string `json:"error"`
Healthy bool `json:"healthy"`
Warnings []string `json:"warnings"`
Body string `json:"body"`
Code int `json:"code"`
Error *string `json:"error"`
}
func (r *WebsocketReport) Run(ctx context.Context, opts *WebsocketReportOptions) {
+16 -8
View File
@@ -51,7 +51,8 @@ curl -X GET http://coder-server:8080/api/v2/debug/health \
"healthy": true,
"healthz_response": "string",
"reachable": true,
"status_code": 0
"status_code": 0,
"warnings": ["string"]
},
"coder_version": "string",
"database": {
@@ -60,7 +61,8 @@ curl -X GET http://coder-server:8080/api/v2/debug/health \
"latency": "string",
"latency_ms": 0,
"reachable": true,
"threshold_ms": 0
"threshold_ms": 0,
"warnings": ["string"]
},
"derp": {
"error": "string",
@@ -134,7 +136,8 @@ curl -X GET http://coder-server:8080/api/v2/debug/health \
"enabled": true,
"error": "string"
},
"uses_websocket": true
"uses_websocket": true,
"warnings": ["string"]
}
],
"region": {
@@ -160,7 +163,8 @@ curl -X GET http://coder-server:8080/api/v2/debug/health \
"regionCode": "string",
"regionID": 0,
"regionName": "string"
}
},
"warnings": ["string"]
},
"property2": {
"error": "string",
@@ -198,7 +202,8 @@ curl -X GET http://coder-server:8080/api/v2/debug/health \
"enabled": true,
"error": "string"
},
"uses_websocket": true
"uses_websocket": true,
"warnings": ["string"]
}
],
"region": {
@@ -224,9 +229,11 @@ curl -X GET http://coder-server:8080/api/v2/debug/health \
"regionCode": "string",
"regionID": 0,
"regionName": "string"
}
},
"warnings": ["string"]
}
}
},
"warnings": ["string"]
},
"failing_sections": ["string"],
"healthy": true,
@@ -235,7 +242,8 @@ curl -X GET http://coder-server:8080/api/v2/debug/health \
"body": "string",
"code": 0,
"error": "string",
"healthy": true
"healthy": true,
"warnings": ["string"]
}
}
```
+66 -41
View File
@@ -7138,7 +7138,8 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"enabled": true,
"error": "string"
},
"uses_websocket": true
"uses_websocket": true,
"warnings": ["string"]
}
```
@@ -7157,6 +7158,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
| `round_trip_ping_ms` | integer | false | | |
| `stun` | [derphealth.StunReport](#derphealthstunreport) | false | | |
| `uses_websocket` | boolean | false | | |
| `warnings` | array of string | false | | |
## derphealth.RegionReport
@@ -7197,7 +7199,8 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"enabled": true,
"error": "string"
},
"uses_websocket": true
"uses_websocket": true,
"warnings": ["string"]
}
],
"region": {
@@ -7223,7 +7226,8 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"regionCode": "string",
"regionID": 0,
"regionName": "string"
}
},
"warnings": ["string"]
}
```
@@ -7235,6 +7239,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
| `healthy` | boolean | false | | |
| `node_reports` | array of [derphealth.NodeReport](#derphealthnodereport) | false | | |
| `region` | [tailcfg.DERPRegion](#tailcfgderpregion) | false | | |
| `warnings` | array of string | false | | |
## derphealth.Report
@@ -7311,7 +7316,8 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"enabled": true,
"error": "string"
},
"uses_websocket": true
"uses_websocket": true,
"warnings": ["string"]
}
],
"region": {
@@ -7337,7 +7343,8 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"regionCode": "string",
"regionID": 0,
"regionName": "string"
}
},
"warnings": ["string"]
},
"property2": {
"error": "string",
@@ -7375,7 +7382,8 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"enabled": true,
"error": "string"
},
"uses_websocket": true
"uses_websocket": true,
"warnings": ["string"]
}
],
"region": {
@@ -7401,9 +7409,11 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"regionCode": "string",
"regionID": 0,
"regionName": "string"
}
},
"warnings": ["string"]
}
}
},
"warnings": ["string"]
}
```
@@ -7418,6 +7428,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
| `netcheck_logs` | array of string | false | | |
| `regions` | object | false | | |
| » `[any property]` | [derphealth.RegionReport](#derphealthregionreport) | false | | |
| `warnings` | array of string | false | | |
## derphealth.StunReport
@@ -7446,20 +7457,22 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"healthy": true,
"healthz_response": "string",
"reachable": true,
"status_code": 0
"status_code": 0,
"warnings": ["string"]
}
```
### 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 | | |
| 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 | | |
| `warnings` | array of string | false | | |
## healthcheck.DatabaseReport
@@ -7470,20 +7483,22 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"latency": "string",
"latency_ms": 0,
"reachable": true,
"threshold_ms": 0
"threshold_ms": 0,
"warnings": ["string"]
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
| -------------- | ------- | -------- | ------------ | ----------- |
| `error` | string | false | | |
| `healthy` | boolean | false | | |
| `latency` | string | false | | |
| `latency_ms` | integer | false | | |
| `reachable` | boolean | false | | |
| `threshold_ms` | integer | false | | |
| Name | Type | Required | Restrictions | Description |
| -------------- | --------------- | -------- | ------------ | ----------- |
| `error` | string | false | | |
| `healthy` | boolean | false | | |
| `latency` | string | false | | |
| `latency_ms` | integer | false | | |
| `reachable` | boolean | false | | |
| `threshold_ms` | integer | false | | |
| `warnings` | array of string | false | | |
## healthcheck.Report
@@ -7495,7 +7510,8 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"healthy": true,
"healthz_response": "string",
"reachable": true,
"status_code": 0
"status_code": 0,
"warnings": ["string"]
},
"coder_version": "string",
"database": {
@@ -7504,7 +7520,8 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"latency": "string",
"latency_ms": 0,
"reachable": true,
"threshold_ms": 0
"threshold_ms": 0,
"warnings": ["string"]
},
"derp": {
"error": "string",
@@ -7578,7 +7595,8 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"enabled": true,
"error": "string"
},
"uses_websocket": true
"uses_websocket": true,
"warnings": ["string"]
}
],
"region": {
@@ -7604,7 +7622,8 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"regionCode": "string",
"regionID": 0,
"regionName": "string"
}
},
"warnings": ["string"]
},
"property2": {
"error": "string",
@@ -7642,7 +7661,8 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"enabled": true,
"error": "string"
},
"uses_websocket": true
"uses_websocket": true,
"warnings": ["string"]
}
],
"region": {
@@ -7668,9 +7688,11 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"regionCode": "string",
"regionID": 0,
"regionName": "string"
}
},
"warnings": ["string"]
}
}
},
"warnings": ["string"]
},
"failing_sections": ["string"],
"healthy": true,
@@ -7679,7 +7701,8 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"body": "string",
"code": 0,
"error": "string",
"healthy": true
"healthy": true,
"warnings": ["string"]
}
}
```
@@ -7704,18 +7727,20 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"body": "string",
"code": 0,
"error": "string",
"healthy": true
"healthy": true,
"warnings": ["string"]
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
| --------- | ------- | -------- | ------------ | ----------- |
| `body` | string | false | | |
| `code` | integer | false | | |
| `error` | string | false | | |
| `healthy` | boolean | false | | |
| Name | Type | Required | Restrictions | Description |
| ---------- | --------------- | -------- | ------------ | ----------- |
| `body` | string | false | | |
| `code` | integer | false | | |
| `error` | string | false | | |
| `healthy` | boolean | false | | |
| `warnings` | array of string | false | | |
## netcheck.Report
+7 -1
View File
@@ -2081,8 +2081,9 @@ export type RegionTypes = Region | WorkspaceProxy;
// From healthcheck/accessurl.go
export interface HealthcheckAccessURLReport {
readonly access_url: string;
readonly healthy: boolean;
readonly warnings: string[];
readonly access_url: string;
readonly reachable: boolean;
readonly status_code: number;
readonly healthz_response: string;
@@ -2092,6 +2093,7 @@ export interface HealthcheckAccessURLReport {
// From healthcheck/database.go
export interface HealthcheckDatabaseReport {
readonly healthy: boolean;
readonly warnings: string[];
readonly reachable: boolean;
readonly latency: string;
readonly latency_ms: number;
@@ -2114,6 +2116,7 @@ export interface HealthcheckReport {
// From healthcheck/websocket.go
export interface HealthcheckWebsocketReport {
readonly healthy: boolean;
readonly warnings: string[];
readonly body: string;
readonly code: number;
readonly error?: string;
@@ -2169,6 +2172,7 @@ export const ClibaseValueSources: ClibaseValueSource[] = [
// From derphealth/derp.go
export interface DerphealthNodeReport {
readonly healthy: boolean;
readonly warnings: string[];
// Named type "tailscale.com/tailcfg.DERPNode" unknown, using "any"
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
readonly node?: any;
@@ -2188,6 +2192,7 @@ export interface DerphealthNodeReport {
// From derphealth/derp.go
export interface DerphealthRegionReport {
readonly healthy: boolean;
readonly warnings: string[];
// Named type "tailscale.com/tailcfg.DERPRegion" unknown, using "any"
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
readonly region?: any;
@@ -2198,6 +2203,7 @@ export interface DerphealthRegionReport {
// From derphealth/derp.go
export interface DerphealthReport {
readonly healthy: boolean;
readonly warnings: string[];
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
@@ -31,3 +31,15 @@ export const UnhealthyDERP: Story = {
},
},
};
export const DERPWarnings: Story = {
args: {
healthStatus: {
...MockHealth,
derp: {
...MockHealth.derp,
warnings: ["foobar"],
},
},
},
};
+28 -11
View File
@@ -85,7 +85,13 @@ export function HealthPageView({
</PageHeaderTitle>
<PageHeaderSubtitle>
{healthStatus.healthy
? "All systems operational"
? Object.keys(sections).some(
(key) =>
healthStatus[key as keyof typeof sections]?.warnings
.length > 0,
)
? "All systems operational, but performance might be degraded"
: "All systems operational"
: "Some issues have been detected"}
</PageHeaderSubtitle>
</div>
@@ -137,9 +143,10 @@ export function HealthPageView({
.map((key) => {
const label = sections[key as keyof typeof sections];
const isActive = tab.value === key;
const isHealthy =
healthStatus[key as keyof typeof sections].healthy;
const healthSection =
healthStatus[key as keyof typeof sections];
const isHealthy = healthSection.healthy;
const isWarning = healthSection.warnings.length > 0;
return (
<Box
component="button"
@@ -171,13 +178,23 @@ export function HealthPageView({
}}
>
{isHealthy ? (
<CheckCircleOutlined
sx={{
width: 16,
height: 16,
color: (theme) => theme.palette.success.light,
}}
/>
isWarning ? (
<CheckCircleOutlined
sx={{
width: 16,
height: 16,
color: (theme) => theme.palette.warning.main,
}}
/>
) : (
<CheckCircleOutlined
sx={{
width: 16,
height: 16,
color: (theme) => theme.palette.success.light,
}}
/>
)
) : (
<ErrorOutline
sx={{
+21 -1
View File
@@ -2376,9 +2376,11 @@ export const MockHealth: TypesGen.HealthcheckReport = {
failing_sections: [],
derp: {
healthy: true,
warnings: [],
regions: {
"999": {
healthy: true,
warnings: [],
region: {
EmbeddedRelay: true,
RegionID: 999,
@@ -2404,6 +2406,7 @@ export const MockHealth: TypesGen.HealthcheckReport = {
node_reports: [
{
healthy: true,
warnings: [],
node: {
Name: "999stun0",
RegionID: 999,
@@ -2428,6 +2431,7 @@ export const MockHealth: TypesGen.HealthcheckReport = {
},
{
healthy: true,
warnings: [],
node: {
Name: "999b",
RegionID: 999,
@@ -2461,6 +2465,7 @@ export const MockHealth: TypesGen.HealthcheckReport = {
},
"10007": {
healthy: true,
warnings: [],
region: {
EmbeddedRelay: false,
RegionID: 10007,
@@ -2486,6 +2491,7 @@ export const MockHealth: TypesGen.HealthcheckReport = {
node_reports: [
{
healthy: true,
warnings: [],
node: {
Name: "10007stun0",
RegionID: 10007,
@@ -2510,6 +2516,7 @@ export const MockHealth: TypesGen.HealthcheckReport = {
},
{
healthy: true,
warnings: [],
node: {
Name: "10007a",
RegionID: 10007,
@@ -2543,6 +2550,7 @@ export const MockHealth: TypesGen.HealthcheckReport = {
},
"10008": {
healthy: true,
warnings: [],
region: {
EmbeddedRelay: false,
RegionID: 10008,
@@ -2568,6 +2576,7 @@ export const MockHealth: TypesGen.HealthcheckReport = {
node_reports: [
{
healthy: true,
warnings: [],
node: {
Name: "10008stun0",
RegionID: 10008,
@@ -2592,6 +2601,7 @@ export const MockHealth: TypesGen.HealthcheckReport = {
},
{
healthy: true,
warnings: [],
node: {
Name: "10008a",
RegionID: 10008,
@@ -2625,6 +2635,7 @@ export const MockHealth: TypesGen.HealthcheckReport = {
},
"10009": {
healthy: true,
warnings: [],
region: {
EmbeddedRelay: false,
RegionID: 10009,
@@ -2650,6 +2661,7 @@ export const MockHealth: TypesGen.HealthcheckReport = {
node_reports: [
{
healthy: true,
warnings: [],
node: {
Name: "10009stun0",
RegionID: 10009,
@@ -2674,6 +2686,7 @@ export const MockHealth: TypesGen.HealthcheckReport = {
},
{
healthy: true,
warnings: [],
node: {
Name: "10009a",
RegionID: 10009,
@@ -2751,19 +2764,22 @@ export const MockHealth: TypesGen.HealthcheckReport = {
],
},
access_url: {
access_url: "https://dev.coder.com",
healthy: true,
warnings: [],
access_url: "https://dev.coder.com",
reachable: true,
status_code: 200,
healthz_response: "OK",
},
websocket: {
healthy: true,
warnings: [],
body: "",
code: 101,
},
database: {
healthy: true,
warnings: [],
reachable: true,
latency: "92570",
latency_ms: 92570,
@@ -2788,6 +2804,7 @@ export const DeploymentHealthUnhealthy: TypesGen.HealthcheckReport = {
coder_version: "v2.3.0-devel+8cca4915a",
access_url: {
healthy: true,
warnings: [],
access_url: "",
healthz_response: "",
reachable: true,
@@ -2795,6 +2812,7 @@ export const DeploymentHealthUnhealthy: TypesGen.HealthcheckReport = {
},
database: {
healthy: false,
warnings: [],
latency: "",
latency_ms: 0,
reachable: true,
@@ -2802,11 +2820,13 @@ export const DeploymentHealthUnhealthy: TypesGen.HealthcheckReport = {
},
derp: {
healthy: false,
warnings: [],
regions: [],
netcheck_logs: [],
},
websocket: {
healthy: false,
warnings: [],
body: "",
code: 0,
},