diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 47eb4a7e4..eea9d45b5 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -488,14 +488,15 @@ class DeviceSerializer(CustomFieldModelSerializer): primary_ip4 = DeviceIPAddressSerializer() primary_ip6 = DeviceIPAddressSerializer() parent_device = serializers.SerializerMethodField() + virtual_chassis = serializers.SerializerMethodField() cluster = NestedClusterSerializer() class Meta: model = Device fields = [ 'id', 'name', 'display_name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag', - 'site', 'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4', 'primary_ip6', - 'cluster', 'comments', 'custom_fields', 'created', 'last_updated', + 'site', 'rack', 'position', 'face', 'parent_device', 'virtual_chassis', 'status', 'primary_ip', + 'primary_ip4', 'primary_ip6', 'cluster', 'comments', 'custom_fields', 'created', 'last_updated', ] def get_parent_device(self, obj): @@ -508,6 +509,16 @@ class DeviceSerializer(CustomFieldModelSerializer): data['device_bay'] = NestedDeviceBaySerializer(instance=device_bay, context=context).data return data + def get_virtual_chassis(self, obj): + try: + vc_membership = obj.vc_membership + except VCMembership.DoesNotExist: + return None + context = {'request': self.context['request']} + data = NestedVirtualChassisSerializer(instance=vc_membership.virtual_chassis, context=context).data + data['vc_membership'] = NestedVCMembershipSerializer(instance=vc_membership, context=context).data + return data + class WritableDeviceSerializer(CustomFieldModelSerializer): @@ -855,6 +866,14 @@ class VCMembershipSerializer(serializers.ModelSerializer): fields = ['id', 'virtual_chassis', 'device', 'position', 'is_master', 'priority'] +class NestedVCMembershipSerializer(serializers.ModelSerializer): + url = serializers.HyperlinkedIdentityField(view_name='dcim-api:vcmembership-detail') + + class Meta: + model = VCMembership + fields = ['id', 'url', 'position', 'is_master', 'priority'] + + class WritableVCMembershipSerializer(ValidatedModelSerializer): class Meta: diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index 6b5334057..23cafe6af 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -235,7 +235,7 @@ class PlatformViewSet(ModelViewSet): class DeviceViewSet(CustomFieldModelViewSet): queryset = Device.objects.select_related( - 'device_type__manufacturer', 'device_role', 'tenant', 'platform', 'site', 'rack', 'parent_bay', + 'device_type__manufacturer', 'device_role', 'tenant', 'platform', 'site', 'rack', 'parent_bay', 'vc_membership', ).prefetch_related( 'primary_ip4__nat_outside', 'primary_ip6__nat_outside', ) diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index b37b558c4..70d421e13 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -643,11 +643,18 @@ class InventoryItemFilter(DeviceComponentFilterSet): fields = ['name', 'part_id', 'serial', 'discovered'] +class VirtualChassisFilter(django_filters.FilterSet): + + class Meta: + model = VirtualChassis + fields = ['domain'] + + class VCMembershipFilter(django_filters.FilterSet): class Meta: model = VCMembership - fields = ['virtual_chassis'] + fields = ['virtual_chassis', 'device', 'position', 'is_master', 'priority'] class ConsoleConnectionFilter(django_filters.FilterSet):