Просмотр исходного кода

Fixes #11991 - Add vdcs to InterfaceImportForm and InterfaceBulkEditForm (#11996)

* Add vdcs to InterfaceImportForm and InterfaceBulkEditForm

* Filter vdcs queryset by device when bulk importing interfaces
kkthxbye 2 лет назад
Родитель
Сommit
2840f9d71d
2 измененных файлов с 27 добавлено и 4 удалено
  1. 10 2
      netbox/dcim/forms/bulk_edit.py
  2. 17 2
      netbox/dcim/forms/bulk_import.py

+ 10 - 2
netbox/dcim/forms/bulk_edit.py

@@ -1175,6 +1175,14 @@ class InterfaceBulkEditForm(
         },
         },
         label=_('LAG')
         label=_('LAG')
     )
     )
+    vdcs = DynamicModelMultipleChoiceField(
+        queryset=VirtualDeviceContext.objects.all(),
+        required=False,
+        label='Virtual Device Contexts',
+        query_params={
+            'device_id': '$device',
+        }
+    )
     speed = forms.IntegerField(
     speed = forms.IntegerField(
         required=False,
         required=False,
         widget=SelectSpeedWidget(),
         widget=SelectSpeedWidget(),
@@ -1240,14 +1248,14 @@ class InterfaceBulkEditForm(
     fieldsets = (
     fieldsets = (
         (None, ('module', 'type', 'label', 'speed', 'duplex', 'description')),
         (None, ('module', 'type', 'label', 'speed', 'duplex', 'description')),
         ('Addressing', ('vrf', 'mac_address', 'wwn')),
         ('Addressing', ('vrf', 'mac_address', 'wwn')),
-        ('Operation', ('mtu', 'tx_power', 'enabled', 'mgmt_only', 'mark_connected')),
+        ('Operation', ('vdcs', 'mtu', 'tx_power', 'enabled', 'mgmt_only', 'mark_connected')),
         ('PoE', ('poe_mode', 'poe_type')),
         ('PoE', ('poe_mode', 'poe_type')),
         ('Related Interfaces', ('parent', 'bridge', 'lag')),
         ('Related Interfaces', ('parent', 'bridge', 'lag')),
         ('802.1Q Switching', ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')),
         ('802.1Q Switching', ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')),
         ('Wireless', ('rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width')),
         ('Wireless', ('rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width')),
     )
     )
     nullable_fields = (
     nullable_fields = (
-        'module', 'label', 'parent', 'bridge', 'lag', 'speed', 'duplex', 'mac_address', 'wwn', 'mtu', 'description',
+        'module', 'label', 'parent', 'bridge', 'lag', 'speed', 'duplex', 'mac_address', 'wwn', 'vdcs', 'mtu', 'description',
         'poe_mode', 'poe_type', 'mode', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power',
         'poe_mode', 'poe_type', 'mode', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power',
         'vlan_group', 'untagged_vlan', 'tagged_vlans', 'vrf',
         'vlan_group', 'untagged_vlan', 'tagged_vlans', 'vrf',
     )
     )

+ 17 - 2
netbox/dcim/forms/bulk_import.py

@@ -11,7 +11,9 @@ from dcim.models import *
 from ipam.models import VRF
 from ipam.models import VRF
 from netbox.forms import NetBoxModelImportForm
 from netbox.forms import NetBoxModelImportForm
 from tenancy.models import Tenant
 from tenancy.models import Tenant
-from utilities.forms import CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, CSVTypedChoiceField, SlugField
+from utilities.forms import (
+    CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, CSVTypedChoiceField, SlugField, CSVModelMultipleChoiceField
+)
 from virtualization.models import Cluster
 from virtualization.models import Cluster
 from wireless.choices import WirelessRoleChoices
 from wireless.choices import WirelessRoleChoices
 from .common import ModuleCommonForm
 from .common import ModuleCommonForm
@@ -667,6 +669,12 @@ class InterfaceImportForm(NetBoxModelImportForm):
         to_field_name='name',
         to_field_name='name',
         help_text=_('Parent LAG interface')
         help_text=_('Parent LAG interface')
     )
     )
+    vdcs = CSVModelMultipleChoiceField(
+        queryset=VirtualDeviceContext.objects.all(),
+        required=False,
+        to_field_name='name',
+        help_text='VDC names separated by commas, encased with double quotes (e.g. "vdc1, vdc2, vdc3")'
+    )
     type = CSVChoiceField(
     type = CSVChoiceField(
         choices=InterfaceTypeChoices,
         choices=InterfaceTypeChoices,
         help_text=_('Physical medium')
         help_text=_('Physical medium')
@@ -706,7 +714,7 @@ class InterfaceImportForm(NetBoxModelImportForm):
         model = Interface
         model = Interface
         fields = (
         fields = (
             'device', 'name', 'label', 'parent', 'bridge', 'lag', 'type', 'speed', 'duplex', 'enabled',
             'device', 'name', 'label', 'parent', 'bridge', 'lag', 'type', 'speed', 'duplex', 'enabled',
-            'mark_connected', 'mac_address', 'wwn', 'mtu', 'mgmt_only', 'description', 'poe_mode', 'poe_type', 'mode',
+            'mark_connected', 'mac_address', 'wwn', 'vdcs', 'mtu', 'mgmt_only', 'description', 'poe_mode', 'poe_type', 'mode',
             'vrf', 'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'tags'
             'vrf', 'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'tags'
         )
         )
 
 
@@ -722,6 +730,7 @@ class InterfaceImportForm(NetBoxModelImportForm):
                 self.fields['parent'].queryset = self.fields['parent'].queryset.filter(**params)
                 self.fields['parent'].queryset = self.fields['parent'].queryset.filter(**params)
                 self.fields['bridge'].queryset = self.fields['bridge'].queryset.filter(**params)
                 self.fields['bridge'].queryset = self.fields['bridge'].queryset.filter(**params)
                 self.fields['lag'].queryset = self.fields['lag'].queryset.filter(**params)
                 self.fields['lag'].queryset = self.fields['lag'].queryset.filter(**params)
+                self.fields['vdcs'].queryset = self.fields['vdcs'].queryset.filter(**params)
 
 
     def clean_enabled(self):
     def clean_enabled(self):
         # Make sure enabled is True when it's not included in the uploaded data
         # Make sure enabled is True when it's not included in the uploaded data
@@ -730,6 +739,12 @@ class InterfaceImportForm(NetBoxModelImportForm):
         else:
         else:
             return self.cleaned_data['enabled']
             return self.cleaned_data['enabled']
 
 
+    def clean_vdcs(self):
+        for vdc in self.cleaned_data['vdcs']:
+            if vdc.device != self.cleaned_data['device']:
+                raise forms.ValidationError(f"VDC {vdc} is not assigned to device {self.cleaned_data['device']}")
+        return self.cleaned_data['vdcs']
+
 
 
 class FrontPortImportForm(NetBoxModelImportForm):
 class FrontPortImportForm(NetBoxModelImportForm):
     device = CSVModelChoiceField(
     device = CSVModelChoiceField(