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

Closes #37: Add role field to ConfigDiffScript #42

Merged
merged 1 commit into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 2 additions & 2 deletions docs/colliecting-diffs.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ You can find scripts list in navbar `Customization -> Scripts`.

![Screenshot of the scripts list](media/screenshots/script-list.png)

In the script, you can define a site, on which devices run compliance, or devices.
If you define both fields, script will run only on devices from `Devices` field
In the script, you can define a site or role, on which devices run compliance, or devices.
If you define all fields, script will run only on devices from `Devices` field

!!! warning
Script runs only on devices with assigned Primary IP, Platform and PlatformSetting
Expand Down
Binary file modified docs/media/screenshots/script.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 23 additions & 9 deletions netbox_config_diff/compliance/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
from core.choices import DataSourceStatusChoices
from core.models import DataFile, DataSource
from dcim.choices import DeviceStatusChoices
from dcim.models import Device, Site
from dcim.models import Device, DeviceRole, Site
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q
from extras.scripts import MultiObjectVar, ObjectVar
Expand All @@ -27,14 +28,19 @@ class ConfigDiffBase(SecretsMixin):
required=False,
description="Run compliance for devices (with primary IP, platform) in this site",
)
role = ObjectVar(
model=DeviceRole,
required=False,
description="Run compliance for devices with this role",
)
devices = MultiObjectVar(
model=Device,
required=False,
query_params={
"has_primary_ip": True,
"platform_id__n": "null",
},
description="If you define devices in this field, the Site field will be ignored",
description="If you define devices in this field, Site, Role fields will be ignored",
)
status = CustomChoiceVar(
choices=DeviceStatusChoices,
Expand All @@ -57,8 +63,8 @@ def run_script(self, data: dict) -> None:
self.update_in_db(devices)

def validate_data(self, data: dict) -> Iterable[Device]:
if not data["site"] and not data["devices"]:
raise AbortScript("Define site or devices")
if not data["site"] and not data["role"] and not data["devices"]:
raise AbortScript("Define site, role or devices")
if data.get("data_source") and data["data_source"].status != DataSourceStatusChoices.COMPLETED:
raise AbortScript("Define synced DataSource")

Expand All @@ -75,13 +81,21 @@ def validate_data(self, data: dict) -> Iterable[Device]:
)
)
else:
devices = Device.objects.filter(
site=data["site"],
status=data["status"],
platform__platform_setting__isnull=False,
).exclude(
filters = {
"status": data["status"],
"platform__platform_setting__isnull": False,
}
if data["site"]:
filters["site"] = data["site"]
elif data["role"]:
if settings.VERSION.split(".", 1)[1].startswith("5"):
filters["device_role"] = data["role"]
else:
filters["role"] = data["role"]
devices = Device.objects.filter(**filters).exclude(
Q(primary_ip4__isnull=True) & Q(primary_ip6__isnull=True),
)

if data.get("devices"):
if qs_diff := data["devices"].difference(devices):
platforms = {d.platform.name for d in qs_diff}
Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def script_data_factory() -> "ScriptDataFactory":
def factory(**fields: Unpack["ScriptData"]) -> "ScriptData":
data = {
"site": None,
"role": None,
"devices": None,
"data_source": None,
"status": "active",
Expand Down
2 changes: 1 addition & 1 deletion tests/test_compliance.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
def test_validate_data_no_data(mock_config_diff: "ConfigDiffBase", script_data: "ScriptData") -> None:
with pytest.raises(AbortScript) as e:
mock_config_diff.validate_data(data=script_data)
assert str(e.value) == "Define site or devices"
assert str(e.value) == "Define site, role or devices"


@pytest.mark.django_db()
Expand Down