Skip to content
Closed
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
8c01058
Initial
jpbruinsslot Apr 10, 2025
ca006ce
Update
jpbruinsslot Apr 10, 2025
2d9008d
Update
jpbruinsslot Apr 16, 2025
c2531ad
Make test work
jpbruinsslot Apr 17, 2025
ea2250c
Restructure method and update tests
jpbruinsslot Apr 22, 2025
164e4e2
Update tests
jpbruinsslot Apr 23, 2025
d2913dd
Merge branch 'main' into feature/mula/dedup
jpbruinsslot Apr 23, 2025
3bd4c0e
Precommit
jpbruinsslot Apr 23, 2025
8171700
Fix tests
jpbruinsslot May 7, 2025
923cd43
Add additional tests
jpbruinsslot May 8, 2025
8a9ed33
Add changes to support changes in katalogus
jpbruinsslot May 8, 2025
1a9abf4
Update
jpbruinsslot May 8, 2025
bd7f34b
Naive implementation
jpbruinsslot May 13, 2025
687a9b2
Rewriting tests
jpbruinsslot May 13, 2025
7f8d5a2
Update tests
jpbruinsslot May 13, 2025
ef52396
Fix tests
jpbruinsslot May 13, 2025
b5308f7
Fix tests
jpbruinsslot May 14, 2025
abb00eb
Fix precommit
jpbruinsslot May 14, 2025
3cf78ad
Bump django from 5.0.13 to 5.0.14 in /rocky (#4281)
dependabot[bot] Apr 23, 2025
fb83669
Translations update from Hosted Weblate (#4374)
weblate Apr 23, 2025
f40d7c0
fix permissions on report_overview.py (#4264)
underdarknl Apr 24, 2025
26898be
Add quick start to docs.openkat.nl (#4349)
stephanie0x00 Apr 25, 2025
4181f30
add observed_at to links on finding_list.html (#4367)
underdarknl Apr 28, 2025
215f995
Update packages (#4399)
ammar92 Apr 29, 2025
35d7d64
Remove unused scan profile increment queues (#4383)
dekkers Apr 29, 2025
a2fbbc5
Add organisation queryparam for schedules endpoint (#4396)
jpbruinsslot Apr 29, 2025
e17d619
Upgrade jaeger and prometheus, and enable spm (#4282)
jpbruinsslot Apr 29, 2025
8f9dad9
Add all organization report task page (#4394)
dekkers Apr 29, 2025
17d65d6
Make the list of boefjes unqiue when querying the KATalogus for info …
underdarknl Apr 29, 2025
6502e8a
Feat/cleaner set scan profile form (#4345)
underdarknl Apr 30, 2025
fda531d
Hotfix for NoReverseMatch in Crisis Room (#4405)
madelondohmen May 1, 2025
edf9c48
(temp) fix time parsing in report_overview.py (#4402)
underdarknl May 1, 2025
da55ba4
Fixed link in tree view (#4404)
ammar92 May 1, 2025
ef1f689
Use Python 3.13 as default Python version in container images and CI …
dekkers May 1, 2025
e031f60
Update plugin tiles when user has no permission to enable/disable (#4…
madelondohmen May 1, 2025
176195f
Remove leftover debug logging (#4418)
dekkers May 1, 2025
bb57fa2
Add grafana pyroscope continuous profiling (#4297)
jpbruinsslot May 2, 2025
ad74040
Updated packages (#4433)
ammar92 May 6, 2025
299db50
Update GitHub actions (#4434)
ammar92 May 6, 2025
28f4400
Update 1.18.rst, add links to issues / bugs (#4419)
underdarknl May 6, 2025
0cc91b7
Fix weblate (#4437)
dekkers May 7, 2025
e848223
Translations update from Hosted Weblate (#4438)
weblate May 7, 2025
76e0b76
Call gc.collect() after execution of task (#4432)
dekkers May 8, 2025
e8f9b76
Fix broken image link in README.rst (#4444)
Potherca May 10, 2025
ef4b382
Translations update from Hosted Weblate (#4439)
weblate May 10, 2025
6e65e9f
Fixes for disable/enable schedule modal (#4400)
madelondohmen May 13, 2025
078d2ec
Fix boefje detail page for client member (#4409)
madelondohmen May 13, 2025
3bb3101
Open asset report from within report (#4435)
madelondohmen May 13, 2025
ff7338a
Docs - add description of origin types (#4289)
stephanie0x00 May 13, 2025
7b6ad15
Updated packages (#4453)
ammar92 May 13, 2025
744d02e
Translations update from Hosted Weblate (#4458)
weblate May 14, 2025
1535c37
Updated Django and other packages (#4441)
ammar92 May 14, 2025
7b21ac8
Integrate new octopoes endpoint
jpbruinsslot May 15, 2025
beddd9a
Update tests
jpbruinsslot May 15, 2025
b7c8c66
Update to new deduplication key
jpbruinsslot May 15, 2025
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
4 changes: 4 additions & 0 deletions mula/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ build-backend = "setuptools.build_meta:__legacy__"

[tool.coverage.run]
relative_files = true
data_file = "/tmp/.coverage"

[tool.coverage.xml]
output = "/tmp/coverage.xml"

omit = [
"scheduler/alembic/*",
Expand Down
28 changes: 27 additions & 1 deletion mula/scheduler/clients/http/external/katalogus.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from scheduler.clients.errors import exception_handler
from scheduler.clients.http import HTTPService
from scheduler.models import Boefje, Organisation, Plugin
from scheduler.models import Boefje, BoefjeConfig, Organisation, Plugin


class Katalogus(HTTPService):
Expand Down Expand Up @@ -138,3 +138,29 @@ def get_new_boefjes_by_org_id(self, organisation_id: str) -> list[Plugin]:
)

return new_boefjes

def get_configs(
self,
organisation_id: str,
boefje_id: str | None = None,
enabled: bool | None = None,
offset: int | None = None,
limit: int | None = None,
) -> list[BoefjeConfig]:
url = f"{self.host}/v1/configs"
try:
response = self.get(
url,
params={
"organisation_id": organisation_id,
"boefje_id": boefje_id,
"enabled": enabled,
"offset": offset,
"limit": limit,
},
)
return [Plugin(**plugin) for plugin in response.json()]
except httpx.HTTPStatusError as e:
if e.response.status_code == httpx.codes.NOT_FOUND:
return []
raise
4 changes: 4 additions & 0 deletions mula/scheduler/clients/http/external/octopoes.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ def get_object(self, organisation_id: str, reference: str) -> OOI | None:
return None
raise

@exception_handler
def get_organisations_by_ooi(self, reference: str) -> list[Organisation]:
raise NotImplementedError("Not implemented")

def is_healthy(self) -> bool:
healthy = True
for org in self.orgs:
Expand Down
2 changes: 1 addition & 1 deletion mula/scheduler/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .base import Base
from .boefje import Boefje, BoefjeMeta
from .boefje import Boefje, BoefjeConfig, BoefjeMeta
from .events import RawData, RawDataReceivedEvent
from .health import ServiceHealth
from .normalizer import Normalizer
Expand Down
11 changes: 11 additions & 0 deletions mula/scheduler/models/boefje.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,14 @@ class BoefjeMeta(BaseModel):

started_at: datetime.datetime | None
ended_at: datetime.datetime | None


class BoefjeConfig(BaseModel):
"""BoefjeConfig is the configuration object for a Boefje"""

id: int
boefje_id: str
enabled: bool
organisation_id: str
env_hash: str
settings: dict
1 change: 1 addition & 0 deletions mula/scheduler/models/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ class Plugin(BaseModel):
run_on: list[RunOn] | None = None
oci_image: str | None = None
oci_arguments: list[str] | None = None
env_hash: str | None = None
1 change: 1 addition & 0 deletions mula/scheduler/models/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class BoefjeTask(BaseModel):
boefje: Boefje
input_ooi: str | None = None
organization: str
env_hash: str # TODO: will this be none?

dispatches: list[Normalizer] = Field(default_factory=list)

Expand Down
54 changes: 54 additions & 0 deletions mula/scheduler/schedulers/schedulers/boefje.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ def process_mutations(self, body: bytes) -> None:
boefje=models.Boefje.model_validate(boefje.model_dump()),
input_ooi=ooi.primary_key if ooi else None,
organization=mutation.client_id,
env_hash=boefje.env_hash,
)
)

Expand Down Expand Up @@ -204,6 +205,7 @@ def process_new_boefjes(self) -> None:
boefje=models.Boefje.model_validate(boefje.dict()),
input_ooi=ooi.primary_key,
organization=org.id,
env_hash=boefje.env_hash,
)

boefje_tasks.append((boefje_task, org.id))
Expand Down Expand Up @@ -339,6 +341,7 @@ def process_rescheduling(self):
boefje=models.Boefje.model_validate(plugin.dict()),
input_ooi=ooi.primary_key if ooi else None,
organization=schedule.organisation,
env_hash=plugin.env_hash,
)
except (StorageError, ValidationError, ExternalServiceError):
self.logger.exception(
Expand Down Expand Up @@ -402,6 +405,14 @@ def push_boefje_task(
task_db.status = models.TaskStatus.FAILED
self.ctx.datastores.task_store.update_task(task_db)

# We check on input_ooi because we allow for boefje tasks without an
# ooi, something we can't deduplicate. Additionally, because we
# potentially call the method itself from `is_ooi_in_other_organisations`,
# we need to make sure that we don't endlessly call it, by checking the
# caller.
if boefje_task.input_ooi is not None and caller != self.is_ooi_in_other_organisations.__name__:
self.is_ooi_in_other_organisations(boefje_task)

task = models.Task(
id=boefje_task.id,
scheduler_id=self.scheduler_id,
Expand Down Expand Up @@ -685,6 +696,49 @@ def get_oois_for_boefje(self, boefje: models.Plugin, organisation: str) -> list[

return oois

# TODO:: exception handling
def is_ooi_in_other_organisations(self, boefje_task: models.BoefjeTask):
"""Is the ooi in other organisations? When the ooi is in other
organisations we don't want to scan those as well, we still create
tasks for those organisations but they will be batched together.
"""
# From the boefje id we can get the same boefje in other organisations.
configs = self.ctx.services.katalogus.get_configs(boefje_id=boefje_task.boefje.id, enabled=True)
for config in configs:
if config.organisation_id == boefje_task.organization:
# Skip the organisation we are currently in
continue

ooi = self.ctx.services.octopoes.get_object(config.organisation_id, boefje_task.input_ooi)

boefje = self.ctx.services.katalogus.get_plugin_by_id_and_org_id(
boefje_task.boefje.id, config.organisation_id
)
# TODO: check if we need this, or if this is already handled
if not self.has_boefje_permission_to_run(boefje, ooi):
self.logger.debug(
"Boefje not allowed to run on ooi",
boefje_id=boefje_task.boefje.id,
ooi_primary_key=ooi.primary_key,
organisation_id=config.organisation_id,
scheduler_id=self.scheduler_id,
)
continue

new_boefje_task = models.BoefjeTask(
boefje=models.Boefje.model_validate(boefje.model_dump()),
input_ooi=ooi.primary_key,
organization=config.organisation_id,
env_hash=boefje.env_hash, # FIXME: get this from config?
)

self.push_boefje_task(
boefje_task=new_boefje_task,
organisation_id=config.organisation_id,
create_schedule=self.create_schedule,
caller=self.is_ooi_in_other_organisations.__name__,
)

def calculate_deadline(self, schedule: models.Schedule) -> models.Schedule:
"""Override Scheduler.calculate_deadline() to calculate the deadline
for a task and based on the boefje interval."""
Expand Down
3 changes: 3 additions & 0 deletions mula/tests/factories/plugin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import uuid

from factory import Factory, LazyFunction, Sequence, fuzzy
from scheduler.models import Plugin
from scheduler.models.ooi import RunOn
Expand All @@ -15,3 +17,4 @@ class Meta:
cron: str | None = None
interval: int | None = None
run_on: RunOn | None = None
env_hash: str = uuid.uuid4().hex
Loading
Loading