From d5c3f9e7801ecfcf6c8cb46b8da25665e0542dbe Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 12 Apr 2017 22:02:23 -0400 Subject: [PATCH] #878: Show assigned IP addresses in device interfaces list --- netbox/dcim/forms.py | 2 +- netbox/dcim/views.py | 13 ++---- netbox/project-static/css/base.css | 10 ++++ netbox/templates/dcim/device.html | 54 ++++++++-------------- netbox/templates/dcim/inc/interface.html | 58 ++++++++++++++++++++---- netbox/templates/dcim/inc/ipaddress.html | 21 --------- 6 files changed, 84 insertions(+), 74 deletions(-) delete mode 100644 netbox/templates/dcim/inc/ipaddress.html diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 8967936ad..80326b137 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1713,7 +1713,7 @@ class IPAddressForm(BootstrapMixin, CustomFieldForm): self.fields['interface'].required = True # If this device has only one interface, select it by default. - if len(interfaces) == 1: + if 'interface' not in self.initial and len(interfaces) == 1: self.fields['interface'].initial = interfaces[0] # If this device does not have any IP addresses assigned, default to setting the first IP as its primary. diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 8962d0219..edaa56d22 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -13,7 +13,7 @@ from django.shortcuts import get_object_or_404, redirect, render from django.utils.http import urlencode from django.views.generic import View -from ipam.models import Prefix, IPAddress, Service, VLAN +from ipam.models import Prefix, Service, VLAN from circuits.models import Circuit from extras.models import Graph, TopologyMap, GRAPH_TYPE_INTERFACE, GRAPH_TYPE_SITE from utilities.forms import ConfirmationForm @@ -700,19 +700,15 @@ def device(request, pk): interfaces = Interface.objects.order_naturally(device.device_type.interface_ordering)\ .filter(device=device, mgmt_only=False)\ .select_related('connected_as_a__interface_b__device', 'connected_as_b__interface_a__device', - 'circuit_termination__circuit') + 'circuit_termination__circuit').prefetch_related('ip_addresses') mgmt_interfaces = Interface.objects.order_naturally(device.device_type.interface_ordering)\ .filter(device=device, mgmt_only=True)\ .select_related('connected_as_a__interface_b__device', 'connected_as_b__interface_a__device', - 'circuit_termination__circuit') + 'circuit_termination__circuit').prefetch_related('ip_addresses') device_bays = natsorted( DeviceBay.objects.filter(device=device).select_related('installed_device__device_type__manufacturer'), key=attrgetter('name') ) - - # Gather relevant device objects - ip_addresses = IPAddress.objects.filter(interface__device=device).select_related('interface', 'vrf')\ - .order_by('address') services = Service.objects.filter(device=device) secrets = device.secrets.all() @@ -743,7 +739,6 @@ def device(request, pk): 'interfaces': interfaces, 'mgmt_interfaces': mgmt_interfaces, 'device_bays': device_bays, - 'ip_addresses': ip_addresses, 'services': services, 'secrets': secrets, 'related_devices': related_devices, @@ -1599,7 +1594,7 @@ def ipaddress_assign(request, pk): return redirect('dcim:device', pk=device.pk) else: - form = forms.IPAddressForm(device) + form = forms.IPAddressForm(device, initial=request.GET) return render(request, 'dcim/ipaddress_assign.html', { 'device': device, diff --git a/netbox/project-static/css/base.css b/netbox/project-static/css/base.css index 11ea04b72..0b740159a 100644 --- a/netbox/project-static/css/base.css +++ b/netbox/project-static/css/base.css @@ -313,6 +313,16 @@ li.occupied + li.available { border-top: 1px solid #474747; } +/* Devices */ +table.component-list tr.ipaddress td { + background-color: #eeffff; + padding-bottom: 4px; + padding-top: 4px; +} +table.component-list tr.ipaddress:hover td { + background-color: #e6f7f7; +} + /* Misc */ .banner-bottom { margin-bottom: 50px; diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html index d38f60cb3..2aa1666c8 100644 --- a/netbox/templates/dcim/device.html +++ b/netbox/templates/dcim/device.html @@ -194,35 +194,6 @@ {% endif %} {% endif %} -
-
- IP Addresses -
- {% if ip_addresses %} - - {% for ip in ip_addresses %} - {% include 'dcim/inc/ipaddress.html' %} - {% endfor %} -
- {% elif interfaces or mgmt_interfaces %} -
- None assigned -
- {% else %} -
- Create an interface to assign an IP. -
- {% endif %} - {% if perms.ipam.add_ipaddress %} - {% if interfaces or mgmt_interfaces %} - - {% endif %} - {% endif %} -
Services @@ -250,7 +221,7 @@
Critical Connections
- +
{% for iface in mgmt_interfaces %} {% include 'dcim/inc/interface.html' with icon='wrench' %} {% empty %} @@ -375,7 +346,7 @@ {% endif %} -
+
{% for devicebay in device_bays %} {% include 'dcim/inc/devicebay.html' with selectable=True %} {% empty %} @@ -416,6 +387,9 @@
Interfaces
+ {% if perms.dcim.change_interface and interfaces|length > 1 %}
-
+
{% for iface in interfaces %} {% include 'dcim/inc/interface.html' with selectable=True %} {% empty %} @@ -485,7 +459,7 @@ {% endif %} -
+
{% for csp in cs_ports %} {% include 'dcim/inc/consoleserverport.html' with selectable=True %} {% empty %} @@ -537,7 +511,7 @@ {% endif %} -
+
{% for po in power_outlets %} {% include 'dcim/inc/poweroutlet.html' with selectable=True %} {% empty %} @@ -628,6 +602,18 @@ $(".powerport-toggle").click(function() { $(".interface-toggle").click(function() { return toggleConnection($(this), "dcim/interface-connections/"); }); +// Toggle the display of IP addresses under interfaces +$('button.toggle-ips').click(function() { + var selected = $(this).attr('selected'); + if (selected) { + $('table.component-list tr.ipaddress').hide(); + } else { + $('table.component-list tr.ipaddress').show(); + } + $(this).attr('selected', !selected); + $(this).children('span').toggleClass('glyphicon-check glyphicon-unchecked'); + return false; +}); diff --git a/netbox/templates/dcim/inc/interface.html b/netbox/templates/dcim/inc/interface.html index a74fee5ac..7fe068304 100644 --- a/netbox/templates/dcim/inc/interface.html +++ b/netbox/templates/dcim/inc/interface.html @@ -1,4 +1,4 @@ - + {% if selectable and perms.dcim.change_interface or perms.dcim.delete_interface %} - {% if iface.is_lag %} {% elif iface.is_virtual %} @@ -53,7 +50,7 @@ Not connected {% endif %} - +{% for ip in iface.ip_addresses.all %} + + {% if selectable and perms.dcim.change_interface or perms.dcim.delete_interface %} + + {% endif %} + + + + + +{% endfor %} diff --git a/netbox/templates/dcim/inc/ipaddress.html b/netbox/templates/dcim/inc/ipaddress.html deleted file mode 100644 index 72920986e..000000000 --- a/netbox/templates/dcim/inc/ipaddress.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - -
@@ -16,9 +16,6 @@
{{ iface.member_interfaces.all|join:", "|default:"No members" }} {% endif %}
- {{ iface.mac_address|default:'' }} - LAG interface + {% if show_graphs %} {% if iface.circuit_termination or iface.connection %} {% endif %} {% endif %} + {% if perms.ipam.add_ipaddress %} + + + + {% endif %} {% if perms.dcim.change_interface %} {% if not iface.is_virtual %} {% if iface.connection %} @@ -73,19 +75,19 @@ {% endif %} - - + + {% elif iface.circuit_termination and perms.circuits.change_circuittermination %} - + {% else %} - + {% endif %} {% endif %} @@ -106,3 +108,41 @@ {% endif %}
+ {{ ip }} + {% if ip.description %} + + {% endif %} + {% if device.primary_ip4 == ip or device.primary_ip6 == ip %} + Primary + {% endif %} + + {% if ip.vrf %} + {{ ip.vrf }} + {% else %} + Global + {% endif %} + + {{ ip.get_status_display }} + + {% if perms.ipam.edit_ipaddress %} + + + + {% endif %} + {% if perms.ipam.delete_ipaddress %} + + + + {% endif %} +
- {{ ip }} - - {{ ip.vrf|default:"Global" }} - {{ ip.interface }} - {% if device.primary_ip4 == ip or device.primary_ip6 == ip %} - Primary - {% endif %} - - {% if perms.ipam.delete_ipaddress %} - - - - {% endif %} -