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

Merge pull request #9331 from kkthxbye-code/fix-9001

Fixes #9001 & #9190 - Add form validation to model installation
Jeremy Stretch 3 лет назад
Родитель
Сommit
3dda7e2da2
1 измененных файлов с 50 добавлено и 0 удалено
  1. 50 0
      netbox/dcim/forms/models.py

+ 50 - 0
netbox/dcim/forms/models.py

@@ -675,6 +675,56 @@ class ModuleForm(NetBoxModelForm):
 
         return super().save(*args, **kwargs)
 
+    def clean(self):
+        super().clean()
+
+        replicate_components = self.cleaned_data.get("replicate_components")
+        adopt_components = self.cleaned_data.get("adopt_components")
+        device = self.cleaned_data['device']
+        module_type = self.cleaned_data['module_type']
+        module_bay = self.cleaned_data['module_bay']
+
+        # Bail out if we are not installing a new module or if we are not replicating components
+        if self.instance.pk or not replicate_components:
+            return
+
+        for templates, component_attribute in [
+                ("consoleporttemplates", "consoleports"),
+                ("consoleserverporttemplates", "consoleserverports"),
+                ("interfacetemplates", "interfaces"),
+                ("powerporttemplates", "powerports"),
+                ("poweroutlettemplates", "poweroutlets"),
+                ("rearporttemplates", "rearports"),
+                ("frontporttemplates", "frontports")
+        ]:
+            # Prefetch installed components
+            installed_components = {
+                component.name: component for component in getattr(device, component_attribute).all()
+            }
+
+            # Get the templates for the module type.
+            for template in getattr(module_type, templates).all():
+                # Installing modules with placeholders require that the bay has a position value
+                if '{module}' in template.name and not module_bay.position:
+                    raise forms.ValidationError(
+                        "Cannot install module with placeholder values in a module bay with no position defined"
+                    )
+
+                resolved_name = template.name.replace('{module}', module_bay.position)
+                existing_item = installed_components.get(resolved_name)
+
+                # It is not possible to adopt components already belonging to a module
+                if adopt_components and existing_item and existing_item.module:
+                    raise forms.ValidationError(
+                        f"Cannot adopt {template.component_model.__name__} '{resolved_name}' as it already belongs to a module"
+                    )
+
+                # If we are not adopting components we error if the component exists
+                if not adopt_components and resolved_name in installed_components:
+                    raise forms.ValidationError(
+                        f"{template.component_model.__name__} - {resolved_name} already exists"
+                    )
+
 
 class CableForm(TenancyForm, NetBoxModelForm):