mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Extend cable trace view to show related paths
This commit is contained in:
@ -34,10 +34,11 @@ from .constants import NONCONNECTABLE_IFACE_TYPES
|
|||||||
from .models import (
|
from .models import (
|
||||||
Cable, CablePath, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
|
Cable, CablePath, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
|
||||||
DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate,
|
DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate,
|
||||||
InventoryItem, Manufacturer, Platform, PowerFeed, PowerOutlet, PowerOutletTemplate, PowerPanel, PowerPort,
|
InventoryItem, Manufacturer, PathEndpoint, Platform, PowerFeed, PowerOutlet, PowerOutletTemplate, PowerPanel,
|
||||||
PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site,
|
PowerPort, PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site,
|
||||||
VirtualChassis,
|
VirtualChassis,
|
||||||
)
|
)
|
||||||
|
from .utils import object_to_path_node
|
||||||
|
|
||||||
|
|
||||||
class BulkDisconnectView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
|
class BulkDisconnectView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
|
||||||
@ -1965,17 +1966,36 @@ class PathTraceView(ObjectView):
|
|||||||
return super().dispatch(request, *args, **kwargs)
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
obj = get_object_or_404(self.queryset, pk=pk)
|
obj = get_object_or_404(self.queryset, pk=pk)
|
||||||
path = obj.trace()
|
related_paths = []
|
||||||
total_length = sum(
|
|
||||||
[entry[1]._abs_length for entry in path if entry[1] and entry[1]._abs_length]
|
# 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', {
|
return render(request, 'dcim/cable_trace.html', {
|
||||||
'obj': obj,
|
'obj': obj,
|
||||||
'trace': path,
|
'path': path,
|
||||||
'total_length': total_length,
|
'related_paths': related_paths,
|
||||||
|
# 'total_length': total_length,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,52 +7,70 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4 col-md-offset-1 text-center">
|
<div class="col-md-9">
|
||||||
<h4>Near End</h4>
|
|
||||||
</div>
|
<div class="row">
|
||||||
<div class="col-md-3 text-center">
|
<div class="col-md-4 col-md-offset-1 text-center">
|
||||||
{% if total_length %}<h5>Total length: {{ total_length|floatformat:"-2" }} Meters<h5>{% endif %}
|
<h4>Near End</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 text-center">
|
<div class="col-md-3 text-center">
|
||||||
<h4>Far End</h4>
|
{% if total_length %}<h5>Total length: {{ total_length|floatformat:"-2" }} Meters<h5>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col-md-4 text-center">
|
||||||
{% for near_end, cable, far_end in trace %}
|
<h4>Far End</h4>
|
||||||
<div class="row">
|
</div>
|
||||||
<div class="col-md-1 text-right">
|
|
||||||
<h3>{{ forloop.counter }}</h3>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
{% for near_end, cable, far_end in path.origin.trace %}
|
||||||
{% include 'dcim/inc/cable_trace_end.html' with end=near_end %}
|
<div class="row">
|
||||||
</div>
|
<div class="col-md-1 text-right">
|
||||||
<div class="col-md-3 text-center">
|
<h3>{{ forloop.counter }}</h3>
|
||||||
{% if cable %}
|
</div>
|
||||||
<h4>
|
<div class="col-md-4">
|
||||||
<a href="{% url 'dcim:cable' pk=cable.pk %}">
|
{% include 'dcim/inc/cable_trace_end.html' with end=near_end %}
|
||||||
{% if cable.label %}<code>{{ cable.label }}</code>{% else %}Cable #{{ cable.pk }}{% endif %}
|
</div>
|
||||||
</a>
|
<div class="col-md-3 text-center">
|
||||||
</h4>
|
{% if cable %}
|
||||||
<p><span class="label label-{{ cable.get_status_class }}">{{ cable.get_status_display }}</span></p>
|
<h4>
|
||||||
<p>{{ cable.get_type_display|default:"" }}</p>
|
<a href="{% url 'dcim:cable' pk=cable.pk %}">
|
||||||
{% if cable.length %}{{ cable.length }} {{ cable.get_length_unit_display }}{% endif %}
|
{% if cable.label %}<code>{{ cable.label }}</code>{% else %}Cable #{{ cable.pk }}{% endif %}
|
||||||
{% if cable.color %}
|
</a>
|
||||||
<span class="label color-block center-block" style="background-color: #{{ cable.color }}"> </span>
|
</h4>
|
||||||
{% endif %}
|
<p><span class="label label-{{ cable.get_status_class }}">{{ cable.get_status_display }}</span></p>
|
||||||
{% else %}
|
<p>{{ cable.get_type_display|default:"" }}</p>
|
||||||
<h4 class="text-muted">No Cable</h4>
|
{% if cable.length %}{{ cable.length }} {{ cable.get_length_unit_display }}{% endif %}
|
||||||
{% endif %}
|
{% if cable.color %}
|
||||||
</div>
|
<span class="label color-block center-block" style="background-color: #{{ cable.color }}"> </span>
|
||||||
<div class="col-md-4">
|
{% endif %}
|
||||||
{% if far_end %}
|
{% else %}
|
||||||
{% include 'dcim/inc/cable_trace_end.html' with end=far_end %}
|
<h4 class="text-muted">No Cable</h4>
|
||||||
{% endif %}
|
{% 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>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<div class="col-md-3">
|
||||||
{% endfor %}
|
|
||||||
<div class="row">
|
<h4 class="text-center">Related Paths</h4>
|
||||||
<div class="col-md-11 col-md-offset-1">
|
<ul class="nav nav-pills nav-stacked">
|
||||||
<h3 class="text-success text-center">Trace completed!</h3>
|
{% 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>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Reference in New Issue
Block a user