Skip to content

Commit

Permalink
add support for netbox 4.2 (#141)
Browse files Browse the repository at this point in the history
  • Loading branch information
amyasnikov committed Jan 22, 2025
1 parent 465d9b3 commit 1633387
Show file tree
Hide file tree
Showing 14 changed files with 87 additions and 16 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
strategy:
fail-fast: false
matrix:
netbox_version: [v4.0.11, v4.1.11]
netbox_version: [v4.0.11, v4.1.11, v4.2.2]
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down Expand Up @@ -61,7 +61,7 @@ jobs:
strategy:
fail-fast: false
matrix:
netbox_version: [v4.0.11, v4.1.3]
netbox_version: [v4.0.11, v4.1.11, v4.2.2]
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion validity/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class NetBoxValidityConfig(PluginConfig):
version = "3.0.5"
base_url = "validity"
django_apps = ["django_bootstrap5"]
min_version = "3.7.0"
min_version = "4.0.0"

# custom field
netbox_version = NetboxVersion(VERSION)
Expand Down
7 changes: 7 additions & 0 deletions validity/models/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from core.models import DataFile, DataSource
from core.signals import post_sync, pre_sync
from django.db.models import Q
from django.urls import reverse
from django.utils import timezone

from validity.j2_env import Environment
Expand All @@ -23,6 +24,9 @@ class VDataFile(DataFile):
class Meta:
proxy = True

def get_absolute_url(self):
return reverse("core:datafile", args=[self.pk])


class VDataSource(DataSource):
objects = VDataSourceQS.as_manager()
Expand Down Expand Up @@ -132,3 +136,6 @@ def sync_in_migration(self, datafile_model: type):
with self._backup_allowed(False):
new_paths = self.partial_sync(Q())
datafile_model.objects.exclude(path__in=new_paths).delete()

def get_absolute_url(self):
return reverse("core:datasource", args=[self.pk])
4 changes: 4 additions & 0 deletions validity/models/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import TYPE_CHECKING, Optional

from dcim.models import Device
from django.urls import reverse

from validity.compliance.serialization import Serializable
from validity.compliance.state import State
Expand Down Expand Up @@ -82,3 +83,6 @@ def primary_ip(self):
return self.primary_ip4
else:
return None

def get_absolute_url(self):
return reverse("dcim:device", args=[self.pk])
4 changes: 2 additions & 2 deletions validity/netbox_changes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
from validity import config


if config.netbox_version >= "4.1.0":
if config.netbox_version >= "4.2.0":
from .current import *
elif config.netbox_version >= "4.0.0":
elif config.netbox_version >= "4.1.0":
from .old import *
else:
from .oldest import *
9 changes: 1 addition & 8 deletions validity/netbox_changes/current.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,2 @@
# NetBox 4.1
from pydoc import locate as __locate

# NetBox 4.2
from .old import *


enqueue_event = __locate("extras.events.enqueue_event")

QUEUE_CREATE_ACTION = "object_created"
8 changes: 7 additions & 1 deletion validity/netbox_changes/old.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# NetBox 4.0
# NetBox 4.1
from pydoc import locate as __locate

from .oldest import *


enqueue_event = __locate("extras.events.enqueue_event")

QUEUE_CREATE_ACTION = "object_created"
2 changes: 1 addition & 1 deletion validity/netbox_changes/oldest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# NetBox 3.7
# NetBox 4.0
from pydoc import locate as __locate


Expand Down
3 changes: 3 additions & 0 deletions validity/template_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@


class PollingInfoExtension(PluginTemplateExtension):
models = ["core.datasource"]
model = "core.datasource"

def get_polling_info(self, data_file) -> str:
Expand All @@ -32,6 +33,7 @@ def right_page(self):


class DataSourceTenantExtension(PluginTemplateExtension):
models = ["core.datasource"]
model = "core.datasource"

def right_page(self):
Expand All @@ -47,6 +49,7 @@ def right_page(self):


class ComplianceTestExtension(PluginTemplateExtension):
models = ["validity.compliancetest"]
model = "validity.compliancetest"

def list_buttons(self):
Expand Down
48 changes: 48 additions & 0 deletions validity/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
from contextlib import contextmanager
from pathlib import Path

import pytest
from core.models import DataSource
from dcim.models import Device, DeviceType, Manufacturer
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.management import call_command
from django.db import connection
from django.test.utils import setup_databases, teardown_databases
from django.utils import timezone
from extras.models import CustomField
from graphene_django.utils.testing import graphql_query
Expand Down Expand Up @@ -103,3 +108,46 @@ def _now(tz):
@pytest.fixture
def launcher_factory(di):
return di[dependencies.launcher_factory]


@contextmanager
def _setup_migrations(use_test_migrations):
class UseTestMigrations:
def __init__(self, getitem_fn):
self.getitem_fn = getitem_fn

def __contains__(self, item):
return True

def __getitem__(self, item):
return self.getitem_fn(item)

if use_test_migrations:
settings.MIGRATION_MODULES = UseTestMigrations(
lambda app: "migrations.apply" if app == "validity" else "migrations.dont_apply"
)
yield
if use_test_migrations:
settings.MIGRATION_MODULES = UseTestMigrations(
lambda app: None
) # force creating the tables according to the models
call_command("migrate", interactive=False, database=connection.alias, run_syncdb=True)
settings.MIGRATION_MODULES = {}


@pytest.fixture(scope="session")
def django_db_setup(request, django_test_environment, django_db_blocker, django_db_use_migrations):
"""
This is the override of pytest-django native fixture.
It allows create the collation first and only then create the tables (many of netbox models require that collation)
"""

with django_db_blocker.unblock(), _setup_migrations(use_test_migrations=not django_db_use_migrations):
db_cfg = setup_databases(verbosity=request.config.option.verbose, interactive=False, serialized_aliases=[])
yield

with django_db_blocker.unblock():
try:
teardown_databases(db_cfg, verbosity=request.config.option.verbose)
except Exception as exc:
request.node.warn(pytest.PytestWarning(f"Error when trying to teardown test databases: {exc!r}"))
11 changes: 11 additions & 0 deletions validity/tests/migrations/apply/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.contrib.postgres.operations import CreateCollation
from django.db import migrations
import sys


class Migration(migrations.Migration):
dependencies = []

operations = [
CreateCollation('natural_sort', provider='icu', locale='und-u-kn-true'),
]
Empty file.
Empty file.
1 change: 0 additions & 1 deletion validity/views/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ def get_queryset(self) -> QuerySet[models.VDevice]:
self.queryset.filter(results__report=self.object)
.annotate_result_stats(self.object.pk, severity_ge)
.prefetch_results(self.object.pk, severity_ge)
.order_by("_name")
)

def get_filterform_initial(self):
Expand Down

0 comments on commit 1633387

Please sign in to comment.