diff --git a/api/openapi.yaml b/api/openapi.yaml index 7d5f977..6249f04 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -170,6 +170,28 @@ paths: description: 'Bad request' 404: description: 'Resource not found' + '/api/jobs/import/': + post: + operationId: 'importJob' + summary: 'Imports a job and its metric data' + requestBody: + required: true + content: + 'application/json': + schema: + type: object + properties: + meta: + $ref: https://raw.githubusercontent.com/ClusterCockpit/cc-specifications/master/schema/json/job-meta.schema.json + data: + $ref: https://raw.githubusercontent.com/ClusterCockpit/cc-specifications/master/schema/json/job-data.schema.json + responses: + 200: + description: 'Import successful' + 400: + description: 'Bad request' + 422: + description: 'Unprocessable Entity' components: schemas: Tag: diff --git a/api/rest.go b/api/rest.go index 8f50c8c..1667caf 100644 --- a/api/rest.go +++ b/api/rest.go @@ -40,6 +40,7 @@ func (api *RestApi) MountRoutes(r *mux.Router) { r.HandleFunc("/jobs/start_job/", api.startJob).Methods(http.MethodPost, http.MethodPut) r.HandleFunc("/jobs/stop_job/", api.stopJob).Methods(http.MethodPost, http.MethodPut) r.HandleFunc("/jobs/stop_job/{id}", api.stopJob).Methods(http.MethodPost, http.MethodPut) + r.HandleFunc("/jobs/import/", api.importJob).Methods(http.MethodPost, http.MethodPut) r.HandleFunc("/jobs/", api.getJobs).Methods(http.MethodGet) // r.HandleFunc("/jobs/{id}", api.getJob).Methods(http.MethodGet) @@ -399,6 +400,29 @@ func (api *RestApi) stopJob(rw http.ResponseWriter, r *http.Request) { }() } +func (api *RestApi) importJob(rw http.ResponseWriter, r *http.Request) { + if user := auth.GetUser(r.Context()); user != nil && !user.HasRole(auth.RoleApi) { + handleError(fmt.Errorf("missing role: %#v", auth.RoleApi), http.StatusForbidden, rw) + return + } + + var body struct { + Meta *schema.JobMeta `json:"meta"` + Data *schema.JobData `json:"data"` + } + if err := decode(r.Body, &body); err != nil { + handleError(fmt.Errorf("import failed: %s", err.Error()), http.StatusBadRequest, rw) + return + } + + if err := api.JobRepository.ImportJob(body.Meta, body.Data); err != nil { + handleError(fmt.Errorf("import failed: %s", err.Error()), http.StatusUnprocessableEntity, rw) + return + } + + rw.Write([]byte(`{ "status": "OK" }`)) +} + func (api *RestApi) getJobMetrics(rw http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] metrics := r.URL.Query()["metric"]