From 8103c399d55409e23861c7eb91350760dd962e6b Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 27 Mar 2017 10:53:32 -0400 Subject: [PATCH 01/10] Fixes #991: Correct server error on "create and connect another" interface connection --- netbox/dcim/views.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 246fe06f0..f2b042599 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1450,9 +1450,10 @@ def interfaceconnection_add(request, pk): )) if '_addanother' in request.POST: base_url = reverse('dcim:interfaceconnection_add', kwargs={'pk': device.pk}) + device_b = interfaceconnection.interface_b.device params = urlencode({ - 'rack_b': interfaceconnection.interface_b.device.rack.pk, - 'device_b': interfaceconnection.interface_b.device.pk, + 'rack_b': device_b.rack.pk if device_b.rack else '', + 'device_b': device_b.pk, }) return HttpResponseRedirect('{}?{}'.format(base_url, params)) else: From e8fd0f3531113852b426156cc900dd9d494f5e69 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 27 Mar 2017 10:55:54 -0400 Subject: [PATCH 02/10] Order interfaces naturally for Device A --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 0e09adbb2..e2cd829b8 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1481,7 +1481,7 @@ class InterfaceConnectionForm(BootstrapMixin, forms.ModelForm): super(InterfaceConnectionForm, self).__init__(*args, **kwargs) # Initialize interface A choices - device_a_interfaces = Interface.objects.filter(device=device_a).exclude( + device_a_interfaces = Interface.objects.order_naturally().filter(device=device_a).exclude( form_factor__in=VIRTUAL_IFACE_TYPES ).select_related( 'circuit_termination', 'connected_as_a', 'connected_as_b' From 28761fc96029525d213baaa5c2fdcc8fb720da56 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 28 Mar 2017 15:57:50 -0400 Subject: [PATCH 03/10] Closes #362: Added per_page query parameter to control pagination page length --- netbox/ipam/views.py | 22 +++++++++++++++++++--- netbox/utilities/paginator.py | 3 ++- netbox/utilities/views.py | 9 ++++++++- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index bcbb80e8b..864909878 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -1,6 +1,7 @@ from django_tables2 import RequestConfig import netaddr +from django.conf import settings from django.contrib.auth.decorators import permission_required from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib import messages @@ -295,7 +296,12 @@ def aggregate(request, pk): prefix_table = tables.PrefixTable(child_prefixes) if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'): prefix_table.base_columns['pk'].visible = True - RequestConfig(request, paginate={'klass': EnhancedPaginator}).configure(prefix_table) + + paginate = { + 'klass': EnhancedPaginator, + 'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT) + } + RequestConfig(request, paginate).configure(prefix_table) # Compile permissions list for rendering the object table permissions = { @@ -427,7 +433,12 @@ def prefix(request, pk): child_prefix_table = tables.PrefixTable(child_prefixes) if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'): child_prefix_table.base_columns['pk'].visible = True - RequestConfig(request, paginate={'klass': EnhancedPaginator}).configure(child_prefix_table) + + paginate = { + 'klass': EnhancedPaginator, + 'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT) + } + RequestConfig(request, paginate).configure(child_prefix_table) # Compile permissions list for rendering the object table permissions = { @@ -500,7 +511,12 @@ def prefix_ipaddresses(request, pk): ip_table = tables.IPAddressTable(ipaddresses) if request.user.has_perm('ipam.change_ipaddress') or request.user.has_perm('ipam.delete_ipaddress'): ip_table.base_columns['pk'].visible = True - RequestConfig(request, paginate={'klass': EnhancedPaginator}).configure(ip_table) + + paginate = { + 'klass': EnhancedPaginator, + 'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT) + } + RequestConfig(request, paginate).configure(ip_table) # Compile permissions list for rendering the object table permissions = { diff --git a/netbox/utilities/paginator.py b/netbox/utilities/paginator.py index 2c0e2fb3d..ae915f773 100644 --- a/netbox/utilities/paginator.py +++ b/netbox/utilities/paginator.py @@ -5,7 +5,8 @@ from django.core.paginator import Paginator, Page class EnhancedPaginator(Paginator): def __init__(self, object_list, per_page, **kwargs): - per_page = getattr(settings, 'PAGINATE_COUNT', 50) + if not isinstance(per_page, int) or per_page < 1: + per_page = getattr(settings, 'PAGINATE_COUNT', 50) super(EnhancedPaginator, self).__init__(object_list, per_page, **kwargs) def _get_page(self, *args, **kwargs): diff --git a/netbox/utilities/views.py b/netbox/utilities/views.py index f38d9a0ab..08bf3f65a 100644 --- a/netbox/utilities/views.py +++ b/netbox/utilities/views.py @@ -1,6 +1,7 @@ from collections import OrderedDict from django_tables2 import RequestConfig +from django.conf import settings from django.contrib import messages from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError @@ -101,7 +102,13 @@ class ObjectListView(View): table = self.table(self.queryset) if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']): table.base_columns['pk'].visible = True - RequestConfig(request, paginate={'klass': EnhancedPaginator}).configure(table) + + # Apply the request context + paginate = { + 'klass': EnhancedPaginator, + 'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT) + } + RequestConfig(request, paginate).configure(table) context = { 'table': table, From 6813787fc766e6b9062bee8e1e0a2f17a88fbcdd Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 29 Mar 2017 12:15:14 -0400 Subject: [PATCH 04/10] Fixes #1013: Show edit/delete reservation buttons on rack view --- netbox/templates/dcim/rack.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/templates/dcim/rack.html b/netbox/templates/dcim/rack.html index d6529c2a4..40c9e812e 100644 --- a/netbox/templates/dcim/rack.html +++ b/netbox/templates/dcim/rack.html @@ -216,12 +216,12 @@ {{ resv.user }} · {{ resv.created }} - {% if perms.change_rackreservation %} + {% if perms.dcim.change_rackreservation %} {% endif %} - {% if perms.delete_rackreservation %} + {% if perms.dcim.delete_rackreservation %} From 05d3354570095ac070fd6173e347dc0e6d5b2eb7 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 3 Apr 2017 14:45:20 -0400 Subject: [PATCH 05/10] Fixes #1022: Record user actions when creating IP addresses in bulk --- netbox/extras/models.py | 9 +++++++-- netbox/utilities/views.py | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/netbox/extras/models.py b/netbox/extras/models.py index f06d0aa29..b46c27f87 100644 --- a/netbox/extras/models.py +++ b/netbox/extras/models.py @@ -56,13 +56,15 @@ ACTION_EDIT = 3 ACTION_BULK_EDIT = 4 ACTION_DELETE = 5 ACTION_BULK_DELETE = 6 +ACTION_BULK_CREATE = 7 ACTION_CHOICES = ( (ACTION_CREATE, 'created'), + (ACTION_BULK_CREATE, 'bulk created'), (ACTION_IMPORT, 'imported'), (ACTION_EDIT, 'modified'), (ACTION_BULK_EDIT, 'bulk edited'), (ACTION_DELETE, 'deleted'), - (ACTION_BULK_DELETE, 'bulk deleted') + (ACTION_BULK_DELETE, 'bulk deleted'), ) @@ -328,6 +330,9 @@ class UserActionManager(models.Manager): def log_import(self, user, content_type, message=''): self.log_bulk_action(user, content_type, ACTION_IMPORT, message) + def log_bulk_create(self, user, content_type, message=''): + self.log_bulk_action(user, content_type, ACTION_BULK_CREATE, message) + def log_bulk_edit(self, user, content_type, message=''): self.log_bulk_action(user, content_type, ACTION_BULK_EDIT, message) @@ -358,7 +363,7 @@ class UserAction(models.Model): return u'{} {} {}'.format(self.user, self.get_action_display(), self.content_type) def icon(self): - if self.action in [ACTION_CREATE, ACTION_IMPORT]: + if self.action in [ACTION_CREATE, ACTION_BULK_CREATE, ACTION_IMPORT]: return mark_safe('') elif self.action in [ACTION_EDIT, ACTION_BULK_EDIT]: return mark_safe('') diff --git a/netbox/utilities/views.py b/netbox/utilities/views.py index 08bf3f65a..010a60daa 100644 --- a/netbox/utilities/views.py +++ b/netbox/utilities/views.py @@ -334,7 +334,9 @@ class BulkAddView(View): form.add_error(None, e) if not form.errors: - messages.success(request, u"Added {} {}.".format(len(new_objs), self.model._meta.verbose_name_plural)) + msg = u"Added {} {}".format(len(new_objs), self.model._meta.verbose_name_plural) + messages.success(request, msg) + UserAction.objects.log_bulk_create(request.user, ContentType.objects.get_for_model(self.model), msg) if '_addanother' in request.POST: return redirect(request.path) return redirect(self.default_return_url) From 0b681c471edd98bcc4722f7be8da6e3548837f59 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 3 Apr 2017 16:01:03 -0400 Subject: [PATCH 06/10] Removed survey notice --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index f2b430929..66c35250b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,3 @@ -**The [2017 NetBox User Survey](https://goo.gl/forms/75HnNS2iE0Y1hVFH3) is open!** Please consider taking a moment to respond. Your feedback helps shape the pace and focus of NetBox development. The survey will remain open until 2017-03-31. Results will be published on the mailing list. - ---- - ![NetBox](docs/netbox_logo.png "NetBox logo") NetBox is an IP address management (IPAM) and data center infrastructure management (DCIM) tool. Initially conceived by the network engineering team at [DigitalOcean](https://www.digitalocean.com/), NetBox was developed specifically to address the needs of network and infrastructure engineers. From f11bb254a5f66701a0a3d436e38699d4a82d31d8 Mon Sep 17 00:00:00 2001 From: Stephen Date: Tue, 4 Apr 2017 16:37:20 +0100 Subject: [PATCH 07/10] Only show Custom Fields on IP Address Assign Page if custom fields are set against the ip address (#1031) --- netbox/templates/dcim/ipaddress_assign.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/netbox/templates/dcim/ipaddress_assign.html b/netbox/templates/dcim/ipaddress_assign.html index 3312a39c3..e8596158c 100644 --- a/netbox/templates/dcim/ipaddress_assign.html +++ b/netbox/templates/dcim/ipaddress_assign.html @@ -43,12 +43,14 @@ {% render_field form.set_as_primary %} + {% if form.custom_fields %}
Custom Fields
{% render_custom_fields form %}
+ {% endif %}
From 11ae9381461842e47cd539f89bdf6cc9f886e454 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 4 Apr 2017 11:55:16 -0400 Subject: [PATCH 08/10] Fixes #1027: Fixed nav menu highlighting when BASE_PATH is set --- netbox/templates/_base.html | 16 ++++++++-------- netbox/utilities/templatetags/helpers.py | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/netbox/templates/_base.html b/netbox/templates/_base.html index 0ebc4f5b4..ba90f0106 100644 --- a/netbox/templates/_base.html +++ b/netbox/templates/_base.html @@ -28,7 +28,7 @@