Files
QSfera/Server/tests/ocwrapper/wrapper/handlers/handler.go
Курнат Андрей 2315f25754 Initial QSfera import
2026-06-07 10:20:04 +03:00

217 lines
4.7 KiB
Go

package handlers
import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"ocwrapper/common"
"ocwrapper/qsfera"
"os"
)
type BasicResponse struct {
Status string `json:"status"`
Message string `json:"message"`
}
type CommandResponse struct {
*BasicResponse
ExitCode int `json:"exitCode"`
}
func parseJsonBody(reqBody io.ReadCloser) (map[string]any, error) {
body, _ := io.ReadAll(reqBody)
if len(body) == 0 || !json.Valid(body) {
return nil, errors.New("invalid json data")
}
var bodyMap map[string]any
json.Unmarshal(body, &bodyMap)
return bodyMap, nil
}
func sendResponse(res http.ResponseWriter, statusCode int, message string) {
res.Header().Set("Content-Type", "application/json")
res.WriteHeader(statusCode)
var status string
if statusCode == http.StatusOK {
status = "OK"
} else {
status = "ERROR"
}
resBody := BasicResponse{
Status: status,
Message: message,
}
jsonResponse, _ := json.Marshal(resBody)
res.Write(jsonResponse)
}
func sendCmdResponse(res http.ResponseWriter, exitCode int, message string) {
resBody := CommandResponse{
BasicResponse: &BasicResponse{
Message: message,
},
ExitCode: exitCode,
}
if exitCode == 0 {
resBody.BasicResponse.Status = "OK"
} else {
resBody.BasicResponse.Status = "ERROR"
}
res.WriteHeader(http.StatusOK)
res.Header().Set("Content-Type", "application/json")
jsonResponse, _ := json.Marshal(resBody)
res.Write(jsonResponse)
}
func SetEnvHandler(res http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPut {
sendResponse(res, http.StatusMethodNotAllowed, "")
return
}
envBody, err := parseJsonBody(req.Body)
if err != nil {
sendResponse(res, http.StatusMethodNotAllowed, "Invalid json body")
return
}
var envMap []string
for key, value := range envBody {
envMap = append(envMap, fmt.Sprintf("%s=%v", key, value))
}
qsfera.EnvConfigs = append(qsfera.EnvConfigs, envMap...)
var message string
success, _ := qsfera.Restart(qsfera.EnvConfigs)
if success {
message = "qsfera configured successfully"
sendResponse(res, http.StatusOK, message)
return
}
message = "Failed to restart qsfera with new configuration"
sendResponse(res, http.StatusInternalServerError, message)
}
func RollbackHandler(res http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodDelete {
sendResponse(res, http.StatusMethodNotAllowed, "")
return
}
var message string
qsfera.EnvConfigs = []string{}
success, _ := qsfera.Restart(os.Environ())
if success {
message = "qsfera configuration rolled back successfully"
sendResponse(res, http.StatusOK, message)
return
}
message = "Failed to restart qsfera with initial configuration"
sendResponse(res, http.StatusInternalServerError, message)
}
func StopQsferaHandler(res http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
sendResponse(res, http.StatusMethodNotAllowed, "")
return
}
success, message := qsfera.Stop()
if success {
sendResponse(res, http.StatusOK, message)
return
}
sendResponse(res, http.StatusInternalServerError, message)
}
func StartQsferaHandler(res http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
sendResponse(res, http.StatusMethodNotAllowed, "")
return
}
if qsfera.IsQsferaRunning() {
sendResponse(res, http.StatusConflict, "qsfera server is already running")
return
}
common.Wg.Add(1)
go qsfera.Start(nil)
success, message := qsfera.WaitForConnection()
if success {
sendResponse(res, http.StatusOK, message)
return
}
sendResponse(res, http.StatusInternalServerError, message)
}
func CommandHandler(res http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
sendResponse(res, http.StatusMethodNotAllowed, "")
return
}
if req.Body == nil {
sendResponse(res, http.StatusBadRequest, "Body is missing")
return
}
body, err := parseJsonBody(req.Body)
if err != nil {
sendResponse(res, http.StatusBadRequest, "Invalid json body")
return
}
if _, ok := body["command"]; !ok {
sendResponse(res, http.StatusBadRequest, "Command is missing")
return
}
command := body["command"].(string)
stdIn := []string{}
if _, ok := body["inputs"]; ok {
if inputs, ok := body["inputs"].([]interface{}); ok {
for _, input := range inputs {
if _, ok := input.(string); ok {
stdIn = append(stdIn, input.(string))
} else {
sendResponse(res, http.StatusBadRequest, "Invalid input data. Expected string")
return
}
}
}
}
raw := false
if r, ok := body["raw"].(bool); ok {
raw = r
}
var exitCode int
var output string
if raw {
exitCode, output = qsfera.RunRawCommand(command, stdIn)
} else {
exitCode, output = qsfera.RunCommand(command, stdIn)
}
sendCmdResponse(res, exitCode, output)
}