Implemented API endpoints for rack reservations

This commit is contained in:
Jeremy Stretch 2017-02-16 13:35:34 -05:00
parent 5c8c0e543f
commit 9da2b8e587
6 changed files with 65 additions and 7 deletions

View File

@ -4,8 +4,8 @@ from ipam.models import IPAddress
from dcim.models import (
ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay, DeviceType,
DeviceRole, Interface, InterfaceConnection, InterfaceTemplate, Manufacturer, Module, Platform, PowerOutlet,
PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack, RackGroup, RackRole, RACK_FACE_FRONT, RACK_FACE_REAR, Site,
SUBDEVICE_ROLE_CHILD, SUBDEVICE_ROLE_PARENT,
PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RACK_FACE_FRONT,
RACK_FACE_REAR, Site, SUBDEVICE_ROLE_CHILD, SUBDEVICE_ROLE_PARENT,
)
from extras.api.serializers import CustomFieldSerializer
from tenancy.api.serializers import TenantNestedSerializer
@ -70,6 +70,12 @@ class RackRoleNestedSerializer(RackRoleSerializer):
# Racks
#
class RackReservationNestedSerializer(serializers.ModelSerializer):
class Meta:
model = RackReservation
fields = ['id', 'units', 'created', 'user', 'description']
class RackSerializer(CustomFieldSerializer, serializers.ModelSerializer):
site = SiteNestedSerializer()
@ -92,10 +98,11 @@ class RackNestedSerializer(RackSerializer):
class RackDetailSerializer(RackSerializer):
front_units = serializers.SerializerMethodField()
rear_units = serializers.SerializerMethodField()
reservations = RackReservationNestedSerializer(many=True)
class Meta(RackSerializer.Meta):
fields = ['id', 'name', 'facility_id', 'display_name', 'site', 'group', 'tenant', 'role', 'type', 'width',
'u_height', 'desc_units', 'comments', 'custom_fields', 'front_units', 'rear_units']
'u_height', 'desc_units', 'reservations', 'comments', 'custom_fields', 'front_units', 'rear_units']
def get_front_units(self, obj):
units = obj.get_rack_units(face=RACK_FACE_FRONT)
@ -110,6 +117,18 @@ class RackDetailSerializer(RackSerializer):
return units
#
# Rack reservations
#
class RackReservationSerializer(serializers.ModelSerializer):
rack = RackNestedSerializer()
class Meta:
model = RackReservation
fields = ['id', 'rack', 'units', 'created', 'user', 'description']
#
# Manufacturers
#

View File

@ -27,6 +27,10 @@ urlpatterns = [
url(r'^racks/(?P<pk>\d+)/$', RackDetailView.as_view(), name='rack_detail'),
url(r'^racks/(?P<pk>\d+)/rack-units/$', RackUnitListView.as_view(), name='rack_units'),
# Rack reservations
url(r'^rack-reservations/$', RackReservationListView.as_view(), name='rackreservation_list'),
url(r'^rack-reservations/(?P<pk>\d+)/$', RackReservationDetailView.as_view(), name='rackreservation_detail'),
# Manufacturers
url(r'^manufacturers/$', ManufacturerListView.as_view(), name='manufacturer_list'),
url(r'^manufacturers/(?P<pk>\d+)/$', ManufacturerDetailView.as_view(), name='manufacturer_detail'),

View File

@ -11,7 +11,8 @@ from django.shortcuts import get_object_or_404
from dcim.models import (
ConsolePort, ConsoleServerPort, Device, DeviceBay, DeviceRole, DeviceType, IFACE_FF_VIRTUAL, Interface,
InterfaceConnection, Manufacturer, Module, Platform, PowerOutlet, PowerPort, Rack, RackGroup, RackRole, Site,
InterfaceConnection, Manufacturer, Module, Platform, PowerOutlet, PowerPort, Rack, RackGroup, RackReservation,
RackRole, Site,
)
from dcim import filters
from extras.api.views import CustomFieldModelAPIView
@ -134,6 +135,27 @@ class RackUnitListView(APIView):
return Response(elevation)
#
# Rack reservations
#
class RackReservationListView(generics.ListAPIView):
"""
List all rack reservation
"""
queryset = RackReservation.objects.all()
serializer_class = serializers.RackReservationSerializer
filter_class = filters.RackReservationFilter
class RackReservationDetailView(generics.RetrieveAPIView):
"""
Retrieve a single rack reservation
"""
queryset = RackReservation.objects.all()
serializer_class = serializers.RackReservationSerializer
#
# Manufacturers
#

View File

@ -8,7 +8,7 @@ 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,
Platform, PowerOutlet, PowerPort, Rack, RackGroup, RackReservation, RackRole, Site,
)
@ -122,6 +122,18 @@ class RackFilter(CustomFieldFilterSet, django_filters.FilterSet):
)
class RackReservationFilter(django_filters.FilterSet):
rack_id = django_filters.ModelMultipleChoiceFilter(
name='rack',
queryset=Rack.objects.all(),
label='Rack (ID)',
)
class Meta:
model = RackReservation
fields = ['rack', 'user']
class DeviceTypeFilter(CustomFieldFilterSet, django_filters.FilterSet):
q = django_filters.MethodFilter(
action='search',

View File

@ -485,10 +485,10 @@ class RackReservation(models.Model):
"""
One or more reserved units within a Rack.
"""
created = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, editable=False, on_delete=models.PROTECT)
rack = models.ForeignKey('Rack', related_name='reservations', editable=False, on_delete=models.CASCADE)
units = ArrayField(models.PositiveSmallIntegerField())
created = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, editable=False, on_delete=models.PROTECT)
description = models.CharField(max_length=100)
class Meta:

View File

@ -151,6 +151,7 @@ class RackTest(APITestCase):
'width',
'u_height',
'desc_units',
'reservations',
'comments',
'custom_fields',
'front_units',