diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 37f756e..86ee444 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: strategy: fail-fast: false matrix: - netbox_version: &nb_versions [v4.4.10, v4.5.8, v4.6.3] + netbox_version: &nb_versions [v4.5.8, v4.6.10, v4.7.0] steps: - name: Checkout uses: actions/checkout@v3 diff --git a/development/docker-compose.yaml b/development/docker-compose.yaml index 18d44c5..a1075ca 100644 --- a/development/docker-compose.yaml +++ b/development/docker-compose.yaml @@ -34,7 +34,7 @@ services: postgres: - image: postgres:14-alpine + image: postgres:17-alpine env_file: .env healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB} -h 127.0.0.1"] diff --git a/validity/__init__.py b/validity/__init__.py index 42eb5ff..74a3eb0 100644 --- a/validity/__init__.py +++ b/validity/__init__.py @@ -19,8 +19,8 @@ class NetBoxValidityConfig(PluginConfig): version = "3.5.2" base_url = "validity" django_apps = ["django_bootstrap5"] - min_version = "4.4.0" - max_version = "4.6.99" + min_version = "4.5.0" + max_version = "4.7.99" graphql_schema = "graphql.schema" # custom field diff --git a/validity/graphql/filters.py b/validity/graphql/filters.py index be8397f..92c9662 100644 --- a/validity/graphql/filters.py +++ b/validity/graphql/filters.py @@ -6,11 +6,12 @@ from core.models import Job from dcim.graphql.filters import DeviceFilter from django.db.models import Q, QuerySet +from netbox.graphql.filters import BaseModelFilter, NetBoxModelFilter from strawberry.scalars import ID from strawberry_django import FilterLookup from validity import models -from validity.netbox_changes import BaseModelFilter, NetBoxModelFilter, StrFilterLookup +from validity.netbox_changes import StrFilterLookup @strawberry_django.filter_type(Job, lookups=True) diff --git a/validity/graphql/types.py b/validity/graphql/types.py index 0e055ca..13c8a8b 100644 --- a/validity/graphql/types.py +++ b/validity/graphql/types.py @@ -25,7 +25,7 @@ @strawberry_django.type( Job, - fields="__all__", + exclude=["execution_time"], ) class VJobType(BaseObjectType): pass diff --git a/validity/netbox_changes/__init__.py b/validity/netbox_changes/__init__.py index b24bc2b..f0be5a4 100644 --- a/validity/netbox_changes/__init__.py +++ b/validity/netbox_changes/__init__.py @@ -16,9 +16,9 @@ def get_base_table_kwargs(self): StrFilterLookup = locate("strawberry_django.StrFilterLookup") if config.netbox_version >= "4.5.5" else FilterLookup[str] -if config.netbox_version >= "4.6.0": +if config.netbox_version >= "4.7.0": from .current import * -elif config.netbox_version >= "4.5.0": +elif config.netbox_version >= "4.6.0": from .old import * else: from .oldest import * diff --git a/validity/netbox_changes/current.py b/validity/netbox_changes/current.py index 8be04bb..6e8ac5f 100644 --- a/validity/netbox_changes/current.py +++ b/validity/netbox_changes/current.py @@ -1,8 +1,4 @@ -# NetBox 4.6 +# NetBox 4.7 -from pydoc import locate from .old import * - - -ChoicesType = locate("django.db.models.enums.ChoicesType") diff --git a/validity/netbox_changes/old.py b/validity/netbox_changes/old.py index 0e0b170..44b8474 100644 --- a/validity/netbox_changes/old.py +++ b/validity/netbox_changes/old.py @@ -1,8 +1,7 @@ -# NetBox 4.5 +# NetBox 4.6 from pydoc import locate from .oldest import * -BaseModelFilter = locate("netbox.graphql.filters.BaseModelFilter") -NetBoxModelFilter = locate("netbox.graphql.filters.NetBoxModelFilter") +ChoicesType = locate("django.db.models.enums.ChoicesType") diff --git a/validity/netbox_changes/oldest.py b/validity/netbox_changes/oldest.py index 37eb854..0b220b6 100644 --- a/validity/netbox_changes/oldest.py +++ b/validity/netbox_changes/oldest.py @@ -1,7 +1,5 @@ -# NetBox 4.4 +# NetBox 4.5 from pydoc import locate -BaseModelFilter = locate("netbox.graphql.filter_mixins.BaseFilterMixin") -NetBoxModelFilter = locate("netbox.graphql.filter_mixins.NetBoxModelFilterMixin") ChoicesType = locate("django.db.models.enums.ChoicesMeta") diff --git a/validity/scripts/keeper.py b/validity/scripts/keeper.py index 8c0d7fb..4dc0c08 100644 --- a/validity/scripts/keeper.py +++ b/validity/scripts/keeper.py @@ -27,11 +27,11 @@ def __enter__(self): def __exit__(self, exc_type, exc, tb): with self.logger: if exc_type: - return self.terminate_errored_job(exc) + self.terminate_errored_job(exc) elif self.job.status == JobStatusChoices.STATUS_RUNNING and self.auto_terminate: self.terminate_job() - def terminate_errored_job(self, error: Exception) -> bool: + def terminate_errored_job(self, error: Exception) -> None: if isinstance(error, AbortScript): self.logger.messages.extend(error.logs) self.logger.failure(str(error)) @@ -41,7 +41,6 @@ def terminate_errored_job(self, error: Exception) -> bool: status = JobStatusChoices.STATUS_ERRORED self.error_callback(self, error) self.terminate_job(status=status, error=repr(error)) - return isinstance(error, AbortScript) def terminate_job( self, status: str = JobStatusChoices.STATUS_COMPLETED, error: str | None = None, output=None diff --git a/validity/tests/migrations/apply/0001_initial.py b/validity/tests/migrations/apply/0001_initial.py index 4ee1beb..2eef623 100644 --- a/validity/tests/migrations/apply/0001_initial.py +++ b/validity/tests/migrations/apply/0001_initial.py @@ -1,4 +1,4 @@ -from django.contrib.postgres.operations import CreateCollation +from django.contrib.postgres.operations import CreateCollation, CreateExtension from django.db import migrations import sys @@ -8,4 +8,5 @@ class Migration(migrations.Migration): operations = [ CreateCollation('natural_sort', provider='icu', locale='und-u-kn-true'), + CreateExtension('ltree'), ] diff --git a/validity/tests/test_scripts/runtests/test_combine.py b/validity/tests/test_scripts/runtests/test_combine.py index 93de6b4..e4cfeae 100644 --- a/validity/tests/test_scripts/runtests/test_combine.py +++ b/validity/tests/test_scripts/runtests/test_combine.py @@ -7,6 +7,7 @@ from validity.scripts.data_models import ExecutionResult, Message from validity.scripts.data_models import TestResultRatio as ResultRatio +from validity.scripts.exceptions import AbortScript from validity.scripts.runtests.combine import CombineWorker from validity.utils.logger import Logger @@ -55,7 +56,8 @@ def test_call_abort(worker, full_runtests_params, job_extractor, monkeypatch): job_extractor.parents[1].job.result.errored = True monkeypatch.setattr(timezone, "now", lambda: datetime.datetime(2020, 1, 1)) worker.job_extractor_factory = lambda: job_extractor - worker(full_runtests_params) + with pytest.raises(AbortScript): + worker(full_runtests_params) job = full_runtests_params.get_job() assert job.status == "errored" assert job.log_entries == [ diff --git a/validity/tests/test_scripts/test_backup.py b/validity/tests/test_scripts/test_backup.py index fbc5ebd..1d80ba7 100644 --- a/validity/tests/test_scripts/test_backup.py +++ b/validity/tests/test_scripts/test_backup.py @@ -9,6 +9,7 @@ from validity.integrations.errors import IntegrationError from validity.scripts.backup import perform_backup from validity.scripts.data_models import FullBackUpParams +from validity.scripts.exceptions import AbortScript @pytest.fixture @@ -41,7 +42,7 @@ def test_backup_success(di, params): def test_backup_failure(di, params): job = params.get_job() backend = Mock(side_effect=IntegrationError("ERROR!!!")) - with di.override({BackupBackend: lambda: backend}): + with pytest.raises(AbortScript), di.override({BackupBackend: lambda: backend}): perform_backup(params) backend.assert_called_once_with(job.object) job.refresh_from_db() diff --git a/validity/tests/test_scripts/test_keeper.py b/validity/tests/test_scripts/test_keeper.py index aa8fac3..d010860 100644 --- a/validity/tests/test_scripts/test_keeper.py +++ b/validity/tests/test_scripts/test_keeper.py @@ -23,9 +23,10 @@ def test_keeper_noerror(timezone_now): @pytest.mark.django_db def test_keeper_abort(timezone_now): timezone_now(datetime.datetime(2000, 1, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc)) - with JobKeeper(job=DSBackupJobFactory(), logger=Logger()) as keeper: - keeper.logger.info("msg1") - raise AbortScript("abort_msg", logs=[Message("warning", "extra_msg")]) + with pytest.raises(AbortScript): + with JobKeeper(job=DSBackupJobFactory(), logger=Logger()) as keeper: + keeper.logger.info("msg1") + raise AbortScript("abort_msg", logs=[Message("warning", "extra_msg")]) keeper.job.refresh_from_db() assert keeper.job.status == "failed" assert keeper.job.log_entries == [