fix(site/src/api/typesGenerated): generate HealthSection enums (#11049)

Relates to #8971

- Introduces a codersdk.HealthSection enum type
- Refactors existing references using strings to use new HealthSection type
This commit is contained in:
Cian Johnston 2023-12-05 20:00:27 +00:00 committed by GitHub
parent f66e802fae
commit feaa9894a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 149 additions and 73 deletions

23
coderd/apidoc/docs.go generated
View File

@ -8973,13 +8973,30 @@ const docTemplate = `{
"GroupSourceOIDC"
]
},
"codersdk.HealthSection": {
"type": "string",
"enum": [
"DERP",
"AccessURL",
"Websocket",
"Database",
"WorkspaceProxy"
],
"x-enum-varnames": [
"HealthSectionDERP",
"HealthSectionAccessURL",
"HealthSectionWebsocket",
"HealthSectionDatabase",
"HealthSectionWorkspaceProxy"
]
},
"codersdk.HealthSettings": {
"type": "object",
"properties": {
"dismissed_healthchecks": {
"type": "array",
"items": {
"type": "string"
"$ref": "#/definitions/codersdk.HealthSection"
}
}
}
@ -10862,7 +10879,7 @@ const docTemplate = `{
"dismissed_healthchecks": {
"type": "array",
"items": {
"type": "string"
"$ref": "#/definitions/codersdk.HealthSection"
}
}
}
@ -12550,7 +12567,7 @@ const docTemplate = `{
"description": "FailingSections is a list of sections that have failed their healthcheck.",
"type": "array",
"items": {
"type": "string"
"$ref": "#/definitions/codersdk.HealthSection"
}
},
"healthy": {

View File

@ -8059,13 +8059,24 @@
"enum": ["user", "oidc"],
"x-enum-varnames": ["GroupSourceUser", "GroupSourceOIDC"]
},
"codersdk.HealthSection": {
"type": "string",
"enum": ["DERP", "AccessURL", "Websocket", "Database", "WorkspaceProxy"],
"x-enum-varnames": [
"HealthSectionDERP",
"HealthSectionAccessURL",
"HealthSectionWebsocket",
"HealthSectionDatabase",
"HealthSectionWorkspaceProxy"
]
},
"codersdk.HealthSettings": {
"type": "object",
"properties": {
"dismissed_healthchecks": {
"type": "array",
"items": {
"type": "string"
"$ref": "#/definitions/codersdk.HealthSection"
}
}
}
@ -9835,7 +9846,7 @@
"dismissed_healthchecks": {
"type": "array",
"items": {
"type": "string"
"$ref": "#/definitions/codersdk.HealthSection"
}
}
}
@ -11431,7 +11442,7 @@
"description": "FailingSections is a list of sections that have failed their healthcheck.",
"type": "array",
"items": {
"type": "string"
"$ref": "#/definitions/codersdk.HealthSection"
}
},
"healthy": {

View File

@ -413,25 +413,25 @@ func New(options *Options) *API {
Database: healthcheck.DatabaseReportOptions{
DB: options.Database,
Threshold: options.DeploymentValues.Healthcheck.ThresholdDatabase.Value(),
Dismissed: slices.Contains(dismissedHealthchecks, healthcheck.SectionDatabase),
Dismissed: slices.Contains(dismissedHealthchecks, codersdk.HealthSectionDatabase),
},
Websocket: healthcheck.WebsocketReportOptions{
AccessURL: options.AccessURL,
APIKey: apiKey,
Dismissed: slices.Contains(dismissedHealthchecks, healthcheck.SectionWebsocket),
Dismissed: slices.Contains(dismissedHealthchecks, codersdk.HealthSectionWebsocket),
},
AccessURL: healthcheck.AccessURLReportOptions{
AccessURL: options.AccessURL,
Dismissed: slices.Contains(dismissedHealthchecks, healthcheck.SectionAccessURL),
Dismissed: slices.Contains(dismissedHealthchecks, codersdk.HealthSectionAccessURL),
},
DerpHealth: derphealth.ReportOptions{
DERPMap: api.DERPMap(),
Dismissed: slices.Contains(dismissedHealthchecks, healthcheck.SectionDERP),
Dismissed: slices.Contains(dismissedHealthchecks, codersdk.HealthSectionDERP),
},
WorkspaceProxy: healthcheck.WorkspaceProxyReportOptions{
CurrentVersion: buildinfo.Version(),
WorkspaceProxiesFetchUpdater: *(options.WorkspaceProxiesFetchUpdater).Load(),
Dismissed: slices.Contains(dismissedHealthchecks, healthcheck.SectionWorkspaceProxy),
Dismissed: slices.Contains(dismissedHealthchecks, codersdk.HealthSectionWorkspaceProxy),
},
})
}

View File

@ -9,6 +9,7 @@ import (
"golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/codersdk"
)
// AuditOAuthConvertState is never stored in the database. It is stored in a cookie
@ -24,8 +25,8 @@ type AuditOAuthConvertState struct {
}
type HealthSettings struct {
ID uuid.UUID `db:"id" json:"id"`
DismissedHealthchecks []string `db:"dismissed_healthchecks" json:"dismissed_healthchecks"`
ID uuid.UUID `db:"id" json:"id"`
DismissedHealthchecks []codersdk.HealthSection `db:"dismissed_healthchecks" json:"dismissed_healthchecks"`
}
type Actions []rbac.Action

View File

@ -147,7 +147,7 @@ func (api *API) deploymentHealthSettings(rw http.ResponseWriter, r *http.Request
}
if len(settings.DismissedHealthchecks) == 0 {
settings.DismissedHealthchecks = []string{}
settings.DismissedHealthchecks = []codersdk.HealthSection{}
}
httpapi.Write(r.Context(), rw, http.StatusOK, settings)
@ -218,6 +218,7 @@ func (api *API) putDeploymentHealthSettings(rw http.ResponseWriter, r *http.Requ
Action: database.AuditActionWrite,
})
defer commitAudit()
aReq.New = database.HealthSettings{
ID: uuid.New(),
DismissedHealthchecks: settings.DismissedHealthchecks,
@ -237,7 +238,7 @@ func (api *API) putDeploymentHealthSettings(rw http.ResponseWriter, r *http.Requ
func validateHealthSettings(settings codersdk.HealthSettings) error {
for _, dismissed := range settings.DismissedHealthchecks {
ok := slices.Contains(healthcheck.Sections, dismissed)
ok := slices.Contains(codersdk.HealthSections, dismissed)
if !ok {
return xerrors.Errorf("unknown healthcheck section: %s", dismissed)
}
@ -257,8 +258,8 @@ func validateHealthSettings(settings codersdk.HealthSettings) error {
// @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{}
func loadDismissedHealthchecks(ctx context.Context, db database.Store, logger slog.Logger) []codersdk.HealthSection {
dismissedHealthchecks := []codersdk.HealthSection{}
settingsJSON, err := db.GetHealthSettings(ctx)
if err == nil {
var settings codersdk.HealthSettings

View File

@ -251,7 +251,7 @@ func TestHealthSettings(t *testing.T) {
require.NoError(t, err)
// then
require.Equal(t, codersdk.HealthSettings{DismissedHealthchecks: []string{}}, settings)
require.Equal(t, codersdk.HealthSettings{DismissedHealthchecks: []codersdk.HealthSection{}}, settings)
})
t.Run("DismissSection", func(t *testing.T) {
@ -265,7 +265,7 @@ func TestHealthSettings(t *testing.T) {
_ = coderdtest.CreateFirstUser(t, adminClient)
expected := codersdk.HealthSettings{
DismissedHealthchecks: []string{healthcheck.SectionDERP, healthcheck.SectionWebsocket},
DismissedHealthchecks: []codersdk.HealthSection{codersdk.HealthSectionDERP, codersdk.HealthSectionWebsocket},
}
// when: dismiss "derp" and "websocket"
@ -289,14 +289,14 @@ func TestHealthSettings(t *testing.T) {
_ = coderdtest.CreateFirstUser(t, adminClient)
initial := codersdk.HealthSettings{
DismissedHealthchecks: []string{healthcheck.SectionDERP, healthcheck.SectionWebsocket},
DismissedHealthchecks: []codersdk.HealthSection{codersdk.HealthSectionDERP, codersdk.HealthSectionWebsocket},
}
err := adminClient.PutHealthSettings(ctx, initial)
require.NoError(t, err)
expected := codersdk.HealthSettings{
DismissedHealthchecks: []string{healthcheck.SectionDERP},
DismissedHealthchecks: []codersdk.HealthSection{codersdk.HealthSectionDERP},
}
// when: undismiss "websocket"
@ -320,7 +320,7 @@ func TestHealthSettings(t *testing.T) {
_ = coderdtest.CreateFirstUser(t, adminClient)
expected := codersdk.HealthSettings{
DismissedHealthchecks: []string{healthcheck.SectionDERP, healthcheck.SectionWebsocket},
DismissedHealthchecks: []codersdk.HealthSection{codersdk.HealthSectionDERP, codersdk.HealthSectionWebsocket},
}
err := adminClient.PutHealthSettings(ctx, expected)

View File

@ -9,18 +9,9 @@ import (
"github.com/coder/coder/v2/coderd/healthcheck/derphealth"
"github.com/coder/coder/v2/coderd/healthcheck/health"
"github.com/coder/coder/v2/coderd/util/ptr"
"github.com/coder/coder/v2/codersdk"
)
const (
SectionDERP string = "DERP"
SectionAccessURL string = "AccessURL"
SectionWebsocket string = "Websocket"
SectionDatabase string = "Database"
SectionWorkspaceProxy string = "WorkspaceProxy"
)
var Sections = []string{SectionAccessURL, SectionDatabase, SectionDERP, SectionWebsocket, SectionWorkspaceProxy}
type Checker interface {
DERP(ctx context.Context, opts *derphealth.ReportOptions) derphealth.Report
AccessURL(ctx context.Context, opts *AccessURLReportOptions) AccessURLReport
@ -39,7 +30,7 @@ type Report struct {
// Severity indicates the status of Coder health.
Severity health.Severity `json:"severity" enums:"ok,warning,error"`
// FailingSections is a list of sections that have failed their healthcheck.
FailingSections []string `json:"failing_sections"`
FailingSections []codersdk.HealthSection `json:"failing_sections"`
DERP derphealth.Report `json:"derp"`
AccessURL AccessURLReport `json:"access_url"`
@ -162,21 +153,21 @@ func Run(ctx context.Context, opts *ReportOptions) *Report {
wg.Wait()
report.Time = time.Now()
report.FailingSections = []string{}
report.FailingSections = []codersdk.HealthSection{}
if !report.DERP.Healthy {
report.FailingSections = append(report.FailingSections, SectionDERP)
report.FailingSections = append(report.FailingSections, codersdk.HealthSectionDERP)
}
if !report.AccessURL.Healthy {
report.FailingSections = append(report.FailingSections, SectionAccessURL)
report.FailingSections = append(report.FailingSections, codersdk.HealthSectionAccessURL)
}
if !report.Websocket.Healthy {
report.FailingSections = append(report.FailingSections, SectionWebsocket)
report.FailingSections = append(report.FailingSections, codersdk.HealthSectionWebsocket)
}
if !report.Database.Healthy {
report.FailingSections = append(report.FailingSections, SectionDatabase)
report.FailingSections = append(report.FailingSections, codersdk.HealthSectionDatabase)
}
if !report.WorkspaceProxy.Healthy {
report.FailingSections = append(report.FailingSections, SectionWorkspaceProxy)
report.FailingSections = append(report.FailingSections, codersdk.HealthSectionWorkspaceProxy)
}
report.Healthy = len(report.FailingSections) == 0

View File

@ -9,6 +9,7 @@ import (
"github.com/coder/coder/v2/coderd/healthcheck"
"github.com/coder/coder/v2/coderd/healthcheck/derphealth"
"github.com/coder/coder/v2/coderd/healthcheck/health"
"github.com/coder/coder/v2/codersdk"
)
type testChecker struct {
@ -47,7 +48,7 @@ func TestHealthcheck(t *testing.T) {
checker *testChecker
healthy bool
severity health.Severity
failingSections []string
failingSections []codersdk.HealthSection
}{{
name: "OK",
checker: &testChecker{
@ -74,7 +75,7 @@ func TestHealthcheck(t *testing.T) {
},
healthy: true,
severity: health.SeverityOK,
failingSections: []string{},
failingSections: []codersdk.HealthSection{},
}, {
name: "DERPFail",
checker: &testChecker{
@ -101,7 +102,7 @@ func TestHealthcheck(t *testing.T) {
},
healthy: false,
severity: health.SeverityError,
failingSections: []string{healthcheck.SectionDERP},
failingSections: []codersdk.HealthSection{codersdk.HealthSectionDERP},
}, {
name: "DERPWarning",
checker: &testChecker{
@ -129,7 +130,7 @@ func TestHealthcheck(t *testing.T) {
},
healthy: true,
severity: health.SeverityWarning,
failingSections: []string{},
failingSections: []codersdk.HealthSection{},
}, {
name: "AccessURLFail",
checker: &testChecker{
@ -156,7 +157,7 @@ func TestHealthcheck(t *testing.T) {
},
healthy: false,
severity: health.SeverityWarning,
failingSections: []string{healthcheck.SectionAccessURL},
failingSections: []codersdk.HealthSection{codersdk.HealthSectionAccessURL},
}, {
name: "WebsocketFail",
checker: &testChecker{
@ -183,7 +184,7 @@ func TestHealthcheck(t *testing.T) {
},
healthy: false,
severity: health.SeverityError,
failingSections: []string{healthcheck.SectionWebsocket},
failingSections: []codersdk.HealthSection{codersdk.HealthSectionWebsocket},
}, {
name: "DatabaseFail",
checker: &testChecker{
@ -210,7 +211,7 @@ func TestHealthcheck(t *testing.T) {
},
healthy: false,
severity: health.SeverityError,
failingSections: []string{healthcheck.SectionDatabase},
failingSections: []codersdk.HealthSection{codersdk.HealthSectionDatabase},
}, {
name: "ProxyFail",
checker: &testChecker{
@ -237,7 +238,7 @@ func TestHealthcheck(t *testing.T) {
},
severity: health.SeverityError,
healthy: false,
failingSections: []string{healthcheck.SectionWorkspaceProxy},
failingSections: []codersdk.HealthSection{codersdk.HealthSectionWorkspaceProxy},
}, {
name: "ProxyWarn",
checker: &testChecker{
@ -265,7 +266,7 @@ func TestHealthcheck(t *testing.T) {
},
severity: health.SeverityWarning,
healthy: true,
failingSections: []string{},
failingSections: []codersdk.HealthSection{},
}, {
name: "AllFail",
healthy: false,
@ -292,12 +293,12 @@ func TestHealthcheck(t *testing.T) {
},
},
severity: health.SeverityError,
failingSections: []string{
healthcheck.SectionDERP,
healthcheck.SectionAccessURL,
healthcheck.SectionWebsocket,
healthcheck.SectionDatabase,
healthcheck.SectionWorkspaceProxy,
failingSections: []codersdk.HealthSection{
codersdk.HealthSectionDERP,
codersdk.HealthSectionAccessURL,
codersdk.HealthSectionWebsocket,
codersdk.HealthSectionDatabase,
codersdk.HealthSectionWorkspaceProxy,
},
}} {
c := c

View File

@ -8,12 +8,31 @@ import (
"golang.org/x/xerrors"
)
type HealthSection string
// If you add another const below, make sure to add it to HealthSections!
const (
HealthSectionDERP HealthSection = "DERP"
HealthSectionAccessURL HealthSection = "AccessURL"
HealthSectionWebsocket HealthSection = "Websocket"
HealthSectionDatabase HealthSection = "Database"
HealthSectionWorkspaceProxy HealthSection = "WorkspaceProxy"
)
var HealthSections = []HealthSection{
HealthSectionDERP,
HealthSectionAccessURL,
HealthSectionWebsocket,
HealthSectionDatabase,
HealthSectionWorkspaceProxy,
}
type HealthSettings struct {
DismissedHealthchecks []string `json:"dismissed_healthchecks"`
DismissedHealthchecks []HealthSection `json:"dismissed_healthchecks"`
}
type UpdateHealthSettings struct {
DismissedHealthchecks []string `json:"dismissed_healthchecks"`
DismissedHealthchecks []HealthSection `json:"dismissed_healthchecks"`
}
func (c *Client) HealthSettings(ctx context.Context) (HealthSettings, error) {

8
docs/api/debug.md generated
View File

@ -280,7 +280,7 @@ curl -X GET http://coder-server:8080/api/v2/debug/health \
}
]
},
"failing_sections": ["string"],
"failing_sections": ["DERP"],
"healthy": true,
"severity": "ok",
"time": "string",
@ -362,7 +362,7 @@ curl -X GET http://coder-server:8080/api/v2/debug/health/settings \
```json
{
"dismissed_healthchecks": ["string"]
"dismissed_healthchecks": ["DERP"]
}
```
@ -392,7 +392,7 @@ curl -X PUT http://coder-server:8080/api/v2/debug/health/settings \
```json
{
"dismissed_healthchecks": ["string"]
"dismissed_healthchecks": ["DERP"]
}
```
@ -408,7 +408,7 @@ curl -X PUT http://coder-server:8080/api/v2/debug/health/settings \
```json
{
"dismissed_healthchecks": ["string"]
"dismissed_healthchecks": ["DERP"]
}
```

38
docs/api/schemas.md generated
View File

@ -3170,19 +3170,37 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
| `user` |
| `oidc` |
## codersdk.HealthSection
```json
"DERP"
```
### Properties
#### Enumerated Values
| Value |
| ---------------- |
| `DERP` |
| `AccessURL` |
| `Websocket` |
| `Database` |
| `WorkspaceProxy` |
## codersdk.HealthSettings
```json
{
"dismissed_healthchecks": ["string"]
"dismissed_healthchecks": ["DERP"]
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
| ------------------------ | --------------- | -------- | ------------ | ----------- |
| `dismissed_healthchecks` | array of string | false | | |
| Name | Type | Required | Restrictions | Description |
| ------------------------ | --------------------------------------------------------- | -------- | ------------ | ----------- |
| `dismissed_healthchecks` | array of [codersdk.HealthSection](#codersdkhealthsection) | false | | |
## codersdk.Healthcheck
@ -5182,15 +5200,15 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
```json
{
"dismissed_healthchecks": ["string"]
"dismissed_healthchecks": ["DERP"]
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
| ------------------------ | --------------- | -------- | ------------ | ----------- |
| `dismissed_healthchecks` | array of string | false | | |
| Name | Type | Required | Restrictions | Description |
| ------------------------ | --------------------------------------------------------- | -------- | ------------ | ----------- |
| `dismissed_healthchecks` | array of [codersdk.HealthSection](#codersdkhealthsection) | false | | |
## codersdk.UpdateRoles
@ -7952,7 +7970,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
}
]
},
"failing_sections": ["string"],
"failing_sections": ["DERP"],
"healthy": true,
"severity": "ok",
"time": "string",
@ -8015,7 +8033,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
| `coder_version` | string | false | | The Coder version of the server that the report was generated on. |
| `database` | [healthcheck.DatabaseReport](#healthcheckdatabasereport) | false | | |
| `derp` | [derphealth.Report](#derphealthreport) | false | | |
| `failing_sections` | array of string | false | | Failing sections is a list of sections that have failed their healthcheck. |
| `failing_sections` | array of [codersdk.HealthSection](#codersdkhealthsection) | 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. Deprecated: use `Severity` instead |
| `severity` | [health.Severity](#healthseverity) | false | | Severity indicates the status of Coder health. |
| `time` | string | false | | Time is the time the report was generated at. |

View File

@ -875,6 +875,8 @@ func (g *Generator) typescriptType(ty types.Type) (TypescriptType, error) {
return TypescriptType{ValueType: "HealthMessage"}, nil
case "github.com/coder/coder/v2/coderd/healthcheck/health.Severity":
return TypescriptType{ValueType: "HealthSeverity"}, nil
case "github.com/coder/coder/v2/codersdk.HealthSection":
return TypescriptType{ValueType: "HealthSection"}, nil
}
// Some hard codes are a bit trickier.

View File

@ -544,7 +544,7 @@ export interface Group {
// From codersdk/health.go
export interface HealthSettings {
readonly dismissed_healthchecks: string[];
readonly dismissed_healthchecks: HealthSection[];
}
// From codersdk/workspaceapps.go
@ -1164,7 +1164,7 @@ export interface UpdateCheckResponse {
// From codersdk/health.go
export interface UpdateHealthSettings {
readonly dismissed_healthchecks: string[];
readonly dismissed_healthchecks: HealthSection[];
}
// From codersdk/users.go
@ -1795,6 +1795,21 @@ export const FeatureNames: FeatureName[] = [
export type GroupSource = "oidc" | "user";
export const GroupSources: GroupSource[] = ["oidc", "user"];
// From codersdk/health.go
export type HealthSection =
| "AccessURL"
| "DERP"
| "Database"
| "Websocket"
| "WorkspaceProxy";
export const HealthSections: HealthSection[] = [
"AccessURL",
"DERP",
"Database",
"Websocket",
"WorkspaceProxy",
];
// From codersdk/insights.go
export type InsightsReportInterval = "day" | "week";
export const InsightsReportIntervals: InsightsReportInterval[] = [
@ -2128,7 +2143,7 @@ export interface HealthcheckReport {
readonly time: string;
readonly healthy: boolean;
readonly severity: HealthSeverity;
readonly failing_sections: string[];
readonly failing_sections: HealthSection[];
readonly derp: DerphealthReport;
readonly access_url: HealthcheckAccessURLReport;
readonly websocket: HealthcheckWebsocketReport;