1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

486 lines
13 KiB
Python
Raw Normal View History

2016-03-01 11:23:03 -05:00
from rest_framework import generics
from rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly
from rest_framework.response import Response
from rest_framework.settings import api_settings
from rest_framework.views import APIView
from django.conf import settings
from django.http import Http404
from django.shortcuts import get_object_or_404
2016-05-18 16:02:53 -04:00
from dcim.models import (
2016-07-05 13:43:19 -04:00
ConsolePort, ConsoleServerPort, Device, DeviceBay, DeviceRole, DeviceType, IFACE_FF_VIRTUAL, Interface,
2016-08-10 11:52:27 -04:00
InterfaceConnection, Manufacturer, Module, Platform, PowerOutlet, PowerPort, Rack, RackGroup, RackRole, Site,
2016-05-18 16:02:53 -04:00
)
from dcim import filters
2016-08-22 13:20:30 -04:00
from extras.api.views import CustomFieldModelAPIView
2016-03-07 23:57:49 -06:00
from extras.api.renderers import BINDZoneRenderer, FlatJSONRenderer
2016-03-01 11:23:03 -05:00
from utilities.api import ServiceUnavailable
2016-08-22 13:20:30 -04:00
from .exceptions import MissingFilterException
from . import serializers
2016-03-01 11:23:03 -05:00
#
# Sites
#
2016-08-22 13:20:30 -04:00
class SiteListView(CustomFieldModelAPIView, generics.ListAPIView):
2016-03-01 11:23:03 -05:00
"""
List all sites
"""
2016-08-22 15:16:49 -04:00
queryset = Site.objects.select_related('tenant').prefetch_related('custom_field_values__field')
2016-05-18 16:02:53 -04:00
serializer_class = serializers.SiteSerializer
2016-03-01 11:23:03 -05:00
2016-08-22 13:20:30 -04:00
class SiteDetailView(CustomFieldModelAPIView, generics.RetrieveAPIView):
2016-03-01 11:23:03 -05:00
"""
Retrieve a single site
"""
2016-08-22 15:16:49 -04:00
queryset = Site.objects.select_related('tenant').prefetch_related('custom_field_values__field')
2016-05-18 16:02:53 -04:00
serializer_class = serializers.SiteSerializer
2016-03-01 11:23:03 -05:00
#
# Rack groups
#
class RackGroupListView(generics.ListAPIView):
"""
List all rack groups
"""
2016-07-27 14:40:19 -04:00
queryset = RackGroup.objects.select_related('site')
2016-05-18 16:02:53 -04:00
serializer_class = serializers.RackGroupSerializer
filter_class = filters.RackGroupFilter
2016-03-01 11:23:03 -05:00
class RackGroupDetailView(generics.RetrieveAPIView):
"""
Retrieve a single rack group
"""
2016-07-27 14:40:19 -04:00
queryset = RackGroup.objects.select_related('site')
2016-05-18 16:02:53 -04:00
serializer_class = serializers.RackGroupSerializer
2016-03-01 11:23:03 -05:00
2016-08-10 11:52:27 -04:00
#
# Rack roles
#
class RackRoleListView(generics.ListAPIView):
"""
List all rack roles
"""
queryset = RackRole.objects.all()
serializer_class = serializers.RackRoleSerializer
class RackRoleDetailView(generics.RetrieveAPIView):
"""
Retrieve a single rack role
"""
queryset = RackRole.objects.all()
serializer_class = serializers.RackRoleSerializer
2016-03-01 11:23:03 -05:00
#
# Racks
#
2016-08-22 13:20:30 -04:00
class RackListView(CustomFieldModelAPIView, generics.ListAPIView):
2016-03-01 11:23:03 -05:00
"""
List racks (filterable)
"""
2016-08-22 15:16:49 -04:00
queryset = Rack.objects.select_related('site', 'group__site', 'tenant')\
.prefetch_related('custom_field_values__field')
2016-05-18 16:02:53 -04:00
serializer_class = serializers.RackSerializer
filter_class = filters.RackFilter
2016-03-01 11:23:03 -05:00
2016-08-22 13:20:30 -04:00
class RackDetailView(CustomFieldModelAPIView, generics.RetrieveAPIView):
2016-03-01 11:23:03 -05:00
"""
Retrieve a single rack
"""
2016-08-22 15:16:49 -04:00
queryset = Rack.objects.select_related('site', 'group__site', 'tenant')\
.prefetch_related('custom_field_values__field')
2016-05-18 16:02:53 -04:00
serializer_class = serializers.RackDetailSerializer
2016-03-01 11:23:03 -05:00
#
# Rack units
#
class RackUnitListView(APIView):
"""
List rack units (by rack)
"""
def get(self, request, pk):
rack = get_object_or_404(Rack, pk=pk)
face = request.GET.get('face', 0)
elevation = rack.get_rack_units(face)
# Serialize Devices within the rack elevation
for u in elevation:
if u['device']:
2016-05-18 16:02:53 -04:00
u['device'] = serializers.DeviceNestedSerializer(instance=u['device']).data
2016-03-01 11:23:03 -05:00
return Response(elevation)
#
# Manufacturers
#
class ManufacturerListView(generics.ListAPIView):
"""
List all hardware manufacturers
"""
queryset = Manufacturer.objects.all()
2016-05-18 16:02:53 -04:00
serializer_class = serializers.ManufacturerSerializer
2016-03-01 11:23:03 -05:00
class ManufacturerDetailView(generics.RetrieveAPIView):
"""
Retrieve a single hardware manufacturers
"""
queryset = Manufacturer.objects.all()
2016-05-18 16:02:53 -04:00
serializer_class = serializers.ManufacturerSerializer
2016-03-01 11:23:03 -05:00
#
# Device Types
#
class DeviceTypeListView(generics.ListAPIView):
"""
List device types (filterable)
"""
queryset = DeviceType.objects.select_related('manufacturer')
2016-05-18 16:02:53 -04:00
serializer_class = serializers.DeviceTypeSerializer
filter_class = filters.DeviceTypeFilter
2016-03-01 11:23:03 -05:00
2016-03-08 22:07:47 -05:00
class DeviceTypeDetailView(generics.RetrieveAPIView):
2016-03-01 11:23:03 -05:00
"""
Retrieve a single device type
"""
queryset = DeviceType.objects.select_related('manufacturer')
serializer_class = serializers.DeviceTypeDetailSerializer
2016-03-01 11:23:03 -05:00
#
# Device roles
#
class DeviceRoleListView(generics.ListAPIView):
"""
List all device roles
"""
queryset = DeviceRole.objects.all()
2016-05-18 16:02:53 -04:00
serializer_class = serializers.DeviceRoleSerializer
2016-03-01 11:23:03 -05:00
class DeviceRoleDetailView(generics.RetrieveAPIView):
"""
Retrieve a single device role
"""
queryset = DeviceRole.objects.all()
2016-05-18 16:02:53 -04:00
serializer_class = serializers.DeviceRoleSerializer
2016-03-01 11:23:03 -05:00
#
# Platforms
#
class PlatformListView(generics.ListAPIView):
"""
List all platforms
"""
queryset = Platform.objects.all()
2016-05-18 16:02:53 -04:00
serializer_class = serializers.PlatformSerializer
2016-03-01 11:23:03 -05:00
class PlatformDetailView(generics.RetrieveAPIView):
"""
Retrieve a single platform
"""
queryset = Platform.objects.all()
2016-05-18 16:02:53 -04:00
serializer_class = serializers.PlatformSerializer
2016-03-01 11:23:03 -05:00
#
# Devices
#
2016-08-22 13:20:30 -04:00
class DeviceListView(CustomFieldModelAPIView, generics.ListAPIView):
2016-03-01 11:23:03 -05:00
"""
List devices (filterable)
"""
2016-07-27 13:42:17 -04:00
queryset = Device.objects.select_related('device_type__manufacturer', 'device_role', 'tenant', 'platform',
2016-07-27 14:40:19 -04:00
'rack__site', 'parent_bay').prefetch_related('primary_ip4__nat_outside',
2016-08-22 13:20:30 -04:00
'primary_ip6__nat_outside',
2016-08-22 15:16:49 -04:00
'custom_field_values__field')
2016-05-18 16:02:53 -04:00
serializer_class = serializers.DeviceSerializer
filter_class = filters.DeviceFilter
2016-03-07 23:57:49 -06:00
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES + [BINDZoneRenderer, FlatJSONRenderer]
2016-03-01 11:23:03 -05:00
2016-08-22 13:20:30 -04:00
class DeviceDetailView(CustomFieldModelAPIView, generics.RetrieveAPIView):
2016-03-01 11:23:03 -05:00
"""
Retrieve a single device
"""
2016-07-27 14:40:19 -04:00
queryset = Device.objects.select_related('device_type__manufacturer', 'device_role', 'tenant', 'platform',
2016-08-22 15:16:49 -04:00
'rack__site', 'parent_bay').prefetch_related('custom_field_values__field')
2016-05-18 16:02:53 -04:00
serializer_class = serializers.DeviceSerializer
2016-03-01 11:23:03 -05:00
#
# Console ports
#
class ConsolePortListView(generics.ListAPIView):
"""
List console ports (by device)
"""
2016-05-18 16:02:53 -04:00
serializer_class = serializers.ConsolePortSerializer
2016-03-01 11:23:03 -05:00
def get_queryset(self):
device = get_object_or_404(Device, pk=self.kwargs['pk'])
return ConsolePort.objects.filter(device=device).select_related('cs_port')
class ConsolePortView(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [DjangoModelPermissionsOrAnonReadOnly]
2016-05-18 16:02:53 -04:00
serializer_class = serializers.ConsolePortSerializer
2016-03-01 11:23:03 -05:00
queryset = ConsolePort.objects.all()
#
# Console server ports
#
class ConsoleServerPortListView(generics.ListAPIView):
"""
List console server ports (by device)
"""
2016-05-18 16:02:53 -04:00
serializer_class = serializers.ConsoleServerPortSerializer
2016-03-01 11:23:03 -05:00
def get_queryset(self):
device = get_object_or_404(Device, pk=self.kwargs['pk'])
return ConsoleServerPort.objects.filter(device=device).select_related('connected_console')
#
# Power ports
#
class PowerPortListView(generics.ListAPIView):
"""
List power ports (by device)
"""
2016-05-18 16:02:53 -04:00
serializer_class = serializers.PowerPortSerializer
2016-03-01 11:23:03 -05:00
def get_queryset(self):
device = get_object_or_404(Device, pk=self.kwargs['pk'])
return PowerPort.objects.filter(device=device).select_related('power_outlet')
class PowerPortView(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [DjangoModelPermissionsOrAnonReadOnly]
2016-05-18 16:02:53 -04:00
serializer_class = serializers.PowerPortSerializer
2016-03-01 11:23:03 -05:00
queryset = PowerPort.objects.all()
#
# Power outlets
#
class PowerOutletListView(generics.ListAPIView):
"""
List power outlets (by device)
"""
2016-05-18 16:02:53 -04:00
serializer_class = serializers.PowerOutletSerializer
2016-03-01 11:23:03 -05:00
def get_queryset(self):
device = get_object_or_404(Device, pk=self.kwargs['pk'])
return PowerOutlet.objects.filter(device=device).select_related('connected_port')
#
# Interfaces
#
class InterfaceListView(generics.ListAPIView):
"""
List interfaces (by device)
"""
2016-05-18 16:02:53 -04:00
serializer_class = serializers.InterfaceSerializer
filter_class = filters.InterfaceFilter
2016-03-01 11:23:03 -05:00
def get_queryset(self):
device = get_object_or_404(Device, pk=self.kwargs['pk'])
queryset = Interface.objects.filter(device=device).select_related('connected_as_a', 'connected_as_b')
# Filter by type (physical or virtual)
iface_type = self.request.query_params.get('type')
if iface_type == 'physical':
queryset = queryset.exclude(form_factor=IFACE_FF_VIRTUAL)
elif iface_type == 'virtual':
queryset = queryset.filter(form_factor=IFACE_FF_VIRTUAL)
elif iface_type is not None:
queryset = queryset.empty()
return queryset
class InterfaceDetailView(generics.RetrieveAPIView):
"""
Retrieve a single interface
"""
queryset = Interface.objects.select_related('device')
2016-05-18 16:02:53 -04:00
serializer_class = serializers.InterfaceDetailSerializer
2016-03-01 11:23:03 -05:00
class InterfaceConnectionView(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [DjangoModelPermissionsOrAnonReadOnly]
2016-05-18 16:02:53 -04:00
serializer_class = serializers.InterfaceConnectionSerializer
2016-03-01 11:23:03 -05:00
queryset = InterfaceConnection.objects.all()
class InterfaceConnectionListView(generics.ListAPIView):
"""
Retrieve a list of all interface connections
"""
serializer_class = serializers.InterfaceConnectionSerializer
queryset = InterfaceConnection.objects.all()
2016-07-05 13:43:19 -04:00
#
# Device bays
#
class DeviceBayListView(generics.ListAPIView):
"""
List device bays (by device)
"""
serializer_class = serializers.DeviceBayNestedSerializer
def get_queryset(self):
device = get_object_or_404(Device, pk=self.kwargs['pk'])
return DeviceBay.objects.filter(device=device).select_related('installed_device')
2016-07-05 13:43:19 -04:00
#
# Modules
#
class ModuleListView(generics.ListAPIView):
"""
List device modules (by device)
"""
serializer_class = serializers.ModuleSerializer
def get_queryset(self):
device = get_object_or_404(Device, pk=self.kwargs['pk'])
return Module.objects.filter(device=device).select_related('device', 'manufacturer')
2016-07-05 13:43:19 -04:00
2016-03-01 11:23:03 -05:00
#
# Live queries
#
class LLDPNeighborsView(APIView):
"""
Retrieve live LLDP neighbors of a device
"""
def get(self, request, pk):
device = get_object_or_404(Device, pk=pk)
if not device.primary_ip:
raise ServiceUnavailable(detail="No IP configured for this device.")
RPC = device.get_rpc_client()
if not RPC:
raise ServiceUnavailable(detail="No RPC client available for this platform ({}).".format(device.platform))
# Connect to device and retrieve inventory info
try:
with RPC(device, username=settings.NETBOX_USERNAME, password=settings.NETBOX_PASSWORD) as rpc_client:
lldp_neighbors = rpc_client.get_lldp_neighbors()
except:
raise ServiceUnavailable(detail="Error connecting to the remote device.")
return Response(lldp_neighbors)
#
# Miscellaneous
#
class RelatedConnectionsView(APIView):
"""
Retrieve all connections related to a given console/power/interface connection
"""
def get(self, request):
peer_device = request.GET.get('peer-device')
peer_interface = request.GET.get('peer-interface')
# Search by interface
if peer_device and peer_interface:
# Determine local interface from peer interface's connection
try:
peer_iface = Interface.objects.get(device__name=peer_device, name=peer_interface)
except Interface.DoesNotExist:
raise Http404()
local_iface = peer_iface.get_connected_interface()
if local_iface:
device = local_iface.device
else:
return Response()
else:
raise MissingFilterException(detail='Must specify search parameters "peer-device" and "peer-interface".')
2016-03-01 11:23:03 -05:00
# Initialize response skeleton
response = {
'device': serializers.DeviceSerializer(device).data,
'console-ports': [],
'power-ports': [],
'interfaces': [],
}
# Console connections
2016-03-01 11:23:03 -05:00
console_ports = ConsolePort.objects.filter(device=device).select_related('cs_port__device')
for cp in console_ports:
data = serializers.ConsolePortSerializer(instance=cp).data
del(data['device'])
response['console-ports'].append(data)
2016-03-01 11:23:03 -05:00
# Power connections
2016-03-01 11:23:03 -05:00
power_ports = PowerPort.objects.filter(device=device).select_related('power_outlet__device')
for pp in power_ports:
data = serializers.PowerPortSerializer(instance=pp).data
del(data['device'])
response['power-ports'].append(data)
2016-03-01 11:23:03 -05:00
# Interface connections
interfaces = Interface.objects.filter(device=device).select_related('connected_as_a', 'connected_as_b',
'circuit')
2016-03-01 11:23:03 -05:00
for iface in interfaces:
data = serializers.InterfaceDetailSerializer(instance=iface).data
del(data['device'])
response['interfaces'].append(data)
2016-03-01 11:23:03 -05:00
2016-06-16 15:02:01 -04:00
return Response(response)