diff --git a/cmd/api/api/diagnostics.go b/cmd/api/api/diagnostics.go new file mode 100644 index 00000000..4a83e80c --- /dev/null +++ b/cmd/api/api/diagnostics.go @@ -0,0 +1,175 @@ +package api + +import ( + "context" + "fmt" + "net" + "sync" + "syscall" + "time" + + "github.com/kernel/hypeman/lib/logger" + "github.com/kernel/hypeman/lib/oapi" +) + +// dnsProbeHost is the external hostname resolved during the DNS check. +// kernel.sh is owned by Kernel and answered by stable infrastructure; +// resolving it tells us the host's stub resolver and uplink DNS can answer +// real-world queries (not just localhost). +const dnsProbeHost = "kernel.sh" + +// egressProbeAddr is the TCP target used to verify outbound network reach. +// 1.1.1.1:443 is operated by Cloudflare and accepts TCP/443 from anywhere +// reachable on the public internet, so a successful dial confirms the host +// can leave its uplink without DNS dependency. +const egressProbeAddr = "1.1.1.1:443" + +// minFreeDiskBytes is the threshold below which the disk check fails. +// 5 GiB leaves headroom for image pulls, snapshots, and overlay growth on +// hosts already running close to capacity. +const minFreeDiskBytes uint64 = 5 * 1024 * 1024 * 1024 + +const probeTimeout = 3 * time.Second + +// GetDiagnostics runs synchronous host probes and returns per-check results. +func (s *ApiService) GetDiagnostics(ctx context.Context, _ oapi.GetDiagnosticsRequestObject) (oapi.GetDiagnosticsResponseObject, error) { + checks := runDiagnosticChecks(ctx, s.Config.DataDir) + + allOK := true + for _, c := range checks { + if !c.Ok { + allOK = false + break + } + } + + if !allOK { + log := logger.FromContext(ctx) + log.WarnContext(ctx, "diagnostics reported failures", "checks", checks) + } + + return oapi.GetDiagnostics200JSONResponse{ + Ok: allOK, + CheckedAt: time.Now().UTC(), + Checks: checks, + }, nil +} + +// runDiagnosticChecks runs all probes in parallel and returns results in a +// stable order so dashboards/alerts can index by position. +func runDiagnosticChecks(ctx context.Context, dataDir string) []oapi.DiagnosticCheck { + results := make([]oapi.DiagnosticCheck, 3) + var wg sync.WaitGroup + wg.Add(3) + + go func() { + defer wg.Done() + results[0] = probeDNS(ctx) + }() + go func() { + defer wg.Done() + results[1] = probeEgressTCP(ctx) + }() + go func() { + defer wg.Done() + results[2] = probeDisk(dataDir) + }() + + wg.Wait() + return results +} + +func probeDNS(ctx context.Context) oapi.DiagnosticCheck { + start := time.Now() + probeCtx, cancel := context.WithTimeout(ctx, probeTimeout) + defer cancel() + + addrs, err := net.DefaultResolver.LookupHost(probeCtx, dnsProbeHost) + dur := time.Since(start).Milliseconds() + if err != nil { + errMsg := err.Error() + return oapi.DiagnosticCheck{ + Name: "dns", + Ok: false, + DurationMs: dur, + Error: &errMsg, + } + } + if len(addrs) == 0 { + errMsg := "no addresses returned" + return oapi.DiagnosticCheck{ + Name: "dns", + Ok: false, + DurationMs: dur, + Error: &errMsg, + } + } + detail := fmt.Sprintf("%s -> %s", dnsProbeHost, addrs[0]) + return oapi.DiagnosticCheck{ + Name: "dns", + Ok: true, + DurationMs: dur, + Detail: &detail, + } +} + +func probeEgressTCP(ctx context.Context) oapi.DiagnosticCheck { + start := time.Now() + d := net.Dialer{Timeout: probeTimeout} + probeCtx, cancel := context.WithTimeout(ctx, probeTimeout) + defer cancel() + + conn, err := d.DialContext(probeCtx, "tcp", egressProbeAddr) + dur := time.Since(start).Milliseconds() + if err != nil { + errMsg := err.Error() + return oapi.DiagnosticCheck{ + Name: "egress_tcp", + Ok: false, + DurationMs: dur, + Error: &errMsg, + } + } + _ = conn.Close() + detail := egressProbeAddr + return oapi.DiagnosticCheck{ + Name: "egress_tcp", + Ok: true, + DurationMs: dur, + Detail: &detail, + } +} + +func probeDisk(dataDir string) oapi.DiagnosticCheck { + start := time.Now() + var stat syscall.Statfs_t + if err := syscall.Statfs(dataDir, &stat); err != nil { + dur := time.Since(start).Milliseconds() + errMsg := err.Error() + return oapi.DiagnosticCheck{ + Name: "disk", + Ok: false, + DurationMs: dur, + Error: &errMsg, + } + } + free := stat.Bavail * uint64(stat.Bsize) + dur := time.Since(start).Milliseconds() + detail := fmt.Sprintf("free=%d bytes path=%s", free, dataDir) + if free < minFreeDiskBytes { + errMsg := fmt.Sprintf("free disk %d below threshold %d", free, minFreeDiskBytes) + return oapi.DiagnosticCheck{ + Name: "disk", + Ok: false, + DurationMs: dur, + Error: &errMsg, + Detail: &detail, + } + } + return oapi.DiagnosticCheck{ + Name: "disk", + Ok: true, + DurationMs: dur, + Detail: &detail, + } +} diff --git a/cmd/api/api/diagnostics_test.go b/cmd/api/api/diagnostics_test.go new file mode 100644 index 00000000..15dfe16b --- /dev/null +++ b/cmd/api/api/diagnostics_test.go @@ -0,0 +1,46 @@ +package api + +import ( + "context" + "testing" + + "github.com/kernel/hypeman/lib/oapi" + "github.com/stretchr/testify/require" +) + +func TestProbeDisk(t *testing.T) { + t.Parallel() + dir := t.TempDir() + + c := probeDisk(dir) + require.Equal(t, "disk", c.Name) + require.True(t, c.Ok, "expected disk probe on a tmpdir to pass: %+v", c) + require.NotNil(t, c.Detail) +} + +func TestProbeDiskMissingPath(t *testing.T) { + t.Parallel() + + c := probeDisk("/nonexistent/path/that/should/not/resolve") + require.Equal(t, "disk", c.Name) + require.False(t, c.Ok) + require.NotNil(t, c.Error) +} + +func TestRunDiagnosticChecksReturnsAllChecks(t *testing.T) { + t.Parallel() + + checks := runDiagnosticChecks(context.Background(), t.TempDir()) + require.Len(t, checks, 3) + + names := make(map[string]oapi.DiagnosticCheck, len(checks)) + for _, c := range checks { + names[c.Name] = c + } + require.Contains(t, names, "dns") + require.Contains(t, names, "egress_tcp") + require.Contains(t, names, "disk") + + // Disk on tmpdir should always succeed. + require.True(t, names["disk"].Ok) +} diff --git a/lib/oapi/oapi.go b/lib/oapi/oapi.go index 093dd8f5..54a4f11d 100644 --- a/lib/oapi/oapi.go +++ b/lib/oapi/oapi.go @@ -637,6 +637,34 @@ type Device struct { // DeviceType Type of PCI device type DeviceType string +// DiagnosticCheck defines model for DiagnosticCheck. +type DiagnosticCheck struct { + // Detail Optional context about the result (e.g., resolved IP, free bytes). + Detail *string `json:"detail,omitempty"` + + // DurationMs How long the check took, in milliseconds. + DurationMs int64 `json:"duration_ms"` + + // Error Error message when ok is false. + Error *string `json:"error,omitempty"` + + // Name Identifier of the check (e.g., "dns", "egress_tcp", "disk"). + Name string `json:"name"` + + // Ok Whether the check passed. + Ok bool `json:"ok"` +} + +// Diagnostics defines model for Diagnostics. +type Diagnostics struct { + // CheckedAt Time the diagnostics were collected. + CheckedAt time.Time `json:"checked_at"` + Checks []DiagnosticCheck `json:"checks"` + + // Ok True iff every individual check passed. + Ok bool `json:"ok"` +} + // DiskBreakdown defines model for DiskBreakdown. type DiskBreakdown struct { // ImagesBytes Disk used by exported rootfs images @@ -1732,6 +1760,9 @@ type ClientInterface interface { // GetDevice request GetDevice(ctx context.Context, id string, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetDiagnostics request + GetDiagnostics(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + // GetHealth request GetHealth(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -2019,6 +2050,18 @@ func (c *Client) GetDevice(ctx context.Context, id string, reqEditors ...Request return c.Client.Do(req) } +func (c *Client) GetDiagnostics(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewGetDiagnosticsRequest(c.Server) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) GetHealth(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewGetHealthRequest(c.Server) if err != nil { @@ -3077,6 +3120,33 @@ func NewGetDeviceRequest(server string, id string) (*http.Request, error) { return req, nil } +// NewGetDiagnosticsRequest generates requests for GetDiagnostics +func NewGetDiagnosticsRequest(server string) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/diagnostics") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + // NewGetHealthRequest generates requests for GetHealth func NewGetHealthRequest(server string) (*http.Request, error) { var err error @@ -5052,6 +5122,9 @@ type ClientWithResponsesInterface interface { // GetDeviceWithResponse request GetDeviceWithResponse(ctx context.Context, id string, reqEditors ...RequestEditorFn) (*GetDeviceResponse, error) + // GetDiagnosticsWithResponse request + GetDiagnosticsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetDiagnosticsResponse, error) + // GetHealthWithResponse request GetHealthWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetHealthResponse, error) @@ -5450,6 +5523,29 @@ func (r GetDeviceResponse) StatusCode() int { return 0 } +type GetDiagnosticsResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *Diagnostics + JSON500 *Error +} + +// Status returns HTTPResponse.Status +func (r GetDiagnosticsResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r GetDiagnosticsResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type GetHealthResponse struct { Body []byte HTTPResponse *http.Response @@ -6582,6 +6678,15 @@ func (c *ClientWithResponses) GetDeviceWithResponse(ctx context.Context, id stri return ParseGetDeviceResponse(rsp) } +// GetDiagnosticsWithResponse request returning *GetDiagnosticsResponse +func (c *ClientWithResponses) GetDiagnosticsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetDiagnosticsResponse, error) { + rsp, err := c.GetDiagnostics(ctx, reqEditors...) + if err != nil { + return nil, err + } + return ParseGetDiagnosticsResponse(rsp) +} + // GetHealthWithResponse request returning *GetHealthResponse func (c *ClientWithResponses) GetHealthWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetHealthResponse, error) { rsp, err := c.GetHealth(ctx, reqEditors...) @@ -7493,6 +7598,39 @@ func ParseGetDeviceResponse(rsp *http.Response) (*GetDeviceResponse, error) { return response, nil } +// ParseGetDiagnosticsResponse parses an HTTP response from a GetDiagnosticsWithResponse call +func ParseGetDiagnosticsResponse(rsp *http.Response) (*GetDiagnosticsResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &GetDiagnosticsResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest Diagnostics + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest Error + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + + return response, nil +} + // ParseGetHealthResponse parses an HTTP response from a GetHealthWithResponse call func ParseGetHealthResponse(rsp *http.Response) (*GetHealthResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -9387,6 +9525,9 @@ type ServerInterface interface { // Get device details // (GET /devices/{id}) GetDevice(w http.ResponseWriter, r *http.Request, id string) + // Active host diagnostics + // (GET /diagnostics) + GetDiagnostics(w http.ResponseWriter, r *http.Request) // Health check // (GET /health) GetHealth(w http.ResponseWriter, r *http.Request) @@ -9579,6 +9720,12 @@ func (_ Unimplemented) GetDevice(w http.ResponseWriter, r *http.Request, id stri w.WriteHeader(http.StatusNotImplemented) } +// Active host diagnostics +// (GET /diagnostics) +func (_ Unimplemented) GetDiagnostics(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + // Health check // (GET /health) func (_ Unimplemented) GetHealth(w http.ResponseWriter, r *http.Request) { @@ -10132,6 +10279,26 @@ func (siw *ServerInterfaceWrapper) GetDevice(w http.ResponseWriter, r *http.Requ handler.ServeHTTP(w, r) } +// GetDiagnostics operation middleware +func (siw *ServerInterfaceWrapper) GetDiagnostics(w http.ResponseWriter, r *http.Request) { + + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetDiagnostics(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + // GetHealth operation middleware func (siw *ServerInterfaceWrapper) GetHealth(w http.ResponseWriter, r *http.Request) { @@ -11682,6 +11849,9 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/devices/{id}", wrapper.GetDevice) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/diagnostics", wrapper.GetDiagnostics) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/health", wrapper.GetHealth) }) @@ -12224,6 +12394,31 @@ func (response GetDevice500JSONResponse) VisitGetDeviceResponse(w http.ResponseW return json.NewEncoder(w).Encode(response) } +type GetDiagnosticsRequestObject struct { +} + +type GetDiagnosticsResponseObject interface { + VisitGetDiagnosticsResponse(w http.ResponseWriter) error +} + +type GetDiagnostics200JSONResponse Diagnostics + +func (response GetDiagnostics200JSONResponse) VisitGetDiagnosticsResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + + return json.NewEncoder(w).Encode(response) +} + +type GetDiagnostics500JSONResponse Error + +func (response GetDiagnostics500JSONResponse) VisitGetDiagnosticsResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + type GetHealthRequestObject struct { } @@ -14041,6 +14236,9 @@ type StrictServerInterface interface { // Get device details // (GET /devices/{id}) GetDevice(ctx context.Context, request GetDeviceRequestObject) (GetDeviceResponseObject, error) + // Active host diagnostics + // (GET /diagnostics) + GetDiagnostics(ctx context.Context, request GetDiagnosticsRequestObject) (GetDiagnosticsResponseObject, error) // Health check // (GET /health) GetHealth(ctx context.Context, request GetHealthRequestObject) (GetHealthResponseObject, error) @@ -14467,6 +14665,30 @@ func (sh *strictHandler) GetDevice(w http.ResponseWriter, r *http.Request, id st } } +// GetDiagnostics operation middleware +func (sh *strictHandler) GetDiagnostics(w http.ResponseWriter, r *http.Request) { + var request GetDiagnosticsRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetDiagnostics(ctx, request.(GetDiagnosticsRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetDiagnostics") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetDiagnosticsResponseObject); ok { + if err := validResponse.VisitGetDiagnosticsResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // GetHealth operation middleware func (sh *strictHandler) GetHealth(w http.ResponseWriter, r *http.Request) { var request GetHealthRequestObject @@ -15654,273 +15876,281 @@ func (sh *strictHandler) GetVolume(w http.ResponseWriter, r *http.Request, id st // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", + "/zcAAP//LJ0srvZ6AQA=", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/openapi.yaml b/openapi.yaml index e6446965..a8d0bd7b 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1152,7 +1152,45 @@ components: type: string enum: [ok] example: ok - + + DiagnosticCheck: + type: object + required: [name, ok, duration_ms] + properties: + name: + type: string + description: Identifier of the check (e.g., "dns", "egress_tcp", "disk"). + example: dns + ok: + type: boolean + description: Whether the check passed. + duration_ms: + type: integer + format: int64 + description: How long the check took, in milliseconds. + error: + type: string + description: Error message when ok is false. + detail: + type: string + description: Optional context about the result (e.g., resolved IP, free bytes). + + Diagnostics: + type: object + required: [ok, checked_at, checks] + properties: + ok: + type: boolean + description: True iff every individual check passed. + checked_at: + type: string + format: date-time + description: Time the diagnostics were collected. + checks: + type: array + items: + $ref: "#/components/schemas/DiagnosticCheck" + IngressMatch: type: object required: [hostname] @@ -1806,7 +1844,32 @@ paths: application/json: schema: $ref: "#/components/schemas/Health" - + + /diagnostics: + get: + summary: Active host diagnostics + description: | + Runs synchronous probes against host-local subsystems and returns the + result of each check. Intended to be polled from the control plane to + observe host-health signals (DNS, outbound network, disk) that pushed + OTEL metrics cannot surface when the host is partially unreachable. + operationId: getDiagnostics + security: + - bearerAuth: [] + responses: + 200: + description: Diagnostics result. Always 200 if the request was served; inspect `ok` and per-check fields for status. + content: + application/json: + schema: + $ref: "#/components/schemas/Diagnostics" + 500: + description: Internal server error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /resources: get: summary: Get host resource capacity and allocations