Преглед изворни кода

Add ability to adopt components when adding a module

kkthxbye-code пре 3 година
родитељ
комит
3fb967b482
2 измењених фајлова са 43 додато и 25 уклоњено
  1. 13 2
      netbox/dcim/forms/models.py
  2. 30 23
      netbox/dcim/models/devices.py

+ 13 - 2
netbox/dcim/forms/models.py

@@ -633,12 +633,18 @@ class ModuleForm(NetBoxModelForm):
         help_text="Automatically populate components associated with this module type"
     )
 
+    adopt_components = forms.BooleanField(
+        required=False,
+        initial=False,
+        help_text="Adopt already existing components"
+    )
+
     fieldsets = (
         ('Module', (
             'device', 'module_bay', 'manufacturer', 'module_type', 'tags',
         )),
         ('Hardware', (
-            'serial', 'asset_tag', 'replicate_components',
+            'serial', 'asset_tag', 'replicate_components', 'adopt_components',
         )),
     )
 
@@ -646,7 +652,7 @@ class ModuleForm(NetBoxModelForm):
         model = Module
         fields = [
             'device', 'module_bay', 'manufacturer', 'module_type', 'serial', 'asset_tag', 'tags',
-            'replicate_components', 'comments',
+            'replicate_components', 'adopt_components', 'comments',
         ]
 
     def __init__(self, *args, **kwargs):
@@ -655,6 +661,8 @@ class ModuleForm(NetBoxModelForm):
         if self.instance.pk:
             self.fields['replicate_components'].initial = False
             self.fields['replicate_components'].disabled = True
+            self.fields['adopt_components'].initial = False
+            self.fields['adopt_components'].disabled = True
 
     def save(self, *args, **kwargs):
 
@@ -662,6 +670,9 @@ class ModuleForm(NetBoxModelForm):
         if self.instance.pk or not self.cleaned_data['replicate_components']:
             self.instance._disable_replication = True
 
+        if self.cleaned_data['adopt_components']:
+            self.instance._adopt_components = True
+
         return super().save(*args, **kwargs)
 
 

+ 30 - 23
netbox/dcim/models/devices.py

@@ -1065,31 +1065,38 @@ class Module(NetBoxModel, ConfigContextModel):
 
         super().save(*args, **kwargs)
 
+        adopt_components = getattr(self, '_adopt_components', False)
+        disable_replication = getattr(self, '_disable_replication', False)
+
         # If this is a new Module and component replication has not been disabled, instantiate all its
         # related components per the ModuleType definition
-        if is_new and not getattr(self, '_disable_replication', False):
-            ConsolePort.objects.bulk_create(
-                [x.instantiate(device=self.device, module=self) for x in self.module_type.consoleporttemplates.all()]
-            )
-            ConsoleServerPort.objects.bulk_create(
-                [x.instantiate(device=self.device, module=self) for x in self.module_type.consoleserverporttemplates.all()]
-            )
-            PowerPort.objects.bulk_create(
-                [x.instantiate(device=self.device, module=self) for x in self.module_type.powerporttemplates.all()]
-            )
-            PowerOutlet.objects.bulk_create(
-                [x.instantiate(device=self.device, module=self) for x in self.module_type.poweroutlettemplates.all()]
-            )
-            Interface.objects.bulk_create(
-                [x.instantiate(device=self.device, module=self) for x in self.module_type.interfacetemplates.all()]
-            )
-            RearPort.objects.bulk_create(
-                [x.instantiate(device=self.device, module=self) for x in self.module_type.rearporttemplates.all()]
-            )
-            FrontPort.objects.bulk_create(
-                [x.instantiate(device=self.device, module=self) for x in self.module_type.frontporttemplates.all()]
-            )
-
+        if is_new and not disable_replication:
+            # Iterate all component templates
+            for templates, component_attribute in [
+                ("consoleporttemplates", "consoleports"),
+                ("consoleserverporttemplates", "consoleserverports"),
+                ("interfacetemplates", "interfaces"),
+                ("powerporttemplates", "powerports"),
+                ("poweroutlettemplates", "poweroutlets"),
+                ("rearporttemplates", "rearports"),
+                ("frontporttemplates", "frontports")
+            ]:
+                # Get the template for the module type.
+                for template in getattr(self.module_type, templates).all():
+                    template_instance = template.instantiate(device=self.device, module=self)
+
+                    if adopt_components:
+                        existing_item = getattr(self.device, component_attribute).filter(name=template_instance.name).first()
+
+                        # Check if there's a component with the same name already
+                        if existing_item:
+                            # Assign it to the module
+                            existing_item.module = self
+                            existing_item.save()
+                            continue
+                        
+                    # If we are not adopting components or the component doesn't already exist
+                    template_instance.save()
 
 #
 # Virtual chassis