diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 64ea030b1e0b7..a0c0abba77c09 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -12305,6 +12305,9 @@ const docTemplate = `{ "derphealth.Report": { "type": "object", "properties": { + "dismissed": { + "type": "boolean" + }, "error": { "type": "string" }, @@ -12383,6 +12386,9 @@ const docTemplate = `{ "access_url": { "type": "string" }, + "dismissed": { + "type": "boolean" + }, "error": { "type": "string" }, @@ -12422,6 +12428,9 @@ const docTemplate = `{ "healthcheck.DatabaseReport": { "type": "object", "properties": { + "dismissed": { + "type": "boolean" + }, "error": { "type": "string" }, @@ -12522,6 +12531,9 @@ const docTemplate = `{ "code": { "type": "integer" }, + "dismissed": { + "type": "boolean" + }, "error": { "type": "string" }, @@ -12552,6 +12564,9 @@ const docTemplate = `{ "healthcheck.WorkspaceProxyReport": { "type": "object", "properties": { + "dismissed": { + "type": "boolean" + }, "error": { "type": "string" }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 1f6a8f07f5670..f2c0226755036 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -11206,6 +11206,9 @@ "derphealth.Report": { "type": "object", "properties": { + "dismissed": { + "type": "boolean" + }, "error": { "type": "string" }, @@ -11272,6 +11275,9 @@ "access_url": { "type": "string" }, + "dismissed": { + "type": "boolean" + }, "error": { "type": "string" }, @@ -11307,6 +11313,9 @@ "healthcheck.DatabaseReport": { "type": "object", "properties": { + "dismissed": { + "type": "boolean" + }, "error": { "type": "string" }, @@ -11399,6 +11408,9 @@ "code": { "type": "integer" }, + "dismissed": { + "type": "boolean" + }, "error": { "type": "string" }, @@ -11425,6 +11437,9 @@ "healthcheck.WorkspaceProxyReport": { "type": "object", "properties": { + "dismissed": { + "type": "boolean" + }, "error": { "type": "string" }, diff --git a/coderd/coderd.go b/coderd/coderd.go index 091ef987ff31e..08784b6ff4e43 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -25,6 +25,7 @@ import ( "github.com/prometheus/client_golang/prometheus" httpSwagger "github.com/swaggo/http-swagger/v2" "go.opentelemetry.io/otel/trace" + "golang.org/x/exp/slices" "golang.org/x/xerrors" "google.golang.org/api/idtoken" "storj.io/drpc/drpcmux" @@ -407,24 +408,30 @@ func New(options *Options) *API { if options.HealthcheckFunc == nil { options.HealthcheckFunc = func(ctx context.Context, apiKey string) *healthcheck.Report { + dismissedHealthchecks := loadDismissedHealthchecks(ctx, options.Database, options.Logger) return healthcheck.Run(ctx, &healthcheck.ReportOptions{ Database: healthcheck.DatabaseReportOptions{ DB: options.Database, Threshold: options.DeploymentValues.Healthcheck.ThresholdDatabase.Value(), + Dismissed: slices.Contains(dismissedHealthchecks, healthcheck.SectionDatabase), }, Websocket: healthcheck.WebsocketReportOptions{ AccessURL: options.AccessURL, APIKey: apiKey, + Dismissed: slices.Contains(dismissedHealthchecks, healthcheck.SectionWebsocket), }, AccessURL: healthcheck.AccessURLReportOptions{ AccessURL: options.AccessURL, + Dismissed: slices.Contains(dismissedHealthchecks, healthcheck.SectionAccessURL), }, DerpHealth: derphealth.ReportOptions{ - DERPMap: api.DERPMap(), + DERPMap: api.DERPMap(), + Dismissed: slices.Contains(dismissedHealthchecks, healthcheck.SectionDERP), }, WorkspaceProxy: healthcheck.WorkspaceProxyReportOptions{ CurrentVersion: buildinfo.Version(), WorkspaceProxiesFetchUpdater: *(options.WorkspaceProxiesFetchUpdater).Load(), + Dismissed: slices.Contains(dismissedHealthchecks, healthcheck.SectionWorkspaceProxy), }, }) } diff --git a/coderd/debug.go b/coderd/debug.go index 08916e1b4d37b..8f61bcfb78859 100644 --- a/coderd/debug.go +++ b/coderd/debug.go @@ -3,15 +3,17 @@ package coderd import ( "bytes" "context" + "database/sql" "encoding/json" "fmt" "net/http" "time" + "github.com/google/uuid" "golang.org/x/exp/slices" "golang.org/x/xerrors" - "github.com/google/uuid" + "cdr.dev/slog" "github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/database" @@ -253,3 +255,19 @@ func validateHealthSettings(settings codersdk.HealthSettings) error { // @Router /debug/ws [get] // @x-apidocgen {"skip": true} func _debugws(http.ResponseWriter, *http.Request) {} //nolint:unused + +func loadDismissedHealthchecks(ctx context.Context, db database.Store, logger slog.Logger) []string { + dismissedHealthchecks := []string{} + settingsJSON, err := db.GetHealthSettings(ctx) + if err == nil { + var settings codersdk.HealthSettings + err = json.Unmarshal([]byte(settingsJSON), &settings) + if len(settings.DismissedHealthchecks) > 0 { + dismissedHealthchecks = settings.DismissedHealthchecks + } + } + if err != nil && !xerrors.Is(err, sql.ErrNoRows) { + logger.Error(ctx, "unable to fetch health settings: %w", err) + } + return dismissedHealthchecks +} diff --git a/coderd/healthcheck/accessurl.go b/coderd/healthcheck/accessurl.go index 110ec3486a896..6f3b0fdc07975 100644 --- a/coderd/healthcheck/accessurl.go +++ b/coderd/healthcheck/accessurl.go @@ -16,9 +16,10 @@ import ( // @typescript-generate AccessURLReport type AccessURLReport struct { // Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. - Healthy bool `json:"healthy"` - Severity health.Severity `json:"severity" enums:"ok,warning,error"` - Warnings []string `json:"warnings"` + Healthy bool `json:"healthy"` + Severity health.Severity `json:"severity" enums:"ok,warning,error"` + Warnings []string `json:"warnings"` + Dismissed bool `json:"dismissed"` AccessURL string `json:"access_url"` Reachable bool `json:"reachable"` @@ -30,6 +31,8 @@ type AccessURLReport struct { type AccessURLReportOptions struct { AccessURL *url.URL Client *http.Client + + Dismissed bool } func (r *AccessURLReport) Run(ctx context.Context, opts *AccessURLReportOptions) { @@ -38,6 +41,8 @@ func (r *AccessURLReport) Run(ctx context.Context, opts *AccessURLReportOptions) r.Severity = health.SeverityOK r.Warnings = []string{} + r.Dismissed = opts.Dismissed + if opts.AccessURL == nil { r.Error = ptr.Ref("access URL is nil") r.Severity = health.SeverityError diff --git a/coderd/healthcheck/accessurl_test.go b/coderd/healthcheck/accessurl_test.go index 43e839c853b96..9e368cc679708 100644 --- a/coderd/healthcheck/accessurl_test.go +++ b/coderd/healthcheck/accessurl_test.go @@ -109,6 +109,23 @@ func TestAccessURL(t *testing.T) { require.NotNil(t, report.Error) assert.Contains(t, *report.Error, expErr.Error()) }) + + t.Run("DismissedError", func(t *testing.T) { + t.Parallel() + + var ( + ctx, cancel = context.WithCancel(context.Background()) + report healthcheck.AccessURLReport + ) + defer cancel() + + report.Run(ctx, &healthcheck.AccessURLReportOptions{ + Dismissed: true, + }) + + assert.True(t, report.Dismissed) + assert.Equal(t, health.SeverityError, report.Severity) + }) } type roundTripFunc func(r *http.Request) (*http.Response, error) diff --git a/coderd/healthcheck/database.go b/coderd/healthcheck/database.go index 07120ad533054..3df3fcd972f59 100644 --- a/coderd/healthcheck/database.go +++ b/coderd/healthcheck/database.go @@ -18,9 +18,10 @@ const ( // @typescript-generate DatabaseReport type DatabaseReport struct { // Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. - Healthy bool `json:"healthy"` - Severity health.Severity `json:"severity" enums:"ok,warning,error"` - Warnings []string `json:"warnings"` + Healthy bool `json:"healthy"` + Severity health.Severity `json:"severity" enums:"ok,warning,error"` + Warnings []string `json:"warnings"` + Dismissed bool `json:"dismissed"` Reachable bool `json:"reachable"` Latency string `json:"latency"` @@ -32,11 +33,15 @@ type DatabaseReport struct { type DatabaseReportOptions struct { DB database.Store Threshold time.Duration + + Dismissed bool } func (r *DatabaseReport) Run(ctx context.Context, opts *DatabaseReportOptions) { r.Warnings = []string{} r.Severity = health.SeverityOK + r.Dismissed = opts.Dismissed + r.ThresholdMS = opts.Threshold.Milliseconds() if r.ThresholdMS == 0 { r.ThresholdMS = DatabaseDefaultThreshold.Milliseconds() diff --git a/coderd/healthcheck/database_test.go b/coderd/healthcheck/database_test.go index a0d817e59606f..8ac5bbe38c2e7 100644 --- a/coderd/healthcheck/database_test.go +++ b/coderd/healthcheck/database_test.go @@ -67,6 +67,26 @@ func TestDatabase(t *testing.T) { assert.Contains(t, *report.Error, err.Error()) }) + t.Run("DismissedError", func(t *testing.T) { + t.Parallel() + + var ( + ctx, cancel = context.WithTimeout(context.Background(), testutil.WaitShort) + report = healthcheck.DatabaseReport{} + db = dbmock.NewMockStore(gomock.NewController(t)) + err = xerrors.New("ping error") + ) + defer cancel() + + db.EXPECT().Ping(gomock.Any()).Return(time.Duration(0), err) + + report.Run(ctx, &healthcheck.DatabaseReportOptions{DB: db, Dismissed: true}) + + assert.Equal(t, health.SeverityError, report.Severity) + assert.True(t, report.Dismissed) + require.NotNil(t, report.Error) + }) + t.Run("Median", func(t *testing.T) { t.Parallel() diff --git a/coderd/healthcheck/derphealth/derp.go b/coderd/healthcheck/derphealth/derp.go index 4f6271cfc8169..3f9f78b319d39 100644 --- a/coderd/healthcheck/derphealth/derp.go +++ b/coderd/healthcheck/derphealth/derp.go @@ -36,9 +36,10 @@ const ( // @typescript-generate Report type Report struct { // Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. - Healthy bool `json:"healthy"` - Severity health.Severity `json:"severity" enums:"ok,warning,error"` - Warnings []string `json:"warnings"` + Healthy bool `json:"healthy"` + Severity health.Severity `json:"severity" enums:"ok,warning,error"` + Warnings []string `json:"warnings"` + Dismissed bool `json:"dismissed"` Regions map[int]*RegionReport `json:"regions"` @@ -95,15 +96,18 @@ type StunReport struct { } type ReportOptions struct { + Dismissed bool + DERPMap *tailcfg.DERPMap } func (r *Report) Run(ctx context.Context, opts *ReportOptions) { r.Healthy = true r.Severity = health.SeverityOK + r.Warnings = []string{} + r.Dismissed = opts.Dismissed r.Regions = map[int]*RegionReport{} - r.Warnings = []string{} wg := &sync.WaitGroup{} mu := sync.Mutex{} diff --git a/coderd/healthcheck/derphealth/derp_test.go b/coderd/healthcheck/derphealth/derp_test.go index fd389f4e62f53..cf307637ac401 100644 --- a/coderd/healthcheck/derphealth/derp_test.go +++ b/coderd/healthcheck/derphealth/derp_test.go @@ -120,6 +120,7 @@ func TestDERP(t *testing.T) { }}, }, }}, + Dismissed: true, // Let's sneak an extra unit test } ) @@ -127,6 +128,7 @@ func TestDERP(t *testing.T) { assert.True(t, report.Healthy) assert.Equal(t, health.SeverityWarning, report.Severity) + assert.True(t, report.Dismissed) for _, region := range report.Regions { assert.True(t, region.Healthy) assert.True(t, region.NodeReports[0].Healthy) diff --git a/coderd/healthcheck/websocket.go b/coderd/healthcheck/websocket.go index c49ba1b2be10d..2a4792c874e80 100644 --- a/coderd/healthcheck/websocket.go +++ b/coderd/healthcheck/websocket.go @@ -15,30 +15,35 @@ import ( "github.com/coder/coder/v2/coderd/healthcheck/health" ) -type WebsocketReportOptions struct { - APIKey string - AccessURL *url.URL - HTTPClient *http.Client -} - // @typescript-generate WebsocketReport type WebsocketReport struct { // Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. - Healthy bool `json:"healthy"` - Severity health.Severity `json:"severity" enums:"ok,warning,error"` - Warnings []string `json:"warnings"` + Healthy bool `json:"healthy"` + Severity health.Severity `json:"severity" enums:"ok,warning,error"` + Warnings []string `json:"warnings"` + Dismissed bool `json:"dismissed"` Body string `json:"body"` Code int `json:"code"` Error *string `json:"error"` } +type WebsocketReportOptions struct { + APIKey string + AccessURL *url.URL + HTTPClient *http.Client + + Dismissed bool +} + func (r *WebsocketReport) Run(ctx context.Context, opts *WebsocketReportOptions) { ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() r.Severity = health.SeverityOK r.Warnings = []string{} + r.Dismissed = opts.Dismissed + u, err := opts.AccessURL.Parse("/api/v2/debug/ws") if err != nil { r.Error = convertError(xerrors.Errorf("parse access url: %w", err)) diff --git a/coderd/healthcheck/websocket_test.go b/coderd/healthcheck/websocket_test.go index 861e1acfd07fa..1beb96ea0631b 100644 --- a/coderd/healthcheck/websocket_test.go +++ b/coderd/healthcheck/websocket_test.go @@ -68,4 +68,22 @@ func TestWebsocket(t *testing.T) { assert.Equal(t, wsReport.Body, "test error") assert.Equal(t, wsReport.Code, http.StatusBadRequest) }) + + t.Run("DismissedError", func(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort) + defer cancel() + + wsReport := healthcheck.WebsocketReport{} + wsReport.Run(ctx, &healthcheck.WebsocketReportOptions{ + AccessURL: &url.URL{Host: "fake"}, + Dismissed: true, + }) + + require.True(t, wsReport.Dismissed) + require.Equal(t, health.SeverityError, wsReport.Severity) + require.NotNil(t, wsReport.Error) + require.Equal(t, health.SeverityError, wsReport.Severity) + }) } diff --git a/coderd/healthcheck/workspaceproxy.go b/coderd/healthcheck/workspaceproxy.go index 9acd527b942e2..8ab8e86dd47cc 100644 --- a/coderd/healthcheck/workspaceproxy.go +++ b/coderd/healthcheck/workspaceproxy.go @@ -14,21 +14,24 @@ import ( "github.com/coder/coder/v2/codersdk" ) +// @typescript-generate WorkspaceProxyReport +type WorkspaceProxyReport struct { + Healthy bool `json:"healthy"` + Severity health.Severity `json:"severity"` + Warnings []string `json:"warnings"` + Dismissed bool `json:"dismissed"` + Error *string `json:"error"` + + WorkspaceProxies codersdk.RegionsResponse[codersdk.WorkspaceProxy] `json:"workspace_proxies"` +} + type WorkspaceProxyReportOptions struct { // CurrentVersion is the current server version. // We pass this in to make it easier to test. CurrentVersion string WorkspaceProxiesFetchUpdater WorkspaceProxiesFetchUpdater -} -// @typescript-generate WorkspaceProxyReport -type WorkspaceProxyReport struct { - Healthy bool `json:"healthy"` - Severity health.Severity `json:"severity"` - Warnings []string `json:"warnings"` - Error *string `json:"error"` - - WorkspaceProxies codersdk.RegionsResponse[codersdk.WorkspaceProxy] `json:"workspace_proxies"` + Dismissed bool } type WorkspaceProxiesFetchUpdater interface { @@ -52,6 +55,7 @@ func (r *WorkspaceProxyReport) Run(ctx context.Context, opts *WorkspaceProxyRepo r.Healthy = true r.Severity = health.SeverityOK r.Warnings = []string{} + r.Dismissed = opts.Dismissed if opts.WorkspaceProxiesFetchUpdater == nil { opts.WorkspaceProxiesFetchUpdater = &AGPLWorkspaceProxiesFetchUpdater{} diff --git a/coderd/healthcheck/workspaceproxy_test.go b/coderd/healthcheck/workspaceproxy_test.go index a96c13384fb5b..3cd560ad3897c 100644 --- a/coderd/healthcheck/workspaceproxy_test.go +++ b/coderd/healthcheck/workspaceproxy_test.go @@ -191,6 +191,22 @@ func TestWorkspaceProxies(t *testing.T) { } } +func TestWorkspaceProxy_ErrorDismissed(t *testing.T) { + t.Parallel() + + var report healthcheck.WorkspaceProxyReport + report.Run(context.Background(), &healthcheck.WorkspaceProxyReportOptions{ + WorkspaceProxiesFetchUpdater: &fakeWorkspaceProxyFetchUpdater{ + fetchFunc: fakeFetchWorkspaceProxiesErr(assert.AnError), + updateFunc: fakeUpdateProxyHealth(assert.AnError), + }, + Dismissed: true, + }) + + assert.True(t, report.Dismissed) + assert.Equal(t, health.SeverityWarning, report.Severity) +} + // yet another implementation of the thing type fakeWorkspaceProxyFetchUpdater struct { fetchFunc func(context.Context) (codersdk.RegionsResponse[codersdk.WorkspaceProxy], error) diff --git a/codersdk/health.go b/codersdk/health.go index ece12ba424771..b2a7b3de73435 100644 --- a/codersdk/health.go +++ b/codersdk/health.go @@ -35,6 +35,7 @@ func (c *Client) PutHealthSettings(ctx context.Context, settings HealthSettings) return err } defer res.Body.Close() + if res.StatusCode == http.StatusNotModified { return xerrors.New("health settings not modified") } diff --git a/docs/api/debug.md b/docs/api/debug.md index de9348e1404e4..826ef3e138e6b 100644 --- a/docs/api/debug.md +++ b/docs/api/debug.md @@ -47,6 +47,7 @@ curl -X GET http://coder-server:8080/api/v2/debug/health \ { "access_url": { "access_url": "string", + "dismissed": true, "error": "string", "healthy": true, "healthz_response": "string", @@ -57,6 +58,7 @@ curl -X GET http://coder-server:8080/api/v2/debug/health \ }, "coder_version": "string", "database": { + "dismissed": true, "error": "string", "healthy": true, "latency": "string", @@ -67,6 +69,7 @@ curl -X GET http://coder-server:8080/api/v2/debug/health \ "warnings": ["string"] }, "derp": { + "dismissed": true, "error": "string", "healthy": true, "netcheck": { @@ -249,12 +252,14 @@ curl -X GET http://coder-server:8080/api/v2/debug/health \ "websocket": { "body": "string", "code": 0, + "dismissed": true, "error": "string", "healthy": true, "severity": "ok", "warnings": ["string"] }, "workspace_proxy": { + "dismissed": true, "error": "string", "healthy": true, "severity": "ok", diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 6de323c0968fe..d00c1a739004e 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -7302,6 +7302,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { + "dismissed": true, "error": "string", "healthy": true, "netcheck": { @@ -7483,6 +7484,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| | Name | Type | Required | Restrictions | Description | | ------------------ | -------------------------------------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------- | +| `dismissed` | boolean | false | | | | `error` | string | false | | | | `healthy` | boolean | false | | Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. | | `netcheck` | [netcheck.Report](#netcheckreport) | false | | | @@ -7540,6 +7542,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { "access_url": "string", + "dismissed": true, "error": "string", "healthy": true, "healthz_response": "string", @@ -7555,6 +7558,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| | Name | Type | Required | Restrictions | Description | | ------------------ | ---------------------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------- | | `access_url` | string | false | | | +| `dismissed` | boolean | false | | | | `error` | string | false | | | | `healthy` | boolean | false | | Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. | | `healthz_response` | string | false | | | @@ -7575,6 +7579,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { + "dismissed": true, "error": "string", "healthy": true, "latency": "string", @@ -7590,6 +7595,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| | Name | Type | Required | Restrictions | Description | | -------------- | ---------------------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------- | +| `dismissed` | boolean | false | | | | `error` | string | false | | | | `healthy` | boolean | false | | Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. | | `latency` | string | false | | | @@ -7613,6 +7619,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| { "access_url": { "access_url": "string", + "dismissed": true, "error": "string", "healthy": true, "healthz_response": "string", @@ -7623,6 +7630,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| }, "coder_version": "string", "database": { + "dismissed": true, "error": "string", "healthy": true, "latency": "string", @@ -7633,6 +7641,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| "warnings": ["string"] }, "derp": { + "dismissed": true, "error": "string", "healthy": true, "netcheck": { @@ -7815,12 +7824,14 @@ If the schedule is empty, the user will be updated to use the default schedule.| "websocket": { "body": "string", "code": 0, + "dismissed": true, "error": "string", "healthy": true, "severity": "ok", "warnings": ["string"] }, "workspace_proxy": { + "dismissed": true, "error": "string", "healthy": true, "severity": "ok", @@ -7885,6 +7896,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| { "body": "string", "code": 0, + "dismissed": true, "error": "string", "healthy": true, "severity": "ok", @@ -7894,14 +7906,15 @@ If the schedule is empty, the user will be updated to use the default schedule.| ### Properties -| Name | Type | Required | Restrictions | Description | -| ---------- | ---------------------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------- | -| `body` | string | false | | | -| `code` | integer | false | | | -| `error` | string | false | | | -| `healthy` | boolean | false | | Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. | -| `severity` | [health.Severity](#healthseverity) | false | | | -| `warnings` | array of string | false | | | +| Name | Type | Required | Restrictions | Description | +| ----------- | ---------------------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------- | +| `body` | string | false | | | +| `code` | integer | false | | | +| `dismissed` | boolean | false | | | +| `error` | string | false | | | +| `healthy` | boolean | false | | Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. | +| `severity` | [health.Severity](#healthseverity) | false | | | +| `warnings` | array of string | false | | | #### Enumerated Values @@ -7915,6 +7928,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { + "dismissed": true, "error": "string", "healthy": true, "severity": "ok", @@ -7953,6 +7967,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| | Name | Type | Required | Restrictions | Description | | ------------------- | ---------------------------------------------------------------------------------------------------- | -------- | ------------ | ----------- | +| `dismissed` | boolean | false | | | | `error` | string | false | | | | `healthy` | boolean | false | | | | `severity` | [health.Severity](#healthseverity) | false | | | diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 901f0c213bb02..9d930d27f1311 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -2100,6 +2100,7 @@ export interface HealthcheckAccessURLReport { readonly healthy: boolean; readonly severity: HealthSeverity; readonly warnings: string[]; + readonly dismissed: boolean; readonly access_url: string; readonly reachable: boolean; readonly status_code: number; @@ -2112,6 +2113,7 @@ export interface HealthcheckDatabaseReport { readonly healthy: boolean; readonly severity: HealthSeverity; readonly warnings: string[]; + readonly dismissed: boolean; readonly reachable: boolean; readonly latency: string; readonly latency_ms: number; @@ -2138,6 +2140,7 @@ export interface HealthcheckWebsocketReport { readonly healthy: boolean; readonly severity: HealthSeverity; readonly warnings: string[]; + readonly dismissed: boolean; readonly body: string; readonly code: number; readonly error?: string; @@ -2148,6 +2151,7 @@ export interface HealthcheckWorkspaceProxyReport { readonly healthy: boolean; readonly severity: HealthSeverity; readonly warnings: string[]; + readonly dismissed: boolean; readonly error?: string; readonly workspace_proxies: RegionsResponse; } @@ -2246,6 +2250,7 @@ export interface DerphealthReport { // This is likely an enum in an external package ("github.com/coder/coder/v2/coderd/healthcheck/health.Severity") readonly severity: string; readonly warnings: string[]; + readonly dismissed: boolean; readonly regions: Record; // Named type "tailscale.com/net/netcheck.Report" unknown, using "any" // eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 076bdf2167e68..6596ed358158b 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -2404,6 +2404,7 @@ export const MockHealth: TypesGen.HealthcheckReport = { healthy: true, severity: "ok", warnings: [], + dismissed: false, regions: { "999": { healthy: true, @@ -2806,6 +2807,7 @@ export const MockHealth: TypesGen.HealthcheckReport = { healthy: true, severity: "ok", warnings: [], + dismissed: false, access_url: "https://dev.coder.com", reachable: true, status_code: 200, @@ -2815,6 +2817,7 @@ export const MockHealth: TypesGen.HealthcheckReport = { healthy: true, severity: "ok", warnings: [], + dismissed: false, body: "", code: 101, }, @@ -2822,6 +2825,7 @@ export const MockHealth: TypesGen.HealthcheckReport = { healthy: true, severity: "ok", warnings: [], + dismissed: false, reachable: true, latency: "92570", latency_ms: 92570, @@ -2831,6 +2835,7 @@ export const MockHealth: TypesGen.HealthcheckReport = { healthy: true, severity: "ok", warnings: [], + dismissed: false, workspace_proxies: { regions: [], }, @@ -2857,6 +2862,7 @@ export const DeploymentHealthUnhealthy: TypesGen.HealthcheckReport = { healthy: true, severity: "ok", warnings: [], + dismissed: false, access_url: "", healthz_response: "", reachable: true, @@ -2866,6 +2872,7 @@ export const DeploymentHealthUnhealthy: TypesGen.HealthcheckReport = { healthy: false, severity: "ok", warnings: [], + dismissed: false, latency: "", latency_ms: 0, reachable: true, @@ -2875,6 +2882,7 @@ export const DeploymentHealthUnhealthy: TypesGen.HealthcheckReport = { healthy: false, severity: "ok", warnings: [], + dismissed: false, regions: [], netcheck_logs: [], }, @@ -2882,6 +2890,7 @@ export const DeploymentHealthUnhealthy: TypesGen.HealthcheckReport = { healthy: false, severity: "ok", warnings: [], + dismissed: false, body: "", code: 0, }, @@ -2890,6 +2899,7 @@ export const DeploymentHealthUnhealthy: TypesGen.HealthcheckReport = { error: "some error", severity: "error", warnings: [], + dismissed: false, workspace_proxies: { regions: [ {