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

Introduced 'cable' field on CableTermination to cache connected Cable

Jeremy Stretch 7 лет назад
Родитель
Сommit
e21b23cd98

+ 54 - 2
netbox/dcim/migrations/0066_cables.py

@@ -20,6 +20,7 @@ def console_connections_to_cables(apps, schema_editor):
     print("\n    Adding console connections... ", end='', flush=True)
     for consoleport in ConsolePort.objects.filter(connected_endpoint__isnull=False):
         c = Cable()
+
         # We have to assign GFK fields manually because we're inside a migration.
         c.termination_a_type = consoleport_type
         c.termination_a_id = consoleport.id
@@ -28,6 +29,10 @@ def console_connections_to_cables(apps, schema_editor):
         c.connection_status = consoleport.connection_status
         c.save()
 
+        # Cache the Cable on its two termination points (replicate Cable.save())
+        ConsolePort.objects.filter(pk=consoleport.id).update(cable=c)
+        ConsoleServerPort.objects.filter(pk=consoleport.connected_endpoint_id).update(cable=c)
+
     cable_count = Cable.objects.filter(termination_a_type=consoleport_type).count()
     print("{} cables created".format(cable_count))
 
@@ -49,6 +54,7 @@ def power_connections_to_cables(apps, schema_editor):
     print("    Adding power connections... ", end='', flush=True)
     for powerport in PowerPort.objects.filter(connected_endpoint__isnull=False):
         c = Cable()
+
         # We have to assign GFK fields manually because we're inside a migration.
         c.termination_a_type = powerport_type
         c.termination_a_id = powerport.id
@@ -57,6 +63,10 @@ def power_connections_to_cables(apps, schema_editor):
         c.connection_status = powerport.connection_status
         c.save()
 
+        # Cache the Cable on its two termination points (replicate Cable.save())
+        PowerPort.objects.filter(pk=powerport.id).update(cable=c)
+        PowerOutlet.objects.filter(pk=powerport.connected_endpoint_id).update(cable=c)
+
     cable_count = Cable.objects.filter(termination_a_type=powerport_type).count()
     print("{} cables created".format(cable_count))
 
@@ -77,11 +87,14 @@ def interface_connections_to_cables(apps, schema_editor):
     print("    Adding interface connections... ", end='', flush=True)
     for conn in InterfaceConnection.objects.all():
         c = Cable()
+
         # We have to assign GFK fields manually because we're inside a migration.
         c.termination_a_type = interface_type
         c.termination_a_id = conn.interface_a_id
+        c.termination_a = conn.interface_a
         c.termination_b_type = interface_type
         c.termination_b_id = conn.interface_b_id
+        c.termination_b = conn.interface_b
         c.connection_status = conn.connection_status
         c.save()
 
@@ -89,11 +102,13 @@ def interface_connections_to_cables(apps, schema_editor):
         # since these are new fields on Interface
         Interface.objects.filter(pk=conn.interface_a_id).update(
             connected_endpoint=conn.interface_b_id,
-            connection_status=conn.connection_status
+            connection_status=conn.connection_status,
+            cable=c
         )
         Interface.objects.filter(pk=conn.interface_b_id).update(
             connected_endpoint=conn.interface_a_id,
-            connection_status=conn.connection_status
+            connection_status=conn.connection_status,
+            cable=c
         )
 
     cable_count = Cable.objects.filter(termination_a_type=interface_type).count()
@@ -146,11 +161,21 @@ class Migration(migrations.Migration):
             name='connected_endpoint',
             field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='connected_endpoint', to='dcim.ConsoleServerPort'),
         ),
+        migrations.AddField(
+            model_name='consoleport',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.Cable'),
+        ),
         migrations.AlterField(
             model_name='consoleserverport',
             name='device',
             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='consoleserverports', to='dcim.Device'),
         ),
+        migrations.AddField(
+            model_name='consoleserverport',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.Cable'),
+        ),
 
         # Alter power port models
         migrations.RenameField(
@@ -163,11 +188,21 @@ class Migration(migrations.Migration):
             name='connected_endpoint',
             field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='connected_endpoint', to='dcim.PowerOutlet'),
         ),
+        migrations.AddField(
+            model_name='powerport',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.Cable'),
+        ),
         migrations.AlterField(
             model_name='poweroutlet',
             name='device',
             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='poweroutlets', to='dcim.Device'),
         ),
