From 6e2ccefa51665fc6e8c3e0ca92b5f0bc8af697de Mon Sep 17 00:00:00 2001 From: Saw-jan Date: Fri, 5 Jul 2024 12:54:42 +0545 Subject: [PATCH] feat: add command and stop endpoints --- tests/ociswrapper/ocis/ocis.go | 45 +++++--- tests/ociswrapper/wrapper/handlers/handler.go | 106 ++++++++++++++++-- tests/ociswrapper/wrapper/wrapper.go | 2 + 3 files changed, 123 insertions(+), 30 deletions(-) diff --git a/tests/ociswrapper/ocis/ocis.go b/tests/ociswrapper/ocis/ocis.go index 60e0382d9..84d8d309f 100644 --- a/tests/ociswrapper/ocis/ocis.go +++ b/tests/ociswrapper/ocis/ocis.go @@ -111,7 +111,7 @@ func Start(envMap map[string]any) { close(outChan) } -func Stop() { +func Stop() (bool, string) { log.Println("Stopping oCIS server...") stopSignal = true @@ -119,13 +119,25 @@ func Stop() { if err != nil { if !strings.HasSuffix(err.Error(), "process already finished") { log.Fatalln(err) + } else { + return true, "oCIS server is already stopped" } } cmd.Process.Wait() - waitUntilCompleteShutdown() + return waitUntilCompleteShutdown() } -func listAllServices(startTime time.Time, timeout time.Duration) { +func Restart(envMap map[string]any) (bool, string) { + Stop() + + log.Println("Restarting oCIS server...") + common.Wg.Add(1) + go Start(envMap) + + return WaitForConnection() +} + +func waitAllServices(startTime time.Time, timeout time.Duration) { timeoutS := timeout * time.Second c := exec.Command(config.Get("bin"), "list") @@ -133,15 +145,15 @@ func listAllServices(startTime time.Time, timeout time.Duration) { if err != nil { if time.Since(startTime) <= timeoutS { time.Sleep(500 * time.Millisecond) - listAllServices(startTime, timeout) + waitAllServices(startTime, timeout) } return } log.Println("All services are up") } -func WaitForConnection() bool { - listAllServices(time.Now(), 30) +func WaitForConnection() (bool, string) { + waitAllServices(time.Now(), 30) transport := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, @@ -168,7 +180,7 @@ func WaitForConnection() bool { select { case <-timeout: log.Println(fmt.Sprintf("%v seconds timeout waiting for oCIS server", int64(timeoutValue.Seconds()))) - return false + return false, "Timeout waiting for oCIS server to start" default: req.Header.Set("X-Request-ID", "ociswrapper-"+strconv.Itoa(int(time.Now().UnixMilli()))) @@ -180,12 +192,12 @@ func WaitForConnection() bool { } log.Println("oCIS server is ready to accept requests") - return true + return true, "oCIS server is up and running" } } } -func waitUntilCompleteShutdown() { +func waitUntilCompleteShutdown() (bool, string) { timeout := 30 * time.Second startTime := time.Now() @@ -200,17 +212,14 @@ func waitUntilCompleteShutdown() { if time.Since(startTime) >= timeout { log.Println(fmt.Sprintf("Unable to kill oCIS server after %v seconds", int64(timeout.Seconds()))) - break + return false, "Timeout waiting for oCIS server to stop" } } + return true, "oCIS server stopped successfully" } -func Restart(envMap map[string]any) bool { - Stop() - - log.Println("Restarting oCIS server...") - common.Wg.Add(1) - go Start(envMap) - - return WaitForConnection() +func RunCommand(command string) (int, string) { + c := exec.Command(config.Get("bin"), command) + out, _ := c.CombinedOutput() + return c.ProcessState.ExitCode(), string(out) } diff --git a/tests/ociswrapper/wrapper/handlers/handler.go b/tests/ociswrapper/wrapper/handlers/handler.go index 09e4c64e0..2531612af 100644 --- a/tests/ociswrapper/wrapper/handlers/handler.go +++ b/tests/ociswrapper/wrapper/handlers/handler.go @@ -8,11 +8,20 @@ import ( "ociswrapper/ocis" ) +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") + return nil, errors.New("invalid json data") } var bodyMap map[string]any @@ -21,17 +30,39 @@ func parseJsonBody(reqBody io.ReadCloser) (map[string]any, error) { return bodyMap, nil } -func sendResponse(res http.ResponseWriter, ocisStatus bool) { - resBody := make(map[string]string) +func sendResponse(res http.ResponseWriter, success bool, message string) { + res.Header().Set("Content-Type", "application/json") - if ocisStatus { + var status string + if success { + status = "OK" res.WriteHeader(http.StatusOK) - resBody["status"] = "OK" - resBody["message"] = "oCIS server is running" } else { + status = "ERROR" res.WriteHeader(http.StatusInternalServerError) - resBody["status"] = "ERROR" - resBody["message"] = "Unable to start oCIS server" + } + + resBody := BasicResponse{ + Status: status, + Message: message, + } + + jsonResponse, _ := json.Marshal(resBody) + res.Write(jsonResponse) +} + +func sendCmdResponse(res http.ResponseWriter, exitCode int, message string) { + var resBody CommandResponse + + res.WriteHeader(http.StatusOK) + if exitCode == 0 { + resBody.Status = "OK" + resBody.ExitCode = exitCode + resBody.Message = message + } else { + resBody.Status = "ERROR" + resBody.ExitCode = exitCode + resBody.Message = message } res.Header().Set("Content-Type", "application/json") @@ -51,9 +82,16 @@ func SetEnvHandler(res http.ResponseWriter, req *http.Request) { return } - ocisStatus := ocis.Restart(environments) + var message string - sendResponse(res, ocisStatus) + success, _ := ocis.Restart(environments) + if success { + message = "oCIS configured successfully" + } else { + message = "Failed to restart oCIS with new configuration" + } + + sendResponse(res, success, message) } func RollbackHandler(res http.ResponseWriter, req *http.Request) { @@ -62,7 +100,51 @@ func RollbackHandler(res http.ResponseWriter, req *http.Request) { return } - ocisStatus := ocis.Restart(nil) + var message string - sendResponse(res, ocisStatus) + success, _ := ocis.Restart(nil) + if success { + message = "oCIS configuration rolled back successfully" + } else { + message = "Failed to restart oCIS with initial configuration" + } + + sendResponse(res, success, message) +} + +func StopOcisHandler(res http.ResponseWriter, req *http.Request) { + if req.Method != http.MethodDelete { + http.Error(res, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + success, message := ocis.Stop() + sendResponse(res, success, message) +} + +func CommandHandler(res http.ResponseWriter, req *http.Request) { + if req.Method != http.MethodPost { + http.Error(res, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + body, err := parseJsonBody(req.Body) + if err != nil { + http.Error(res, "Bad request", http.StatusBadRequest) + return + } + if body["command"] == nil { + http.Error(res, "Bad request", http.StatusBadRequest) + return + } + + command, ok := body["command"].(string) + if !ok || command == "" { + http.Error(res, "Bad request", http.StatusBadRequest) + return + } + + exitCode, out := ocis.RunCommand(command) + + sendCmdResponse(res, exitCode, out) } diff --git a/tests/ociswrapper/wrapper/wrapper.go b/tests/ociswrapper/wrapper/wrapper.go index e5fc80c9a..3ecf94285 100644 --- a/tests/ociswrapper/wrapper/wrapper.go +++ b/tests/ociswrapper/wrapper/wrapper.go @@ -24,6 +24,8 @@ func Start(port string) { mux.HandleFunc("/", http.NotFound) mux.HandleFunc("/config", handlers.SetEnvHandler) mux.HandleFunc("/rollback", handlers.RollbackHandler) + mux.HandleFunc("/command", handlers.CommandHandler) + mux.HandleFunc("/stop", handlers.StopOcisHandler) httpServer.Handler = mux