from rest_framework.viewsets import ModelViewSet, ViewSet, ReadOnlyModelViewSet from rest_framework.decorators import action from rest_framework.response import Response from .serializers import PreDeviceRoleSerializer from django.conf import settings from utilities.api import IsAuthenticatedOrLoginNotRequired from dcim.models import DeviceRole, Device, Cable class PreSelectDeviceRolesViewSet(ReadOnlyModelViewSet): preselected_device_roles_raw = settings.PLUGINS_CONFIG["netbox_topology_views"]["preselected_device_roles"] preselected_device_roles = preselected_device_roles_raw.split(",") queryset = DeviceRole.objects.filter(name__in=preselected_device_roles) serializer_class = PreDeviceRoleSerializer class SearchViewSet(ViewSet): _ignore_model_permissions = True permission_classes = [IsAuthenticatedOrLoginNotRequired] def _filter(self, site, role, name): filter_devices = Device.objects.all() if name is not None: filter_devices = filter_devices.filter(name__contains=name) if site is not None: filter_devices = filter_devices.filter(site__id__in=site) if role is not None: filter_devices = filter_devices.filter(device_role__id__in=role) return filter_devices @action(detail=False, methods=['post']) def search(self, request): name = None sites = None devicerole = None if "devicerole" in request.data: if request.data["devicerole"]: devicerole = request.data["devicerole"] if "sites" in request.data: if request.data["sites"]: sites = request.data["sites"] if "name" in request.data: if request.data["name"]: name = request.data["name"] devices = self._filter(sites, devicerole, name) nodes = [] edges = [] edge_ids = 0 cable_ids = [] for device in devices: cables = device.get_cables() for cable in cables: if cable.id not in cable_ids: cable_ids.append(cable.id) edge_ids += 1 edge = {} edge["id"] = edge_ids edge["from"] = cable.termination_a.device.id edge["to"] = cable.termination_b.device.id edge["title"] = "Connection between
" + cable.termination_a.device.name + " [" + cable.termination_a.name + "]
" + cable.termination_b.device.name + " [" + cable.termination_b.name + "]" edges.append(edge) node = {} node["id"] = device.id node["name"] = device.name node["label"] = device.name + " " + device.device_type.display_name node["shape"] = 'image' if device.device_role.slug in settings.PLUGINS_CONFIG["netbox_topology_views"]["device_img"]: node["image"] = '../../static/netbox_topology_views/img/' + device.device_role.slug + ".png" else: node["image"] = "../../static/netbox_topology_views/img/role-unknown.png" for device_custom_field in device.custom_field_values.all(): if device_custom_field.field.name == "coordinates": cords = device_custom_field.serialized_value.split(";") node["x"] = int(cords[0]) node["y"] = int(cords[1]) node["physics"] = False nodes.append(node) results = {} results["nodes"] = nodes results["edges"] = edges return Response(results)