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

Merge branch '150-interface-vlans' into develop-2.3

This commit is contained in:
Jeremy Stretch
2017-11-14 15:22:40 -05:00
parent 5c13382071
commit ba42ad2115
12 changed files with 469 additions and 59 deletions

View File

@@ -7,8 +7,8 @@ from rest_framework.validators import UniqueTogetherValidator
from circuits.models import Circuit, CircuitTermination
from dcim.constants import (
CONNECTION_STATUS_CHOICES, IFACE_FF_CHOICES, IFACE_ORDERING_CHOICES, RACK_FACE_CHOICES, RACK_TYPE_CHOICES,
RACK_WIDTH_CHOICES, STATUS_CHOICES, SUBDEVICE_ROLE_CHOICES,
CONNECTION_STATUS_CHOICES, IFACE_FF_CHOICES, IFACE_MODE_CHOICES, IFACE_ORDERING_CHOICES, RACK_FACE_CHOICES,
RACK_TYPE_CHOICES, RACK_WIDTH_CHOICES, STATUS_CHOICES, SUBDEVICE_ROLE_CHOICES,
)
from dcim.models import (
ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
@@ -17,7 +17,7 @@ from dcim.models import (
RackReservation, RackRole, Region, Site,
)
from extras.api.customfields import CustomFieldModelSerializer
from ipam.models import IPAddress
from ipam.models import IPAddress, VLAN
from tenancy.api.serializers import NestedTenantSerializer
from utilities.api import ChoiceFieldSerializer, ValidatedModelSerializer
from virtualization.models import Cluster
@@ -628,6 +628,15 @@ class InterfaceCircuitTerminationSerializer(serializers.ModelSerializer):
]
# Cannot import ipam.api.NestedVLANSerializer due to circular dependency
class InterfaceVLANSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlan-detail')
class Meta:
model = VLAN
fields = ['id', 'url', 'vid', 'name', 'display_name']
class InterfaceSerializer(serializers.ModelSerializer):
device = NestedDeviceSerializer()
form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES)
@@ -635,12 +644,15 @@ class InterfaceSerializer(serializers.ModelSerializer):
is_connected = serializers.SerializerMethodField(read_only=True)
interface_connection = serializers.SerializerMethodField(read_only=True)
circuit_termination = InterfaceCircuitTerminationSerializer()
untagged_vlan = InterfaceVLANSerializer()
mode = ChoiceFieldSerializer(choices=IFACE_MODE_CHOICES)
tagged_vlans = InterfaceVLANSerializer(many=True)
class Meta:
model = Interface
fields = [
'id', 'device', 'name', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only', 'description',
'is_connected', 'interface_connection', 'circuit_termination',
'is_connected', 'interface_connection', 'circuit_termination', 'mode', 'untagged_vlan', 'tagged_vlans',
]
def get_is_connected(self, obj):
@@ -685,7 +697,37 @@ class WritableInterfaceSerializer(ValidatedModelSerializer):
model = Interface
fields = [
'id', 'device', 'name', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only', 'description',
'mode', 'untagged_vlan', 'tagged_vlans',
]
ignore_validation_fields = [
'tagged_vlans'
]
def validate(self, data):
# Get the device for later use
if self.instance:
device = self.instance.device
else:
device = data.get('device')
# Validate VLANs belong to the device's site or global
# We have to do this here decause of the ManyToMany relationship
native_vlan = data.get('native_vlan')
if native_vlan:
if native_vlan.site != device.site and native_vlan.site is not None:
raise serializers.ValidationError("Native VLAN is invalid for the interface's device.")
tagged_vlan_members = data.get('tagged_vlan_members')
if tagged_vlan_members:
for vlan in tagged_vlan_members:
if vlan.site != device.site and vlan.site is not None:
raise serializers.ValidationError("Tagged VLAN {} is invalid for the interface's device.".format(vlan))
# Enforce model validation
super(WritableInterfaceSerializer, self).validate(data)
return data
#