package healthcheck import ( "context" "io" "net/http" "net/url" "time" "github.com/coder/coder/v2/coderd/healthcheck/health" "github.com/coder/coder/v2/codersdk/healthsdk" ) type AccessURLReport healthsdk.AccessURLReport type AccessURLReportOptions struct { AccessURL *url.URL Client *http.Client Dismissed bool } func (r *AccessURLReport) Run(ctx context.Context, opts *AccessURLReportOptions) { ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() r.Severity = health.SeverityOK r.Warnings = []health.Message{} r.Dismissed = opts.Dismissed if opts.AccessURL == nil { r.Error = health.Errorf(health.CodeAccessURLNotSet, "Access URL not set") r.Severity = health.SeverityError return } r.AccessURL = opts.AccessURL.String() if opts.Client == nil { opts.Client = http.DefaultClient } accessURL, err := opts.AccessURL.Parse("/healthz") if err != nil { r.Error = health.Errorf(health.CodeAccessURLInvalid, "parse healthz endpoint: %s", err) r.Severity = health.SeverityError return } req, err := http.NewRequestWithContext(ctx, "GET", accessURL.String(), nil) if err != nil { r.Error = health.Errorf(health.CodeAccessURLFetch, "create healthz request: %s", err) r.Severity = health.SeverityError return } res, err := opts.Client.Do(req) if err != nil { r.Error = health.Errorf(health.CodeAccessURLFetch, "get healthz endpoint: %s", err) r.Severity = health.SeverityError return } defer res.Body.Close() body, err := io.ReadAll(res.Body) if err != nil { r.Error = health.Errorf(health.CodeAccessURLFetch, "read healthz response: %s", err) r.Severity = health.SeverityError return } r.Reachable = true r.Healthy = res.StatusCode == http.StatusOK r.StatusCode = res.StatusCode if res.StatusCode != http.StatusOK { r.Severity = health.SeverityWarning r.Warnings = append(r.Warnings, health.Messagef(health.CodeAccessURLNotOK, "/healthz did not return 200 OK")) } r.HealthzResponse = string(body) }