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

Playbooks (solves #628) #1123

Merged
merged 224 commits into from Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
224 commits
Select commit Hold shift + click to select a range
98b4ed4
Initialising work on Playbooks
0x0elliot May 29, 2022
ead6745
Setting up playbook_config.json
0x0elliot May 30, 2022
1ecb583
Setting up playbook_config.json
0x0elliot May 30, 2022
5006db3
Debugging playbook dataclass file
0x0elliot May 30, 2022
f773eeb
Debugging playbook serializer file
0x0elliot May 30, 2022
40b2390
Debugging playbook serializer file
0x0elliot May 30, 2022
e276dd2
Debugging playbook serializer file
0x0elliot May 30, 2022
bbf2da3
Debugging core serializer file for playbooks
0x0elliot May 30, 2022
722f300
Debugging core serializer file for playbooks
0x0elliot May 30, 2022
167412f
Setting up test cases, urls and views for playbooks
0x0elliot Jun 1, 2022
34fc9e2
Fixing playbook tests
0x0elliot Jun 1, 2022
326e4da
Adding playbooks urls
0x0elliot Jun 1, 2022
fc7047f
Fixing playbooks urls
0x0elliot Jun 1, 2022
5cdcbad
Debugging playbooks python_module
0x0elliot Jun 1, 2022
5097914
Saving progress
0x0elliot Jun 1, 2022
dada182
Analyze request update.
0x0elliot Jun 2, 2022
24b0e16
Updated Job models
0x0elliot Jun 2, 2022
2922df4
Cleaning playbooks_manager
0x0elliot Jun 2, 2022
b0687f7
Cleaning playbooks_manager
0x0elliot Jun 2, 2022
cfc99c9
Adding test playbook values
0x0elliot Jun 2, 2022
d59b94d
Cleaning playbooks dataclass
0x0elliot Jun 2, 2022
47fe138
Updating playbook_config.json for testin
0x0elliot Jun 2, 2022
6344144
Debugging controller file
0x0elliot Jun 3, 2022
e04d42a
Debugging controller file
0x0elliot Jun 3, 2022
4d28516
Debugging controller file
0x0elliot Jun 3, 2022
96750fb
Debugging controller file
0x0elliot Jun 3, 2022
9d7a9be
Adding playbook specific responses
0x0elliot Jun 3, 2022
7f25656
Debugging backend
0x0elliot Jun 3, 2022
cc9d67d
Optimising job reports for playbooks
0x0elliot Jun 5, 2022
9987bf5
Adding frontend scanning support for IntelOwl.
0x0elliot Jun 11, 2022
c43c99d
Adding frontend scanning support for IntelOwl.
0x0elliot Jun 15, 2022
552abf1
Adding scan all support for IntelOwl
0x0elliot Jul 4, 2022
67b4a4b
Getting plugins page ready
0x0elliot Jul 5, 2022
cc2a52c
Setting up job results page
0x0elliot Jul 5, 2022
a00eac7
Refactoring playbook scanform
0x0elliot Jul 11, 2022
9caaeff
Fixing runtime_configuration bug
0x0elliot Jul 12, 2022
9ee68cd
Fixing job status update bug to set job status to running for Playbooks
0x0elliot Jul 12, 2022
70f6fb6
Fixing job status update bug for playbooks
0x0elliot Jul 12, 2022
0163803
Fixing job status update bug for playbooks using chords
0x0elliot Jul 12, 2022
b7fd866
populating analyzers_to_execute and connectors_to_execute in Playbook…
0x0elliot Jul 13, 2022
f1f583b
Adding proper logging to Playbooks
0x0elliot Jul 13, 2022
11e2837
Taking care of conflicts
0x0elliot Jul 13, 2022
35cbec8
Taking care of conflicts
0x0elliot Jul 13, 2022
02d06d0
Making it work after taking care of conflicts.
0x0elliot Jul 13, 2022
d1a3bc4
Fixing scanform changes
0x0elliot Jul 13, 2022
bb0a89b
Fixing scanform changes
0x0elliot Jul 13, 2022
daae530
Fixing the frontend after merging Playbooks branch
0x0elliot Jul 15, 2022
367c2b0
Removing grouping of Playbooks for now
0x0elliot Jul 22, 2022
c87daeb
Adding backend changes to support the additions of multiple observables
0x0elliot Jul 22, 2022
1ec5814
Taking care of errors in adding Backend support
0x0elliot Jul 22, 2022
0db6aa4
Fixing dataclass errors after merge
0x0elliot Jul 22, 2022
f1f7dd3
Fixing dataclass errors after merge [All parameters]
0x0elliot Jul 22, 2022
4c99a02
Fixing the frontend after taking care of backend merge conflicts
0x0elliot Jul 23, 2022
6696e39
Fixing frontend bugs
0x0elliot Jul 23, 2022
45762ed
Acting on FFlake8 suggestions
0x0elliot Jul 23, 2022
f7de493
Making requested changes (cleaning up the code mostly)
0x0elliot Jul 28, 2022
c67603a
Fixing circular imports issue
0x0elliot Jul 28, 2022
0a781b0
Fixing circular import issues by creating a utility.py file
0x0elliot Jul 28, 2022
26154dd
Fixing circular import issues by creating a utility.py file and impor…
0x0elliot Jul 28, 2022
b620879
Fixing invalid arguments bug for filter_playbooks()
0x0elliot Jul 28, 2022
09865ab
Fixing cleaning data in from_dict() for PlaybookConfig
0x0elliot Jul 29, 2022
3fb1712
Fixing cleaning data in from_dict() for PlaybookConfig [1] (pop error)
0x0elliot Jul 29, 2022
7a877d5
Fixing cleaning data in from_dict() for PlaybookConfig [2] (dictionar…
0x0elliot Jul 29, 2022
f63b1db
Fixing cleaning data in from_dict() for PlaybookConfig [3] (dictionar…
0x0elliot Jul 29, 2022
5d1ff21
Fixing cleaning data in from_dict() for PlaybookConfig [4] (dictionar…
0x0elliot Jul 29, 2022
4942529
Returning appropriate response for Playbook endpoints
0x0elliot Jul 29, 2022
95e1ce8
Cleaning up API response for Playbook endpoints
0x0elliot Jul 29, 2022
157a8ef
Fixing up the frontend to show jobIds and redirect accordingly.
0x0elliot Jul 29, 2022
6688468
Fixing scanpage frontend and backend API bugs
0x0elliot Jul 30, 2022
46ac8cd
Fixing package.json format
0x0elliot Jul 30, 2022
3ea1154
Fixing up the frontend to show jobIds and redirect accordingly [1]
0x0elliot Jul 30, 2022
87fe9e6
Fixing backend type errors
0x0elliot Jul 30, 2022
d78c520
Adding migrations
0x0elliot Jul 31, 2022
ac30a98
Merge pull request #29 from 0x0elliot/Migrations_Playbooks
0x0elliot Jul 31, 2022
e72a8a8
Adding migrations
0x0elliot Jul 31, 2022
40ae296
Adding FREE_TO_USE_ANALYZERS Playbooks
0x0elliot Aug 18, 2022
6adaec4
Adding Playbook tests.
0x0elliot Aug 19, 2022
613d9c2
Adding Playbook tests and removing comments which were for me
0x0elliot Aug 19, 2022
6fbedbe
Adding playbook test cases
0x0elliot Aug 21, 2022
651ddac
Fixing frontend bugs
0x0elliot Aug 22, 2022
0bf0ff4
Fixing frontend bugs [2]
0x0elliot Aug 22, 2022
0777e0d
Fixing frontend bugs [3]
0x0elliot Aug 22, 2022
5f5dae2
Fixing frontend bugs [4]
0x0elliot Aug 22, 2022
260d7f5
Fixing frontend bugs [5]
0x0elliot Aug 22, 2022
73e0de1
Fixing frontend bugs where plugins other than Playbooks weren't loading
0x0elliot Aug 23, 2022
39dae3d
Merge branch 'upstream/develop' into Playbooks
0x0elliot Aug 24, 2022
89d845e
Fixing import error for logging
0x0elliot Aug 24, 2022
6395a7d
Removing utility.py and making all it's functions classmethods/static…
0x0elliot Aug 25, 2022
5b58c7f
Fixing logging library's import error
0x0elliot Aug 25, 2022
23daf91
Fixing backend API bugs [1]
0x0elliot Aug 25, 2022
1002af1
fixing uuid import error
0x0elliot Aug 25, 2022
8f91798
Adding pre-commit suggested changes
0x0elliot Aug 25, 2022
17f91ba
Fixing frontend bug where requests for files were sent to observable …
0x0elliot Aug 28, 2022
e84c6f8
Fixing frontend bug where requests for files were sent to observable …
0x0elliot Aug 28, 2022
7d6d8f6
Fixing frontend bug where requests for files were sent to observable …
0x0elliot Aug 28, 2022
218f149
Fixing parent_playbook=null issue
0x0elliot Aug 28, 2022
de82f32
Fixing parent_playbook=null issue [1]
0x0elliot Aug 28, 2022
7504b69
Adding free to use playbooks with all free analyzers, Fixing supports'
0x0elliot Aug 29, 2022
8eaaa8c
Fixing ObservableTypeWithFile inheritence errors
0x0elliot Aug 29, 2022
1a4db42
Adding 'AllTypes' as an ENUM for choices in Playbooks
0x0elliot Aug 29, 2022
859b6b3
Fixing inheritence errors in AllTypes
0x0elliot Aug 29, 2022
0417b3b
Fixing issue where backend runs any observable for playbooks whether …
0x0elliot Aug 29, 2022
bd1e69d
Fixing issue where backend runs any observable for playbooks whether …
0x0elliot Aug 29, 2022
b9aa4bc
Adding linting
0x0elliot Aug 29, 2022
e865dca
Enabling multiple observable job results in playbook analyze scan res…
0x0elliot Sep 2, 2022
5befbc1
Fixing migrations
0x0elliot Sep 2, 2022
efe9ab3
Untracking yarn.lock
0x0elliot Sep 2, 2022
6bfaafd
Adding test case for stack_analyzers and fixing AnalyzerActionViewSet…
0x0elliot Sep 5, 2022
bc1e649
Adding test cases and fixing frontend bugs
0x0elliot Sep 5, 2022
bb5c362
Adding linting
0x0elliot Sep 5, 2022
73f25ab
Adding linting
0x0elliot Sep 5, 2022
28e8fa2
Fixing test cases
0x0elliot Sep 6, 2022
21194a8
Fixing test cases [1] and adding linting
0x0elliot Sep 6, 2022
2a05a6b
Fixing test cases [2] and adding linting
0x0elliot Sep 6, 2022
34ff6a9
Fixing test cases [3] and adding linting
0x0elliot Sep 6, 2022
7ceed95
Fixing test cases [4] and adding linting
0x0elliot Sep 6, 2022
30aab9b
Fixing test cases [5] and adding linting
0x0elliot Sep 6, 2022
a42d4ac
Fixing test cases [5] and adding linting
0x0elliot Sep 6, 2022
6f079a7
Adding suggestions for the frontend.
0x0elliot Sep 7, 2022
5896997
Adding suggestions for the frontend [1]
0x0elliot Sep 7, 2022
9c1ac81
Adding suggestions for the frontend [2]
0x0elliot Sep 7, 2022
d1aede8
Reducing Description max length
0x0elliot Sep 7, 2022
b4cfedc
Reducing Description minWidth for Playbooks plugin page
0x0elliot Sep 7, 2022
d4e0265
Reducing Description minWidth for Playbooks plugin page [1]
0x0elliot Sep 7, 2022
29fcbea
Reducing Description minWidth for Playbooks plugin page [2]
0x0elliot Sep 7, 2022
e53273d
Adding the handling of analyzer/connector report numbers differently …
0x0elliot Sep 8, 2022
210692c
Fixing package.json changes
0x0elliot Sep 8, 2022
3bcee2d
Fixing test case breaking changes
0x0elliot Sep 8, 2022
3417212
Fixing test case breaking changes [1]
0x0elliot Sep 8, 2022
eadf0c2
Fixing the number of analyzers, connectors and playbooks that show up…
0x0elliot Sep 8, 2022
e13fc60
Adding analyzer/connector to playbook toggle through radio buttons
0x0elliot Sep 11, 2022
97b2e7e
Removing frontend comments
0x0elliot Sep 11, 2022
c8d5758
Wrapping up frontend for Playbooks feature along with all known bugs …
0x0elliot Sep 11, 2022
4b8c680
Fixing pre-commit errors
0x0elliot Sep 11, 2022
0779584
Disabling run_all
0x0elliot Sep 11, 2022
7da72ad
Adding frontend support for disabling run_all for playbooks
0x0elliot Sep 12, 2022
70c2d51
improving UX for playbooks
0x0elliot Sep 13, 2022
fb222b1
Rewriting playbook serializers
0x0elliot Sep 17, 2022
8e9c58b
Fixing Serializers
0x0elliot Sep 17, 2022
1c71009
Fixing lint errors
0x0elliot Sep 17, 2022
82868c8
Fixing status code 500 for playbook APIs
0x0elliot Sep 17, 2022
68e3d14
Fixing bug in playbook serializers that led to no analyzers/connector…
0x0elliot Sep 17, 2022
d560192
Fixing 500 bugs in playbook run APIs
0x0elliot Sep 17, 2022
8fada5e
Fixing start_playbook() related errors
0x0elliot Sep 17, 2022
dce0215
Fixing playbook file scan errors
0x0elliot Sep 17, 2022
93e6d68
Fixing playbook file scan errors [1]
0x0elliot Sep 17, 2022
fffcb48
Fixing playbook file scan errors [2]
0x0elliot Sep 17, 2022
d091f51
Fixing playbook file scan errors [3]
0x0elliot Sep 17, 2022
0208324
Fixing playbook file scan errors [4]
0x0elliot Sep 17, 2022
e7fc34b
Fixing serializers and frontend
0x0elliot Sep 19, 2022
0d8af14
Fixing serializers [Analyzers and connectors] and frontend
0x0elliot Sep 19, 2022
1b3a9af
Revert "Fixing serializers and frontend"
0x0elliot Sep 19, 2022
a371c41
Reverting
0x0elliot Sep 19, 2022
7efb0a1
Fixing serializers
0x0elliot Sep 19, 2022
cfd4373
Fixing serializers
0x0elliot Sep 19, 2022
1202584
Fixing serializers [1]
0x0elliot Sep 19, 2022
c8d1318
Fixing serializers [2]
0x0elliot Sep 19, 2022
b555e70
Fixing serializers validation
0x0elliot Sep 19, 2022
15b43ab
Fixing serializers validation for connectors
0x0elliot Sep 19, 2022
2f8f356
Adding playbook documentation
0x0elliot Sep 19, 2022
9490ae2
Fixing bug where error led to parent_playbook remaining empty
0x0elliot Sep 26, 2022
df7ff31
Making it necessary for playbooks to be not empty
0x0elliot Sep 29, 2022
099ac1b
Minor fix for the last commit
0x0elliot Sep 29, 2022
a0e6002
Making parent_playbook nullable
0x0elliot Sep 29, 2022
c0e770e
Adding new migrations and model changes
0x0elliot Sep 29, 2022
426e1a8
Fixing multiple values for argument errors
0x0elliot Sep 30, 2022
ac46216
Adding support for playbooks and custom configs & fixing bugs
0x0elliot Sep 30, 2022
3040cd1
Fixing response bugs
0x0elliot Oct 1, 2022
03348e6
Fixing response serializer bugs [1]
0x0elliot Oct 1, 2022
e57a756
Fixing tasks for playbooks
0x0elliot Oct 1, 2022
aedf659
Removing unnecessary warnings from showing up on the UI
0x0elliot Oct 1, 2022
8a0057a
Adding warning changes for all serializers and optimising filter_conn…
0x0elliot Oct 1, 2022
470c48d
Fixing playbook related model values and optimising before_run() methods
0x0elliot Oct 1, 2022
f9d2687
Fixing not null errors due to parent_playbook value
0x0elliot Oct 1, 2022
eedb971
Adding better logging in test cases
0x0elliot Oct 1, 2022
3b018cd
Adding debugging logs for test cases
0x0elliot Oct 1, 2022
ee5d410
Adding debugging logs for test cases [fixing linting]
0x0elliot Oct 1, 2022
d520d2b
Adding debugging logs for test cases [1]
0x0elliot Oct 1, 2022
1ee5673
Fixing connector checks during CI checks
0x0elliot Oct 1, 2022
c3871f8
Fixing connector serializer
0x0elliot Oct 1, 2022
2b841d5
Optimising connector support in playbooks
0x0elliot Oct 2, 2022
42c38bd
Fixing CI related connector test case issues
0x0elliot Oct 2, 2022
e917904
Fixing before_run function for files
0x0elliot Oct 2, 2022
ce2ade7
Fixing typo in controller function start_playbook()
0x0elliot Oct 2, 2022
9c7e619
Adding changes for playbooks
0x0elliot Oct 4, 2022
0089909
Adding test cases for playbooks
0x0elliot Oct 4, 2022
d1df3f5
Updating tests for playbooks
0x0elliot Oct 4, 2022
3c1a49a
Fixing tests
0x0elliot Oct 4, 2022
7e80a99
Fixing auto-imports
0x0elliot Oct 4, 2022
5adf26e
Fixing test_start_playbooks_observable
0x0elliot Oct 4, 2022
320abbc
Adding TEST_PLAYBOOKS for ci
0x0elliot Oct 4, 2022
ec5d63c
Adding debugging logs for playbook tests
0x0elliot Oct 4, 2022
7d8c676
Handling exceptions in playbook serializers
0x0elliot Oct 4, 2022
49e7597
Fixing linting errors
0x0elliot Oct 4, 2022
3e3810c
Moving playbooks up for a while
0x0elliot Oct 4, 2022
1af40df
Covering edge cases for playbooks
0x0elliot Oct 4, 2022
2b73be3
Moving playbook test workflow up and covering edge cases for playbooks
0x0elliot Oct 4, 2022
c259071
Debugging tests for playbooks
0x0elliot Oct 4, 2022
5628800
Fixing playbook tests
0x0elliot Oct 4, 2022
31a51c7
Making playbook tests for a single playbook
0x0elliot Oct 4, 2022
f80c94d
Fixing bugs in playbook tests
0x0elliot Oct 4, 2022
a39b8fe
Fixing bugs in playbook tests [1]
0x0elliot Oct 4, 2022
f09d482
Fixing bugs in playbook tests [2]
0x0elliot Oct 4, 2022
5a333e9
Adding documentation and playbook test case for files
0x0elliot Oct 4, 2022
e4d92d3
Fixing tests for playbook files
0x0elliot Oct 4, 2022
81241b9
Fixing tests for playbook files [adding querydict]
0x0elliot Oct 4, 2022
e39b037
Fixing bugs in tests for playbook files
0x0elliot Oct 4, 2022
9dc40dc
Removing failing integrations
0x0elliot Oct 4, 2022
ff035a3
Removing failing integrations
0x0elliot Oct 4, 2022
6d56dea
Removing useless f strings
0x0elliot Oct 4, 2022
ef3c153
Removing analyzers which took too long from free playbook provided
0x0elliot Oct 4, 2022
ada825d
Pushing playbooks down in github workflows
0x0elliot Oct 4, 2022
9e08b88
Fixing frontend warnings
0x0elliot Oct 5, 2022
03c7a7d
Bump django from 3.2.14 to 3.2.15 in /requirements (#1144)
dependabot[bot] Aug 18, 2022
153857b
Adding PR suggested changes
0x0elliot Oct 6, 2022
8b839f2
Adding instructions for contributors to add free analyzers in free an…
0x0elliot Oct 6, 2022
f2a3f0f
Adding instructions for contributors to add free analyzers in free an…
0x0elliot Oct 6, 2022
a13d4ae
Letting analyzers fail in playbook tests
0x0elliot Oct 6, 2022
5d15bff
Fixing linting
0x0elliot Oct 6, 2022
9055e56
fixing playbook tests
0x0elliot Oct 6, 2022
411bcf9
fixing linting errors
0x0elliot Oct 6, 2022
ace29b3
Squashing migrations together
0x0elliot Oct 7, 2022
a8f098b
Adding instructions in PR templates
0x0elliot Oct 8, 2022
fc77fe1
adjusted migrations
mlodic Oct 10, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/ISSUE_TEMPLATE/new_analyzer.md
Expand Up @@ -14,7 +14,8 @@ assignees: ''
## Type of analyzer
**this can be observable, file, and docker**


## Why should we use it


## Possible implementation
## Possible implementation
1 change: 1 addition & 0 deletions .github/release_template.md
Expand Up @@ -16,3 +16,4 @@ WARNING: The release will be live within an hour!
- [ ] Wait for [dockerHub](https://hub.docker.com/repository/docker/intelowlproject/intelowl) to finish the builds
- [ ] Merge the PR to the `master` branch. **Note:** Only use "Merge and commit" as the merge strategy and not "Squash and merge". Using "Squash and merge" makes history between branches misaligned.
- [ ] Remove the "wait" statement in the release description.
- [ ] If the analyzer is free, Please add it in the `FREE_TO_USE_ANALYZERS` playbook in `playbook_config.json`
4 changes: 4 additions & 0 deletions .github/workflows/pull_request_automation.yml
Expand Up @@ -136,6 +136,10 @@ jobs:
run: |
docker/scripts/coverage_test.sh tests.analyzers_manager.test_file_scripts

- name: "Test: Playbooks Manager"
run: |
docker/scripts/coverage_test.sh tests.playbooks_manager.test_controller

- name: "Coverage: generate xml and transfer from docker container to host"
run: |
docker exec intelowl_uwsgi coverage combine
Expand Down
12 changes: 7 additions & 5 deletions api_app/analyzers_manager/classes.py
Expand Up @@ -93,7 +93,9 @@ def _validate_result(self, result, level=0, max_recursion=190):
result = 9223372036854775807
return result

def before_run(self):
def before_run(self, *args, **kwargs):
parent_playbook = kwargs.get("parent_playbook", "")
self.add_parent_playbook(parent_playbook=parent_playbook)
self.report.update_status(status=self.report.Status.RUNNING)

def after_run(self):
Expand Down Expand Up @@ -136,8 +138,8 @@ def __post__init__(self):
self.observable_classification = self._job.observable_classification
return super(ObservableAnalyzer, self).__post__init__()

def before_run(self):
super().before_run()
def before_run(self, *args, **kwargs):
super().before_run(**kwargs)
logger.info(
f"STARTED analyzer: {self.__repr__()} -> "
f"Observable: {self.observable_name}."
Expand Down Expand Up @@ -184,8 +186,8 @@ def __post__init__(self):
self.file_mimetype = self._job.file_mimetype
return super(FileAnalyzer, self).__post__init__()

def before_run(self):
super().before_run()
def before_run(self, *args, **kwargs):
super().before_run(**kwargs)
logger.info(
f"STARTED analyzer: {self.__repr__()} -> "
f"File: ({self.filename}, md5: {self.md5})"
Expand Down
9 changes: 9 additions & 0 deletions api_app/analyzers_manager/constants.py
Expand Up @@ -20,3 +20,12 @@ class ObservableTypes(models.TextChoices):
DOMAIN = "domain"
HASH = "hash"
GENERIC = "generic"


class AllTypes(models.TextChoices):
IP = "ip"
URL = "url"
DOMAIN = "domain"
HASH = "hash"
GENERIC = "generic"
FILE = "file"
112 changes: 13 additions & 99 deletions api_app/analyzers_manager/controller.py
Expand Up @@ -4,16 +4,13 @@
import logging
from typing import Dict, List

from celery import chord, uuid
from django.conf import settings
from celery import chord
from django.utils.module_loading import import_string
from rest_framework.exceptions import ValidationError

from intel_owl import tasks
from intel_owl.celery import app as celery_app
from intel_owl.consts import DEFAULT_QUEUE

from ..exceptions import AlreadyFailedJobException
from ..helpers import get_now
from ..models import Job
from .classes import DockerBasedAnalyzer
from .dataclasses import AnalyzerConfig
Expand All @@ -27,115 +24,32 @@ def start_analyzers(
analyzers_to_execute: List[str],
runtime_configuration: Dict[str, Dict] = None,
) -> None:
from intel_owl import tasks

# we should not use mutable objects as default to avoid unexpected issues
if runtime_configuration is None:
runtime_configuration = {}

# to store the celery task signatures
task_signatures = []
cleaned_result = AnalyzerConfig.stack_analyzers(
job_id=job_id,
analyzers_to_execute=analyzers_to_execute,
runtime_configuration=runtime_configuration,
)

# get analyzer config
analyzer_dataclasses = AnalyzerConfig.all()

# get job
job = Job.objects.get(pk=job_id)
job.update_status(Job.Status.RUNNING) # set job status to running

# loop over and create task signatures
for a_name in analyzers_to_execute:
# get corresponding dataclass
config = analyzer_dataclasses[a_name]

# if disabled or unconfigured (this check is bypassed in STAGE_CI)
if not config.is_ready_to_use and not settings.STAGE_CI:
logger.info(f"skipping execution of analyzer {a_name}, job_id {job_id}")
continue

# get runtime_configuration if any specified for this analyzer
runtime_params = runtime_configuration.get(a_name, {})
# gen new task_id
task_id = uuid()
# construct arguments
args = [
job_id,
config.asdict(),
{"runtime_configuration": runtime_params, "task_id": task_id},
]
# get celery queue
queue = config.config.queue
if queue not in settings.CELERY_QUEUES:
logger.warning(
f"Analyzer {a_name} has a wrong queue: {queue}."
f" Setting to `{DEFAULT_QUEUE}`"
)
queue = DEFAULT_QUEUE
# get soft_time_limit
soft_time_limit = config.config.soft_time_limit
# create task signature and add to list
task_signatures.append(
tasks.run_analyzer.signature(
args,
{},
queue=queue,
soft_time_limit=soft_time_limit,
task_id=task_id,
)
)
task_signatures = cleaned_result[0]

# fire the analyzers in a grouped celery task
# also link the callback to be executed
# canvas docs: https://docs.celeryproject.org/en/stable/userguide/canvas.html
runner = chord(task_signatures)
cb_signature = tasks.post_all_analyzers_finished.signature(
[job.pk, runtime_configuration], immutable=True
[job_id, runtime_configuration], immutable=True
)

runner(cb_signature)

return None


def job_cleanup(job: Job) -> None:
logger.info(f"[STARTING] job_cleanup for <-- {job.__repr__()}.")
status_to_set = job.Status.RUNNING

try:
if job.status == job.Status.FAILED:
raise AlreadyFailedJobException()

stats = job.get_analyzer_reports_stats()

logger.info(f"[REPORT] {job.__repr__()}, status:{job.status}, reports:{stats}")

if len(job.analyzers_to_execute) == stats["all"]:
if stats["running"] > 0 or stats["pending"] > 0:
status_to_set = job.Status.RUNNING
elif stats["success"] == stats["all"]:
status_to_set = job.Status.REPORTED_WITHOUT_FAILS
elif stats["failed"] == stats["all"]:
status_to_set = job.Status.FAILED
elif stats["failed"] >= 1 or stats["killed"] >= 1:
status_to_set = job.Status.REPORTED_WITH_FAILS
elif stats["killed"] == stats["all"]:
status_to_set = job.Status.KILLED

except AlreadyFailedJobException:
logger.error(
f"[REPORT] {job.__repr__()}, status: failed. Do not process the report"
)

except Exception as e:
logger.exception(f"job_id: {job.pk}, Error: {e}")
job.append_error(str(e), save=False)

finally:
if not (job.status == job.Status.FAILED and job.finished_analysis_time):
job.finished_analysis_time = get_now()
job.status = status_to_set
job.save(update_fields=["status", "errors", "finished_analysis_time"])


def set_failed_analyzer(
job_id: int, name: str, err_msg, **report_defaults
) -> AnalyzerReport:
Expand All @@ -153,7 +67,7 @@ def set_failed_analyzer(


def run_analyzer(
job_id: int, config_dict: dict, report_defaults: dict
job_id: int, config_dict: dict, report_defaults: dict, parent_playbook
) -> AnalyzerReport:
aconfig = AnalyzerConfig.from_dict(config_dict)
try:
Expand All @@ -164,7 +78,7 @@ def run_analyzer(
raise Exception(f"Class: {cls_path} couldn't be imported")
# else
instance = klass(config=aconfig, job_id=job_id, report_defaults=report_defaults)
report = instance.start()
report = instance.start(parent_playbook=parent_playbook)
except Exception as e:
report = set_failed_analyzer(job_id, aconfig.name, str(e), **report_defaults)

Expand All @@ -180,7 +94,7 @@ def post_all_analyzers_finished(job_id: int, runtime_configuration: dict) -> Non
# get job instance
job = Job.objects.get(pk=job_id)
# execute some callbacks
job_cleanup(job)
job.job_cleanup()
# fire connectors when job finishes with success
# avoid re-triggering of connectors (case: recurring analyzer run)
if job.status == Job.Status.REPORTED_WITHOUT_FAILS and (
Expand Down
88 changes: 87 additions & 1 deletion api_app/analyzers_manager/dataclasses.py
@@ -1,9 +1,16 @@
# This file is a part of IntelOwl https://github.com/intelowlproject/IntelOwl
# See the file 'LICENSE' for copying permission.
import dataclasses
import logging
import typing

from celery import uuid
from celery.canvas import Signature
from django.conf import settings

from api_app.core.dataclasses import AbstractConfig
from api_app.models import Job
from intel_owl.consts import DEFAULT_QUEUE

from .constants import HashChoices, TypeChoices
from .serializers import AnalyzerConfigSerializer
Expand All @@ -12,6 +19,8 @@
"AnalyzerConfig",
]

logger = logging.getLogger(__name__)


@dataclasses.dataclass
class AnalyzerConfig(AbstractConfig):
Expand All @@ -31,7 +40,6 @@ class AnalyzerConfig(AbstractConfig):
run_hash_type: typing.Literal["md5", "sha256"] = HashChoices.MD5

# utils

@property
def is_type_observable(self) -> bool:
return self.type == TypeChoices.OBSERVABLE
Expand Down Expand Up @@ -104,3 +112,81 @@ def all(cls) -> typing.Dict[str, "AnalyzerConfig"]:
def filter(cls, names: typing.List[str]) -> typing.Dict[str, "AnalyzerConfig"]:
all_analyzer_config = cls.all()
return {name: ac for name, ac in all_analyzer_config.items() if name in names}

@staticmethod
def runnable_analyzers(analyzers_to_execute: typing.List[str]) -> typing.List[str]:
analyzer_dataclass = AnalyzerConfig.all()
return [
analyzer
for analyzer in analyzers_to_execute
if analyzer_dataclass.get(analyzer)
]

@classmethod
def stack_analyzers(
cls,
job_id: int,
analyzers_to_execute: typing.List[str],
runtime_configuration: typing.Dict[str, typing.Dict] = None,
parent_playbook="",
) -> typing.Tuple[typing.List[Signature], typing.List[str]]:
from intel_owl import tasks

# to store the celery task signatures
task_signatures = []
analyzers_used = []

analyzers_to_run = cls.runnable_analyzers(
analyzers_to_execute=analyzers_to_execute
)

analyzer_dataclasses = cls.all()

# get job
job = Job.objects.get(pk=job_id)
job.update_status(Job.Status.RUNNING) # set job status to running

# loop over and create task signatures
for a_name in analyzers_to_run:
# get corresponding dataclass
config = analyzer_dataclasses.get(a_name, None)

# if disabled or unconfigured (this check is bypassed in STAGE_CI)
if not config.is_ready_to_use and not settings.STAGE_CI:
logger.info(f"skipping execution of analyzer {a_name}, job_id {job_id}")
continue

# get runtime_configuration if any specified for this analyzer
runtime_params = runtime_configuration.get(a_name, {})
# gen new task_id
task_id = uuid()
# construct arguments
args = [
job_id,
config.asdict(),
{"runtime_configuration": runtime_params, "task_id": task_id},
parent_playbook,
Copy link
Member

Choose a reason for hiding this comment

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

parent_playbook should be treated like any other parameter here. I'll get into the start method too

Copy link
Member Author

Choose a reason for hiding this comment

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

i don't get this. it is being treated like any other parameter. do you mean, not like any other explicit parameter and instead with the help of kwargs?

Copy link
Member

Choose a reason for hiding this comment

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

yes

{"runtime_configuration": runtime_params, "task_id": task_id, "parent_playbook":parent_playbook}

]
# get celery queue
queue = config.config.queue
if queue not in settings.CELERY_QUEUES:
logger.warning(
f"Analyzer {a_name} has a wrong queue."
f" Setting to `{DEFAULT_QUEUE}`"
)
queue = DEFAULT_QUEUE
# get soft_time_limit
soft_time_limit = config.config.soft_time_limit
# create task signature and add to list
task_signatures.append(
tasks.run_analyzer.signature(
args,
{},
queue=queue,
soft_time_limit=soft_time_limit,
task_id=task_id,
)
)
analyzers_used.append(a_name)

return task_signatures, analyzers_used
@@ -0,0 +1,18 @@
# Generated by Django 3.2.14 on 2022-10-07 18:52

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("analyzers_manager", "0001_initial"),
]

operations = [
migrations.AddField(
model_name="analyzerreport",
name="parent_playbook",
field=models.CharField(blank=True, default="", max_length=128),
),
]
1 change: 1 addition & 0 deletions api_app/analyzers_manager/serializers.py
Expand Up @@ -29,6 +29,7 @@ class Meta:
"end_time",
"runtime_configuration",
"type",
"parent_playbook",
)


Expand Down