Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reporter api #137

Merged
merged 40 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
233191e
add first reporter api documentation
lucamrgs May 1, 2024
0baa488
create api reporter instantiation and links. must test
lucamrgs May 6, 2024
0c8f3b3
add model for api response
lucamrgs May 7, 2024
b2c9373
add parsing from cache entry to reporter api results
lucamrgs May 7, 2024
607dcb8
enroll soarca-level cache object in both api and reporting
lucamrgs May 7, 2024
de79172
add template report api testing
lucamrgs May 7, 2024
73467f8
rename report model to cache model
lucamrgs May 7, 2024
4b0a21a
add get executions base test
lucamrgs May 7, 2024
35ad402
add reporter api testing
lucamrgs May 7, 2024
1610440
split unittest and integration test on reporter api
lucamrgs May 7, 2024
efe5afd
trying to solve lint error cannot parse response comment
lucamrgs May 7, 2024
df5e1e2
solving lint error due to scheme specification
lucamrgs May 7, 2024
6d25758
remove schemes specification
lucamrgs May 7, 2024
9ef4e67
remove scheme from success specification
lucamrgs May 7, 2024
b650e83
add right scheme to response
lucamrgs May 7, 2024
de82654
fix lint error check in controller and recorder body bytes in tests
lucamrgs May 7, 2024
824b88c
change reporter documentation according to review
lucamrgs May 14, 2024
7f58da3
change get executions to return full executions information
lucamrgs May 14, 2024
9e3bbc0
fix commented test check
lucamrgs May 14, 2024
b27bd8b
remove unused function for cache
lucamrgs May 14, 2024
e8266ed
inject cache size from controller
lucamrgs May 14, 2024
b14a27f
add comment ref to cyentific workflow status repo in reporter api model
lucamrgs May 14, 2024
3d38c23
move reporter api init setup to reporter api file
lucamrgs May 14, 2024
bda81e2
use error soarca package in reporter api
lucamrgs May 14, 2024
b92772a
change mustparse to parse in reporter api
lucamrgs May 14, 2024
6af48b8
change default request interval in reporter api to const var
lucamrgs May 14, 2024
b89e7c3
fix playbook error var use in reporter api
lucamrgs May 14, 2024
c2da441
change uuid parse to mustparse in cache tests
lucamrgs May 14, 2024
bc7aa3a
separate mock cache from mock downstram reporter
lucamrgs May 14, 2024
bb688c1
add file mock cache
lucamrgs May 14, 2024
0d16403
remove unused fcns from cache mock
lucamrgs May 14, 2024
fee2f3a
move report api dynamic tests to unittest
lucamrgs May 14, 2024
e0e5f33
align reporter api model with cyentific workflow status model
lucamrgs May 14, 2024
c3cfbcf
implement status text
lucamrgs May 14, 2024
8d6197e
fix lint error check
lucamrgs May 14, 2024
867f444
add command types to cacao model
lucamrgs May 15, 2024
841c51a
change reporter api resutls model
lucamrgs May 15, 2024
9990771
remove deep copy of cache entries now passed by reference to api
lucamrgs May 15, 2024
4c0c736
fix lint bool comparison complaint
lucamrgs May 15, 2024
98b95c1
change reporting status int to status type in tests
lucamrgs May 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions docs/content/en/docs/core-components/api-reporter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
---
title: Reporter API Description
description: >
Descriptions for the Reporter REST API endpoints
categories: [API]
tags: [protocol, http, rest, api]
weight: 2
date: 2024-05-1
---

# Endpoint description

We will use HTTP status codes https://en.wikipedia.org/wiki/List_of_HTTP_status_codes


```plantuml
@startuml
protocol Reporter {
GET /reporter
GET /reporter/{execution-id}
}
@enduml
```


## /reporter
The reporter endpoint is used to fetch information about ongoing playbook executions in SOARCA

### GET `/reporter`
Get all execution IDs of currently ongoing executions.

