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

Collapsed VCMembership into the Device model (WIP)

This commit is contained in:
Jeremy Stretch
2018-01-31 22:47:27 -05:00
parent 6b101d2c49
commit a4019be28c
15 changed files with 485 additions and 765 deletions

View File

@@ -14,7 +14,7 @@ from dcim.models import (
ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
DeviceBayTemplate, DeviceType, DeviceRole, Interface, InterfaceConnection, InterfaceTemplate, Manufacturer,
InventoryItem, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack, RackGroup,
RackReservation, RackRole, Region, Site, VirtualChassis, VCMembership
RackReservation, RackRole, Region, Site, VirtualChassis,
)
from extras.api.customfields import CustomFieldModelSerializer
from ipam.models import IPAddress, VLAN
@@ -489,7 +489,6 @@ class DeviceSerializer(CustomFieldModelSerializer):
primary_ip4 = DeviceIPAddressSerializer()
primary_ip6 = DeviceIPAddressSerializer()
parent_device = serializers.SerializerMethodField()
virtual_chassis = serializers.SerializerMethodField()
cluster = NestedClusterSerializer()
class Meta:
@@ -497,7 +496,8 @@ class DeviceSerializer(CustomFieldModelSerializer):
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', 'comments', 'custom_fields', 'created', 'last_updated',
'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'comments', 'custom_fields', 'created',
'last_updated',
]
def get_parent_device(self, obj):
@@ -510,16 +510,6 @@ 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):
@@ -833,10 +823,11 @@ class WritableInterfaceConnectionSerializer(ValidatedModelSerializer):
#
class VirtualChassisSerializer(serializers.ModelSerializer):
master = NestedDeviceSerializer()
class Meta:
model = VirtualChassis
fields = ['id', 'domain']
fields = ['id', 'master', 'domain']
class NestedVirtualChassisSerializer(serializers.ModelSerializer):
@@ -851,44 +842,4 @@ class WritableVirtualChassisSerializer(ValidatedModelSerializer):
class Meta:
model = VirtualChassis
fields = ['id', 'domain']
#
# Virtual chassis memberships
#
class VCMembershipSerializer(serializers.ModelSerializer):
virtual_chassis = NestedVirtualChassisSerializer()
device = NestedDeviceSerializer()
class Meta:
model = VCMembership
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:
model = VCMembership
fields = ['id', 'virtual_chassis', 'device', 'position', 'is_master', 'priority']
def validate(self, data):
# Validate uniqueness of (virtual_chassis, position)
validator = UniqueTogetherValidator(queryset=VCMembership.objects.all(), fields=('virtual_chassis', 'position'))
validator.set_context(self)
validator(data)
# Enforce model validation
super(WritableVCMembershipSerializer, self).validate(data)
return data
fields = ['id', 'master', 'domain']

View File

@@ -62,7 +62,6 @@ router.register(r'interface-connections', views.InterfaceConnectionViewSet)
# Virtual chassis
router.register(r'virtual-chassis', views.VirtualChassisViewSet)
router.register(r'vc-memberships', views.VCMembershipViewSet)
# Miscellaneous
router.register(r'connected-device', views.ConnectedDeviceViewSet, base_name='connected-device')

View File

@@ -16,7 +16,7 @@ from dcim.models import (
ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
DeviceBayTemplate, DeviceRole, DeviceType, Interface, InterfaceConnection, InterfaceTemplate, Manufacturer,
InventoryItem, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack, RackGroup,
RackReservation, RackRole, Region, Site, VCMembership, VirtualChassis
RackReservation, RackRole, Region, Site, VirtualChassis,
)
from extras.api.serializers import RenderedGraphSerializer
from extras.api.views import CustomFieldModelViewSet
@@ -403,32 +403,6 @@ class VirtualChassisViewSet(ModelViewSet):
write_serializer_class = serializers.WritableVirtualChassisSerializer
class VCMembershipViewSet(ModelViewSet):
queryset = VCMembership.objects.select_related('virtual_chassis', 'device')
serializer_class = serializers.VCMembershipSerializer
write_serializer_class = serializers.WritableVCMembershipSerializer
filter_class = filters.VCMembershipFilter
def create(self, request, *args, **kwargs):
with transaction.atomic():
# Automatically create a new VirtualChassis for new VCMemberships with no VC specified
if isinstance(request.data, list):
for i, vcm in enumerate(request.data):
if not vcm.get('virtual_chassis') and vcm.get('is_master'):
vc = VirtualChassis()
vc.save()
request.data[i]['virtual_chassis'] = vc.pk
else:
if not request.data.get('virtual_chassis') and request.data.get('is_master'):
vc = VirtualChassis()
vc.save()
request.data['virtual_chassis'] = vc.pk
return super(VCMembershipViewSet, self).create(request, *args, **kwargs)
#
# Miscellaneous
#