From c1217ec842339603df4d0255d06c51e0bf3b1526 Mon Sep 17 00:00:00 2001 From: lucamrgs <39555424+lucamrgs@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:37:26 +0200 Subject: [PATCH] fixed via add forgotten cache result parsing for GET /reporter/ call (#196) --- models/api/reporter.go | 24 ++-------------- models/cache/cache.go | 13 +++++++++ routes/reporter/reporter_api.go | 16 ++++++++++- routes/reporter/reporter_parser.go | 11 ++------ .../routes/reporter_api/reporter_api_test.go | 28 +++++++++++-------- 5 files changed, 51 insertions(+), 41 deletions(-) diff --git a/models/api/reporter.go b/models/api/reporter.go index 76806371..b69e4807 100644 --- a/models/api/reporter.go +++ b/models/api/reporter.go @@ -60,29 +60,11 @@ type StepExecutionReport struct { // the execution ID for the invoked playbook } -func CacheStatusEnum2String(status cache_model.Status) (string, error) { - switch status { - case cache_model.SuccessfullyExecuted: - return SuccessfullyExecuted, nil - case cache_model.Failed: - return Failed, nil - case cache_model.Ongoing: - return Ongoing, nil - case cache_model.ServerSideError: - return ServerSideError, nil - case cache_model.ClientSideError: - return ClientSideError, nil - case cache_model.TimeoutError: - return TimeoutError, nil - case cache_model.ExceptionConditionError: - return ExceptionConditionError, nil - case cache_model.AwaitUserInput: - return AwaitUserInput, nil - default: - return "", errors.New("unable to read execution information status") - } +func CacheStatusEnum2String(status cache_model.Status) string { + return status.String() } +// Level must be either "step" or "playbook" func GetCacheStatusText(status string, level string) (string, error) { if level != ReportLevelPlaybook && level != ReportLevelStep { return "", errors.New("invalid reporting level provided. use either 'playbook' or 'step'") diff --git a/models/cache/cache.go b/models/cache/cache.go index a678bfbc..de03e67f 100644 --- a/models/cache/cache.go +++ b/models/cache/cache.go @@ -20,6 +20,19 @@ const ( AwaitUserInput ) +func (status Status) String() string { + return [...]string{ + "successfully_executed", + "failed", + "ongoing", + "server_side_error", + "client_side_error", + "timeout_error", + "exception_condition_error", + "await_user_input", + }[status] +} + type ExecutionEntry struct { ExecutionId uuid.UUID PlaybookId string diff --git a/routes/reporter/reporter_api.go b/routes/reporter/reporter_api.go index ea2da0d7..da813909 100644 --- a/routes/reporter/reporter_api.go +++ b/routes/reporter/reporter_api.go @@ -3,6 +3,7 @@ package reporter import ( "net/http" "soarca/internal/controller/informer" + "soarca/models/api" "reflect" "soarca/routes/error" @@ -49,7 +50,20 @@ func (executionInformer *executionInformer) getExecutions(g *gin.Context) { error.SendErrorResponse(g, http.StatusInternalServerError, "Could not get executions from informer", "GET /reporter/", "") return } - g.JSON(http.StatusOK, executions) + + executionsParsed := []api.PlaybookExecutionReport{} + for _, executionEntry := range executions { + executionEntryParsed, err := parseCachePlaybookEntry(executionEntry) + if err != nil { + log.Debug("Could not parse entry to reporter result model") + log.Error(err) + error.SendErrorResponse(g, http.StatusInternalServerError, "Could not parse execution report", "GET /reporter/", "") + return + } + executionsParsed = append(executionsParsed, executionEntryParsed) + } + + g.JSON(http.StatusOK, executionsParsed) } // getExecutionReport GET handler for obtaining the information about an execution. diff --git a/routes/reporter/reporter_parser.go b/routes/reporter/reporter_parser.go index 4d89da43..c494dc3f 100644 --- a/routes/reporter/reporter_parser.go +++ b/routes/reporter/reporter_parser.go @@ -8,10 +8,7 @@ import ( const defaultRequestInterval int = 5 func parseCachePlaybookEntry(cacheEntry cache_model.ExecutionEntry) (api_model.PlaybookExecutionReport, error) { - playbookStatus, err := api_model.CacheStatusEnum2String(cacheEntry.Status) - if err != nil { - return api_model.PlaybookExecutionReport{}, err - } + playbookStatus := api_model.CacheStatusEnum2String(cacheEntry.Status) playbookStatusText, err := api_model.GetCacheStatusText(playbookStatus, api_model.ReportLevelPlaybook) if err != nil { @@ -44,10 +41,8 @@ func parseCacheStepEntries(cacheStepEntries map[string]cache_model.StepResult) ( parsedEntries := map[string]api_model.StepExecutionReport{} for stepId, stepEntry := range cacheStepEntries { - stepStatus, err := api_model.CacheStatusEnum2String(stepEntry.Status) - if err != nil { - return map[string]api_model.StepExecutionReport{}, err - } + stepStatus := api_model.CacheStatusEnum2String(stepEntry.Status) + stepStatusText, err := api_model.GetCacheStatusText(stepStatus, api_model.ReportLevelStep) if err != nil { return map[string]api_model.StepExecutionReport{}, err diff --git a/test/unittest/routes/reporter_api/reporter_api_test.go b/test/unittest/routes/reporter_api/reporter_api_test.go index de48c76f..d9315a74 100644 --- a/test/unittest/routes/reporter_api/reporter_api_test.go +++ b/test/unittest/routes/reporter_api/reporter_api_test.go @@ -99,19 +99,24 @@ func TestGetExecutions(t *testing.T) { expectedStarted, _ := time.Parse(layout, str) expectedEnded, _ := time.Parse(layout, "0001-01-01T00:00:00Z") - expectedExecutions := []cache_model.ExecutionEntry{} + expectedStatus := cache_model.Ongoing.String() + expectedStatusText, _ := api_model.GetCacheStatusText(expectedStatus, "playbook") + + expectedExecutionsReport := []api_model.PlaybookExecutionReport{} for _, executionId := range executionIds { t.Log(executionId) - entry := cache_model.ExecutionEntry{ - ExecutionId: executionId, - PlaybookId: "test", - Started: expectedStarted, - Ended: expectedEnded, - StepResults: map[string]cache_model.StepResult{}, - Error: nil, - Status: cache_model.Ongoing, + entry := api_model.PlaybookExecutionReport{ + Type: "execution_status", + ExecutionId: executionId.String(), + PlaybookId: "test", + Started: expectedStarted, + Ended: expectedEnded, + Status: expectedStatus, + StatusText: expectedStatusText, + StepResults: map[string]api_model.StepExecutionReport{}, + RequestInterval: 5, } - expectedExecutions = append(expectedExecutions, entry) + expectedExecutionsReport = append(expectedExecutionsReport, entry) } err := cacheReporter.ReportWorkflowStart(executionId0, playbook) @@ -140,12 +145,13 @@ func TestGetExecutions(t *testing.T) { } app.ServeHTTP(recorder, request) - expectedByte, err := json.Marshal(expectedExecutions) + expectedByte, err := json.Marshal(expectedExecutionsReport) if err != nil { t.Log("failed to decode expected struct to json") t.Fail() } expectedString := string(expectedByte) + assert.Equal(t, expectedString, recorder.Body.String()) assert.Equal(t, 200, recorder.Code)