diff --git a/netbox/circuits/api/serializers.py b/netbox/circuits/api/serializers.py index 0cc2a277b..ec6d6a18a 100644 --- a/netbox/circuits/api/serializers.py +++ b/netbox/circuits/api/serializers.py @@ -1,7 +1,7 @@ from rest_framework import serializers from circuits.models import Provider, Circuit, CircuitTermination, CircuitType -from dcim.api.serializers import NestedSiteSerializer, DeviceInterfaceSerializer +from dcim.api.serializers import NestedSiteSerializer, InterfaceSerializer from extras.api.serializers import CustomFieldValueSerializer from tenancy.api.serializers import NestedTenantSerializer @@ -63,7 +63,7 @@ class NestedCircuitTypeSerializer(serializers.ModelSerializer): class CircuitTerminationSerializer(serializers.ModelSerializer): site = NestedSiteSerializer() - interface = DeviceInterfaceSerializer() + interface = InterfaceSerializer() class Meta: model = CircuitTermination diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 1585109f1..0fa883d40 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -345,20 +345,18 @@ class WritableDeviceSerializer(serializers.ModelSerializer): # class ConsoleServerPortSerializer(serializers.ModelSerializer): - device = NestedDeviceSerializer(read_only=True) + device = NestedDeviceSerializer() class Meta: model = ConsoleServerPort fields = ['id', 'device', 'name', 'connected_console'] -class DeviceConsoleServerPortSerializer(serializers.ModelSerializer): - url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail') +class WritableConsoleServerPortSerializer(serializers.ModelSerializer): class Meta: model = ConsoleServerPort - fields = ['id', 'url', 'name', 'connected_console'] - read_only_fields = ['connected_console'] + fields = ['id', 'device', 'name', 'connected_console'] # @@ -366,7 +364,7 @@ class DeviceConsoleServerPortSerializer(serializers.ModelSerializer): # class ConsolePortSerializer(serializers.ModelSerializer): - device = NestedDeviceSerializer(read_only=True) + device = NestedDeviceSerializer() cs_port = ConsoleServerPortSerializer() class Meta: @@ -374,13 +372,11 @@ class ConsolePortSerializer(serializers.ModelSerializer): fields = ['id', 'device', 'name', 'cs_port', 'connection_status'] -class DeviceConsolePortSerializer(serializers.ModelSerializer): - url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail') +class WritableConsolePortSerializer(serializers.ModelSerializer): class Meta: model = ConsolePort - fields = ['id', 'url', 'name', 'cs_port', 'connection_status'] - read_only_fields = ['cs_port', 'connection_status'] + fields = ['id', 'device', 'name', 'cs_port', 'connection_status'] # @@ -388,20 +384,18 @@ class DeviceConsolePortSerializer(serializers.ModelSerializer): # class PowerOutletSerializer(serializers.ModelSerializer): - device = NestedDeviceSerializer(read_only=True) + device = NestedDeviceSerializer() class Meta: model = PowerOutlet fields = ['id', 'device', 'name', 'connected_port'] -class DevicePowerOutletSerializer(serializers.ModelSerializer): - url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail') +class WritablePowerOutletSerializer(serializers.ModelSerializer): class Meta: model = PowerOutlet - fields = ['id', 'url', 'name', 'connected_port'] - read_only_fields = ['connected_port'] + fields = ['id', 'device', 'name', 'connected_port'] # @@ -409,7 +403,7 @@ class DevicePowerOutletSerializer(serializers.ModelSerializer): # class PowerPortSerializer(serializers.ModelSerializer): - device = NestedDeviceSerializer(read_only=True) + device = NestedDeviceSerializer() power_outlet = PowerOutletSerializer() class Meta: @@ -417,13 +411,11 @@ class PowerPortSerializer(serializers.ModelSerializer): fields = ['id', 'device', 'name', 'power_outlet', 'connection_status'] -class DevicePowerPortSerializer(serializers.ModelSerializer): - url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail') +class WritablePowerPortSerializer(serializers.ModelSerializer): class Meta: model = PowerPort - fields = ['id', 'url', 'name', 'power_outlet', 'connection_status'] - read_only_fields = ['power_outlet', 'connection_status'] + fields = ['id', 'device', 'name', 'power_outlet', 'connection_status'] # @@ -432,7 +424,7 @@ class DevicePowerPortSerializer(serializers.ModelSerializer): class InterfaceSerializer(serializers.ModelSerializer): - device = NestedDeviceSerializer(read_only=True) + device = NestedDeviceSerializer() connection = serializers.SerializerMethodField(read_only=True) connected_interface = serializers.SerializerMethodField(read_only=True) @@ -463,18 +455,51 @@ class PeerInterfaceSerializer(serializers.ModelSerializer): fields = ['id', 'url', 'device', 'name', 'form_factor', 'mac_address', 'mgmt_only', 'description'] -class DeviceInterfaceSerializer(serializers.ModelSerializer): - url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail') - connection = serializers.SerializerMethodField() +class WritableInterfaceSerializer(serializers.ModelSerializer): class Meta: model = Interface - fields = ['id', 'url', 'name', 'form_factor', 'mac_address', 'mgmt_only', 'description', 'connection'] + fields = ['id', 'device', 'name', 'form_factor', 'mac_address', 'mgmt_only', 'description'] - def get_connection(self, obj): - if obj.connection: - return NestedInterfaceConnectionSerializer(obj.connection, context=self.context).data - return None + +# +# Device bays +# + +class DeviceBaySerializer(serializers.ModelSerializer): + device = NestedDeviceSerializer() + installed_device = NestedDeviceSerializer() + + class Meta: + model = DeviceBay + fields = ['id', 'device', 'name', 'installed_device'] + + +class WritableDeviceBaySerializer(serializers.ModelSerializer): + + class Meta: + model = DeviceBay + fields = ['id', 'device', 'name'] + + +# +# Modules +# + +class ModuleSerializer(serializers.ModelSerializer): + device = NestedDeviceSerializer() + manufacturer = NestedManufacturerSerializer() + + class Meta: + model = Module + fields = ['id', 'device', 'parent', 'name', 'manufacturer', 'part_id', 'serial', 'discovered'] + + +class WritableModuleSerializer(serializers.ModelSerializer): + + class Meta: + model = Module + fields = ['id', 'device', 'parent', 'name', 'manufacturer', 'part_id', 'serial', 'discovered'] # @@ -503,47 +528,3 @@ class WritableInterfaceConnectionSerializer(serializers.ModelSerializer): class Meta: model = InterfaceConnection fields = ['id', 'interface_a', 'interface_b', 'connection_status'] - - -# -# Device bays -# - -class DeviceBaySerializer(serializers.ModelSerializer): - device = NestedDeviceSerializer(read_only=True) - installed_device = NestedDeviceSerializer() - - class Meta: - model = DeviceBay - fields = ['id', 'device', 'name', 'installed_device'] - - -class DeviceDeviceBaySerializer(serializers.ModelSerializer): - url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicebay-detail') - - class Meta: - model = DeviceBay - fields = ['id', 'url', 'name', 'installed_device'] - read_only_fields = ['installed_device'] - - -# -# Modules -# - -class ModuleSerializer(serializers.ModelSerializer): - device = NestedDeviceSerializer(read_only=True) - manufacturer = NestedManufacturerSerializer() - - class Meta: - model = Module - fields = ['id', 'device', 'parent', 'name', 'manufacturer', 'part_id', 'serial', 'discovered'] - - -class DeviceModuleSerializer(serializers.ModelSerializer): - url = serializers.HyperlinkedIdentityField(view_name='dcim-api:module-detail') - manufacturer = NestedManufacturerSerializer() - - class Meta: - model = Module - fields = ['id', 'url', 'name', 'manufacturer', 'part_id', 'serial', 'discovered'] diff --git a/netbox/dcim/api/urls.py b/netbox/dcim/api/urls.py index 0bf692dbb..1ce2b518f 100644 --- a/netbox/dcim/api/urls.py +++ b/netbox/dcim/api/urls.py @@ -3,7 +3,7 @@ from django.conf.urls import include, url from rest_framework import routers from extras.api.views import TopologyMapView -from ipam.api.views import ServiceViewSet, DeviceServiceViewSet +from ipam.api.views import ServiceViewSet from . import views @@ -21,37 +21,29 @@ router.register(r'racks', views.RackViewSet) router.register(r'manufacturers', views.ManufacturerViewSet) router.register(r'device-types', views.DeviceTypeViewSet) +# TODO: Device type components + # Devices router.register(r'device-roles', views.DeviceRoleViewSet) router.register(r'platforms', views.PlatformViewSet) router.register(r'devices', views.DeviceViewSet) + +# Device components router.register(r'console-ports', views.ConsolePortViewSet) router.register(r'console-server-ports', views.ConsoleServerPortViewSet) router.register(r'power-ports', views.PowerPortViewSet) router.register(r'power-outlets', views.PowerOutletViewSet) router.register(r'interfaces', views.InterfaceViewSet) -router.register(r'interface-connections', views.InterfaceConnectionViewSet) router.register(r'device-bays', views.DeviceBayViewSet) router.register(r'modules', views.ModuleViewSet) router.register(r'services', ServiceViewSet) -# TODO: Device type components - -# Device components -device_router = routers.DefaultRouter() -device_router.register(r'console-ports', views.DeviceConsolePortViewSet, base_name='consoleport') -device_router.register(r'console-server-ports', views.DeviceConsoleServerPortViewSet, base_name='consoleserverport') -device_router.register(r'power-ports', views.DevicePowerPortViewSet, base_name='powerport') -device_router.register(r'power-outlets', views.DevicePowerOutletViewSet, base_name='poweroutlet') -device_router.register(r'interfaces', views.DeviceInterfaceViewSet, base_name='interface') -device_router.register(r'device-bays', views.DeviceDeviceBayViewSet, base_name='devicebay') -device_router.register(r'modules', views.DeviceModuleViewSet, base_name='module') -device_router.register(r'services', DeviceServiceViewSet, base_name='service') +# Interface connections +router.register(r'interface-connections', views.InterfaceConnectionViewSet) urlpatterns = [ url(r'', include(router.urls)), - url(r'^devices/(?P\d+)/', include(device_router.urls)), # Miscellaneous url(r'^related-connections/$', views.RelatedConnectionsView.as_view(), name='related_connections'), diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index 27724e289..4c7899a6a 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -1,11 +1,8 @@ from rest_framework.decorators import detail_route -from rest_framework.mixins import ( - CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin, -) from rest_framework.response import Response from rest_framework.settings import api_settings from rest_framework.views import APIView -from rest_framework.viewsets import GenericViewSet, ModelViewSet +from rest_framework.viewsets import ModelViewSet from django.conf import settings from django.contrib.contenttypes.models import ContentType @@ -175,101 +172,42 @@ class DeviceViewSet(WritableSerializerMixin, CustomFieldModelViewSet): # -# Console Ports +# Device components # -class ConsolePortViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin, - GenericViewSet): - queryset = ConsolePort.objects.select_related('cs_port') +class ConsolePortViewSet(WritableSerializerMixin, ModelViewSet): + queryset = ConsolePort.objects.select_related('device', 'cs_port__device') serializer_class = serializers.ConsolePortSerializer + write_serializer_class= serializers.WritableConsolePortSerializer + filter_class = filters.ConsolePortFilter -class DeviceConsolePortViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): - serializer_class = serializers.DeviceConsolePortSerializer - - def get_queryset(self): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - return ConsolePort.objects.filter(device=device).select_related('cs_port') - - def perform_create(self, serializer): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - serializer.save(device=device) - - -# -# Console Server Ports -# - -class ConsoleServerPortViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin, - GenericViewSet): - queryset = ConsoleServerPort.objects.select_related('connected_console') +class ConsoleServerPortViewSet(WritableSerializerMixin, ModelViewSet): + queryset = ConsoleServerPort.objects.select_related('device', 'connected_console__device') serializer_class = serializers.ConsoleServerPortSerializer + write_serializer_class= serializers.WritableConsoleServerPortSerializer + filter_class = filters.ConsoleServerPortFilter -class DeviceConsoleServerPortViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): - serializer_class = serializers.DeviceConsoleServerPortSerializer - - def get_queryset(self): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - return ConsoleServerPort.objects.filter(device=device).select_related('connected_console') - - def perform_create(self, serializer): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - serializer.save(device=device) - - -# -# Power Ports -# - -class PowerPortViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin, - GenericViewSet): - queryset = PowerPort.objects.select_related('power_outlet') +class PowerPortViewSet(WritableSerializerMixin, ModelViewSet): + queryset = PowerPort.objects.select_related('device', 'power_outlet__device') serializer_class = serializers.PowerPortSerializer + write_serializer_class= serializers.WritablePowerPortSerializer + filter_class = filters.PowerPortFilter -class DevicePowerPortViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): - serializer_class = serializers.DevicePowerPortSerializer - - def get_queryset(self): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - return PowerPort.objects.filter(device=device).select_related('power_outlet') - - def perform_create(self, serializer): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - serializer.save(device=device) - - -# -# Power Outlets -# - -class PowerOutletViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin, - GenericViewSet): - queryset = PowerOutlet.objects.select_related('connected_port') +class PowerOutletViewSet(WritableSerializerMixin, ModelViewSet): + queryset = PowerOutlet.objects.select_related('device', 'connected_port__device') serializer_class = serializers.PowerOutletSerializer + write_serializer_class= serializers.WritablePowerOutletSerializer + filter_class = filters.PowerOutletFilter -class DevicePowerOutletViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): - serializer_class = serializers.DevicePowerOutletSerializer - - def get_queryset(self): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - return PowerOutlet.objects.filter(device=device).select_related('connected_port') - - def perform_create(self, serializer): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - serializer.save(device=device) - - -# -# Interfaces -# - -class InterfaceViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin, - GenericViewSet): +class InterfaceViewSet(WritableSerializerMixin, ModelViewSet): queryset = Interface.objects.select_related('device') serializer_class = serializers.InterfaceSerializer + write_serializer_class= serializers.WritableInterfaceSerializer + filter_class = filters.InterfaceFilter @detail_route() def graphs(self, request, pk=None): @@ -279,61 +217,18 @@ class InterfaceViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, return Response(serializer.data) -class DeviceInterfaceViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): - serializer_class = serializers.DeviceInterfaceSerializer - filter_class = filters.InterfaceFilter - - def get_queryset(self): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - return Interface.objects.order_naturally(device.device_type.interface_ordering).filter(device=device)\ - .select_related('connected_as_a', 'connected_as_b', 'circuit_termination') - - def perform_create(self, serializer): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - serializer.save(device=device) - - -# -# Device bays -# - -class DeviceBayViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin, - GenericViewSet): +class DeviceBayViewSet(WritableSerializerMixin, ModelViewSet): queryset = DeviceBay.objects.select_related('installed_device') serializer_class = serializers.DeviceBaySerializer + write_serializer_class= serializers.WritableDeviceBaySerializer + filter_class = filters.DeviceBayFilter -class DeviceDeviceBayViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): - serializer_class = serializers.DeviceDeviceBaySerializer - - def get_queryset(self): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - return DeviceBay.objects.filter(device=device).select_related('installed_device') - - def perform_create(self, serializer): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - serializer.save(device=device) - - -# -# Modules -# - -class ModuleViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin, GenericViewSet): +class ModuleViewSet(WritableSerializerMixin, ModelViewSet): queryset = Module.objects.select_related('device', 'manufacturer') serializer_class = serializers.ModuleSerializer - - -class DeviceModuleViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): - serializer_class = serializers.DeviceModuleSerializer - - def get_queryset(self): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - return Module.objects.filter(device=device).select_related('device', 'manufacturer') - - def perform_create(self, serializer): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - serializer.save(device=device) + write_serializer_class= serializers.WritableModuleSerializer + filter_class = filters.ModuleFilter # diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index 79024b605..60db5913a 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -7,8 +7,8 @@ from extras.filters import CustomFieldFilterSet from tenancy.models import Tenant from utilities.filters import NullableModelMultipleChoiceFilter from .models import ( - ConsolePort, ConsoleServerPort, Device, DeviceRole, DeviceType, Interface, InterfaceConnection, Manufacturer, - Platform, PowerOutlet, PowerPort, Rack, RackGroup, RackRole, Site, + ConsolePort, ConsoleServerPort, Device, DeviceBay, DeviceRole, DeviceType, Interface, InterfaceConnection, + Manufacturer, Module, Platform, PowerOutlet, PowerPort, Rack, RackGroup, RackRole, Site, ) @@ -368,6 +368,42 @@ class InterfaceFilter(django_filters.FilterSet): fields = ['name'] +class DeviceBayFilter(django_filters.FilterSet): + device_id = django_filters.ModelMultipleChoiceFilter( + name='device', + queryset=Device.objects.all(), + label='Device (ID)', + ) + device = django_filters.ModelMultipleChoiceFilter( + name='device', + queryset=Device.objects.all(), + to_field_name='name', + label='Device (name)', + ) + + class Meta: + model = DeviceBay + fields = ['name'] + + +class ModuleFilter(django_filters.FilterSet): + device_id = django_filters.ModelMultipleChoiceFilter( + name='device', + queryset=Device.objects.all(), + label='Device (ID)', + ) + device = django_filters.ModelMultipleChoiceFilter( + name='device', + queryset=Device.objects.all(), + to_field_name='name', + label='Device (name)', + ) + + class Meta: + model = Module + fields = ['name'] + + class ConsoleConnectionFilter(django_filters.FilterSet): site = django_filters.MethodFilter( action='filter_site', diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index 9104f55b9..bf7cf6e49 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -1,6 +1,6 @@ from rest_framework import serializers -from dcim.api.serializers import NestedDeviceSerializer, DeviceInterfaceSerializer, NestedSiteSerializer +from dcim.api.serializers import NestedDeviceSerializer, InterfaceSerializer, NestedSiteSerializer from extras.api.serializers import CustomFieldValueSerializer from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF from tenancy.api.serializers import NestedTenantSerializer @@ -207,7 +207,7 @@ class WritablePrefixSerializer(serializers.ModelSerializer): class IPAddressSerializer(serializers.ModelSerializer): vrf = NestedVRFSerializer() tenant = NestedTenantSerializer() - interface = DeviceInterfaceSerializer() + interface = InterfaceSerializer() custom_field_values = CustomFieldValueSerializer(many=True) class Meta: @@ -249,10 +249,8 @@ class ServiceSerializer(serializers.ModelSerializer): fields = ['id', 'device', 'name', 'port', 'protocol', 'ipaddresses', 'description'] -class DeviceServiceSerializer(serializers.ModelSerializer): - url = serializers.HyperlinkedIdentityField(view_name='ipam-api:service-detail') - ipaddresses = NestedIPAddressSerializer(many=True) +class WritableServiceSerializer(serializers.ModelSerializer): class Meta: model = Service - fields = ['id', 'url', 'name', 'port', 'protocol', 'ipaddresses', 'description'] + fields = ['id', 'device', 'name', 'port', 'protocol', 'ipaddresses', 'description'] diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index a95784578..3bd1f71c3 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -1,11 +1,5 @@ -from django.shortcuts import get_object_or_404 +from rest_framework.viewsets import ModelViewSet -from rest_framework.mixins import ( - CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin, -) -from rest_framework.viewsets import GenericViewSet, ModelViewSet - -from dcim.models import Device from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF from ipam import filters from extras.api.views import CustomFieldModelViewSet @@ -101,14 +95,7 @@ class VLANViewSet(WritableSerializerMixin, CustomFieldModelViewSet): # Services # -class ServiceViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin, GenericViewSet): +class ServiceViewSet(WritableSerializerMixin, ModelViewSet): queryset = Service.objects.select_related('device') serializer_class = serializers.ServiceSerializer - - -class DeviceServiceViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): - serializer_class = serializers.DeviceServiceSerializer - - def get_queryset(self): - device = get_object_or_404(Device, pk=self.kwargs['pk']) - return Service.objects.filter(device=device).select_related('device') + write_serializer_class = serializers.WritableServiceSerializer