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

Feature/boefje normalizer config models #3118

Merged
merged 47 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
f7749e9
WIP: removed references to Repositories
Donnype May 21, 2024
d137794
Create brute-force migration
Donnype May 22, 2024
8736f9f
Fix migrations test setup
Donnype May 22, 2024
72f7ba1
Fail explicitly on non-local plugins being present
Donnype May 22, 2024
e12961e
More cleanup, renaming and moving code to create the structure we use…
Donnype May 23, 2024
ef3d4d0
PR feedback: Base64Str type for env vars
Donnype May 28, 2024
4211d4b
Fix test comment on revision id
Donnype May 28, 2024
b7cd08e
Add database models for boefje and normalizer
Donnype May 28, 2024
21852a5
Add repository and api for boefje and normalizer models
Donnype May 28, 2024
943965e
Add patch and delete endpoints including tests
Donnype May 28, 2024
7e09f73
Some style fixes, comments, and cleaning of errors and context manage…
Donnype May 29, 2024
79cc0eb
Fix settings api bug
Donnype May 29, 2024
8790ab9
Change environment keys backward compatible
Donnype May 29, 2024
46e00ba
Fix KATalogus entrypoints
Donnype May 29, 2024
27324d0
Merge branch 'feature/persisting-plugins' into feature/boefje-normali…
Donnype May 29, 2024
6eac6e3
Merge branch 'main' into feature/persisting-plugins
Donnype May 30, 2024
aa9f613
Documentation on phasing out the repository model in the release notes
Donnype May 30, 2024
a599337
Merge branch 'feature/persisting-plugins' into feature/boefje-normali…
Donnype May 30, 2024
38a330f
Merge branch 'main' into feature/persisting-plugins
Donnype May 30, 2024
a5740d5
Merge branch 'feature/persisting-plugins' into feature/boefje-normali…
Donnype May 30, 2024
3eebead
Merge branch 'main' into feature/boefje-normalizer-models
Donnype May 30, 2024
daba33b
Refactor katalogus code location and add boefje and normalizer config…
Donnype Jun 1, 2024
bd25215
Disable the option to edit the id field on boefje and normalizers
Donnype Jun 1, 2024
6b3b7ce
Merge branch 'feature/boefje-normalizer-models' into feature/boefje-n…
Donnype Jun 1, 2024
50ed342
Add first migration test for upgrades
Donnype Jun 1, 2024
b64eefc
Add downgrade test and fix the related issues
Donnype Jun 1, 2024
d26d517
Migrate plugin_state as well
Donnype Jun 2, 2024
79e3ee7
Do not allow CRUD operations for local (static) plugins
Donnype Jun 4, 2024
242cd9c
Merge branch 'main' into feature/boefje-normalizer-models
Donnype Jun 7, 2024
f02ec3c
Merge branch 'main' into feature/boefje-normalizer-models
Donnype Jun 11, 2024
b53fcee
Rename Patch models
Donnype Jun 11, 2024
94d4228
Merge branch 'feature/boefje-normalizer-models' into feature/boefje-n…
Donnype Jun 11, 2024
424e05c
Merge branch 'main' into feature/boefje-normalizer-models
stephanie0x00 Jun 12, 2024
5b6d5a7
Merge branch 'main' into feature/boefje-normalizer-models
Donnype Jun 13, 2024
8253cef
Add static field in the database as well
Donnype Jun 13, 2024
073e175
Merge branch 'main' into feature/boefje-normalizer-models
underdarknl Jun 13, 2024
1662bcb
Merge branch 'main' into feature/boefje-normalizer-models
underdarknl Jun 17, 2024
d40c066
Merge branch 'main' into feature/boefje-normalizer-models
underdarknl Jun 18, 2024
50a3561
Merge branch 'main' into feature/boefje-normalizer-models
Donnype Jun 20, 2024
484eb0e
Merge branch 'feature/boefje-normalizer-models' into feature/boefje-n…
Donnype Jun 20, 2024
5b95ab6
Revert automatically refactored changes from values to settings
Donnype Jun 20, 2024
d481b56
Merge branch 'main' into feature/boefje-normalizer-config-models
Donnype Jun 24, 2024
c1fa3b6
PR feedback: some simplifications
Donnype Jul 2, 2024
537e22c
Merge branch 'main' into feature/boefje-normalizer-config-models
Donnype Jul 2, 2024
b0d7f98
Merge branch 'main' into feature/boefje-normalizer-config-models
Donnype Jul 4, 2024
e167467
Merge branch 'main' into feature/boefje-normalizer-config-models
Donnype Jul 9, 2024
094779d
Merge branch 'main' into feature/boefje-normalizer-config-models
underdarknl Jul 9, 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
2 changes: 1 addition & 1 deletion boefjes/.ci/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ services:
dockerfile: boefjes/Dockerfile
args:
- ENVIRONMENT=dev
command: sh -c 'python -m pytest -v boefjes/katalogus/tests/integration'
command: sh -c 'python -m pytest -v tests/integration'
depends_on:
- ci_katalogus-db
env_file:
Expand Down
2 changes: 1 addition & 1 deletion boefjes/boefjes/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from boefjes.config import settings
from boefjes.job_handler import get_environment_settings, get_octopoes_api_connector, serialize_ooi
from boefjes.job_models import BoefjeMeta
from boefjes.katalogus.local_repository import LocalPluginRepository, get_local_repository
from boefjes.local_repository import LocalPluginRepository, get_local_repository
from boefjes.plugins.models import _default_mime_types
from octopoes.models import Reference
from octopoes.models.exception import ObjectNotFoundException
Expand Down
2 changes: 1 addition & 1 deletion boefjes/boefjes/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
)
from boefjes.config import Settings
from boefjes.job_handler import BoefjeHandler, NormalizerHandler, bytes_api_client
from boefjes.katalogus.local_repository import get_local_repository
from boefjes.local import LocalBoefjeJobRunner, LocalNormalizerJobRunner
from boefjes.local_repository import get_local_repository
from boefjes.runtime_interfaces import Handler, WorkerManager

