Skip to content

Commit

Permalink
Merge pull request #24 from netbox-community/v1.1.2
Browse files Browse the repository at this point in the history
Patches
  • Loading branch information
minitriga authored Oct 1, 2024
2 parents 2bc16d6 + c4bf573 commit 95f089a
Show file tree
Hide file tree
Showing 16 changed files with 1,854 additions and 324 deletions.
3 changes: 3 additions & 0 deletions .djlintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"ignore": "H021,H023"
}
5 changes: 5 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@ repos:
args: [ --fix ]
# Run the formatter.
- id: ruff-format
- repo: https://github.com/djlint/djLint
rev: v1.35.2
hooks:
- id: djlint-reformat-django
- id: djlint-django
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ systemctl restart netbox

| netbox version | plugin version |
| -------------- | ----------------------------- |
| >= 4.0.0 | >= v1.1.0 |
| >= 4.0.0 < 4.1.0 | >= v1.1.2 |
| <= 4.0.0 | = v1.0.0 |

## Dependencies
Expand All @@ -57,7 +57,7 @@ Python:

Javascript:
- Gridstack (Currently running same versions as Netbox)
- Bootsrap (Currently running same versions as Netbox)
- Bootstrap (Currently running same versions as Netbox)

### Update

Expand Down
2 changes: 1 addition & 1 deletion netbox_reorder_rack/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class NetboxReorderRackConfig(PluginConfig):
name = "netbox_reorder_rack"
verbose_name = "NetBox Reorder Rack"
description = "NetBox plugin to reorder rack layouts."
version = "1.1.1"
version = "1.1.2"
base_url = "reorder"


Expand Down
121 changes: 102 additions & 19 deletions netbox_reorder_rack/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,24 @@
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.db import transaction
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from rest_framework import status
from rest_framework import viewsets
from rest_framework.exceptions import PermissionDenied
from rest_framework.response import Response
from utilities.permissions import get_permission_for_model


def get_device_name(device):
if device.virtual_chassis:
name = f"{device.virtual_chassis.name}:{device.vc_position}"
elif device.name:
name = device.name
else:
name = str(device.device_type)

return name


class ReorderRackSerializer(serializers.Serializer):
Expand All @@ -26,34 +40,103 @@ class SaveViewSet(PermissionRequiredMixin, viewsets.ViewSet):

def update(self, request, pk):
rack = get_object_or_404(Rack, pk=pk)
permission = get_permission_for_model(Device, "change")

# Validate input using serializer
serializer = ReorderRackSerializer(data=request.data)
serializer.is_valid(raise_exception=True)

try:
serializer = ReorderRackSerializer(request.data)
with transaction.atomic():
for device in rack.devices.all():
device.position = None
device.clean()
device.save()
changes_made = False # Flag to track if any changes were made

for new in request.data["front"]:
device = rack.devices.filter(pk=new["id"]).first()
device.position = decimal.Decimal(new["y"])
device.face = new["face"]
device.clean()
device.save()
with transaction.atomic():
# Update devices in different categories
changes_made |= self._update_device_positions(
request,
rack,
serializer.validated_data["front"],
permission,
"front",
)
changes_made |= self._update_device_positions(
request, rack, serializer.validated_data["rear"], permission, "rear"
)
changes_made |= self._update_device_positions(
request,
rack,
serializer.validated_data["other"],
permission,
"other",
is_other=True,
)

for new in request.data["rear"]:
device = rack.devices.filter(pk=new["id"]).first()
device.position = decimal.Decimal(new["y"])
device.face = new["face"]
device.clean()
device.save()
# If no changes were made, return 304 or a custom response
if not changes_made:
return Response(
{"message": "No changes detected."},
status=status.HTTP_304_NOT_MODIFIED,
)

return Response(
{"message": "POST request received", "data": serializer.data},
{
"message": "Devices reordered successfully",
"data": serializer.data,
},
status=status.HTTP_201_CREATED,
)
except PermissionDenied as e:
return Response(
{"message": "Permission denied", "error": str(e)},
status=status.HTTP_403_FORBIDDEN,
)
except Exception as e:
return Response(
{"message": "Error saving data", "error": str(e)},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)

def _update_device_positions(
self, request, rack, device_data_list, permission, device_type, is_other=False
):
"""Helper method to update device positions based on the category."""
changes_made = False # Local flag to track if changes are made

for device_data in device_data_list:
device = rack.devices.filter(pk=device_data["id"]).first()
current_device = get_object_or_404(
Device.objects.restrict(request.user), pk=device_data["id"]
)

if is_other:
if device.position != device_data["y"]:
device.position = None
device.face = ""
self._check_permission(request, device, permission)

# Save the device and mark changes as made
device.clean()
device.save()
changes_made = True
# Update position and face for 'front' and 'rear' devices if changed
elif not is_other:
if current_device.face != device_data[
"face"
] or device.position != decimal.Decimal(device_data["y"]):
device.position = decimal.Decimal(device_data["y"])
device.face = device_data["face"]

self._check_permission(request, device, permission)

# Save the device and mark changes as made
device.clean()
device.save()
changes_made = True

return changes_made # Return whether changes were made

def _check_permission(self, request, device, permission):
"""Helper method to check if the user has permission for the device."""
if not request.user.has_perm(permission, obj=device):
raise PermissionDenied(
_(f"You do not have permissions to edit {get_device_name(device)}.")
)
13 changes: 10 additions & 3 deletions netbox_reorder_rack/static/netbox_reorder_rack/js/rack.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions netbox_reorder_rack/static/netbox_reorder_rack/js/rack.js.map

Large diffs are not rendered by default.

Loading

0 comments on commit 95f089a

Please sign in to comment.