aboutsummaryrefslogtreecommitdiffstats
path: root/syz-cluster/controller/api.go
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2025-02-13 13:59:19 +0100
committerAleksandr Nogikh <nogikh@google.com>2025-02-14 13:40:12 +0000
commiteaf86f3f4dc8a7190abf09fe840e20bcf83709d8 (patch)
treec28d030a8923833ffc39005b1a57946cd48fea62 /syz-cluster/controller/api.go
parent59c86b9e1c7a0f91fbb1b680676f33b4cc7bf137 (diff)
syz-cluster/controller: move the API server to pkg/controller
This will facilitate its reuse in tests.
Diffstat (limited to 'syz-cluster/controller/api.go')
-rw-r--r--syz-cluster/controller/api.go198
1 files changed, 0 insertions, 198 deletions
diff --git a/syz-cluster/controller/api.go b/syz-cluster/controller/api.go
deleted file mode 100644
index cddaaf2e2..000000000
--- a/syz-cluster/controller/api.go
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2024 syzkaller project authors. All rights reserved.
-// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
-
-// nolint: dupl // The methods look similar, but extracting the common parts will only make the code worse.
-package main
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "net/http"
-
- "github.com/google/syzkaller/syz-cluster/pkg/api"
- "github.com/google/syzkaller/syz-cluster/pkg/app"
- "github.com/google/syzkaller/syz-cluster/pkg/service"
-)
-
-type ControllerAPI struct {
- seriesService *service.SeriesService
- sessionService *service.SessionService
- buildService *service.BuildService
- testService *service.SessionTestService
- findingService *service.FindingService
-}
-
-func NewControllerAPI(env *app.AppEnvironment) *ControllerAPI {
- return &ControllerAPI{
- seriesService: service.NewSeriesService(env),
- sessionService: service.NewSessionService(env),
- buildService: service.NewBuildService(env),
- testService: service.NewSessionTestService(env),
- findingService: service.NewFindingService(env),
- }
-}
-
-func (c ControllerAPI) Mux() *http.ServeMux {
- mux := http.NewServeMux()
- mux.HandleFunc("/sessions/{session_id}/series", c.getSessionSeries)
- mux.HandleFunc("/sessions/{session_id}/skip", c.skipSession)
- mux.HandleFunc("/sessions/upload", c.uploadSession)
- mux.HandleFunc("/series/{series_id}", c.getSeries)
- mux.HandleFunc("/builds/last", c.getLastBuild)
- mux.HandleFunc("/builds/upload", c.uploadBuild)
- mux.HandleFunc("/tests/upload", c.uploadTest)
- mux.HandleFunc("/findings/upload", c.uploadFinding)
- mux.HandleFunc("/series/upload", c.uploadSeries)
- return mux
-}
-
-func (c ControllerAPI) getSessionSeries(w http.ResponseWriter, r *http.Request) {
- resp, err := c.seriesService.GetSessionSeries(r.Context(), r.PathValue("session_id"))
- if err == service.ErrSeriesNotFound || err == service.ErrSessionNotFound {
- http.Error(w, fmt.Sprint(err), http.StatusNotFound)
- return
- } else if err != nil {
- http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
- return
- }
- reply(w, resp)
-}
-
-func (c ControllerAPI) skipSession(w http.ResponseWriter, r *http.Request) {
- req := parseBody[api.SkipRequest](w, r)
- if req == nil {
- return
- }
- err := c.sessionService.SkipSession(r.Context(), r.PathValue("session_id"), req)
- if errors.Is(err, service.ErrSessionNotFound) {
- http.Error(w, fmt.Sprint(err), http.StatusNotFound)
- return
- } else if err != nil {
- http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
- return
- }
- reply[interface{}](w, nil)
-}
-
-func (c ControllerAPI) getSeries(w http.ResponseWriter, r *http.Request) {
- resp, err := c.seriesService.GetSeries(r.Context(), r.PathValue("series_id"))
- if errors.Is(err, service.ErrSeriesNotFound) {
- http.Error(w, fmt.Sprint(err), http.StatusNotFound)
- return
- } else if err != nil {
- http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
- return
- }
- reply(w, resp)
-}
-
-func (c ControllerAPI) uploadBuild(w http.ResponseWriter, r *http.Request) {
- req := parseBody[api.UploadBuildReq](w, r)
- if req == nil {
- return
- }
- resp, err := c.buildService.Upload(r.Context(), req)
- if err != nil {
- // TODO: sometimes it's not StatusInternalServerError.
- http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
- return
- }
- reply(w, resp)
-}
-
-func (c ControllerAPI) uploadTest(w http.ResponseWriter, r *http.Request) {
- req := parseBody[api.TestResult](w, r)
- if req == nil {
- return
- }
- // TODO: add parameters validation (and also of the Log size).
- err := c.testService.Save(r.Context(), req)
- if err != nil {
- http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
- return
- }
- reply[interface{}](w, nil)
-}
-
-func (c ControllerAPI) uploadFinding(w http.ResponseWriter, r *http.Request) {
- req := parseBody[api.Finding](w, r)
- if req == nil {
- return
- }
- // TODO: add parameters validation.
- err := c.findingService.Save(r.Context(), req)
- if err != nil {
- http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
- return
- }
- reply[interface{}](w, nil)
-}
-
-func (c ControllerAPI) getLastBuild(w http.ResponseWriter, r *http.Request) {
- req := parseBody[api.LastBuildReq](w, r)
- if req == nil {
- return
- }
- resp, err := c.buildService.LastBuild(r.Context(), req)
- if err != nil {
- http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
- return
- }
- reply[*api.Build](w, resp)
-}
-
-func (c ControllerAPI) uploadSeries(w http.ResponseWriter, r *http.Request) {
- req := parseBody[api.Series](w, r)
- if req == nil {
- return
- }
- resp, err := c.seriesService.UploadSeries(r.Context(), req)
- if err != nil {
- http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
- return
- }
- reply[*api.UploadSeriesResp](w, resp)
-}
-
-func (c ControllerAPI) uploadSession(w http.ResponseWriter, r *http.Request) {
- req := parseBody[api.NewSession](w, r)
- if req == nil {
- return
- }
- resp, err := c.sessionService.UploadSession(r.Context(), req)
- if err != nil {
- http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
- return
- }
- reply[*api.UploadSessionResp](w, resp)
-}
-
-func reply[T any](w http.ResponseWriter, resp T) {
- w.Header().Set("Content-Type", "application/json")
- err := json.NewEncoder(w).Encode(resp)
- if err != nil {
- http.Error(w, "failed to serialize the response", http.StatusInternalServerError)
- return
- }
-}
-
-func parseBody[T any](w http.ResponseWriter, r *http.Request) *T {
- if r.Method != http.MethodPost {
- http.Error(w, "must be called via POST", http.StatusMethodNotAllowed)
- return nil
- }
- body, err := io.ReadAll(r.Body)
- if err != nil {
- http.Error(w, "failed to read body", http.StatusBadRequest)
- return nil
- }
- var data T
- err = json.Unmarshal(body, &data)
- if err != nil {
- http.Error(w, "invalid body", http.StatusBadRequest)
- return nil
- }
- return &data
-}