logger = logging.getLogger(__name__)
Expand Down
2 changes: 1 addition & 1 deletion boefjes/boefjes/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from pydantic_settings import BaseSettings, PydanticBaseSettingsSource, SettingsConfigDict
from pydantic_settings.sources import EnvSettingsSource

from boefjes.katalogus.models import EncryptionMiddleware
from boefjes.models import EncryptionMiddleware

BASE_DIR: Path = Path(__file__).parent.resolve()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,19 @@
from jsonschema.validators import validate
from sqlalchemy.orm import Session

from boefjes.katalogus.local_repository import LocalPluginRepository, get_local_repository
from boefjes.katalogus.models import Boefje, FilterParameters, Normalizer, PaginationParameters, PluginType
from boefjes.katalogus.storage.interfaces import (
from boefjes.local_repository import LocalPluginRepository, get_local_repository
from boefjes.models import Boefje, FilterParameters, Normalizer, PaginationParameters, PluginType
from boefjes.sql.config_storage import create_config_storage
from boefjes.sql.db import session_managed_iterator
from boefjes.sql.plugin_storage import create_plugin_storage
from boefjes.storage.interfaces import (
ConfigStorage,
ExistingPluginId,
NotFound,
PluginEnabledStorage,
PluginNotFound,
PluginStorage,
SettingsNotConformingToSchema,
SettingsStorage,
)
from boefjes.sql.db import session_managed_iterator
from boefjes.sql.plugin_enabled_storage import create_plugin_enabled_storage
from boefjes.sql.plugin_storage import create_plugin_storage
from boefjes.sql.setting_storage import create_setting_storage

logger = logging.getLogger(__name__)

Expand All @@ -31,33 +30,29 @@ class PluginService:
def __init__(
self,
plugin_storage: PluginStorage,
plugin_enabled_store: PluginEnabledStorage,
settings_storage: SettingsStorage,
config_storage: ConfigStorage,
local_repo: LocalPluginRepository,
):
self.plugin_storage = plugin_storage
self.plugin_enabled_store = plugin_enabled_store
self.settings_storage = settings_storage
self.config_storage = config_storage
self.local_repo = local_repo

def __enter__(self):
self.plugin_enabled_store.__enter__()
self.plugin_storage.__enter__()
self.settings_storage.__enter__()
self.config_storage.__enter__()

return self

def __exit__(self, exc_type, exc_val, exc_tb):
self.plugin_enabled_store.__exit__(exc_type, exc_val, exc_tb)
self.plugin_storage.__exit__(exc_type, exc_val, exc_tb)
self.settings_storage.__exit__(exc_type, exc_val, exc_tb)
self.config_storage.__exit__(exc_type, exc_val, exc_tb)

def get_all(self, organisation_id: str) -> list[PluginType]:
all_plugins = self.get_all_without_enabled()
all_plugins = self._get_all_without_enabled()

return [self._set_plugin_enabled(plugin, organisation_id) for plugin in all_plugins.values()]

def get_all_without_enabled(self):
def _get_all_without_enabled(self):
all_plugins = {plugin.id: plugin for plugin in self.local_repo.get_all()}

for plugin in self.plugin_storage.get_all():
Expand Down Expand Up @@ -88,24 +83,25 @@ def by_plugin_ids(self, plugin_ids: list[str], organisation_id: str) -> list[Plu
return found_plugins

def get_all_settings(self, organisation_id: str, plugin_id: str):
return self.settings_storage.get_all(organisation_id, plugin_id)
return self.config_storage.get_all_settings(organisation_id, plugin_id)

def clone_settings_to_organisation(self, from_organisation: str, to_organisation: str):
# One requirement is that only boefjes enabled in the from_organisation end up being enabled for the target.
for plugin_id in self.plugin_enabled_store.get_all_enabled(to_organisation):
for plugin_id in self.config_storage.get_enabled_boefjes(to_organisation):
self.set_enabled_by_id(plugin_id, to_organisation, enabled=False)

for plugin in self.get_all(from_organisation):
if all_settings := self.get_all_settings(from_organisation, plugin.id):
self.upsert_settings(all_settings, to_organisation, plugin.id)

for plugin_id in self.plugin_enabled_store.get_all_enabled(from_organisation):
for plugin_id in self.config_storage.get_enabled_boefjes(from_organisation):
self.set_enabled_by_id(plugin_id, to_organisation, enabled=True)

def upsert_settings(self, values: dict, organisation_id: str, plugin_id: str):
self._assert_settings_match_schema(values, organisation_id, plugin_id)
def upsert_settings(self, settings: dict, organisation_id: str, plugin_id: str):
self._assert_settings_match_schema(settings, organisation_id, plugin_id)
self._put_boefje(plugin_id)

return self.settings_storage.upsert(values, organisation_id, plugin_id)
return self.config_storage.upsert(organisation_id, plugin_id, settings=settings)

def create_boefje(self, boefje: Boefje) -> None:
try:
Expand All @@ -121,8 +117,38 @@ def create_normalizer(self, normalizer: Normalizer) -> None:
except KeyError:
self.plugin_storage.create_normalizer(normalizer)

def _put_boefje(self, boefje_id: str) -> None:
"""Check existence of a boefje, and insert a database entry if it concerns a local boefje"""

try:
self.plugin_storage.boefje_by_id(boefje_id)
except PluginNotFound:
try:
plugin = self.local_repo.by_id(boefje_id)
except KeyError:
raise

if plugin.type != "boefje":
raise
self.plugin_storage.create_boefje(plugin)

def _put_normalizer(self, normalizer_id: str) -> None:
"""Check existence of a normalizer, and insert a database entry if it concerns a local normalizer"""

try:
self.plugin_storage.normalizer_by_id(normalizer_id)
except PluginNotFound:
try:
plugin = self.local_repo.by_id(normalizer_id)
except KeyError:
raise

if plugin.type != "normalizer":
raise
self.plugin_storage.create_normalizer(plugin)

def delete_settings(self, organisation_id: str, plugin_id: str):
self.settings_storage.delete(organisation_id, plugin_id)
self.config_storage.delete(organisation_id, plugin_id)

try:
self._assert_settings_match_schema({}, organisation_id, plugin_id)
Expand Down Expand Up @@ -154,14 +180,15 @@ def description(self, plugin_id: str, organisation_id: str) -> str:

def set_enabled_by_id(self, plugin_id: str, organisation_id: str, enabled: bool):
if enabled:
all_settings = self.settings_storage.get_all(organisation_id, plugin_id)
all_settings = self.get_all_settings(organisation_id, plugin_id)
self._assert_settings_match_schema(all_settings, organisation_id, plugin_id)

self.plugin_enabled_store.update_or_create_by_id(
plugin_id,
enabled,
organisation_id,
)
try:
self._put_boefje(plugin_id)
except PluginNotFound:
self._put_normalizer(plugin_id)

self.config_storage.upsert(organisation_id, plugin_id, enabled=enabled)

def _assert_settings_match_schema(self, all_settings: dict, organisation_id: str, plugin_id: str):
schema = self.schema(plugin_id)
Expand All @@ -174,7 +201,7 @@ def _assert_settings_match_schema(self, all_settings: dict, organisation_id: str

def _set_plugin_enabled(self, plugin: PluginType, organisation_id: str) -> PluginType:
with contextlib.suppress(KeyError, NotFound):
plugin.enabled = self.plugin_enabled_store.get_by_id(plugin.id, organisation_id)
plugin.enabled = self.config_storage.is_enabled_by_id(plugin.id, organisation_id)

return plugin

Expand All @@ -183,8 +210,7 @@ def get_plugin_service(organisation_id: str) -> Iterator[PluginService]:
def closure(session: Session):
return PluginService(
create_plugin_storage(session),
create_plugin_enabled_storage(session),
create_setting_storage(session),
create_config_storage(session),
get_local_repository(),
)

Expand Down
2 changes: 1 addition & 1 deletion boefjes/boefjes/docker_boefjes_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from boefjes.clients.scheduler_client import SchedulerAPIClient, TaskStatus
from boefjes.config import settings
from boefjes.job_models import BoefjeMeta
from boefjes.katalogus.models import Boefje
from boefjes.models import Boefje

logger = logging.getLogger(__name__)

Expand Down
2 changes: 1 addition & 1 deletion boefjes/boefjes/job_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from boefjes.config import settings
from boefjes.docker_boefjes_runner import DockerBoefjesRunner
from boefjes.job_models import BoefjeMeta, NormalizerMeta, SerializedOOI, SerializedOOIValue
from boefjes.katalogus.local_repository import LocalPluginRepository
from boefjes.local_repository import LocalPluginRepository
from boefjes.plugins.models import _default_mime_types
from boefjes.runtime_interfaces import BoefjeJobRunner, Handler, NormalizerJobRunner
from octopoes.api.models import Affirmation, Declaration, Observation
Expand Down
12 changes: 0 additions & 12 deletions boefjes/boefjes/katalogus/dependencies/organisations.py

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from fastapi import APIRouter, Depends, HTTPException, status

from boefjes.katalogus.dependencies.organisations import get_organisations_store
from boefjes.katalogus.models import Organisation
from boefjes.katalogus.storage.interfaces import OrganisationNotFound, OrganisationStorage
from boefjes.models import Organisation
from boefjes.sql.db import ObjectNotFoundException
from boefjes.sql.organisation_storage import get_organisations_store
from boefjes.storage.interfaces import OrganisationNotFound, OrganisationStorage

router = APIRouter(prefix="/organisations", tags=["organisations"])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
from fastapi.responses import FileResponse, JSONResponse, Response
from pydantic import BaseModel, Field

from boefjes.katalogus.api.organisations import check_organisation_exists
from boefjes.katalogus.dependencies.plugins import (
from boefjes.dependencies.plugins import (
PluginService,
get_pagination_parameters,
get_plugin_service,
get_plugins_filter_parameters,
)
from boefjes.katalogus.models import FilterParameters, PaginationParameters, PluginType
from boefjes.katalogus.storage.interfaces import PluginStorage
from boefjes.katalogus.organisations import check_organisation_exists
from boefjes.models import FilterParameters, PaginationParameters, PluginType
from boefjes.sql.plugin_storage import get_plugin_storage
from boefjes.storage.interfaces import PluginStorage

router = APIRouter(
prefix="/organisations/{organisation_id}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
from pydantic import BaseModel, Field

from boefjes.config import settings
from boefjes.katalogus.api import organisations, plugins
from boefjes.katalogus.api import settings as settings_router
from boefjes.katalogus.storage.interfaces import NotFound, StorageError
from boefjes.katalogus import organisations, plugins
from boefjes.katalogus import settings as settings_router
from boefjes.katalogus.version import __version__
from boefjes.storage.interfaces import NotAllowed, NotFound, StorageError

with settings.log_cfg.open() as f:
logging.config.dictConfig(json.load(f))
Expand Down Expand Up @@ -59,6 +59,14 @@ def entity_not_found_handler(request: Request, exc: NotFound):
)


@app.exception_handler(NotAllowed)
def not_allowed_handler(request: Request, exc: NotAllowed):
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content={"message": exc.message},
)


@app.exception_handler(StorageError)
def storage_error_handler(request: Request, exc: StorageError):
return JSONResponse(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from fastapi import APIRouter, Depends

from boefjes.katalogus.api.organisations import check_organisation_exists
from boefjes.katalogus.dependencies.plugins import PluginService, get_plugin_service
from boefjes.dependencies.plugins import PluginService, get_plugin_service
from boefjes.katalogus.organisations import check_organisation_exists

router = APIRouter(
prefix="/organisations/{organisation_id}/{plugin_id}/settings",
Expand Down
Empty file.
2 changes: 1 addition & 1 deletion boefjes/boefjes/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
NormalizerResults,
ObservationsWithoutInputOOI,
)
from boefjes.katalogus.local_repository import LocalPluginRepository
from boefjes.local_repository import LocalPluginRepository
from boefjes.runtime_interfaces import BoefjeJobRunner, JobRuntimeError, NormalizerJobRunner
from octopoes.models import OOI, DeclaredScanProfile

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from pathlib import Path
from typing import Any

from boefjes.katalogus.models import PluginType
from boefjes.models import PluginType
from boefjes.plugins.models import (
BOEFJE_DEFINITION_FILE,
BOEFJES_DIR,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
from sqlalchemy.engine import Connection
from sqlalchemy.orm import sessionmaker

from boefjes.sql.config_storage import create_encrypter
from boefjes.sql.db import get_engine
from boefjes.sql.setting_storage import create_encrypter

# revision identifiers, used by Alembic.
revision = "cd34fdfafdaf"
Expand Down
Loading