Browse Source

Cleaned up API for virtual chassis

Jeremy Stretch 7 years ago
parent
commit
25ad58d42c
4 changed files with 29 additions and 12 deletions
  1. 15 4
      netbox/dcim/api/serializers.py
  2. 2 1
      netbox/dcim/api/views.py
  3. 5 0
      netbox/dcim/filters.py
  4. 7 7
      netbox/dcim/models.py

+ 15 - 4
netbox/dcim/api/serializers.py

@@ -476,6 +476,16 @@ class NestedClusterSerializer(serializers.ModelSerializer):
         fields = ['id', 'url', 'name']
 
 
+# Cannot import NestedVirtualChassisSerializer due to circular dependency
+class DeviceVirtualChassisSerializer(serializers.ModelSerializer):
+    url = serializers.HyperlinkedIdentityField(view_name='dcim-api:virtualchassis-detail')
+    master = NestedDeviceSerializer()
+
+    class Meta:
+        model = VirtualChassis
+        fields = ['id', 'url', 'master']
+
+
 class DeviceSerializer(CustomFieldModelSerializer):
     device_type = NestedDeviceTypeSerializer()
     device_role = NestedDeviceRoleSerializer()
@@ -490,13 +500,14 @@ class DeviceSerializer(CustomFieldModelSerializer):
     primary_ip6 = DeviceIPAddressSerializer()
     parent_device = serializers.SerializerMethodField()
     cluster = NestedClusterSerializer()
+    virtual_chassis = DeviceVirtualChassisSerializer()
 
     class Meta:
         model = Device
         fields = [
             'id', 'name', 'display_name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag',
-            'site', 'rack', 'position', 'face', 'parent_device', 'virtual_chassis', 'status', 'primary_ip',
-            'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'comments', 'custom_fields', 'created',
+            'site', 'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4', 'primary_ip6',
+            'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'comments', 'custom_fields', 'created',
             'last_updated',
         ]
 
@@ -517,8 +528,8 @@ class WritableDeviceSerializer(CustomFieldModelSerializer):
         model = Device
         fields = [
             'id', 'name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag', 'site', 'rack',
-            'position', 'face', 'status', 'primary_ip4', 'primary_ip6', 'cluster', 'comments', 'custom_fields',
-            'created', 'last_updated',
+            'position', 'face', 'status', 'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'vc_position',
+            'vc_priority', 'comments', 'custom_fields', 'created', 'last_updated',
         ]
         validators = []
 

+ 2 - 1
netbox/dcim/api/views.py

@@ -235,7 +235,8 @@ class PlatformViewSet(ModelViewSet):
 
 class DeviceViewSet(CustomFieldModelViewSet):
     queryset = Device.objects.select_related(
-        'device_type__manufacturer', 'device_role', 'tenant', 'platform', 'site', 'rack', 'parent_bay', 'vc_membership',
+        'device_type__manufacturer', 'device_role', 'tenant', 'platform', 'site', 'rack', 'parent_bay',
+        'virtual_chassis__master',
     ).prefetch_related(
         'primary_ip4__nat_outside', 'primary_ip6__nat_outside',
     )

+ 5 - 0
netbox/dcim/filters.py

@@ -487,6 +487,11 @@ class DeviceFilter(CustomFieldFilterSet, django_filters.FilterSet):
         method='_has_primary_ip',
         label='Has a primary IP',
     )
+    virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
+        name='virtual_chassis',
+        queryset=VirtualChassis.objects.all(),
+        label='Virtual chassis (ID)',
+    )
 
     class Meta:
         model = Device

+ 7 - 7
netbox/dcim/models.py

@@ -1078,8 +1078,8 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
     def display_name(self):
         if self.name:
             return self.name
-        elif hasattr(self, 'vc_membership') and self.vc_membership.virtual_chassis.master.name:
-            return "{}:{}".format(self.vc_membership.virtual_chassis.master, self.vc_membership.position)
+        elif hasattr(self, 'virtual_chassis') and self.virtual_chassis.master.name:
+            return "{}:{}".format(self.virtual_chassis.master, self.vc_position)
         elif hasattr(self, 'device_type'):
             return "{}".format(self.device_type)
         return ""
@@ -1108,8 +1108,8 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
         """
         If this Device is a VirtualChassis member, return the VC master. Otherwise, return None.
         """
-        if hasattr(self, 'vc_membership'):
-            return self.vc_membership.virtual_chassis.master
+        if hasattr(self, 'virtual_chassis'):
+            return self.virtual_chassis.master
         else:
             return None
 
@@ -1117,11 +1117,11 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
     def vc_interfaces(self):
         """
         Return a QuerySet matching all Interfaces assigned to this Device or, if this Device is a VC master, to another
-        Device belonging to the same virtual chassis.
+        Device belonging to the same VirtualChassis.
         """
         filter = Q(device=self)
-        if hasattr(self, 'vc_membership') and self.vc_membership.is_master:
-            filter |= Q(device__vc_membership__virtual_chassis=self.vc_membership.virtual_chassis, mgmt_only=False)
+        if hasattr(self, 'virtual_chassis') and self.virtual_chassis.master == self:
+            filter |= Q(device__virtual_chassis=self.virtual_chassis, mgmt_only=False)
         return Interface.objects.filter(filter)
 
     def get_children(self):