+        migrations.AddField(
+            model_name='poweroutlet',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.Cable'),
+        ),
 
         # Alter the Interface model
         migrations.AddField(
@@ -180,6 +215,23 @@ class Migration(migrations.Migration):
             name='connection_status',
             field=models.NullBooleanField(default=True),
         ),
+        migrations.AddField(
+            model_name='interface',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.Cable'),
+        ),
+
+        # Alter front/rear port models
+        migrations.AddField(
+            model_name='frontport',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.Cable'),
+        ),
+        migrations.AddField(
+            model_name='rearport',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.Cable'),
+        ),
 
         # Copy console/power/interface connections as Cables
         migrations.RunPython(console_connections_to_cables),

+ 12 - 0
netbox/dcim/models.py

@@ -66,6 +66,12 @@ class ComponentModel(models.Model):
 
 
 class CableTermination(models.Model):
+    cable = models.ForeignKey(
+        to='dcim.Cable',
+        on_delete=models.SET_NULL,
+        blank=True,
+        null=True
+    )
 
     class Meta:
         abstract = True
@@ -2339,6 +2345,12 @@ class Cable(ChangeLoggedModel):
 
         super(Cable, self).save(*args, **kwargs)
 
+        # Cache the Cable on its two termination points
+        self.termination_a.cable = self
+        self.termination_a.save()
+        self.termination_b.cable = self
+        self.termination_b.save()
+
     def get_path_endpoints(self):
         """
         Traverse both ends of a cable path and return its connected endpoints. Note that one or both endpoints may be

+ 1 - 1
netbox/dcim/signals.py

@@ -32,7 +32,7 @@ def update_connected_endpoints(instance, **kwargs):
         termination_a.connection_status = True
         termination_a.save()
         termination_b.connected_endpoint = termination_a
-        termination_a.connection_status = True
+        termination_b.connection_status = True
         termination_b.save()
 
 

+ 17 - 11
netbox/dcim/views.py

@@ -876,47 +876,53 @@ class DeviceView(View):
 
         # VirtualChassis members
         if device.virtual_chassis is not None:
-            vc_members = Device.objects.filter(virtual_chassis=device.virtual_chassis).order_by('vc_position')
+            vc_members = Device.objects.filter(
+                virtual_chassis=device.virtual_chassis
+            ).order_by('vc_position')
         else:
             vc_members = []
 
         # Console ports
         console_ports = natsorted(
-            ConsolePort.objects.filter(device=device).select_related('connected_endpoint__device'), key=attrgetter('name')
+            device.console_ports.select_related('connected_endpoint__device', 'cable'),
+            key=attrgetter('name')
         )
 
         # Console server ports
-        consoleserverports = ConsoleServerPort.objects.filter(device=device).select_related('connected_endpoint__device')
+        consoleserverports = device.consoleserverports.select_related('connected_endpoint__device', 'cable')
 
         # Power ports
         power_ports = natsorted(
-            PowerPort.objects.filter(device=device).select_related('connected_endpoint__device'), key=attrgetter('name')
+            device.power_ports.select_related('connected_endpoint__device', 'cable'),
+            key=attrgetter('name')
         )
 
         # Power outlets
-        poweroutlets = PowerOutlet.objects.filter(device=device).select_related('connected_endpoint__device')
+        poweroutlets = device.poweroutlets.select_related('connected_endpoint__device', 'cable')
 
         # Interfaces
         interfaces = device.vc_interfaces.order_naturally(
             device.device_type.interface_ordering
         ).select_related(
-            'connected_endpoint__device', 'circuit_termination__circuit'
-        ).prefetch_related('ip_addresses')
+            'lag', 'connected_endpoint__device', 'circuit_termination__circuit', 'cable'
+        ).prefetch_related(
+            'cable__termination_a', 'cable__termination_b', 'ip_addresses'
+        )
 
         # Front ports
-        front_ports = device.front_ports.select_related('rear_port')
+        front_ports = device.front_ports.select_related('rear_port', 'cable')
 
         # Rear ports
-        rear_ports = device.rear_ports.all()
+        rear_ports = device.rear_ports.select_related('cable')
 
         # Device bays
         device_bays = natsorted(
-            DeviceBay.objects.filter(device=device).select_related('installed_device__device_type__manufacturer'),
+            device.device_bays.select_related('installed_device__device_type__manufacturer'),
             key=attrgetter('name')
         )
 
         # Services
-        services = Service.objects.filter(device=device)
+        services = device.services.all()
 
         # Secrets
         secrets = device.secrets.all()

+ 5 - 8
netbox/templates/dcim/inc/consoleport.html

@@ -7,14 +7,11 @@
 
     {# Cable #}
     <td>
-        {% with cable=cp.get_connected_cable %}
-            {% if cable %}
-                Cable <a href="{{ cable.get_absolute_url }}">{{ cable }}</a>
-                {% if cable.far_end != cp.connected_endpoint %}
-                    to <a href="{{ cable.far_end.device.get_absolute_url }}">{{ cable.far_end.device }}</a> {{ cable.far_end }}
-                {% endif %}
-            {% endif %}
-        {% endwith %}
+        {% if cp.cable %}
+            <a href="{{ cp.cable.get_absolute_url }}">{{ cp.cable }}</a>
+        {% else %}
+            &mdash;
+        {% endif %}
     </td>
 
     {# Connection #}

+ 5 - 8
netbox/templates/dcim/inc/consoleserverport.html

@@ -14,14 +14,11 @@
 
     {# Cable #}
     <td>
-        {% with cable=csp.get_connected_cable %}
-            {% if cable %}
-                <a href="{{ cable.get_absolute_url }}">{{ cable }}</a>
-                {% if cable.far_end != csp.connected_endpoint %}
-                    to <a href="{{ cable.far_end.device.get_absolute_url }}">{{ cable.far_end.device }}</a> {{ cable.far_end }}
-                {% endif %}
-            {% endif %}
-        {% endwith %}
+        {% if csp.cable %}
+            <a href="{{ csp.cable.get_absolute_url }}">{{ csp.cable }}</a>
+        {% else %}
+            &mdash;
+        {% endif %}
     </td>
 
     {# Connection #}

+ 6 - 9
netbox/templates/dcim/inc/interface.html

@@ -26,18 +26,15 @@
     <td>{{ iface.description|default:"&mdash;" }}</td>
 
     {# 802.1Q mode #}
-    <td>{{ iface.get_mode_display }}</td>
+    <td>{{ iface.get_mode_display|default:"&mdash;" }}</td>
 
     {# Cable #}
     <td>
-        {% with cable=iface.get_connected_cable %}
-            {% if cable %}
-                <a href="{{ cable.get_absolute_url }}">{{ cable }}</a>
-                {% if cable.far_end != iface.connected_endpoint %}
-                    to <a href="{{ cable.far_end.device.get_absolute_url }}">{{ cable.far_end.device }}</a> {{ cable.far_end }}
-                {% endif %}
-            {% endif %}
-        {% endwith %}
+        {% if iface.cable %}
+            <a href="{{ iface.cable.get_absolute_url }}">{{ iface.cable }}</a>
+        {% else %}
+            &mdash;
+        {% endif %}
     </td>
 
     {# Connection or type #}

+ 5 - 8
netbox/templates/dcim/inc/poweroutlet.html

@@ -14,14 +14,11 @@
 
     {# Cable #}
     <td>
-        {% with cable=po.get_connected_cable %}
-            {% if cable %}
-                <a href="{{ cable.get_absolute_url }}">{{ cable }}</a>
-                {% if cable.far_end != po.connected_endpoint %}
-                    to <a href="{{ cable.far_end.device.get_absolute_url }}">{{ cable.far_end.device }}</a> {{ cable.far_end }}
-                {% endif %}
-            {% endif %}
-        {% endwith %}
+        {% if po.cable %}
+            <a href="{{ po.cable.get_absolute_url }}">{{ po.cable }}</a>
+        {% else %}
+            &mdash;
+        {% endif %}
     </td>
 
     {# Connection #}

+ 5 - 8
netbox/templates/dcim/inc/powerport.html

@@ -7,14 +7,11 @@
 
     {# Cable #}
     <td>
-        {% with cable=pp.get_connected_cable %}
-            {% if cable %}
-                Cable <a href="{{ cable.get_absolute_url }}">{{ cable }}</a>
-                {% if cable.far_end != pp.connected_endpoint %}
-                    to <a href="{{ cable.far_end.device.get_absolute_url }}">{{ cable.far_end.device }}</a> {{ cable.far_end }}
-                {% endif %}
-            {% endif %}
-        {% endwith %}
+        {% if pp.cable %}
+            <a href="{{ pp.cable.get_absolute_url }}">{{ pp.cable }}</a>
+        {% else %}
+            &mdash;
+        {% endif %}
     </td>
 
     {# Connection #}