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

Closes #1944: Enable assigning VLANs to virtual machine interfaces

This commit is contained in:
Jeremy Stretch
2018-03-14 14:53:28 -04:00
parent ae6848b194
commit 8bd268d81c
7 changed files with 183 additions and 77 deletions

View File

@@ -14,11 +14,10 @@ from ipam.models import IPAddress, VLAN, VLANGroup
from tenancy.forms import TenancyForm
from tenancy.models import Tenant
from utilities.forms import (
AnnotatedMultipleChoiceField, APISelect, APISelectMultiple, add_blank_choice, ArrayFieldSelectMultiple,
BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect, ChainedFieldsMixin, ChainedModelChoiceField,
ChainedModelMultipleChoiceField, CommentField, ComponentForm, ConfirmationForm, CSVChoiceField, ExpandableNameField,
FilterChoiceField, FilterTreeNodeMultipleChoiceField, FlexibleModelChoiceField, Livesearch, SelectWithDisabled,
SelectWithPK, SmallTextarea, SlugField,
AnnotatedMultipleChoiceField, APISelect, add_blank_choice, ArrayFieldSelectMultiple, BootstrapMixin, BulkEditForm,
BulkEditNullBooleanSelect, ChainedFieldsMixin, ChainedModelChoiceField, CommentField, ComponentForm,
ConfirmationForm, CSVChoiceField, ExpandableNameField, FilterChoiceField, FilterTreeNodeMultipleChoiceField,
FlexibleModelChoiceField, Livesearch, SelectWithDisabled, SelectWithPK, SmallTextarea, SlugField,
)
from virtualization.models import Cluster
from .constants import (
@@ -37,6 +36,12 @@ from .models import (
DEVICE_BY_PK_RE = '{\d+\}'
INTERFACE_MODE_HELP_TEXT = """
Access: One untagged VLAN<br />
Tagged: One untagged VLAN and/or one or more tagged VLANs<br />
Tagged All: Implies all VLANs are available (w/optional untagged VLAN)
"""
def get_device_by_name_or_pk(name):
"""
@@ -1657,7 +1662,7 @@ class InterfaceForm(BootstrapMixin, forms.ModelForm):
class Meta:
model = Interface
fields = [
'device', 'name', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only', 'description',
'device', 'name', 'form_factor', 'enabled', 'lag', 'mac_address', 'mtu', 'mgmt_only', 'description',
'mode', 'untagged_vlan', 'tagged_vlans',
]
widgets = {
@@ -1667,9 +1672,7 @@ class InterfaceForm(BootstrapMixin, forms.ModelForm):
'mode': '802.1Q Mode',
}
help_texts = {
'mode': "Access: One untagged VLAN<br />"
"Tagged: One untagged VLAN and/or one or more tagged VLANs<br />"
"Tagged All: Implies all VLANs are available (w/optional untagged VLAN)"
'mode': INTERFACE_MODE_HELP_TEXT,
}
def __init__(self, *args, **kwargs):
@@ -1732,17 +1735,37 @@ class InterfaceAssignVLANsForm(BootstrapMixin, forms.ModelForm):
if self.instance.untagged_vlan is not None:
assigned_vlans.append(self.instance.untagged_vlan.pk)
# Initialize VLAN choices
device = self.instance.device
vlan_choices = [
('Global', [(vlan.pk, vlan) for vlan in VLAN.objects.filter(site=None).exclude(pk__in=assigned_vlans)]),
(device.site.name, [(vlan.pk, vlan) for vlan in VLAN.objects.filter(site=device.site, group=None).exclude(pk__in=assigned_vlans)]),
]
for group in VLANGroup.objects.filter(site=device.site):
vlan_choices.append((
'{} / {}'.format(group.site.name, group.name),
[(vlan.pk, vlan) for vlan in VLAN.objects.filter(group=group).exclude(pk__in=assigned_vlans)]
))
# Compile VLAN choices
vlan_choices = []
# Add global VLANs
global_vlans = VLAN.objects.filter(site=None, group=None).exclude(pk__in=assigned_vlans)
vlan_choices.append((
'Global', [(vlan.pk, vlan) for vlan in global_vlans])
)
# Add grouped global VLANs
for group in VLANGroup.objects.filter(site=None):
global_group_vlans = VLAN.objects.filter(group=group).exclude(pk__in=assigned_vlans)
vlan_choices.append(
(group.name, [(vlan.pk, vlan) for vlan in global_group_vlans])
)
parent = self.instance.parent
if parent is not None:
# Add site VLANs
site_vlans = VLAN.objects.filter(site=parent.site, group=None).exclude(pk__in=assigned_vlans)
vlan_choices.append((parent.site.name, [(vlan.pk, vlan) for vlan in site_vlans]))
# Add grouped site VLANs
for group in VLANGroup.objects.filter(site=parent.site):
site_group_vlans = VLAN.objects.filter(group=group).exclude(pk__in=assigned_vlans)
vlan_choices.append((
'{} / {}'.format(group.site.name, group.name),
[(vlan.pk, vlan) for vlan in site_group_vlans]
))
self.fields['vlans'].choices = vlan_choices
def clean(self):