#### Call payload
None

#### Response
200/OK with payload:

```plantuml
@startjson
[
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just return a list of all executions not only the id's, we could use the /reporter/meta to return the execution-id and playbook-id.

{
"executions": [
{"execution_id" : "1", "playbook_id" : "a", "started" : "<timestamp>", "..." : "..."},
"..."]
}
]
@endjson
```
#### Error
400/BAD REQUEST with payload:
General error



### GET `/reporter/{execution-id}`
Get information about ongoing execution

#### Call payload
None

#### Response

Response data model:


|field |content |type | description |
| ----------------- | --------------------- | ----------------- | ----------- |
|type |"execution_status" |string |The type of this content
|id |UUID |string |The id of the execution
|execution_id |UUID |string |The id of the execution
|playbook_id |UUID |string |The id of the CACAO playbook executed by the execution
|started |timestamp |string |The time at which the execution of the playbook started
|ended |timestamp |string |The time at which the execution of the playbook ended (if so)
|status |execution-status-enum |string |The current [status](#execution-stataus) of the execution
|status_text |explanation |string |A natural language explanation of the current status or related info
|step_results |step_results |dictionary |Map of step-id to related [step execution data](#step-execution-data)
|request_interval |seconds |integer |Suggests the polling interval for the next request (default suggested is 5 seconds).


##### Step execution data
|field |content |type | description |
| ----------------- | --------------------- | ----------------- | ----------- |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated execution field is missing here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also see what other fields would make sense to include

|step_id |UUID |string |The id of the step being executed
|started |timestamp |string |The time at which the execution of the step started
|ended |timestamp |string |The time at which the execution of the step ended (if so)
|status |execution-status-enum |string |The current [status](#execution-stataus) of the execution of this step
|status_text |explanation |string |A natural language explanation of the current status or related info
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing this implementation this feels a bit wierd to only set the error text

|executed_by |entity-identifier |string |The entity executed the workflow step. This can be an organization, a team, a role, a defence component, etc.
|commands_b64 |list of base64 |list of string |A list of Base64 encodings of the commands that were invoked during the execution of a workflow step, including any values stemming from variables. These are the actual commands executed.
|error |error |string |Error raised along the execution of the step
|variables |cacao variables |dictionary |Map of [cacao variables](https://docs.oasis-open.org/cacao/security-playbooks/v2.0/cs01/security-playbooks-v2.0-cs01.html#_Toc152256555) handled in the step (both in and out) with current values and definitions
|automated_execution | boolean |string |This property identifies if the workflow step was executed manually or automatically. It is either true or false.

##### Execution stataus
Table from [Cyentific RNI workflow Status](https://github.com/cyentific-rni/workflow-status/blob/main/README.md#21-refined-execution-status-enumeration)
**Vocabulary Name:** `execution-status-enum`
| Property Name | Description|
| :--- | :--- |
| successfully_executed | The workflow step was executed successfully (completed). |
|failed| The workflow step failed. |
|ongoing| The workflow step is in progress. |
|server_side_error| A server-side error occurred. |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've sugested await_user_input cyentific-rni/workflow-status#3 if that goes true we need to add that here

|client_side_error| A client-side error occurred.|
|timeout_error| A timeout error occurred. The timeout of a CACAO workflow step is specified in the “timeout” property. |
|exception_condition_error| A exception condition error ocurred. A CACAO playbook can incorporate an exception condition at the playbook level and, in particular, with the "workflow_exception" property. |


If the execution has completed and no further steps need to be executed

200/OK
with payload:

```plantuml
@startjson
[
{
"type" : "execution-status",
"id" : "<execution-id>",
"execution_id" : "<execution-id>",
"playbook_id" : "<playbook-id>",
"started" : "<time-string>",
"ended" : "<time-string>",
"status" : "<status-enum-value>",
"status_text": "<status description>",
"errors" : ["error1", "..."],
"step_results" : {
"<step-id-1>" : {
"execution_id": "<execution-id>",
"step_id" : "<step-id>",
"started" : "<time-string>",
"ended" : "<time-string>",
"status" : "<status-enum-value>",
"status_text": "<status description>",
"errors" : ["error1", "..."],
"variables": {
"<variable-name-1>" : {
"type": "<type>",
"name": "<variable-name>",
"description": "<description>",
"value": "<value>",
"constant": "<true/false>",
"external": "<true/false>"
}
}
}
},
"request_interval" : "<n-seconds>"
}
]
@endjson

The payload will include all information that the finished execution has created.


If the execution is still ongoing:

206/Partial Content
with payload equal to the 200 response, but impliclty not including all information from the execution, since the execution is still ongoing.

The step results object will list the steps that have been executed until the report request, and those that are being executed at the moment of the report request.

The "request_interval" suggests the polling interval for the next request (default suggested is 5 seconds).

#### Error
400/BAD REQUEST with payload:
General error

404/NOT FOUND
No execution with the specified ID was found.


25 changes: 24 additions & 1 deletion internal/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,20 @@ import (
"soarca/internal/fin/protocol"
"soarca/internal/guid"
"soarca/internal/reporter"
cache "soarca/internal/reporter/downstream_reporter/cache"
"soarca/logger"
"soarca/utils"
httpUtil "soarca/utils/http"
"soarca/utils/stix/expression/comparison"
timeUtil "soarca/utils/time"

downstreamReporter "soarca/internal/reporter/downstream_reporter"

"github.com/gin-gonic/gin"

mongo "soarca/database/mongodb"
playbookrepository "soarca/database/playbook"
routes "soarca/routes"
"soarca/routes"
)

var log *logger.Log
Expand All @@ -49,6 +51,10 @@ type Controller struct {

var mainController = Controller{}

var mainCache = cache.Cache{}

const defaultCacheSize int = 10

func (controller *Controller) NewDecomposer() decomposer.IDecomposer {
ssh := new(ssh.SshCapability)
capabilities := map[string]capability.ICapability{ssh.GetType(): ssh}
Expand Down Expand Up @@ -76,7 +82,13 @@ func (controller *Controller) NewDecomposer() decomposer.IDecomposer {
}
}

// NOTE: Enrolling mainCache by default as reporter
reporter := reporter.New([]downstreamReporter.IDownStreamReporter{})
downstreamReporters := []downstreamReporter.IDownStreamReporter{&mainCache}
err := reporter.RegisterReporters(downstreamReporters)
if err != nil {
log.Error("could not load main Cache as reporter for decomposer and executors")
}

actionExecutor := action.New(capabilities, reporter)
playbookActionExecutor := playbook_action.New(controller, controller, reporter)
Expand Down Expand Up @@ -129,6 +141,9 @@ func Initialize() error {
}
}

cacheSize, _ := strconv.Atoi(utils.GetEnv("MAX_EXECUTIONS", strconv.Itoa(defaultCacheSize)))
mainCache = *cache.New(&timeUtil.Time{}, cacheSize)

errCore := initializeCore(app)

if errCore != nil {
Expand Down Expand Up @@ -171,6 +186,14 @@ func initializeCore(app *gin.Engine) error {
}
}

// NOTE: Assuming that the cache is the main information mediator for
// the reporter API
err = routes.Reporter(app, &mainCache)
if err != nil {
log.Error(err)
return err
}

routes.Logging(app)
routes.Swagger(app)

Expand Down
12 changes: 12 additions & 0 deletions internal/controller/informer/execution_informer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package informer

import (
"soarca/models/cache"

"github.com/google/uuid"
)

type IExecutionInformer interface {
GetExecutions() ([]cache.ExecutionEntry, error)
GetExecutionReport(executionKey uuid.UUID) (cache.ExecutionEntry, error)
}
Loading