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

Add support for VM interface termination via bulk import

jeremystretch 3 лет назад
Родитель
Сommit
29a46d2c18
1 измененных файлов с 22 добавлено и 13 удалено
  1. 22 13
      netbox/ipam/forms/bulk_import.py

+ 22 - 13
netbox/ipam/forms/bulk_import.py

@@ -453,49 +453,58 @@ class L2VPNTerminationCSVForm(NetBoxModelCSVForm):
         to_field_name='name',
         label='L2VPN',
     )
-
     device = CSVModelChoiceField(
         queryset=Device.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Required if assigned to a interface'
+        help_text='Parent device (for interface)'
+    )
+    virtual_machine = CSVModelChoiceField(
+        queryset=VirtualMachine.objects.all(),
+        required=False,
+        to_field_name='name',
+        help_text='Parent virtual machine (for interface)'
     )
-
     interface = CSVModelChoiceField(
-        queryset=Interface.objects.all(),
+        queryset=Interface.objects.none(),  # Can also refer to VMInterface
         required=False,
         to_field_name='name',
-        help_text='Required if not assigned to a vlan'
+        help_text='Assigned interface (device or VM)'
     )
-
     vlan = CSVModelChoiceField(
         queryset=VLAN.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Required if not assigned to a interface'
+        help_text='Assigned VLAN'
     )
 
     class Meta:
         model = L2VPNTermination
-        fields = ('l2vpn', 'device', 'interface', 'vlan')
+        fields = ('l2vpn', 'device', 'virtual_machine', 'interface', 'vlan')
 
     def __init__(self, data=None, *args, **kwargs):
         super().__init__(data, *args, **kwargs)
+
         if data:
-            # Limit interface queryset by assigned device
+
+            # Limit interface queryset by device or VM
             if data.get('device'):
                 self.fields['interface'].queryset = Interface.objects.filter(
                     **{f"device__{self.fields['device'].to_field_name}": data['device']}
                 )
+            elif data.get('virtual_machine'):
+                self.fields['interface'].queryset = VMInterface.objects.filter(
+                    **{f"virtual_machine__{self.fields['virtual_machine'].to_field_name}": data['virtual_machine']}
+                )
 
     def clean(self):
         super().clean()
 
+        if self.cleaned_data.get('device') and self.cleaned_data.get('virtual_machine'):
+            raise ValidationError('Cannot import device and VM interface terminations simultaneously.')
         if not (self.cleaned_data.get('interface') or self.cleaned_data.get('vlan')):
-            raise ValidationError('You must have either a interface or a VLAN')
-
+            raise ValidationError('Each termination must specify either an interface or a VLAN.')
         if self.cleaned_data.get('interface') and self.cleaned_data.get('vlan'):
-            raise ValidationError('Cannot assign both a interface and vlan')
+            raise ValidationError('Cannot assign both an interface and a VLAN.')
 
-        # Set Assigned Object
         self.instance.assigned_object = self.cleaned_data.get('interface') or self.cleaned_data.get('vlan')