diff --git a/netbox/dcim/api/urls.py b/netbox/dcim/api/urls.py index 7ac824bac..c649d1ab6 100644 --- a/netbox/dcim/api/urls.py +++ b/netbox/dcim/api/urls.py @@ -4,6 +4,7 @@ from rest_framework import routers from extras.models import GRAPH_TYPE_INTERFACE, GRAPH_TYPE_SITE from extras.api.views import GraphListView, TopologyMapView +from ipam.api.views import ChildServiceViewSet from . import views @@ -37,12 +38,12 @@ urlpatterns = [ url(r'^devices/(?P\d+)/lldp-neighbors/$', views.LLDPNeighborsView.as_view(), name='device_lldp-neighbors'), url(r'^devices/(?P\d+)/console-ports/$', views.ChildConsolePortViewSet.as_view({'get': 'list'}), name='consoleport-list'), url(r'^devices/(?P\d+)/console-server-ports/$', views.ChildConsoleServerPortViewSet.as_view({'get': 'list'}), name='consoleserverport-list'), - url(r'^devices/(?P\d+)/power-ports/$', views.NestedPowerPortViewSet.as_view({'get': 'list'}), name='powerport-list'), - url(r'^devices/(?P\d+)/power-outlets/$', views.NestedPowerOutletViewSet.as_view({'get': 'list'}), name='poweroutlet-list'), - url(r'^devices/(?P\d+)/interfaces/$', views.NestedInterfaceViewSet.as_view({'get': 'list'}), name='interface-list'), - url(r'^devices/(?P\d+)/device-bays/$', views.NestedDeviceBayViewSet.as_view({'get': 'list'}), name='devicebay-list'), - url(r'^devices/(?P\d+)/modules/$', views.NestedModuleViewSet.as_view({'get': 'list'}), name='module-list'), - # TODO: Services + url(r'^devices/(?P\d+)/power-ports/$', views.ChildPowerPortViewSet.as_view({'get': 'list'}), name='powerport-list'), + url(r'^devices/(?P\d+)/power-outlets/$', views.ChildPowerOutletViewSet.as_view({'get': 'list'}), name='poweroutlet-list'), + url(r'^devices/(?P\d+)/interfaces/$', views.ChildInterfaceViewSet.as_view({'get': 'list'}), name='interface-list'), + url(r'^devices/(?P\d+)/device-bays/$', views.ChildDeviceBayViewSet.as_view({'get': 'list'}), name='devicebay-list'), + url(r'^devices/(?P\d+)/modules/$', views.ChildModuleViewSet.as_view({'get': 'list'}), name='module-list'), + url(r'^devices/(?P\d+)/services/$', ChildServiceViewSet.as_view({'get': 'list'}), name='service-list'), # Console ports url(r'^console-ports/(?P\d+)/$', views.ConsolePortViewSet.as_view({'get': 'retrieve'}), name='consoleport-detail'), diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index 44ebd4677..b5946ff38 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -151,7 +151,7 @@ class ConsolePortViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin class ChildConsolePortViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): - serializer_class = serializers.ChildConsoleServerPortSerializer + serializer_class = serializers.ChildConsolePortSerializer def get_queryset(self): device = get_object_or_404(Device, pk=self.kwargs['pk']) @@ -186,7 +186,7 @@ class PowerPortViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, serializer_class = serializers.PowerPortSerializer -class NestedPowerPortViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): +class ChildPowerPortViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): serializer_class = serializers.ChildPowerPortSerializer def get_queryset(self): @@ -204,7 +204,7 @@ class PowerOutletViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin serializer_class = serializers.PowerOutletSerializer -class NestedPowerOutletViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): +class ChildPowerOutletViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): serializer_class = serializers.ChildPowerOutletSerializer def get_queryset(self): @@ -222,7 +222,7 @@ class InterfaceViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, serializer_class = serializers.InterfaceDetailSerializer -class NestedInterfaceViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): +class ChildInterfaceViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): serializer_class = serializers.ChildInterfaceSerializer filter_class = filters.InterfaceFilter @@ -242,7 +242,7 @@ class DeviceBayViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, serializer_class = serializers.DeviceBaySerializer -class NestedDeviceBayViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): +class ChildDeviceBayViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): serializer_class = serializers.ChildDeviceBaySerializer def get_queryset(self): @@ -259,7 +259,7 @@ class ModuleViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, Wri serializer_class = serializers.ModuleSerializer -class NestedModuleViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): +class ChildModuleViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): serializer_class = serializers.ChildModuleSerializer def get_queryset(self): diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index 4394cc1a8..8c7fb2fa7 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -189,3 +189,11 @@ class ServiceSerializer(serializers.ModelSerializer): class Meta: model = Service fields = ['id', 'device', 'name', 'port', 'protocol', 'ipaddresses', 'description'] + + +class ChildServiceSerializer(serializers.HyperlinkedModelSerializer): + ipaddresses = NestedIPAddressSerializer(many=True) + + class Meta: + model = Service + fields = ['id', 'url', 'name', 'port', 'protocol', 'ipaddresses', 'description'] diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index 94d1e6814..feedac9a7 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -1,8 +1,13 @@ -from rest_framework.viewsets import ModelViewSet +from django.shortcuts import get_object_or_404 +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 from utilities.api import WritableSerializerMixin from . import serializers @@ -90,7 +95,14 @@ class VLANViewSet(WritableSerializerMixin, CustomFieldModelViewSet): # Services # -class ServiceViewSet(WritableSerializerMixin, ModelViewSet): - queryset = Service.objects.select_related('device').prefetch_related('ipaddresses') +class ServiceViewSet(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, WritableSerializerMixin, GenericViewSet): + queryset = Service.objects.select_related('device') serializer_class = serializers.ServiceSerializer - filter_class = filters.ServiceFilter + + +class ChildServiceViewSet(CreateModelMixin, ListModelMixin, WritableSerializerMixin, GenericViewSet): + serializer_class = serializers.ChildServiceSerializer + + def get_queryset(self): + device = get_object_or_404(Device, pk=self.kwargs['pk']) + return Service.objects.filter(device=device).select_related('device')