diff --git a/netbox/dcim/api/urls.py b/netbox/dcim/api/urls.py index f648c869d..c7177aa8b 100644 --- a/netbox/dcim/api/urls.py +++ b/netbox/dcim/api/urls.py @@ -50,7 +50,9 @@ router.register(r'interfaces', views.InterfaceViewSet) router.register(r'device-bays', views.DeviceBayViewSet) router.register(r'inventory-items', views.InventoryItemViewSet) -# Interface connections +# Connections +router.register(r'console-connections', views.ConsoleConnectionViewSet, base_name='consoleconnections') +router.register(r'power-connections', views.PowerConnectionViewSet, base_name='powerconnections') router.register(r'interface-connections', views.InterfaceConnectionViewSet) # Miscellaneous diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index 1b6da12ba..67ea8504e 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -1,7 +1,8 @@ from rest_framework.decorators import detail_route +from rest_framework.mixins import ListModelMixin from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response -from rest_framework.viewsets import ModelViewSet, ViewSet +from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet, ViewSet from django.conf import settings from django.shortcuts import get_object_or_404 @@ -303,9 +304,21 @@ class InventoryItemViewSet(WritableSerializerMixin, ModelViewSet): # -# Interface connections +# Connections # +class ConsoleConnectionViewSet(ListModelMixin, GenericViewSet): + queryset = ConsolePort.objects.select_related('device', 'cs_port__device').filter(cs_port__isnull=False) + serializer_class = serializers.ConsolePortSerializer + filter_class = filters.ConsoleConnectionFilter + + +class PowerConnectionViewSet(ListModelMixin, GenericViewSet): + queryset = PowerPort.objects.select_related('device', 'power_outlet__device').filter(power_outlet__isnull=False) + serializer_class = serializers.PowerPortSerializer + filter_class = filters.PowerConnectionFilter + + class InterfaceConnectionViewSet(WritableSerializerMixin, ModelViewSet): queryset = InterfaceConnection.objects.select_related('interface_a__device', 'interface_b__device') serializer_class = serializers.InterfaceConnectionSerializer diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index 720cd0161..7992f8e05 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -494,6 +494,10 @@ class ConsoleConnectionFilter(django_filters.FilterSet): label='Device', ) + class Meta: + model = ConsolePort + fields = ['name', 'connection_status'] + def filter_site(self, queryset, name, value): if not value.strip(): return queryset @@ -518,6 +522,10 @@ class PowerConnectionFilter(django_filters.FilterSet): label='Device', ) + class Meta: + model = PowerPort + fields = ['name', 'connection_status'] + def filter_site(self, queryset, name, value): if not value.strip(): return queryset diff --git a/netbox/dcim/tests/test_api.py b/netbox/dcim/tests/test_api.py index ef8c6f299..2f3b38449 100644 --- a/netbox/dcim/tests/test_api.py +++ b/netbox/dcim/tests/test_api.py @@ -1933,6 +1933,92 @@ class InventoryItemTest(HttpStatusMixin, APITestCase): self.assertEqual(InventoryItem.objects.count(), 2) +class ConsoleConnectionTest(HttpStatusMixin, APITestCase): + + def setUp(self): + + user = User.objects.create(username='testuser', is_superuser=True) + token = Token.objects.create(user=user) + self.header = {'HTTP_AUTHORIZATION': 'Token {}'.format(token.key)} + + site = Site.objects.create(name='Test Site 1', slug='test-site-1') + manufacturer = Manufacturer.objects.create(name='Test Manufacturer 1', slug='test-manufacturer-1') + devicetype = DeviceType.objects.create( + manufacturer=manufacturer, model='Test Device Type 1', slug='test-device-type-1' + ) + devicerole = DeviceRole.objects.create( + name='Test Device Role 1', slug='test-device-role-1', color='ff0000' + ) + device1 = Device.objects.create( + device_type=devicetype, device_role=devicerole, name='Test Device 1', site=site + ) + device2 = Device.objects.create( + device_type=devicetype, device_role=devicerole, name='Test Device 2', site=site + ) + cs_port1 = ConsoleServerPort.objects.create(device=device1, name='Test CS Port 1') + cs_port2 = ConsoleServerPort.objects.create(device=device1, name='Test CS Port 2') + cs_port3 = ConsoleServerPort.objects.create(device=device1, name='Test CS Port 3') + ConsolePort.objects.create( + device=device2, cs_port=cs_port1, name='Test Console Port 1', connection_status=True + ) + ConsolePort.objects.create( + device=device2, cs_port=cs_port2, name='Test Console Port 2', connection_status=True + ) + ConsolePort.objects.create( + device=device2, cs_port=cs_port3, name='Test Console Port 3', connection_status=True + ) + + def test_list_consoleconnections(self): + + url = reverse('dcim-api:consoleconnections-list') + response = self.client.get(url, **self.header) + + self.assertEqual(response.data['count'], 3) + + +class PowerConnectionTest(HttpStatusMixin, APITestCase): + + def setUp(self): + + user = User.objects.create(username='testuser', is_superuser=True) + token = Token.objects.create(user=user) + self.header = {'HTTP_AUTHORIZATION': 'Token {}'.format(token.key)} + + site = Site.objects.create(name='Test Site 1', slug='test-site-1') + manufacturer = Manufacturer.objects.create(name='Test Manufacturer 1', slug='test-manufacturer-1') + devicetype = DeviceType.objects.create( + manufacturer=manufacturer, model='Test Device Type 1', slug='test-device-type-1' + ) + devicerole = DeviceRole.objects.create( + name='Test Device Role 1', slug='test-device-role-1', color='ff0000' + ) + device1 = Device.objects.create( + device_type=devicetype, device_role=devicerole, name='Test Device 1', site=site + ) + device2 = Device.objects.create( + device_type=devicetype, device_role=devicerole, name='Test Device 2', site=site + ) + power_outlet1 = PowerOutlet.objects.create(device=device1, name='Test Power Outlet 1') + power_outlet2 = PowerOutlet.objects.create(device=device1, name='Test Power Outlet 2') + power_outlet3 = PowerOutlet.objects.create(device=device1, name='Test Power Outlet 3') + PowerPort.objects.create( + device=device2, power_outlet=power_outlet1, name='Test Power Port 1', connection_status=True + ) + PowerPort.objects.create( + device=device2, power_outlet=power_outlet2, name='Test Power Port 2', connection_status=True + ) + PowerPort.objects.create( + device=device2, power_outlet=power_outlet3, name='Test Power Port 3', connection_status=True + ) + + def test_list_powerconnections(self): + + url = reverse('dcim-api:powerconnections-list') + response = self.client.get(url, **self.header) + + self.assertEqual(response.data['count'], 3) + + class InterfaceConnectionTest(HttpStatusMixin, APITestCase): def setUp(self):