From 35aa8acd095aa59c8d5ab23b4e6fbe135c1899dc Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 11 Aug 2016 13:54:07 -0400 Subject: [PATCH 01/10] Post-release version bump --- netbox/netbox/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 67f808745f2..81098d5c55b 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -12,7 +12,7 @@ "the documentation.") -VERSION = '1.5.1' +VERSION = '1.5.2-dev' # Import local configuration for setting in ['ALLOWED_HOSTS', 'DATABASE', 'SECRET_KEY']: From b74f338aa17577237fd5bac14e173de420b2deb6 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 12 Aug 2016 11:24:29 -0400 Subject: [PATCH 02/10] Fixes #463: Prevent prepopulation of livesearch field with '---------' --- netbox/project-static/js/livesearch.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/netbox/project-static/js/livesearch.js b/netbox/project-static/js/livesearch.js index ed46fe1ff25..919fccf3b66 100644 --- a/netbox/project-static/js/livesearch.js +++ b/netbox/project-static/js/livesearch.js @@ -8,9 +8,15 @@ $(document).ready(function() { } // Update livesearch text when real field changes - search_field.val(real_field.children('option:selected').text()); - real_field.change(function() { + if (real_field.val()) { search_field.val(real_field.children('option:selected').text()); + } + real_field.change(function() { + if (real_field.val()) { + search_field.val(real_field.children('option:selected').text()); + } else { + search_field.val(''); + } }); search_field.autocomplete({ From bf1b8ab9b885960ba55f06669f51fe306e3e3b78 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 12 Aug 2016 13:29:24 -0400 Subject: [PATCH 03/10] Enable custom export templates for Tenants --- netbox/extras/models.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/netbox/extras/models.py b/netbox/extras/models.py index 2f761868072..6a32f573876 100644 --- a/netbox/extras/models.py +++ b/netbox/extras/models.py @@ -18,9 +18,10 @@ ) EXPORTTEMPLATE_MODELS = [ - 'site', 'rack', 'device', 'consoleport', 'powerport', 'interfaceconnection', - 'aggregate', 'prefix', 'ipaddress', 'vlan', - 'provider', 'circuit' + 'site', 'rack', 'device', 'consoleport', 'powerport', 'interfaceconnection', # DCIM + 'aggregate', 'prefix', 'ipaddress', 'vlan', # IPAM + 'provider', 'circuit', # Circuits + 'tenant', # Tenants ] ACTION_CREATE = 1 From 4f774f8ba618cb539e29e2aaf432bdc9b4e6e663 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Sat, 13 Aug 2016 01:02:03 -0400 Subject: [PATCH 04/10] Fixes #460: Corrected ordering of IP addresses with differing prefix lengths --- netbox/ipam/models.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index bd49feef10e..65724d41060 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -5,6 +5,7 @@ from django.core.urlresolvers import reverse from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models +from django.db.models.expressions import RawSQL from dcim.models import Interface from tenancy.models import Tenant @@ -295,6 +296,18 @@ def get_status_class(self): return STATUS_CHOICE_CLASSES[self.status] +class IPAddressManager(models.Manager): + + def get_queryset(self): + """ + By default, PostgreSQL will order INETs with shorter (larger) prefix lengths ahead of those with longer + (smaller) masks. This makes no sense when ordering IPs, which should be ordered solely by family and host + address. Here, we alter the default ordering to use HOST(address) instead of the raw address value. + """ + qs = super(IPAddressManager, self).get_queryset() + return qs.annotate(host=RawSQL('HOST(ipam_ipaddress.address)', [])).order_by('family', 'host') + + class IPAddress(CreatedUpdatedModel): """ An IPAddress represents an individual IPv4 or IPv6 address and its mask. The mask length should match what is @@ -317,6 +330,8 @@ class IPAddress(CreatedUpdatedModel): null=True, verbose_name='NAT IP (inside)') description = models.CharField(max_length=100, blank=True) + objects = IPAddressManager() + class Meta: ordering = ['family', 'address'] verbose_name = 'IP address' From 8faa16c831544aa4bec2e3fc16fc9e32462b43ae Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 15 Aug 2016 15:39:48 -0400 Subject: [PATCH 05/10] Fixes #460: For real this time --- netbox/ipam/models.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index 65724d41060..eebc43fad1d 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -302,10 +302,12 @@ def get_queryset(self): """ By default, PostgreSQL will order INETs with shorter (larger) prefix lengths ahead of those with longer (smaller) masks. This makes no sense when ordering IPs, which should be ordered solely by family and host - address. Here, we alter the default ordering to use HOST(address) instead of the raw address value. + address. We can use HOST() to extract just the host portion of the address (ignoring its mask), but we must + then re-cast this value to INET() so that records will be ordered properly. We are essentially re-casting each + IP address as a /32 or /128. """ qs = super(IPAddressManager, self).get_queryset() - return qs.annotate(host=RawSQL('HOST(ipam_ipaddress.address)', [])).order_by('family', 'host') + return qs.annotate(host=RawSQL('INET(HOST(ipam_ipaddress.address))', [])).order_by('family', 'host') class IPAddress(CreatedUpdatedModel): From 13136d0ccb97513544d1dfa887eceb3d9f52f97f Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 15 Aug 2016 15:52:06 -0400 Subject: [PATCH 06/10] Fixes #468: Added validation to prevent a connected interface from having its form factor set to 'virtual' --- netbox/dcim/models.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index b1c6b60b71e..a0e2b4e0fb5 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -1032,6 +1032,13 @@ class Meta: def __unicode__(self): return self.name + def clean(self): + + if self.form_factor == IFACE_FF_VIRTUAL and self.is_connected: + raise ValidationError({'form_factor': "Virtual interfaces cannot be connected to another interface or " + "circuit. Disconnect the interface or choose a physical form " + "factor."}) + @property def is_physical(self): return self.form_factor != IFACE_FF_VIRTUAL From 78c3b25f0a1b93b5b0c02602208e48b9cc1ed7c0 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 15 Aug 2016 16:11:17 -0400 Subject: [PATCH 07/10] Fixes #467: Include prefixes and IPs which inherit tenancy from their VRF in tenant stats --- netbox/tenancy/views.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/netbox/tenancy/views.py b/netbox/tenancy/views.py index ec220b9be2e..a1191545862 100644 --- a/netbox/tenancy/views.py +++ b/netbox/tenancy/views.py @@ -1,5 +1,5 @@ from django.contrib.auth.mixins import PermissionRequiredMixin -from django.db.models import Count +from django.db.models import Count, Q from django.shortcuts import get_object_or_404, render from circuits.models import Circuit @@ -59,8 +59,14 @@ def tenant(request, slug): 'rack_count': Rack.objects.filter(tenant=tenant).count(), 'device_count': Device.objects.filter(tenant=tenant).count(), 'vrf_count': VRF.objects.filter(tenant=tenant).count(), - 'prefix_count': Prefix.objects.filter(tenant=tenant).count(), - 'ipaddress_count': IPAddress.objects.filter(tenant=tenant).count(), + 'prefix_count': Prefix.objects.filter( + Q(tenant=tenant) | + Q(tenant__isnull=True, vrf__tenant=tenant) + ).count(), + 'ipaddress_count': IPAddress.objects.filter( + Q(tenant=tenant) | + Q(tenant__isnull=True, vrf__tenant=tenant) + ).count(), 'vlan_count': VLAN.objects.filter(tenant=tenant).count(), 'circuit_count': Circuit.objects.filter(tenant=tenant).count(), } From d045429b510cd6b83b3fbceea603ea5b82155ee7 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 15 Aug 2016 17:57:17 -0400 Subject: [PATCH 08/10] Fixes #469: Added missing import buttons to list views --- netbox/templates/circuits/circuit_list.html | 4 ++++ netbox/templates/circuits/provider_list.html | 4 ++++ netbox/templates/ipam/aggregate_list.html | 4 ++++ netbox/templates/tenancy/tenant_list.html | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/netbox/templates/circuits/circuit_list.html b/netbox/templates/circuits/circuit_list.html index f30339ec6f6..db6861b2e8e 100644 --- a/netbox/templates/circuits/circuit_list.html +++ b/netbox/templates/circuits/circuit_list.html @@ -10,6 +10,10 @@ Add a circuit + + + Import circuits + {% endif %} {% include 'inc/export_button.html' with obj_type='circuits' %} diff --git a/netbox/templates/circuits/provider_list.html b/netbox/templates/circuits/provider_list.html index 54dfdac93de..ca3dbfc09b3 100644 --- a/netbox/templates/circuits/provider_list.html +++ b/netbox/templates/circuits/provider_list.html @@ -9,6 +9,10 @@ Add a provider + + + Import providers + {% endif %} {% include 'inc/export_button.html' with obj_type='providers' %} diff --git a/netbox/templates/ipam/aggregate_list.html b/netbox/templates/ipam/aggregate_list.html index 52bca7219e5..aef7d84c19d 100644 --- a/netbox/templates/ipam/aggregate_list.html +++ b/netbox/templates/ipam/aggregate_list.html @@ -11,6 +11,10 @@ Add an aggregate + + + Import aggregates + {% endif %} {% include 'inc/export_button.html' with obj_type='aggregates' %} diff --git a/netbox/templates/tenancy/tenant_list.html b/netbox/templates/tenancy/tenant_list.html index 24f796da346..529f01c7646 100644 --- a/netbox/templates/tenancy/tenant_list.html +++ b/netbox/templates/tenancy/tenant_list.html @@ -10,6 +10,10 @@ Add a tenant + + + Import tenants + {% endif %} {% include 'inc/export_button.html' with obj_type='tenants' %} From 989ec721d31f5d4c4bf485a82cca4766c5cc4856 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 16 Aug 2016 09:29:20 -0400 Subject: [PATCH 09/10] Fixes #472: Hide the connection button for interfaces which have a circuit terminated to them --- netbox/templates/dcim/inc/_interface.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/netbox/templates/dcim/inc/_interface.html b/netbox/templates/dcim/inc/_interface.html index a3d1b8e0422..a48200c302c 100644 --- a/netbox/templates/dcim/inc/_interface.html +++ b/netbox/templates/dcim/inc/_interface.html @@ -56,6 +56,10 @@ + {% elif iface.circuit and perms.circuits.change_circuit %} + + + {% else %} From 2eb8b4fe71ee1a129eabdda53d3b3cd13dbba7f6 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 16 Aug 2016 09:32:53 -0400 Subject: [PATCH 10/10] Release v1.5.2 --- netbox/netbox/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 81098d5c55b..0384382b006 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -12,7 +12,7 @@ "the documentation.") -VERSION = '1.5.2-dev' +VERSION = '1.5.2' # Import local configuration for setting in ['ALLOWED_HOSTS', 'DATABASE', 'SECRET_KEY']: