Explorar el Código

Extend cable trace view to show related paths

Jeremy Stretch hace 5 años
padre
commit
19430ddeb5
Se han modificado 2 ficheros con 90 adiciones y 52 borrados
  1. 29 9
      netbox/dcim/views.py
  2. 61 43
      netbox/templates/dcim/cable_trace.html

+ 29 - 9
netbox/dcim/views.py

@@ -34,10 +34,11 @@ from .constants import NONCONNECTABLE_IFACE_TYPES
 from .models import (
     Cable, CablePath, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
     DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate,
-    InventoryItem, Manufacturer, Platform, PowerFeed, PowerOutlet, PowerOutletTemplate, PowerPanel, PowerPort,
-    PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site,
+    InventoryItem, Manufacturer, PathEndpoint, Platform, PowerFeed, PowerOutlet, PowerOutletTemplate, PowerPanel,
+    PowerPort, PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site,
     VirtualChassis,
 )
+from .utils import object_to_path_node
 
 
 class BulkDisconnectView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
@@ -1965,17 +1966,36 @@ class PathTraceView(ObjectView):
         return super().dispatch(request, *args, **kwargs)
 
     def get(self, request, pk):
-
         obj = get_object_or_404(self.queryset, pk=pk)
-        path = obj.trace()
-        total_length = sum(
-            [entry[1]._abs_length for entry in path if entry[1] and entry[1]._abs_length]
-        )
+        related_paths = []
+
+        # If tracing a PathEndpoint, locate the CablePath (if one exists) by its origin
+        if isinstance(obj, PathEndpoint):
+            path = obj._path
+        # Otherwise, find all CablePaths which traverse the specified object
+        else:
+            related_paths = CablePath.objects.filter(
+                path__contains=[object_to_path_node(obj)]
+            ).prefetch_related('origin')
+            # Check for specification of a particular path (when tracing pass-through ports)
+            try:
+                path_id = int(request.GET.get('cablepath_id'))
+            except TypeError:
+                path_id = None
+            if path_id in list(related_paths.values_list('pk', flat=True)):
+                path = CablePath.objects.get(pk=path_id)
+            else:
+                path = related_paths.first()
+
+        # total_length = sum(
+        #     [entry[1]._abs_length for entry in path if entry[1] and entry[1]._abs_length]
+        # )
 
         return render(request, 'dcim/cable_trace.html', {
             'obj': obj,
-            'trace': path,
-            'total_length': total_length,
+            'path': path,
+            'related_paths': related_paths,
+            # 'total_length': total_length,
         })
 
 

+ 61 - 43
netbox/templates/dcim/cable_trace.html

@@ -7,52 +7,70 @@
 
 {% block content %}
     <div class="row">
-        <div class="col-md-4 col-md-offset-1 text-center">
-            <h4>Near End</h4>
-        </div>
-        <div class="col-md-3 text-center">
-            {% if total_length %}<h5>Total length: {{ total_length|floatformat:"-2" }} Meters<h5>{% endif %}
-        </div>
-        <div class="col-md-4 text-center">
-            <h4>Far End</h4>
-        </div>
-    </div>
-    {% for near_end, cable, far_end in trace %}
-        <div class="row">
-            <div class="col-md-1 text-right">
-                <h3>{{ forloop.counter }}</h3>
-            </div>
-            <div class="col-md-4">
-                {% include 'dcim/inc/cable_trace_end.html' with end=near_end %}
-            </div>
-            <div class="col-md-3 text-center">
-                {% if cable %}
-                    <h4>
-                        <a href="{% url 'dcim:cable' pk=cable.pk %}">
-                            {% if cable.label %}<code>{{ cable.label }}</code>{% else %}Cable #{{ cable.pk }}{% endif %}
-                        </a>
-                    </h4>
-                    <p><span class="label label-{{ cable.get_status_class }}">{{ cable.get_status_display }}</span></p>
-                    <p>{{ cable.get_type_display|default:"" }}</p>
-                    {% if cable.length %}{{ cable.length }} {{ cable.get_length_unit_display }}{% endif %}
-                    {% if cable.color %}
-                        <span class="label color-block center-block" style="background-color: #{{ cable.color }}">&nbsp;</span>
-                    {% endif %}
-                {% else %}
-                    <h4 class="text-muted">No Cable</h4>
-                {% endif %}
+        <div class="col-md-9">
+
+            <div class="row">
+                <div class="col-md-4 col-md-offset-1 text-center">
+                    <h4>Near End</h4>
+                </div>
+                <div class="col-md-3 text-center">
+                    {% if total_length %}<h5>Total length: {{ total_length|floatformat:"-2" }} Meters<h5>{% endif %}
+                </div>
+                <div class="col-md-4 text-center">
+                    <h4>Far End</h4>
+                </div>
             </div>
-            <div class="col-md-4">
-                {% if far_end %}
-                    {% include 'dcim/inc/cable_trace_end.html' with end=far_end %}
-                {% endif %}
+            {% for near_end, cable, far_end in path.origin.trace %}
+                <div class="row">
+                    <div class="col-md-1 text-right">
+                        <h3>{{ forloop.counter }}</h3>
+                    </div>
+                    <div class="col-md-4">
+                        {% include 'dcim/inc/cable_trace_end.html' with end=near_end %}
+                    </div>
+                    <div class="col-md-3 text-center">
+                        {% if cable %}
+                            <h4>
+                                <a href="{% url 'dcim:cable' pk=cable.pk %}">
+                                    {% if cable.label %}<code>{{ cable.label }}</code>{% else %}Cable #{{ cable.pk }}{% endif %}
+                                </a>
+                            </h4>
+                            <p><span class="label label-{{ cable.get_status_class }}">{{ cable.get_status_display }}</span></p>
+                            <p>{{ cable.get_type_display|default:"" }}</p>
+                            {% if cable.length %}{{ cable.length }} {{ cable.get_length_unit_display }}{% endif %}
+                            {% if cable.color %}
+                                <span class="label color-block center-block" style="background-color: #{{ cable.color }}">&nbsp;</span>
+                            {% endif %}
+                        {% else %}
+                            <h4 class="text-muted">No Cable</h4>
+                        {% endif %}
+                    </div>
+                    <div class="col-md-4">
+                        {% if far_end %}
+                            {% include 'dcim/inc/cable_trace_end.html' with end=far_end %}
+                        {% endif %}
+                    </div>
+                </div>
+                <hr />
+            {% endfor %}
+            <div class="row">
+                <div class="col-md-11 col-md-offset-1">
+                    <h3 class="text-success text-center">Trace completed!</h3>
+                </div>
             </div>
+
         </div>
-        <hr />
-    {% endfor %}
-    <div class="row">
-        <div class="col-md-11 col-md-offset-1">
-            <h3 class="text-success text-center">Trace completed!</h3>
+        <div class="col-md-3">
+
+            <h4 class="text-center">Related Paths</h4>
+            <ul class="nav nav-pills nav-stacked">
+                {% for cablepath in related_paths %}
+                    <li role="presentation"{% if cablepath.pk == path.pk %} class="active"{% endif %}>
+                        <a href="?cablepath_id={{ cablepath.pk }}">From {{ cablepath.origin }} ({{ cablepath.origin.parent }})</a>
+                    </li>
+                {% endfor %}
+            </ul>
+
         </div>
     </div>
 {% endblock %}