From 802af06c0f8d59160b46255749e17b7ead733298 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 21 Aug 2020 12:58:48 -0400 Subject: [PATCH 01/73] Closes #4991: Add Python and NetBox versions to error page --- docs/release-notes/version-2.9.md | 8 ++++++++ netbox/templates/500.html | 5 ++++- netbox/utilities/views.py | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index cc38fdb5e..8bee68e8a 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -1,5 +1,13 @@ # NetBox v2.9 +## v2.9.1 (FUTURE) + +### Enhancements + +* [#4991](https://github.com/netbox-community/netbox/issues/4991) - Add Python and NetBox versions to error page + +--- + ## v2.9.0 (2020-08-21) ### New Features diff --git a/netbox/templates/500.html b/netbox/templates/500.html index bd59b7233..61115cbab 100644 --- a/netbox/templates/500.html +++ b/netbox/templates/500.html @@ -31,7 +31,10 @@ The complete exception is provided below:

{{ exception }}
-{{ error }}
+{{ error }} + +Python version: {{ python_version }} +NetBox version: {{ netbox_version }}

If further assistance is required, please post to the NetBox mailing list.

diff --git a/netbox/utilities/views.py b/netbox/utilities/views.py index c7db2f649..079068648 100644 --- a/netbox/utilities/views.py +++ b/netbox/utilities/views.py @@ -1,8 +1,10 @@ import logging +import platform import re import sys from copy import deepcopy +from django.conf import settings from django.contrib import messages from django.contrib.auth.decorators import login_required from django.contrib.contenttypes.models import ContentType @@ -1421,6 +1423,8 @@ def server_error(request, template_name=ERROR_500_TEMPLATE_NAME): type_, error, traceback = sys.exc_info() return HttpResponseServerError(template.render({ + 'python_version': platform.python_version(), + 'netbox_version': settings.VERSION, 'exception': str(type_), 'error': error, })) From ed65603632af3e542a79543cd1d4a5c5d666598b Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 21 Aug 2020 13:17:41 -0400 Subject: [PATCH 02/73] Closes #4540: Add IP address status type for SLAAC --- docs/models/ipam/ipaddress.md | 1 + docs/release-notes/version-2.9.md | 1 + netbox/ipam/choices.py | 2 ++ 3 files changed, 4 insertions(+) diff --git a/docs/models/ipam/ipaddress.md b/docs/models/ipam/ipaddress.md index 04ac417db..1ea613997 100644 --- a/docs/models/ipam/ipaddress.md +++ b/docs/models/ipam/ipaddress.md @@ -10,6 +10,7 @@ Each IP address can also be assigned an operational status and a functional role * Reserved * Deprecated * DHCP +* SLAAC (IPv6 Stateless Address Autoconfiguration) Roles are used to indicate some special attribute of an IP address; for example, use as a loopback or as the the virtual IP for a VRRP group. (Note that functional roles are conceptual in nature, and thus cannot be customized by the user.) Available roles include: diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 8bee68e8a..74095a7fe 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -4,6 +4,7 @@ ### Enhancements +* [#4540](https://github.com/netbox-community/netbox/issues/4540) - Add IP address status type for SLAAC * [#4991](https://github.com/netbox-community/netbox/issues/4991) - Add Python and NetBox versions to error page --- diff --git a/netbox/ipam/choices.py b/netbox/ipam/choices.py index 68fdfd9df..f3ff19ddc 100644 --- a/netbox/ipam/choices.py +++ b/netbox/ipam/choices.py @@ -41,12 +41,14 @@ class IPAddressStatusChoices(ChoiceSet): STATUS_RESERVED = 'reserved' STATUS_DEPRECATED = 'deprecated' STATUS_DHCP = 'dhcp' + STATUS_SLAAC = 'slaac' CHOICES = ( (STATUS_ACTIVE, 'Active'), (STATUS_RESERVED, 'Reserved'), (STATUS_DEPRECATED, 'Deprecated'), (STATUS_DHCP, 'DHCP'), + (STATUS_SLAAC, 'SLAAC'), ) From f37997ac5433ac0f43ddc1457d4c6c88034d6990 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 21 Aug 2020 13:35:03 -0400 Subject: [PATCH 03/73] Closes #4814: Allow nested LAG interfaces --- docs/models/dcim/interface.md | 2 +- docs/release-notes/version-2.9.md | 1 + netbox/dcim/forms.py | 5 ++++- netbox/dcim/models/device_components.py | 16 +++++----------- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/docs/models/dcim/interface.md b/docs/models/dcim/interface.md index be43ac2a6..756e320af 100644 --- a/docs/models/dcim/interface.md +++ b/docs/models/dcim/interface.md @@ -4,7 +4,7 @@ Interfaces in NetBox represent network interfaces used to exchange data with con Interfaces may be physical or virtual in nature, but only physical interfaces may be connected via cables. Cables can connect interfaces to pass-through ports, circuit terminations, or other interfaces. -Physical interfaces may be arranged into a link aggregation group (LAG) and associated with a parent LAG (virtual) interface. Like all virtual interfaces, LAG interfaces cannot be connected physically. +Physical interfaces may be arranged into a link aggregation group (LAG) and associated with a parent LAG (virtual) interface. LAG interfaces can be recursively nested to model bonding of trunk groups. Like all virtual interfaces, LAG interfaces cannot be connected physically. IP addresses can be assigned to interfaces. VLANs can also be assigned to each interface as either tagged or untagged. (An interface may have only one untagged VLAN.) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 74095a7fe..d42e35b92 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -5,6 +5,7 @@ ### Enhancements * [#4540](https://github.com/netbox-community/netbox/issues/4540) - Add IP address status type for SLAAC +* [#4814](https://github.com/netbox-community/netbox/issues/4814) - Allow nested LAG interfaces * [#4991](https://github.com/netbox-community/netbox/issues/4991) - Add Python and NetBox versions to error page --- diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 6dd5cb6bf..2b8bf4e9e 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -2686,7 +2686,10 @@ class InterfaceForm(InterfaceCommonForm, BootstrapMixin, forms.ModelForm): device_query = Q(device=device) if device.virtual_chassis: device_query |= Q(device__virtual_chassis=device.virtual_chassis) - self.fields['lag'].queryset = Interface.objects.filter(device_query, type=InterfaceTypeChoices.TYPE_LAG) + self.fields['lag'].queryset = Interface.objects.filter( + device_query, + type=InterfaceTypeChoices.TYPE_LAG + ).exclude(pk=self.instance.pk) # Add current site to VLANs query params self.fields['untagged_vlan'].widget.add_query_param('site_id', device.site.pk) diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py index 92b0605e9..d7e077a16 100644 --- a/netbox/dcim/models/device_components.py +++ b/netbox/dcim/models/device_components.py @@ -702,18 +702,12 @@ class Interface(CableTermination, ComponentModel, BaseInterface): }) # A virtual interface cannot have a parent LAG - if self.type in NONCONNECTABLE_IFACE_TYPES and self.lag is not None: - raise ValidationError({ - 'lag': "{} interfaces cannot have a parent LAG interface.".format(self.get_type_display()) - }) + if self.type == InterfaceTypeChoices.TYPE_VIRTUAL and self.lag is not None: + raise ValidationError({'lag': "Virtual interfaces cannot have a parent LAG interface."}) - # Only a LAG can have LAG members - if self.type != InterfaceTypeChoices.TYPE_LAG and self.member_interfaces.exists(): - raise ValidationError({ - 'type': "Cannot change interface type; it has LAG members ({}).".format( - ", ".join([iface.name for iface in self.member_interfaces.all()]) - ) - }) + # A LAG interface cannot be its own parent + if self.pk and self.lag_id == self.pk: + raise ValidationError({'lag': "A LAG interface cannot be its own parent."}) # Validate untagged VLAN if self.untagged_vlan and self.untagged_vlan.site not in [self.parent.site, None]: From 2116b928b683d61c42ba12aeba5d44b18bc24417 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 21 Aug 2020 16:44:13 -0400 Subject: [PATCH 04/73] Add link to v2.9 release notes --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index a94aa3cc4..87962acc0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -76,6 +76,7 @@ nav: - User Preferences: 'development/user-preferences.md' - Release Checklist: 'development/release-checklist.md' - Release Notes: + - Version 2.9: 'release-notes/version-2.9.md' - Version 2.8: 'release-notes/version-2.8.md' - Version 2.7: 'release-notes/version-2.7.md' - Version 2.6: 'release-notes/version-2.6.md' From 728088f5fa5c8dfcc5c8b3f70810e2d664ddda36 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Sat, 22 Aug 2020 20:39:46 -0400 Subject: [PATCH 05/73] Closes #5033: Support backward compatibility for REMOTE_AUTH_BACKEND --- docs/release-notes/version-2.9.md | 4 +++- netbox/netbox/settings.py | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index d42e35b92..07b989588 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -7,6 +7,7 @@ * [#4540](https://github.com/netbox-community/netbox/issues/4540) - Add IP address status type for SLAAC * [#4814](https://github.com/netbox-community/netbox/issues/4814) - Allow nested LAG interfaces * [#4991](https://github.com/netbox-community/netbox/issues/4991) - Add Python and NetBox versions to error page +* [#5033](https://github.com/netbox-community/netbox/issues/5033) - Support backward compatibility for `REMOTE_AUTH_BACKEND` configuration parameter --- @@ -66,7 +67,8 @@ Two new REST API endpoints have been added to facilitate the retrieval and manip ### Configuration Changes -* If in use, LDAP authentication must be enabled by setting `REMOTE_AUTH_BACKEND` to `'netbox.authentication.LDAPBackend'`. (LDAP configuration parameters in `ldap_config.py` remain unchanged.) +* If using NetBox's built-in remote authentication backend, update `REMOTE_AUTH_BACKEND` to `'netbox.authentication.RemoteUserBackend'`, as the authentication class has moved. +* If using LDAP authentication, set `REMOTE_AUTH_BACKEND` to `'netbox.authentication.LDAPBackend'`. (LDAP configuration parameters in `ldap_config.py` remain unchanged.) * `REMOTE_AUTH_DEFAULT_PERMISSIONS` now takes a dictionary rather than a list. This is a mapping of permission names to a dictionary of constraining attributes, or `None`. For example, `['dcim.add_site', 'dcim.change_site']` would become `{'dcim.add_site': None, 'dcim.change_site': None}`. ### REST API Changes diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index fd50f6b5a..e4ab844d0 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -142,6 +142,13 @@ if type(REMOTE_AUTH_DEFAULT_PERMISSIONS) is not dict: ) except TypeError: raise ImproperlyConfigured("REMOTE_AUTH_DEFAULT_PERMISSIONS must be a dictionary.") +# Backward compatibility for REMOTE_AUTH_BACKEND +if REMOTE_AUTH_BACKEND == 'utilities.auth_backends.RemoteUserBackend': + warnings.warn( + "RemoteUserBackend has moved! Please update your configuration to:\n" + " REMOTE_AUTH_BACKEND='netbox.authentication.RemoteUserBackend'" + ) + REMOTE_AUTH_BACKEND = 'netbox.authentication.RemoteUserBackend' # From aedba0e8be49c1706eb95c9a7424d5fd8c3e0412 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Sat, 22 Aug 2020 20:53:21 -0400 Subject: [PATCH 06/73] Closes #5030: Call out required minimum versions for depdencies in upgrade documentation --- docs/installation/upgrading.md | 11 +++++++++-- docs/release-notes/version-2.9.md | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/installation/upgrading.md b/docs/installation/upgrading.md index 807b9b1e6..34274342c 100644 --- a/docs/installation/upgrading.md +++ b/docs/installation/upgrading.md @@ -4,8 +4,15 @@ Prior to upgrading your NetBox instance, be sure to carefully review all [release notes](../../release-notes/) that have been published since your current version was released. Although the upgrade process typically does not involve additional work, certain releases may introduce breaking or backward-incompatible changes. These are called out in the release notes under the version in which the change went into effect. -!!! note - Beginning with version 2.8, NetBox requires Python 3.6 or later. +## Update Dependencies to Required Versions + +NetBox v2.9.0 and later requires the following: + +| Dependency | Minimum Version | +|------------|-----------------| +| Python | 3.6 | +| PostgreSQL | 9.6 | +| Redis | 4.0 | ## Install the Latest Code diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 07b989588..a02bcf3ea 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -13,6 +13,8 @@ ## v2.9.0 (2020-08-21) +**Note:** Redis 4.0 or later is required for this release. + ### New Features #### Object-Based Permissions ([#554](https://github.com/netbox-community/netbox/issues/554)) From 35a280eb31be691523567a77470564f28282960a Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Sat, 22 Aug 2020 21:03:51 -0400 Subject: [PATCH 07/73] Release v2.9.1 --- docs/release-notes/version-2.9.md | 2 +- netbox/netbox/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index a02bcf3ea..549067b13 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -1,6 +1,6 @@ # NetBox v2.9 -## v2.9.1 (FUTURE) +## v2.9.1 (2020-08-22) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index e4ab844d0..74cfcbd83 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -16,7 +16,7 @@ from django.core.validators import URLValidator # Environment setup # -VERSION = '2.9.1-dev' +VERSION = '2.9.1' # Hostname HOSTNAME = platform.node() From 3522eafd2ca7924e4883feeb63006972502f0fc5 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Sat, 22 Aug 2020 21:06:06 -0400 Subject: [PATCH 08/73] 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 74cfcbd83..6a836ff74 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -16,7 +16,7 @@ from django.core.validators import URLValidator # Environment setup # -VERSION = '2.9.1' +VERSION = '2.9.2-dev' # Hostname HOSTNAME = platform.node() From fcc15d2e33535db8d8a28b3698aa106baf3413e2 Mon Sep 17 00:00:00 2001 From: Joakim Bakke Hellum Date: Sun, 23 Aug 2020 20:49:50 +0200 Subject: [PATCH 09/73] Use correct serializer for available-prefixes POST response POST `/ipam/prefixes/{id}/available-prefixes/` returns single `Prefix` object, not list of `AvailablePrefix` objects. --- netbox/ipam/api/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index 0d273e4d8..280bb4322 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -88,7 +88,7 @@ class PrefixViewSet(CustomFieldModelViewSet): return super().get_serializer_class() @swagger_auto_schema(method='get', responses={200: serializers.AvailablePrefixSerializer(many=True)}) - @swagger_auto_schema(method='post', responses={201: serializers.AvailablePrefixSerializer(many=True)}) + @swagger_auto_schema(method='post', responses={201: serializers.PrefixSerializer(many=False)}) @action(detail=True, url_path='available-prefixes', methods=['get', 'post']) @advisory_lock(ADVISORY_LOCK_KEYS['available-prefixes']) def available_prefixes(self, request, pk=None): From 6e28490b848b4903f050d306b1a914701e43d6d4 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 24 Aug 2020 09:41:04 -0400 Subject: [PATCH 10/73] Fixes #5038: Fix validation of primary IPs assigned to virtual machines --- docs/release-notes/version-2.9.md | 8 ++++++++ netbox/dcim/forms.py | 2 +- netbox/virtualization/forms.py | 27 ++++++++++++++------------- netbox/virtualization/models.py | 6 +++--- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 549067b13..d521cb13c 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -1,5 +1,13 @@ # NetBox v2.9 +## v2.9.2 (FUTURE) + +### Bug Fixes + +* [#5038](https://github.com/netbox-community/netbox/issues/5038) - Fix validation of primary IPs assigned to virtual machines + +--- + ## v2.9.1 (2020-08-22) ### Enhancements diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 2b8bf4e9e..2e4aaed2e 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1811,7 +1811,7 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): nat_inside__assigned_object_id__in=interface_ids ).prefetch_related('assigned_object') if nat_ips: - ip_list = [(ip.id, f'{ip.address} ({ip.assigned_object})') for ip in nat_ips] + ip_list = [(ip.id, f'{ip.address} (NAT)') for ip in nat_ips] ip_choices.append(('NAT IPs', ip_list)) self.fields['primary_ip{}'.format(family)].choices = ip_choices diff --git a/netbox/virtualization/forms.py b/netbox/virtualization/forms.py index a64a0a7d8..8ba288d1c 100644 --- a/netbox/virtualization/forms.py +++ b/netbox/virtualization/forms.py @@ -1,4 +1,5 @@ from django import forms +from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from dcim.choices import InterfaceModeChoices @@ -325,28 +326,28 @@ class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): # Compile list of choices for primary IPv4 and IPv6 addresses for family in [4, 6]: ip_choices = [(None, '---------')] + + # Gather PKs of all interfaces belonging to this VM + interface_ids = self.instance.interfaces.values_list('pk', flat=True) + # Collect interface IPs - interface_ips = IPAddress.objects.prefetch_related('interface').filter( + interface_ips = IPAddress.objects.filter( address__family=family, - vminterface__in=self.instance.interfaces.values_list('id', flat=True) + assigned_object_type=ContentType.objects.get_for_model(VMInterface), + assigned_object_id__in=interface_ids ) if interface_ips: - ip_choices.append( - ('Interface IPs', [ - (ip.id, '{} ({})'.format(ip.address, ip.interface)) for ip in interface_ips - ]) - ) + ip_list = [(ip.id, f'{ip.address} ({ip.assigned_object})') for ip in interface_ips] + ip_choices.append(('Interface IPs', ip_list)) # Collect NAT IPs nat_ips = IPAddress.objects.prefetch_related('nat_inside').filter( address__family=family, - nat_inside__vminterface__in=self.instance.interfaces.values_list('id', flat=True) + nat_inside__assigned_object_type=ContentType.objects.get_for_model(VMInterface), + nat_inside__assigned_object_id__in=interface_ids ) if nat_ips: - ip_choices.append( - ('NAT IPs', [ - (ip.id, '{} ({})'.format(ip.address, ip.nat_inside.address)) for ip in nat_ips - ]) - ) + ip_list = [(ip.id, f'{ip.address} (NAT)') for ip in nat_ips] + ip_choices.append(('NAT IPs', ip_list)) self.fields['primary_ip{}'.format(family)].choices = ip_choices else: diff --git a/netbox/virtualization/models.py b/netbox/virtualization/models.py index f787aef0e..7d0b99872 100644 --- a/netbox/virtualization/models.py +++ b/netbox/virtualization/models.py @@ -335,13 +335,13 @@ class VirtualMachine(ChangeLoggedModel, ConfigContextModel, CustomFieldModel): for field in ['primary_ip4', 'primary_ip6']: ip = getattr(self, field) if ip is not None: - if ip.interface in interfaces: + if ip.assigned_object in interfaces: pass - elif self.primary_ip4.nat_inside is not None and self.primary_ip4.nat_inside.interface in interfaces: + elif ip.nat_inside is not None and ip.nat_inside.assigned_object in interfaces: pass else: raise ValidationError({ - field: "The specified IP address ({}) is not assigned to this VM.".format(ip), + field: f"The specified IP address ({ip}) is not assigned to this VM.", }) def to_csv(self): From e7cf87be97a6ce9e34e58fbe75a5609a0002b00f Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 24 Aug 2020 10:39:41 -0400 Subject: [PATCH 11/73] Fixes #5035: Fix exception when modifying an IP address assigned to a VM --- docs/release-notes/version-2.9.md | 1 + netbox/ipam/models.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index d521cb13c..7f085505a 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -4,6 +4,7 @@ ### Bug Fixes +* [#5035](https://github.com/netbox-community/netbox/issues/5035) - Fix exception when modifying an IP address assigned to a VM * [#5038](https://github.com/netbox-community/netbox/issues/5038) - Fix validation of primary IPs assigned to virtual machines --- diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index 58dd96089..cf9ecbf89 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -745,7 +745,7 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel): 'vminterface': f"IP address is primary for virtual machine {vm} but not assigned to an " f"interface" }) - elif self.interface.virtual_machine != vm: + elif self.assigned_object.virtual_machine != vm: raise ValidationError({ 'vminterface': f"IP address is primary for virtual machine {vm} but assigned to " f"{self.assigned_object.virtual_machine} ({self.assigned_object})" From 9147823305f00c4932a1e9ca13f24c46c7f576bc Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 24 Aug 2020 10:47:26 -0400 Subject: [PATCH 12/73] Fixes #5042: Fix display of SLAAC label for IP addresses status --- docs/release-notes/version-2.9.md | 1 + netbox/ipam/models.py | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 7f085505a..2683e85cf 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -6,6 +6,7 @@ * [#5035](https://github.com/netbox-community/netbox/issues/5035) - Fix exception when modifying an IP address assigned to a VM * [#5038](https://github.com/netbox-community/netbox/issues/5038) - Fix validation of primary IPs assigned to virtual machines +* [#5042](https://github.com/netbox-community/netbox/issues/5042) - Fix display of SLAAC label for IP addresses status --- diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index cf9ecbf89..2aeee30fc 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -669,6 +669,7 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel): 'reserved': 'info', 'deprecated': 'danger', 'dhcp': 'success', + 'slaac': 'success', } ROLE_CLASS_MAP = { From 78d6561e3928e2d221044cf3fb1096e16437f398 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 24 Aug 2020 10:51:47 -0400 Subject: [PATCH 13/73] Fixes #5040: Limit SLAAC status to IPv6 addresses --- docs/release-notes/version-2.9.md | 1 + netbox/ipam/models.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 2683e85cf..54bd5a84d 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -6,6 +6,7 @@ * [#5035](https://github.com/netbox-community/netbox/issues/5035) - Fix exception when modifying an IP address assigned to a VM * [#5038](https://github.com/netbox-community/netbox/issues/5038) - Fix validation of primary IPs assigned to virtual machines +* [#5040](https://github.com/netbox-community/netbox/issues/5040) - Limit SLAAC status to IPv6 addresses * [#5042](https://github.com/netbox-community/netbox/issues/5042) - Fix display of SLAAC label for IP addresses status --- diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index 2aeee30fc..832e09330 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -752,6 +752,12 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel): f"{self.assigned_object.virtual_machine} ({self.assigned_object})" }) + # Validate IP status selection + if self.status == IPAddressStatusChoices.STATUS_SLAAC and self.family != 6: + raise ValidationError({ + 'status': "Only IPv6 addresses can be assigned SLAAC status" + }) + def save(self, *args, **kwargs): # Force dns_name to lowercase From 32a0e519add5c8a3542fdd6346d222623ad81a66 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 24 Aug 2020 10:56:23 -0400 Subject: [PATCH 14/73] Fixes #5041: Fix form tabs when assigning an IP to a VM interface --- docs/release-notes/version-2.9.md | 1 + netbox/templates/ipam/inc/ipadress_edit_header.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 54bd5a84d..6ed07d536 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -7,6 +7,7 @@ * [#5035](https://github.com/netbox-community/netbox/issues/5035) - Fix exception when modifying an IP address assigned to a VM * [#5038](https://github.com/netbox-community/netbox/issues/5038) - Fix validation of primary IPs assigned to virtual machines * [#5040](https://github.com/netbox-community/netbox/issues/5040) - Limit SLAAC status to IPv6 addresses +* [#5041](https://github.com/netbox-community/netbox/issues/5041) - Fix form tabs when assigning an IP to a VM interface * [#5042](https://github.com/netbox-community/netbox/issues/5042) - Fix display of SLAAC label for IP addresses status --- diff --git a/netbox/templates/ipam/inc/ipadress_edit_header.html b/netbox/templates/ipam/inc/ipadress_edit_header.html index b8ec3878a..ed9692eea 100644 --- a/netbox/templates/ipam/inc/ipadress_edit_header.html +++ b/netbox/templates/ipam/inc/ipadress_edit_header.html @@ -4,7 +4,7 @@ - {% if 'interface' in request.GET %} + {% if 'interface' in request.GET or 'vminterface' in request.GET %} From df97eb2f72c602d4eef7fb3d51ba7d2cf4532b97 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 24 Aug 2020 11:33:45 -0400 Subject: [PATCH 15/73] Fixes #5045: Allow assignment of interfaces to non-master VC peer LAG during import --- docs/release-notes/version-2.9.md | 1 + netbox/dcim/forms.py | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 6ed07d536..6c1b17c42 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -9,6 +9,7 @@ * [#5040](https://github.com/netbox-community/netbox/issues/5040) - Limit SLAAC status to IPv6 addresses * [#5041](https://github.com/netbox-community/netbox/issues/5041) - Fix form tabs when assigning an IP to a VM interface * [#5042](https://github.com/netbox-community/netbox/issues/5042) - Fix display of SLAAC label for IP addresses status +* [#5045](https://github.com/netbox-community/netbox/issues/5045) - Allow assignment of interfaces to non-master VC peer LAG during import --- diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 2e4aaed2e..b6ba55d6d 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -2879,17 +2879,22 @@ class InterfaceCSVForm(CSVModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - # Limit LAG choices to interfaces belonging to this device (or VC master) + # Limit LAG choices to interfaces belonging to this device (or virtual chassis) device = None if self.is_bound and 'device' in self.data: try: device = self.fields['device'].to_python(self.data['device']) except forms.ValidationError: pass - - if device: + if device and device.virtual_chassis: self.fields['lag'].queryset = Interface.objects.filter( - device__in=[device, device.get_vc_master()], type=InterfaceTypeChoices.TYPE_LAG + Q(device=device) | Q(device__virtual_chassis=device.virtual_chassis), + type=InterfaceTypeChoices.TYPE_LAG + ) + elif device: + self.fields['lag'].queryset = Interface.objects.filter( + device=device, + type=InterfaceTypeChoices.TYPE_LAG ) else: self.fields['lag'].queryset = Interface.objects.none() From 5da7590eea2c4e7eaa7c57bc4c18b78c8cefb626 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 24 Aug 2020 12:04:48 -0400 Subject: [PATCH 16/73] Fixes #4988: Fix ordering of rack reservations with identical creation times --- docs/release-notes/version-2.9.md | 1 + .../migrations/0115_rackreservation_order.py | 17 +++++++++++++++++ netbox/dcim/models/racks.py | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 netbox/dcim/migrations/0115_rackreservation_order.py diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 6c1b17c42..7d9b2c1e3 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -4,6 +4,7 @@ ### Bug Fixes +* [#4988](https://github.com/netbox-community/netbox/issues/4988) - Fix ordering of rack reservations with identical creation times * [#5035](https://github.com/netbox-community/netbox/issues/5035) - Fix exception when modifying an IP address assigned to a VM * [#5038](https://github.com/netbox-community/netbox/issues/5038) - Fix validation of primary IPs assigned to virtual machines * [#5040](https://github.com/netbox-community/netbox/issues/5040) - Limit SLAAC status to IPv6 addresses diff --git a/netbox/dcim/migrations/0115_rackreservation_order.py b/netbox/dcim/migrations/0115_rackreservation_order.py new file mode 100644 index 000000000..594f6b9a4 --- /dev/null +++ b/netbox/dcim/migrations/0115_rackreservation_order.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1 on 2020-08-24 16:03 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0114_update_jsonfield'), + ] + + operations = [ + migrations.AlterModelOptions( + name='rackreservation', + options={'ordering': ['created', 'pk']}, + ), + ] diff --git a/netbox/dcim/models/racks.py b/netbox/dcim/models/racks.py index 3169272b4..6c5ab08b9 100644 --- a/netbox/dcim/models/racks.py +++ b/netbox/dcim/models/racks.py @@ -600,7 +600,7 @@ class RackReservation(ChangeLoggedModel): csv_headers = ['site', 'rack_group', 'rack', 'units', 'tenant', 'user', 'description'] class Meta: - ordering = ['created'] + ordering = ['created', 'pk'] def __str__(self): return "Reservation for rack {}".format(self.rack) From a0790e911975c0a7ead4a97439fe3d17822740d8 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 24 Aug 2020 15:17:36 -0400 Subject: [PATCH 17/73] Changelog for #5002 --- docs/release-notes/version-2.9.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 7d9b2c1e3..d407026e0 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -5,6 +5,7 @@ ### Bug Fixes * [#4988](https://github.com/netbox-community/netbox/issues/4988) - Fix ordering of rack reservations with identical creation times +* [#5002](https://github.com/netbox-community/netbox/issues/5002) - Correct OpenAPI definition for `available-prefixes` endpoint * [#5035](https://github.com/netbox-community/netbox/issues/5035) - Fix exception when modifying an IP address assigned to a VM * [#5038](https://github.com/netbox-community/netbox/issues/5038) - Fix validation of primary IPs assigned to virtual machines * [#5040](https://github.com/netbox-community/netbox/issues/5040) - Limit SLAAC status to IPv6 addresses From f23900fc8c60d1e0e4f651ad27c0b29ea4fb1799 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 27 Aug 2020 09:22:53 -0400 Subject: [PATCH 18/73] Fixes #5059: Fix inclusion of checkboxes for interfaces in virtual machine view --- docs/release-notes/version-2.9.md | 1 + netbox/templates/virtualization/inc/vminterface.html | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index d407026e0..36e54c6fd 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -12,6 +12,7 @@ * [#5041](https://github.com/netbox-community/netbox/issues/5041) - Fix form tabs when assigning an IP to a VM interface * [#5042](https://github.com/netbox-community/netbox/issues/5042) - Fix display of SLAAC label for IP addresses status * [#5045](https://github.com/netbox-community/netbox/issues/5045) - Allow assignment of interfaces to non-master VC peer LAG during import +* [#5059](https://github.com/netbox-community/netbox/issues/5059) - Fix inclusion of checkboxes for interfaces in virtual machine view --- diff --git a/netbox/templates/virtualization/inc/vminterface.html b/netbox/templates/virtualization/inc/vminterface.html index 5410fba7a..9ee1fa396 100644 --- a/netbox/templates/virtualization/inc/vminterface.html +++ b/netbox/templates/virtualization/inc/vminterface.html @@ -2,7 +2,7 @@ {# Checkbox #} - {% if perms.virtualization.change_interface or perms.virtualization.delete_interface %} + {% if perms.virtualization.change_vminterface or perms.virtualization.delete_vminterface %} @@ -48,12 +48,12 @@ {% endif %} - {% if perms.virtualization.change_interface %} + {% if perms.virtualization.change_vminterface %} {% endif %} - {% if perms.virtualization.delete_interface %} + {% if perms.virtualization.delete_vminterface %} @@ -65,7 +65,7 @@ {% if ipaddresses %} {# Placeholder #} - {% if perms.virtualization.change_interface or perms.virtualization.delete_interface %} + {% if perms.virtualization.change_vminterface or perms.virtualization.delete_vminterface %} {% endif %} From 5fe4e6cc96bd5486c410ecad5cf4896d82a72ab6 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 27 Aug 2020 09:26:56 -0400 Subject: [PATCH 19/73] Fixes #5058: Correct URL for front rack elevation images when using external storage --- docs/release-notes/version-2.9.md | 1 + netbox/dcim/elevations.py | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 36e54c6fd..47efc5e7c 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -12,6 +12,7 @@ * [#5041](https://github.com/netbox-community/netbox/issues/5041) - Fix form tabs when assigning an IP to a VM interface * [#5042](https://github.com/netbox-community/netbox/issues/5042) - Fix display of SLAAC label for IP addresses status * [#5045](https://github.com/netbox-community/netbox/issues/5045) - Allow assignment of interfaces to non-master VC peer LAG during import +* [#5058](https://github.com/netbox-community/netbox/issues/5058) - Correct URL for front rack elevation images when using external storage * [#5059](https://github.com/netbox-community/netbox/issues/5059) - Fix inclusion of checkboxes for interfaces in virtual machine view --- diff --git a/netbox/dcim/elevations.py b/netbox/dcim/elevations.py index cef95a7b6..5a22188b8 100644 --- a/netbox/dcim/elevations.py +++ b/netbox/dcim/elevations.py @@ -94,8 +94,12 @@ class RackElevationSVG: # Embed front device type image if one exists if self.include_images and device.device_type.front_image: - url = '{}{}'.format(self.base_url, device.device_type.front_image.url) - image = drawing.image(href=url, insert=start, size=end, class_='device-image') + image = drawing.image( + href=device.device_type.front_image.url, + insert=start, + size=end, + class_='device-image' + ) image.fit(scale='slice') link.add(image) @@ -107,8 +111,12 @@ class RackElevationSVG: # Embed rear device type image if one exists if self.include_images and device.device_type.rear_image: - url = device.device_type.rear_image.url - image = drawing.image(href=url, insert=start, size=end, class_='device-image') + image = drawing.image( + href=device.device_type.rear_image.url, + insert=start, + size=end, + class_='device-image' + ) image.fit(scale='slice') drawing.add(image) From fa73bf8e872a3fb5a4d4508bd82e2a9945484b2d Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 27 Aug 2020 09:43:20 -0400 Subject: [PATCH 20/73] Closes #5505: Add tags column to device/VM component list tables --- docs/release-notes/version-2.9.md | 4 +++ netbox/dcim/tables.py | 50 +++++++++++++++++++++++++------ netbox/virtualization/tables.py | 5 +++- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 47efc5e7c..fb84d84e1 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -2,6 +2,10 @@ ## v2.9.2 (FUTURE) +### Enhancements + +* [#5055](https://github.com/netbox-community/netbox/issues/5055) - Add tags column to device/VM component list tables + ### Bug Fixes * [#4988](https://github.com/netbox-community/netbox/issues/4988) - Fix ordering of rack reservations with identical creation times diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index e48eaedba..78fa1dea6 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -706,34 +706,48 @@ class DeviceComponentTable(BaseTable): class ConsolePortTable(DeviceComponentTable): + tags = TagColumn( + url_name='dcim:consoleport_list' + ) class Meta(DeviceComponentTable.Meta): model = ConsolePort - fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'cable') + fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'cable', 'tags') default_columns = ('pk', 'device', 'name', 'label', 'type', 'description') class ConsoleServerPortTable(DeviceComponentTable): + tags = TagColumn( + url_name='dcim:consoleserverport_list' + ) class Meta(DeviceComponentTable.Meta): model = ConsoleServerPort - fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'cable') + fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'cable', 'tags') default_columns = ('pk', 'device', 'name', 'label', 'type', 'description') class PowerPortTable(DeviceComponentTable): + tags = TagColumn( + url_name='dcim:powerport_list' + ) class Meta(DeviceComponentTable.Meta): model = PowerPort - fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'maximum_draw', 'allocated_draw', 'cable') + fields = ( + 'pk', 'device', 'name', 'label', 'type', 'description', 'maximum_draw', 'allocated_draw', 'cable', 'tags', + ) default_columns = ('pk', 'device', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description') class PowerOutletTable(DeviceComponentTable): + tags = TagColumn( + url_name='dcim:poweroutlet_list' + ) class Meta(DeviceComponentTable.Meta): model = PowerOutlet - fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'power_port', 'feed_leg', 'cable') + fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'power_port', 'feed_leg', 'cable', 'tags') default_columns = ('pk', 'device', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description') @@ -753,12 +767,15 @@ class BaseInterfaceTable(BaseTable): class InterfaceTable(DeviceComponentTable, BaseInterfaceTable): + tags = TagColumn( + url_name='dcim:interface_list' + ) class Meta(DeviceComponentTable.Meta): model = Interface fields = ( 'pk', 'device', 'name', 'label', 'enabled', 'type', 'mgmt_only', 'mtu', 'mode', 'mac_address', - 'description', 'cable', 'ip_addresses', 'untagged_vlan', 'tagged_vlans', + 'description', 'cable', 'tags', 'ip_addresses', 'untagged_vlan', 'tagged_vlans', ) default_columns = ('pk', 'device', 'name', 'label', 'enabled', 'type', 'description') @@ -767,18 +784,26 @@ class FrontPortTable(DeviceComponentTable): rear_port_position = tables.Column( verbose_name='Position' ) + tags = TagColumn( + url_name='dcim:frontport_list' + ) class Meta(DeviceComponentTable.Meta): model = FrontPort - fields = ('pk', 'device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'cable') + fields = ( + 'pk', 'device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'cable', 'tags', + ) default_columns = ('pk', 'device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description') class RearPortTable(DeviceComponentTable): + tags = TagColumn( + url_name='dcim:rearport_list' + ) class Meta(DeviceComponentTable.Meta): model = RearPort - fields = ('pk', 'device', 'name', 'label', 'type', 'positions', 'description', 'cable') + fields = ('pk', 'device', 'name', 'label', 'type', 'positions', 'description', 'cable', 'tags') default_columns = ('pk', 'device', 'name', 'label', 'type', 'description') @@ -786,10 +811,13 @@ class DeviceBayTable(DeviceComponentTable): installed_device = tables.Column( linkify=True ) + tags = TagColumn( + url_name='dcim:devicebay_list' + ) class Meta(DeviceComponentTable.Meta): model = DeviceBay - fields = ('pk', 'device', 'name', 'label', 'installed_device', 'description') + fields = ('pk', 'device', 'name', 'label', 'installed_device', 'description', 'tags') default_columns = ('pk', 'device', 'name', 'label', 'installed_device', 'description') @@ -798,12 +826,16 @@ class InventoryItemTable(DeviceComponentTable): linkify=True ) discovered = BooleanColumn() + tags = TagColumn( + url_name='dcim:inventoryitem_list' + ) + cable = None # Override DeviceComponentTable class Meta(DeviceComponentTable.Meta): model = InventoryItem fields = ( 'pk', 'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description', - 'discovered', + 'discovered', 'tags', ) default_columns = ('pk', 'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag') diff --git a/netbox/virtualization/tables.py b/netbox/virtualization/tables.py index 039934d70..5f5b9326d 100644 --- a/netbox/virtualization/tables.py +++ b/netbox/virtualization/tables.py @@ -154,11 +154,14 @@ class VMInterfaceTable(BaseInterfaceTable): name = tables.Column( linkify=True ) + tags = TagColumn( + url_name='virtualization:vminterface_list' + ) class Meta(BaseTable.Meta): model = VMInterface fields = ( - 'pk', 'virtual_machine', 'name', 'enabled', 'mac_address', 'mtu', 'description', 'ip_addresses', + 'pk', 'virtual_machine', 'name', 'enabled', 'mac_address', 'mtu', 'description', 'tags', 'ip_addresses', 'untagged_vlan', 'tagged_vlans', ) default_columns = ('pk', 'virtual_machine', 'name', 'enabled', 'description') From 5cdccb47f4d408ca99887148642dfdc437875b16 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 27 Aug 2020 11:27:17 -0400 Subject: [PATCH 21/73] Fixes #5060: Fix validation when bulk-importing child devices --- docs/release-notes/version-2.9.md | 1 + netbox/dcim/models/devices.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index fb84d84e1..3bcdbbccb 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -18,6 +18,7 @@ * [#5045](https://github.com/netbox-community/netbox/issues/5045) - Allow assignment of interfaces to non-master VC peer LAG during import * [#5058](https://github.com/netbox-community/netbox/issues/5058) - Correct URL for front rack elevation images when using external storage * [#5059](https://github.com/netbox-community/netbox/issues/5059) - Fix inclusion of checkboxes for interfaces in virtual machine view +* [#5060](https://github.com/netbox-community/netbox/issues/5060) - Fix validation when bulk-importing child devices --- diff --git a/netbox/dcim/models/devices.py b/netbox/dcim/models/devices.py index 4189e0446..e96becadf 100644 --- a/netbox/dcim/models/devices.py +++ b/netbox/dcim/models/devices.py @@ -633,7 +633,7 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel): # Check for a duplicate name on a device assigned to the same Site and no Tenant. This is necessary # because Django does not consider two NULL fields to be equal, and thus will not trigger a violation # of the uniqueness constraint without manual intervention. - if self.name and self.tenant is None: + if self.name and hasattr(self, 'site') and self.tenant is None: if Device.objects.exclude(pk=self.pk).filter( name=self.name, site=self.site, From 523c32b8afabf4ba7245f6ce0e76a7489f20bb7c Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 27 Aug 2020 13:26:41 -0400 Subject: [PATCH 22/73] Fixes #5061: Allow adding/removing tags when bulk editing virtual machine interfaces --- docs/release-notes/version-2.9.md | 1 + netbox/virtualization/forms.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 3bcdbbccb..57aae0c7a 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -19,6 +19,7 @@ * [#5058](https://github.com/netbox-community/netbox/issues/5058) - Correct URL for front rack elevation images when using external storage * [#5059](https://github.com/netbox-community/netbox/issues/5059) - Fix inclusion of checkboxes for interfaces in virtual machine view * [#5060](https://github.com/netbox-community/netbox/issues/5060) - Fix validation when bulk-importing child devices +* [#5061](https://github.com/netbox-community/netbox/issues/5061) - Allow adding/removing tags when bulk editing virtual machine interfaces --- diff --git a/netbox/virtualization/forms.py b/netbox/virtualization/forms.py index 8ba288d1c..5d002decc 100644 --- a/netbox/virtualization/forms.py +++ b/netbox/virtualization/forms.py @@ -684,7 +684,7 @@ class VMInterfaceCSVForm(CSVModelForm): return self.cleaned_data['enabled'] -class VMInterfaceBulkEditForm(BootstrapMixin, BulkEditForm): +class VMInterfaceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, BulkEditForm): pk = forms.ModelMultipleChoiceField( queryset=VMInterface.objects.all(), widget=forms.MultipleHiddenInput() From e8e4ff4111a23bb34cc10187d4f1a1963c406787 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 27 Aug 2020 13:46:31 -0400 Subject: [PATCH 23/73] Closes #5056: Add interface and parent columns to IP address list --- docs/release-notes/version-2.9.md | 1 + netbox/ipam/api/views.py | 2 +- netbox/ipam/tables.py | 16 ++++++++++++---- netbox/ipam/views.py | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 57aae0c7a..30aeb2070 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -5,6 +5,7 @@ ### Enhancements * [#5055](https://github.com/netbox-community/netbox/issues/5055) - Add tags column to device/VM component list tables +* [#5056](https://github.com/netbox-community/netbox/issues/5056) - Add interface and parent columns to IP address list ### Bug Fixes diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index 280bb4322..dd0731bb8 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -247,7 +247,7 @@ class PrefixViewSet(CustomFieldModelViewSet): class IPAddressViewSet(CustomFieldModelViewSet): queryset = IPAddress.objects.prefetch_related( - 'vrf__tenant', 'tenant', 'nat_inside', 'nat_outside', 'tags', + 'vrf__tenant', 'tenant', 'nat_inside', 'nat_outside', 'tags', 'assigned_object' ) serializer_class = serializers.IPAddressSerializer filterset_class = filters.IPAddressFilterSet diff --git a/netbox/ipam/tables.py b/netbox/ipam/tables.py index 5a4e2c133..7b4aa44ba 100644 --- a/netbox/ipam/tables.py +++ b/netbox/ipam/tables.py @@ -387,15 +387,23 @@ class IPAddressTable(BaseTable): tenant = tables.TemplateColumn( template_code=TENANT_LINK ) - assigned = tables.BooleanColumn( - accessor='assigned_object_id', - verbose_name='Assigned' + assigned_object = tables.Column( + linkify=True, + orderable=False, + verbose_name='Interface' + ) + assigned_object_parent = tables.Column( + accessor='assigned_object__parent', + linkify=True, + orderable=False, + verbose_name='Interface Parent' ) class Meta(BaseTable.Meta): model = IPAddress fields = ( - 'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'assigned', 'dns_name', 'description', + 'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'assigned_object', 'assigned_object_parent', 'dns_name', + 'description', ) row_attrs = { 'class': lambda record: 'success' if not isinstance(record, IPAddress) else '', diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 8ea33764c..68f7da8ad 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -493,7 +493,7 @@ class PrefixBulkDeleteView(BulkDeleteView): class IPAddressListView(ObjectListView): queryset = IPAddress.objects.prefetch_related( - 'vrf__tenant', 'tenant', 'nat_inside' + 'vrf__tenant', 'tenant', 'nat_inside', 'assigned_object' ) filterset = filters.IPAddressFilterSet filterset_form = forms.IPAddressFilterForm From f3e4911c6885c9dec281f8f4fe661d354184607a Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 27 Aug 2020 14:03:51 -0400 Subject: [PATCH 24/73] Release v2.9.2 --- docs/release-notes/version-2.9.md | 2 +- netbox/netbox/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 30aeb2070..e853a06e4 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -1,6 +1,6 @@ # NetBox v2.9 -## v2.9.2 (FUTURE) +## v2.9.2 (2020-08-27) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 6a836ff74..61dc9cd72 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -16,7 +16,7 @@ from django.core.validators import URLValidator # Environment setup # -VERSION = '2.9.2-dev' +VERSION = '2.9.2' # Hostname HOSTNAME = platform.node() From 2435c177f53186b1f9d4683377b3e73315a7e0d3 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 27 Aug 2020 14:15:09 -0400 Subject: [PATCH 25/73] 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 61dc9cd72..bfffe7135 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -16,7 +16,7 @@ from django.core.validators import URLValidator # Environment setup # -VERSION = '2.9.2' +VERSION = '2.9.3-dev' # Hostname HOSTNAME = platform.node() From bfcbd9da6c17df65b63a355c276cea0b53d5d305 Mon Sep 17 00:00:00 2001 From: Simeon Keske Date: Sun, 30 Aug 2020 01:44:27 +0200 Subject: [PATCH 26/73] Redirect users away from /login, if they are already logged in --- netbox/users/views.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/netbox/users/views.py b/netbox/users/views.py index 755232444..011281b45 100644 --- a/netbox/users/views.py +++ b/netbox/users/views.py @@ -36,6 +36,15 @@ class LoginView(View): return super().dispatch(*args, **kwargs) def get(self, request): + if request.user.is_authenticated: + # Already logged-in, determine where to redirect + redirect_to = request.GET.get('next', reverse('home')) + if redirect_to and not is_safe_url(url=redirect_to, allowed_hosts=request.get_host()): + logger.warning(f"Ignoring unsafe 'next' URL passed to login form: {redirect_to}") + redirect_to = reverse('home') + + return HttpResponseRedirect(redirect_to) + form = LoginForm(request) return render(request, self.template_name, { From 5bff50cade41dd55756e0ff4ff3f0df5fca50041 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 31 Aug 2020 15:26:00 -0400 Subject: [PATCH 27/73] Fixes #5063: Fix "add device" link in rack elevations for opposite side of half-depth devices --- docs/release-notes/version-2.9.md | 8 ++++++++ netbox/dcim/elevations.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index e853a06e4..9593ea414 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -1,5 +1,13 @@ # NetBox v2.9 +## v2.9.3 (FUTURE) + +### Bug Fixes + +* [#5063](https://github.com/netbox-community/netbox/issues/5063) - Fix "add device" link in rack elevations for opposite side of half-depth devices + +--- + ## v2.9.2 (2020-08-27) ### Enhancements diff --git a/netbox/dcim/elevations.py b/netbox/dcim/elevations.py index 5a22188b8..93c44f087 100644 --- a/netbox/dcim/elevations.py +++ b/netbox/dcim/elevations.py @@ -149,7 +149,7 @@ class RackElevationSVG: unit_cursor = 0 for u in elevation: o = other[unit_cursor] - if not u['device'] and o['device']: + if not u['device'] and o['device'] and o['device'].device_type.is_full_depth: u['device'] = o['device'] u['height'] = 1 unit_cursor += u.get('height', 1) From 473d76c9d1cf24deab6991b1eb994fa11f53a65e Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 31 Aug 2020 15:34:40 -0400 Subject: [PATCH 28/73] Fixes #5074: Fix inclusion of VC member interfaces when viewing VC master --- docs/release-notes/version-2.9.md | 1 + netbox/dcim/views.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 9593ea414..bfc5642af 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -5,6 +5,7 @@ ### Bug Fixes * [#5063](https://github.com/netbox-community/netbox/issues/5063) - Fix "add device" link in rack elevations for opposite side of half-depth devices +* [#5074](https://github.com/netbox-community/netbox/issues/5074) - Fix inclusion of VC member interfaces when viewing VC master --- diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index c016f6e54..5b0a396bf 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1033,7 +1033,7 @@ class DeviceView(ObjectView): ) # Interfaces - interfaces = device.vc_interfaces.restrict(request.user, 'view').filter(device=device).prefetch_related( + interfaces = device.vc_interfaces.restrict(request.user, 'view').prefetch_related( Prefetch('ip_addresses', queryset=IPAddress.objects.restrict(request.user)), Prefetch('member_interfaces', queryset=Interface.objects.restrict(request.user)), 'lag', '_connected_interface__device', '_connected_circuittermination__circuit', 'cable', From 967073eaaf6764096f603df354c63d6b7656760b Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 1 Sep 2020 09:54:45 -0400 Subject: [PATCH 29/73] Fixes #5081: Fix exception during webhook processing with custom select field --- docs/release-notes/version-2.9.md | 1 + netbox/extras/api/customfields.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index bfc5642af..aec9817f2 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -6,6 +6,7 @@ * [#5063](https://github.com/netbox-community/netbox/issues/5063) - Fix "add device" link in rack elevations for opposite side of half-depth devices * [#5074](https://github.com/netbox-community/netbox/issues/5074) - Fix inclusion of VC member interfaces when viewing VC master +* [#5081](https://github.com/netbox-community/netbox/issues/5081) - Fix exception during webhook processing with custom select field --- diff --git a/netbox/extras/api/customfields.py b/netbox/extras/api/customfields.py index 5ef983977..f096fb4a6 100644 --- a/netbox/extras/api/customfields.py +++ b/netbox/extras/api/customfields.py @@ -158,7 +158,7 @@ class CustomFieldModelSerializer(ValidatedModelSerializer): instance.custom_fields = {} for field in custom_fields: value = instance.cf.get(field.name) - if field.type == CustomFieldTypeChoices.TYPE_SELECT and value is not None: + if field.type == CustomFieldTypeChoices.TYPE_SELECT and value: instance.custom_fields[field.name] = CustomFieldChoiceSerializer(value).data else: instance.custom_fields[field.name] = value From 7dbeaf7a0108e393ceaeefd6d3911c8fc79b24b6 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 1 Sep 2020 10:19:28 -0400 Subject: [PATCH 30/73] Fixes #5078: Fix assignment of existing IP addresses to interfaces via web UI --- docs/release-notes/version-2.9.md | 1 + netbox/ipam/tables.py | 6 +----- netbox/ipam/views.py | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index aec9817f2..17b2ddffe 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -6,6 +6,7 @@ * [#5063](https://github.com/netbox-community/netbox/issues/5063) - Fix "add device" link in rack elevations for opposite side of half-depth devices * [#5074](https://github.com/netbox-community/netbox/issues/5074) - Fix inclusion of VC member interfaces when viewing VC master +* [#5078](https://github.com/netbox-community/netbox/issues/5078) - Fix assignment of existing IP addresses to interfaces via web UI * [#5081](https://github.com/netbox-community/netbox/issues/5081) - Fix exception during webhook processing with custom select field --- diff --git a/netbox/ipam/tables.py b/netbox/ipam/tables.py index 7b4aa44ba..a16dcf333 100644 --- a/netbox/ipam/tables.py +++ b/netbox/ipam/tables.py @@ -67,11 +67,7 @@ IPADDRESS_LINK = """ """ IPADDRESS_ASSIGN_LINK = """ -{% if request.GET %} - {{ record }} -{% else %} - {{ record }} -{% endif %} +{{ record }} """ VRF_LINK = """ diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 68f7da8ad..1f0e2607e 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -582,7 +582,7 @@ class IPAddressAssignView(ObjectView): def dispatch(self, request, *args, **kwargs): # Redirect user if an interface has not been provided - if 'interface' not in request.GET: + if 'interface' not in request.GET and 'vminterface' not in request.GET: return redirect('ipam:ipaddress_add') return super().dispatch(request, *args, **kwargs) @@ -609,7 +609,7 @@ class IPAddressAssignView(ObjectView): return render(request, 'ipam/ipaddress_assign.html', { 'form': form, 'table': table, - 'return_url': request.GET.get('return_url', ''), + 'return_url': request.GET.get('return_url'), }) From b3b7e08c50583fe06be1bef1083c0994e00abbf9 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 1 Sep 2020 10:24:17 -0400 Subject: [PATCH 31/73] Closes #5076: Specify pip3 --- docs/installation/3-netbox.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation/3-netbox.md b/docs/installation/3-netbox.md index 05f6d825e..235e39a8f 100644 --- a/docs/installation/3-netbox.md +++ b/docs/installation/3-netbox.md @@ -25,7 +25,7 @@ Begin by installing all system packages required by NetBox and its dependencies. Before continuing with either platform, update pip (Python's package management tool) to its latest release: ```no-highlight -# pip install --upgrade pip +# pip3 install --upgrade pip ``` ## Download NetBox From a0103036e4a90eddb6d955c239a15d8a1bc10764 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 1 Sep 2020 13:59:50 -0400 Subject: [PATCH 32/73] Fixes #5087: Restore label field when editing console server ports, power ports, and power outlets --- docs/release-notes/version-2.9.md | 1 + netbox/dcim/forms.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 17b2ddffe..18881d7c1 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -8,6 +8,7 @@ * [#5074](https://github.com/netbox-community/netbox/issues/5074) - Fix inclusion of VC member interfaces when viewing VC master * [#5078](https://github.com/netbox-community/netbox/issues/5078) - Fix assignment of existing IP addresses to interfaces via web UI * [#5081](https://github.com/netbox-community/netbox/issues/5081) - Fix exception during webhook processing with custom select field +* [#5087](https://github.com/netbox-community/netbox/issues/5087) - Restore label field when editing console server ports, power ports, and power outlets --- diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index b6ba55d6d..43f77de51 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -2317,7 +2317,7 @@ class ConsoleServerPortForm(BootstrapMixin, forms.ModelForm): class Meta: model = ConsoleServerPort fields = [ - 'device', 'name', 'type', 'description', 'tags', + 'device', 'name', 'label', 'type', 'description', 'tags', ] widgets = { 'device': forms.HiddenInput(), @@ -2390,7 +2390,7 @@ class PowerPortForm(BootstrapMixin, forms.ModelForm): class Meta: model = PowerPort fields = [ - 'device', 'name', 'type', 'maximum_draw', 'allocated_draw', 'description', 'tags', + 'device', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'tags', ] widgets = { 'device': forms.HiddenInput(), @@ -2479,7 +2479,7 @@ class PowerOutletForm(BootstrapMixin, forms.ModelForm): class Meta: model = PowerOutlet fields = [ - 'device', 'name', 'type', 'power_port', 'feed_leg', 'description', 'tags', + 'device', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'tags', ] widgets = { 'device': forms.HiddenInput(), From 6305a35a4f5e2c75e0fb5f95b8bdbf5e0ed23391 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 1 Sep 2020 15:18:47 -0400 Subject: [PATCH 33/73] Fixes #5085: Fix ordering by assignment in IP addresses table --- docs/release-notes/version-2.9.md | 1 + netbox/ipam/tables.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 18881d7c1..12a50880c 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -8,6 +8,7 @@ * [#5074](https://github.com/netbox-community/netbox/issues/5074) - Fix inclusion of VC member interfaces when viewing VC master * [#5078](https://github.com/netbox-community/netbox/issues/5078) - Fix assignment of existing IP addresses to interfaces via web UI * [#5081](https://github.com/netbox-community/netbox/issues/5081) - Fix exception during webhook processing with custom select field +* [#5085](https://github.com/netbox-community/netbox/issues/5085) - Fix ordering by assignment in IP addresses table * [#5087](https://github.com/netbox-community/netbox/issues/5087) - Restore label field when editing console server ports, power ports, and power outlets --- diff --git a/netbox/ipam/tables.py b/netbox/ipam/tables.py index a16dcf333..32af7c262 100644 --- a/netbox/ipam/tables.py +++ b/netbox/ipam/tables.py @@ -415,6 +415,10 @@ class IPAddressDetailTable(IPAddressTable): tenant = tables.TemplateColumn( template_code=COL_TENANT ) + assigned = tables.BooleanColumn( + accessor='assigned_object_id', + verbose_name='Assigned' + ) tags = TagColumn( url_name='ipam:ipaddress_list' ) From 5d7935c8556bc540aeea6c0de49b8214be5a12bf Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 1 Sep 2020 16:28:11 -0400 Subject: [PATCH 34/73] Fixes #5090: Fix status display for console/power/interface connections --- docs/release-notes/version-2.9.md | 1 + netbox/dcim/tables.py | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 12a50880c..14a15fc3f 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -10,6 +10,7 @@ * [#5081](https://github.com/netbox-community/netbox/issues/5081) - Fix exception during webhook processing with custom select field * [#5085](https://github.com/netbox-community/netbox/issues/5085) - Fix ordering by assignment in IP addresses table * [#5087](https://github.com/netbox-community/netbox/issues/5087) - Restore label field when editing console server ports, power ports, and power outlets +* [#5090](https://github.com/netbox-community/netbox/issues/5090) - Fix status display for console/power/interface connections --- diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 78fa1dea6..9afdd7fff 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -152,6 +152,10 @@ INTERFACE_TAGGED_VLANS = """ {% endfor %} """ +CONNECTION_STATUS = """ +{{ record.get_connection_status_display }} +""" + # # Regions @@ -916,7 +920,10 @@ class ConsoleConnectionTable(BaseTable): name = tables.Column( verbose_name='Console Port' ) - connection_status = BooleanColumn() + connection_status = tables.TemplateColumn( + template_code=CONNECTION_STATUS, + verbose_name='Status' + ) class Meta(BaseTable.Meta): model = ConsolePort @@ -941,6 +948,10 @@ class PowerConnectionTable(BaseTable): name = tables.Column( verbose_name='Power Port' ) + connection_status = tables.TemplateColumn( + template_code=CONNECTION_STATUS, + verbose_name='Status' + ) class Meta(BaseTable.Meta): model = PowerPort @@ -972,6 +983,10 @@ class InterfaceConnectionTable(BaseTable): args=[Accessor('_connected_interface__pk')], verbose_name='Interface B' ) + connection_status = tables.TemplateColumn( + template_code=CONNECTION_STATUS, + verbose_name='Status' + ) class Meta(BaseTable.Meta): model = Interface From 268aa755c470a1d7577bfa63f1d6d5c2ac79158c Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 2 Sep 2020 10:21:22 -0400 Subject: [PATCH 35/73] Closes #5080: Add 8P6C, 8P4C, 8P2C port types --- docs/release-notes/version-2.9.md | 4 ++++ netbox/dcim/choices.py | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 14a15fc3f..19218732a 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -2,6 +2,10 @@ ## v2.9.3 (FUTURE) +### Enhancements + +* [#5080](https://github.com/netbox-community/netbox/issues/5080) - Add 8P6C, 8P4C, 8P2C port types + ### Bug Fixes * [#5063](https://github.com/netbox-community/netbox/issues/5063) - Fix "add device" link in rack elevations for opposite side of half-depth devices diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index dc12e686e..fa4f81792 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -814,6 +814,9 @@ class InterfaceModeChoices(ChoiceSet): class PortTypeChoices(ChoiceSet): TYPE_8P8C = '8p8c' + TYPE_8P6C = '8p6c' + TYPE_8P4C = '8p4c' + TYPE_8P2C = '8p2c' TYPE_110_PUNCH = '110-punch' TYPE_BNC = 'bnc' TYPE_MRJ21 = 'mrj21' @@ -833,6 +836,9 @@ class PortTypeChoices(ChoiceSet): 'Copper', ( (TYPE_8P8C, '8P8C'), + (TYPE_8P6C, '8P6C'), + (TYPE_8P4C, '8P4C'), + (TYPE_8P2C, '8P2C'), (TYPE_110_PUNCH, '110 Punch'), (TYPE_BNC, 'BNC'), (TYPE_MRJ21, 'MRJ21'), From b559c827d24059af92779b2988b111da1fc1bbb6 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 2 Sep 2020 13:30:19 -0400 Subject: [PATCH 36/73] Fixes #5091: Avoid KeyError when handling invalid table preferences --- docs/release-notes/version-2.9.md | 1 + netbox/utilities/tables.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 19218732a..f5705bca8 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -15,6 +15,7 @@ * [#5085](https://github.com/netbox-community/netbox/issues/5085) - Fix ordering by assignment in IP addresses table * [#5087](https://github.com/netbox-community/netbox/issues/5087) - Restore label field when editing console server ports, power ports, and power outlets * [#5090](https://github.com/netbox-community/netbox/issues/5090) - Fix status display for console/power/interface connections +* [#5091](https://github.com/netbox-community/netbox/issues/5091) - Avoid KeyError when handling invalid table preferences --- diff --git a/netbox/utilities/tables.py b/netbox/utilities/tables.py index 0144ea2d1..6df6b2e26 100644 --- a/netbox/utilities/tables.py +++ b/netbox/utilities/tables.py @@ -44,7 +44,7 @@ class BaseTable(tables.Table): self.columns.show(name) else: self.columns.hide(name) - self.sequence = columns + self.sequence = [c for c in columns if c in self.base_columns] # Always include PK and actions column, if defined on the table if pk: From babdc1db3806ab701ebfa9a06e4a57776b924b05 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 2 Sep 2020 13:33:59 -0400 Subject: [PATCH 37/73] Link to console/power ports in connection views --- netbox/dcim/tables.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 9afdd7fff..371eff9db 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -912,12 +912,14 @@ class ConsoleConnectionTable(BaseTable): verbose_name='Console Server' ) connected_endpoint = tables.Column( + linkify=True, verbose_name='Port' ) device = tables.Column( linkify=True ) name = tables.Column( + linkify=True, verbose_name='Console Port' ) connection_status = tables.TemplateColumn( @@ -940,12 +942,14 @@ class PowerConnectionTable(BaseTable): ) outlet = tables.Column( accessor=Accessor('_connected_poweroutlet'), + linkify=True, verbose_name='Outlet' ) device = tables.Column( linkify=True ) name = tables.Column( + linkify=True, verbose_name='Power Port' ) connection_status = tables.TemplateColumn( From d289b260340b2386077a1b9f8cf77f5a0684f3cb Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 2 Sep 2020 13:45:15 -0400 Subject: [PATCH 38/73] Fixes #5089: Redirect to device view after editing component --- docs/release-notes/version-2.9.md | 1 + netbox/templates/dcim/inc/consoleport.html | 2 +- netbox/templates/dcim/inc/consoleserverport.html | 2 +- netbox/templates/dcim/inc/devicebay.html | 2 +- netbox/templates/dcim/inc/poweroutlet.html | 2 +- netbox/templates/dcim/inc/powerport.html | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index f5705bca8..0b6b80b62 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -14,6 +14,7 @@ * [#5081](https://github.com/netbox-community/netbox/issues/5081) - Fix exception during webhook processing with custom select field * [#5085](https://github.com/netbox-community/netbox/issues/5085) - Fix ordering by assignment in IP addresses table * [#5087](https://github.com/netbox-community/netbox/issues/5087) - Restore label field when editing console server ports, power ports, and power outlets +* [#5089](https://github.com/netbox-community/netbox/issues/5089) - Redirect to device view after editing component * [#5090](https://github.com/netbox-community/netbox/issues/5090) - Fix status display for console/power/interface connections * [#5091](https://github.com/netbox-community/netbox/issues/5091) - Avoid KeyError when handling invalid table preferences diff --git a/netbox/templates/dcim/inc/consoleport.html b/netbox/templates/dcim/inc/consoleport.html index dc2111b8a..6fa5e8b91 100644 --- a/netbox/templates/dcim/inc/consoleport.html +++ b/netbox/templates/dcim/inc/consoleport.html @@ -66,7 +66,7 @@ {% endif %} {% if perms.dcim.change_consoleport %} - + {% endif %} diff --git a/netbox/templates/dcim/inc/consoleserverport.html b/netbox/templates/dcim/inc/consoleserverport.html index dcf168ae7..fca1fa5f4 100644 --- a/netbox/templates/dcim/inc/consoleserverport.html +++ b/netbox/templates/dcim/inc/consoleserverport.html @@ -68,7 +68,7 @@ {% endif %} {% if perms.dcim.change_consoleserverport %} - + {% endif %} diff --git a/netbox/templates/dcim/inc/devicebay.html b/netbox/templates/dcim/inc/devicebay.html index ee6a66d8f..bde7b8641 100644 --- a/netbox/templates/dcim/inc/devicebay.html +++ b/netbox/templates/dcim/inc/devicebay.html @@ -52,7 +52,7 @@ {% endif %} - + {% endif %} diff --git a/netbox/templates/dcim/inc/poweroutlet.html b/netbox/templates/dcim/inc/poweroutlet.html index d9a77d647..5800f4b48 100644 --- a/netbox/templates/dcim/inc/poweroutlet.html +++ b/netbox/templates/dcim/inc/poweroutlet.html @@ -81,7 +81,7 @@ {% endif %} {% if perms.dcim.change_poweroutlet %} - + {% endif %} diff --git a/netbox/templates/dcim/inc/powerport.html b/netbox/templates/dcim/inc/powerport.html index 58eed145a..b30fc8456 100644 --- a/netbox/templates/dcim/inc/powerport.html +++ b/netbox/templates/dcim/inc/powerport.html @@ -78,7 +78,7 @@ {% endif %} {% if perms.dcim.change_powerport %} - + {% endif %} From bbbfc2759397b9a5cf41f52094d041c60d9a0ac0 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 2 Sep 2020 16:10:07 -0400 Subject: [PATCH 39/73] Fixes #5072: Add REST API filters for image attachments --- docs/release-notes/version-2.9.md | 1 + netbox/extras/api/views.py | 1 + netbox/extras/filters.py | 10 +++- netbox/extras/tests/test_filters.py | 82 ++++++++++++++++++++++++++++- 4 files changed, 91 insertions(+), 3 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 0b6b80b62..5fa6fb6d2 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -4,6 +4,7 @@ ### Enhancements +* [#5072](https://github.com/netbox-community/netbox/issues/5072) - Add REST API filters for image attachments * [#5080](https://github.com/netbox-community/netbox/issues/5080) - Add 8P6C, 8P4C, 8P2C port types ### Bug Fixes diff --git a/netbox/extras/api/views.py b/netbox/extras/api/views.py index 289a51c83..a63dbe44d 100644 --- a/netbox/extras/api/views.py +++ b/netbox/extras/api/views.py @@ -140,6 +140,7 @@ class ImageAttachmentViewSet(ModelViewSet): metadata_class = ContentTypeMetadata queryset = ImageAttachment.objects.all() serializer_class = serializers.ImageAttachmentSerializer + filterset_class = filters.ImageAttachmentFilterSet # diff --git a/netbox/extras/filters.py b/netbox/extras/filters.py index e8962da01..1af98e885 100644 --- a/netbox/extras/filters.py +++ b/netbox/extras/filters.py @@ -7,7 +7,7 @@ from tenancy.models import Tenant, TenantGroup from utilities.filters import BaseFilterSet from virtualization.models import Cluster, ClusterGroup from .choices import * -from .models import ConfigContext, CustomField, Graph, ExportTemplate, ObjectChange, JobResult, Tag +from .models import ConfigContext, CustomField, ExportTemplate, Graph, ImageAttachment, JobResult, ObjectChange, Tag __all__ = ( @@ -17,6 +17,7 @@ __all__ = ( 'CustomFieldFilterSet', 'ExportTemplateFilterSet', 'GraphFilterSet', + 'ImageAttachmentFilterSet', 'LocalConfigContextFilterSet', 'ObjectChangeFilterSet', 'TagFilterSet', @@ -104,6 +105,13 @@ class ExportTemplateFilterSet(BaseFilterSet): fields = ['id', 'content_type', 'name', 'template_language'] +class ImageAttachmentFilterSet(BaseFilterSet): + + class Meta: + model = ImageAttachment + fields = ['id', 'content_type', 'object_id', 'name'] + + class TagFilterSet(BaseFilterSet): q = django_filters.CharFilter( method='search', diff --git a/netbox/extras/tests/test_filters.py b/netbox/extras/tests/test_filters.py index 72db138e2..d6e077db4 100644 --- a/netbox/extras/tests/test_filters.py +++ b/netbox/extras/tests/test_filters.py @@ -1,11 +1,11 @@ from django.contrib.contenttypes.models import ContentType from django.test import TestCase -from dcim.models import DeviceRole, Platform, Region, Site +from dcim.models import DeviceRole, Platform, Rack, Region, Site from extras.choices import * from extras.filters import * from extras.utils import FeatureQuery -from extras.models import ConfigContext, ExportTemplate, Graph, Tag +from extras.models import ConfigContext, ExportTemplate, Graph, ImageAttachment, Tag from tenancy.models import Tenant, TenantGroup from virtualization.models import Cluster, ClusterGroup, ClusterType @@ -78,6 +78,84 @@ class ExportTemplateTestCase(TestCase): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) +class ImageAttachmentTestCase(TestCase): + queryset = ImageAttachment.objects.all() + filterset = ImageAttachmentFilterSet + + @classmethod + def setUpTestData(cls): + + site_ct = ContentType.objects.get(app_label='dcim', model='site') + rack_ct = ContentType.objects.get(app_label='dcim', model='rack') + + sites = ( + Site(name='Site 1', slug='site-1'), + Site(name='Site 2', slug='site-2'), + ) + Site.objects.bulk_create(sites) + + racks = ( + Rack(name='Rack 1', site=sites[0]), + Rack(name='Rack 2', site=sites[1]), + ) + Rack.objects.bulk_create(racks) + + image_attachments = ( + ImageAttachment( + content_type=site_ct, + object_id=sites[0].pk, + name='Image Attachment 1', + image='http://example.com/image1.png', + image_height=100, + image_width=100 + ), + ImageAttachment( + content_type=site_ct, + object_id=sites[1].pk, + name='Image Attachment 2', + image='http://example.com/image2.png', + image_height=100, + image_width=100 + ), + ImageAttachment( + content_type=rack_ct, + object_id=racks[0].pk, + name='Image Attachment 3', + image='http://example.com/image3.png', + image_height=100, + image_width=100 + ), + ImageAttachment( + content_type=rack_ct, + object_id=racks[1].pk, + name='Image Attachment 4', + image='http://example.com/image4.png', + image_height=100, + image_width=100 + ) + ) + ImageAttachment.objects.bulk_create(image_attachments) + + def test_id(self): + params = {'id': self.queryset.values_list('pk', flat=True)[:2]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + def test_name(self): + params = {'name': ['Image Attachment 1', 'Image Attachment 2']} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + def test_content_type(self): + params = {'content_type': ContentType.objects.get(app_label='dcim', model='site').pk} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + def test_content_type_and_object_id(self): + params = { + 'content_type': ContentType.objects.get(app_label='dcim', model='site').pk, + 'object_id': [Site.objects.first().pk], + } + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + + class ConfigContextTestCase(TestCase): queryset = ConfigContext.objects.all() filterset = ConfigContextFilterSet From f92569d4688bf58758c0009a3bb13261d25033ac Mon Sep 17 00:00:00 2001 From: Simeon Keske Date: Wed, 2 Sep 2020 22:33:39 +0200 Subject: [PATCH 40/73] move redirect code to own function --- netbox/users/views.py | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/netbox/users/views.py b/netbox/users/views.py index 011281b45..46221f649 100644 --- a/netbox/users/views.py +++ b/netbox/users/views.py @@ -36,17 +36,12 @@ class LoginView(View): return super().dispatch(*args, **kwargs) def get(self, request): - if request.user.is_authenticated: - # Already logged-in, determine where to redirect - redirect_to = request.GET.get('next', reverse('home')) - if redirect_to and not is_safe_url(url=redirect_to, allowed_hosts=request.get_host()): - logger.warning(f"Ignoring unsafe 'next' URL passed to login form: {redirect_to}") - redirect_to = reverse('home') - - return HttpResponseRedirect(redirect_to) - form = LoginForm(request) + if request.user.is_authenticated: + logger = logging.getLogger('netbox.auth.login') + return self.redirect_to_next(request, logger) + return render(request, self.template_name, { 'form': form, }) @@ -58,12 +53,6 @@ class LoginView(View): if form.is_valid(): logger.debug("Login form validation was successful") - # Determine where to direct user after successful login - redirect_to = request.POST.get('next', reverse('home')) - if redirect_to and not is_safe_url(url=redirect_to, allowed_hosts=request.get_host()): - logger.warning(f"Ignoring unsafe 'next' URL passed to login form: {redirect_to}") - redirect_to = reverse('home') - # If maintenance mode is enabled, assume the database is read-only, and disable updating the user's # last_login time upon authentication. if settings.MAINTENANCE_MODE: @@ -75,8 +64,7 @@ class LoginView(View): logger.info(f"User {request.user} successfully authenticated") messages.info(request, "Logged in as {}.".format(request.user)) - logger.debug(f"Redirecting user to {redirect_to}") - return HttpResponseRedirect(redirect_to) + return self.redirect_to_next(request, logger) else: logger.debug("Login form validation failed") @@ -85,6 +73,19 @@ class LoginView(View): 'form': form, }) + def redirect_to_next(self, request, logger): + if request.method == "POST": + redirect_to = request.POST.get('next', reverse('home')) + else: + redirect_to = request.GET.get('next', reverse('home')) + + if redirect_to and not is_safe_url(url=redirect_to, allowed_hosts=request.get_host()): + logger.warning(f"Ignoring unsafe 'next' URL passed to login form: {redirect_to}") + redirect_to = reverse('home') + + logger.debug(f"Redirecting user to {redirect_to}") + return HttpResponseRedirect(redirect_to) + class LogoutView(View): """ From de081d0205ac92f7107da4c93a847bd15f532799 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 3 Sep 2020 11:28:25 -0400 Subject: [PATCH 41/73] Fixes #5095: Fix display of assigned prefixes in VLANs list --- netbox/ipam/tables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/ipam/tables.py b/netbox/ipam/tables.py index 32af7c262..d7a64f7db 100644 --- a/netbox/ipam/tables.py +++ b/netbox/ipam/tables.py @@ -99,7 +99,7 @@ VLAN_LINK = """ """ VLAN_PREFIXES = """ -{% for prefix in record.prefixes.unrestricted %} +{% for prefix in record.prefixes.all %} {{ prefix }}{% if not forloop.last %}
{% endif %} {% empty %} — From dd0185816cc1beabe9bdae3d968a166e4cf005e0 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 4 Sep 2020 13:57:29 -0400 Subject: [PATCH 42/73] Changelog for #4977, #5095 --- docs/release-notes/version-2.9.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 5fa6fb6d2..d99b161e0 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -4,6 +4,7 @@ ### Enhancements +* [#4977](https://github.com/netbox-community/netbox/issues/4977) - Redirect authenticated users from login view * [#5072](https://github.com/netbox-community/netbox/issues/5072) - Add REST API filters for image attachments * [#5080](https://github.com/netbox-community/netbox/issues/5080) - Add 8P6C, 8P4C, 8P2C port types @@ -18,6 +19,7 @@ * [#5089](https://github.com/netbox-community/netbox/issues/5089) - Redirect to device view after editing component * [#5090](https://github.com/netbox-community/netbox/issues/5090) - Fix status display for console/power/interface connections * [#5091](https://github.com/netbox-community/netbox/issues/5091) - Avoid KeyError when handling invalid table preferences +* [#5095](https://github.com/netbox-community/netbox/issues/5095) - Avoid KeyError when handling invalid table preferences --- From 78d104e60c1e9e85aad50744c97cb2b0ca23b5d4 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 4 Sep 2020 14:13:35 -0400 Subject: [PATCH 43/73] Fixes #5046: Disabled plugin menu items are no longer clickable --- docs/plugins/development.md | 3 +++ docs/release-notes/version-2.9.md | 1 + netbox/templates/inc/plugin_menu_items.html | 28 ++++++++++++--------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/docs/plugins/development.md b/docs/plugins/development.md index b704ad7fc..f4db3c84d 100644 --- a/docs/plugins/development.md +++ b/docs/plugins/development.md @@ -328,6 +328,9 @@ A `PluginMenuButton` has the following attributes: * `color` - One of the choices provided by `ButtonColorChoices` (optional) * `permissions` - A list of permissions required to display this button (optional) +!!! note + Any buttons associated within a menu item will be shown only if the user has permission to view the link, regardless of what permissions are set on the buttons. + ## Extending Core Templates Plugins can inject custom content into certain areas of the detail views of applicable models. This is accomplished by subclassing `PluginTemplateExtension`, designating a particular NetBox model, and defining the desired methods to render custom content. Four methods are available: diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index d99b161e0..5505fed8f 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -10,6 +10,7 @@ ### Bug Fixes +* [#5046](https://github.com/netbox-community/netbox/issues/5046) - Disabled plugin menu items are no longer clickable * [#5063](https://github.com/netbox-community/netbox/issues/5063) - Fix "add device" link in rack elevations for opposite side of half-depth devices * [#5074](https://github.com/netbox-community/netbox/issues/5074) - Fix inclusion of VC member interfaces when viewing VC master * [#5078](https://github.com/netbox-community/netbox/issues/5078) - Fix assignment of existing IP addresses to interfaces via web UI diff --git a/netbox/templates/inc/plugin_menu_items.html b/netbox/templates/inc/plugin_menu_items.html index 0df4a5e8a..3d9a46a52 100644 --- a/netbox/templates/inc/plugin_menu_items.html +++ b/netbox/templates/inc/plugin_menu_items.html @@ -5,18 +5,22 @@ {% for section_name, menu_items in registry.plugin_menu_items.items %} {% for menu_item in menu_items %} - - {% if menu_item.buttons %} -
- {% for button in menu_item.buttons %} - {% if not button.permissions or request.user|has_perms:button.permissions %} - - {% endif %} - {% endfor %} -
- {% endif %} - {{ menu_item.link_text }} - + {% if not menu_item.permissions or request.user|has_perms:menu_item.permissions %} +
  • + {% if menu_item.buttons %} +
    + {% for button in menu_item.buttons %} + {% if not button.permissions or request.user|has_perms:button.permissions %} + + {% endif %} + {% endfor %} +
    + {% endif %} + {{ menu_item.link_text }} +
  • + {% else %} +
  • {{ menu_item.link_text }}
  • + {% endif %} {% endfor %} {% if not forloop.last %}
  • From f1877fcea9a6c4f7c59e82a8e2428a72c0cdb806 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 4 Sep 2020 15:10:34 -0400 Subject: [PATCH 44/73] Closes #5048: Show the device/VM name when editing a component --- docs/release-notes/version-2.9.md | 1 + netbox/dcim/views.py | 7 +++++++ .../templates/dcim/device_component_edit.html | 16 +++++++++++++++ netbox/templates/dcim/interface_edit.html | 15 ++++++++++++++ netbox/templates/utilities/obj_edit.html | 4 +++- .../virtualmachine_component_add.html | 2 +- .../virtualization/vminterface_edit.html | 20 +++++++++++++++++++ 7 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 netbox/templates/dcim/device_component_edit.html diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 5505fed8f..09456ae14 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -5,6 +5,7 @@ ### Enhancements * [#4977](https://github.com/netbox-community/netbox/issues/4977) - Redirect authenticated users from login view +* [#5048](https://github.com/netbox-community/netbox/issues/5048) - Show the device/VM name when editing a component * [#5072](https://github.com/netbox-community/netbox/issues/5072) - Add REST API filters for image attachments * [#5080](https://github.com/netbox-community/netbox/issues/5080) - Add 8P6C, 8P4C, 8P2C port types diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 5b0a396bf..9f4dcc90e 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1233,6 +1233,7 @@ class ConsolePortCreateView(ComponentCreateView): class ConsolePortEditView(ObjectEditView): queryset = ConsolePort.objects.all() model_form = forms.ConsolePortForm + template_name = 'dcim/device_component_edit.html' class ConsolePortDeleteView(ObjectDeleteView): @@ -1292,6 +1293,7 @@ class ConsoleServerPortCreateView(ComponentCreateView): class ConsoleServerPortEditView(ObjectEditView): queryset = ConsoleServerPort.objects.all() model_form = forms.ConsoleServerPortForm + template_name = 'dcim/device_component_edit.html' class ConsoleServerPortDeleteView(ObjectDeleteView): @@ -1351,6 +1353,7 @@ class PowerPortCreateView(ComponentCreateView): class PowerPortEditView(ObjectEditView): queryset = PowerPort.objects.all() model_form = forms.PowerPortForm + template_name = 'dcim/device_component_edit.html' class PowerPortDeleteView(ObjectDeleteView): @@ -1410,6 +1413,7 @@ class PowerOutletCreateView(ComponentCreateView): class PowerOutletEditView(ObjectEditView): queryset = PowerOutlet.objects.all() model_form = forms.PowerOutletForm + template_name = 'dcim/device_component_edit.html' class PowerOutletDeleteView(ObjectDeleteView): @@ -1561,6 +1565,7 @@ class FrontPortCreateView(ComponentCreateView): class FrontPortEditView(ObjectEditView): queryset = FrontPort.objects.all() model_form = forms.FrontPortForm + template_name = 'dcim/device_component_edit.html' class FrontPortDeleteView(ObjectDeleteView): @@ -1620,6 +1625,7 @@ class RearPortCreateView(ComponentCreateView): class RearPortEditView(ObjectEditView): queryset = RearPort.objects.all() model_form = forms.RearPortForm + template_name = 'dcim/device_component_edit.html' class RearPortDeleteView(ObjectDeleteView): @@ -1679,6 +1685,7 @@ class DeviceBayCreateView(ComponentCreateView): class DeviceBayEditView(ObjectEditView): queryset = DeviceBay.objects.all() model_form = forms.DeviceBayForm + template_name = 'dcim/device_component_edit.html' class DeviceBayDeleteView(ObjectDeleteView): diff --git a/netbox/templates/dcim/device_component_edit.html b/netbox/templates/dcim/device_component_edit.html new file mode 100644 index 000000000..e0f1a2326 --- /dev/null +++ b/netbox/templates/dcim/device_component_edit.html @@ -0,0 +1,16 @@ +{% extends 'utilities/obj_edit.html' %} +{% load form_helpers %} + +{% block form_fields %} + {% if form.instance.device %} +
    + + +
    + {% endif %} + {% render_form form %} +{% endblock %} diff --git a/netbox/templates/dcim/interface_edit.html b/netbox/templates/dcim/interface_edit.html index eaffe2bca..7a5c99905 100644 --- a/netbox/templates/dcim/interface_edit.html +++ b/netbox/templates/dcim/interface_edit.html @@ -5,6 +5,16 @@
    Interface
    + {% if form.instance.device %} +
    + + +
    + {% endif %} {% render_field form.name %} {% render_field form.label %} {% render_field form.type %} @@ -14,6 +24,11 @@ {% render_field form.mtu %} {% render_field form.mgmt_only %} {% render_field form.description %} +
    +
    +
    +
    802.1Q Switching
    +
    {% render_field form.mode %} {% render_field form.untagged_vlan %} {% render_field form.tagged_vlans %} diff --git a/netbox/templates/utilities/obj_edit.html b/netbox/templates/utilities/obj_edit.html index 5230b2594..0bd051161 100644 --- a/netbox/templates/utilities/obj_edit.html +++ b/netbox/templates/utilities/obj_edit.html @@ -31,7 +31,9 @@
    {{ obj_type|capfirst }}
    - {% render_form form %} + {% block form_fields %} + {% render_form form %} + {% endblock %}
    {% endblock %} diff --git a/netbox/templates/virtualization/virtualmachine_component_add.html b/netbox/templates/virtualization/virtualmachine_component_add.html index aafefffa1..11b120ee0 100644 --- a/netbox/templates/virtualization/virtualmachine_component_add.html +++ b/netbox/templates/virtualization/virtualmachine_component_add.html @@ -2,7 +2,7 @@ {% load helpers %} {% load form_helpers %} -{% block title %}Create {{ component_type }} ({{ parent }}){% endblock %} +{% block title %}Create {{ component_type }}{% endblock %} {% block content %}
    diff --git a/netbox/templates/virtualization/vminterface_edit.html b/netbox/templates/virtualization/vminterface_edit.html index 6b0313284..12018ba5d 100644 --- a/netbox/templates/virtualization/vminterface_edit.html +++ b/netbox/templates/virtualization/vminterface_edit.html @@ -5,14 +5,34 @@
    Interface
    + {% if form.instance.virtual_machine %} +
    + + +
    + {% endif %} {% render_field form.name %} {% render_field form.enabled %} {% render_field form.mac_address %} {% render_field form.mtu %} {% render_field form.description %} +
    +
    +
    +
    802.1Q Switching
    +
    {% render_field form.mode %} {% render_field form.untagged_vlan %} {% render_field form.tagged_vlans %} +
    +
    +
    +
    Tags
    +
    {% render_field form.tags %}
    From 5f9e687c9cda136d4f08a92172bd41fa2b1dddbc Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 4 Sep 2020 15:45:23 -0400 Subject: [PATCH 45/73] Release v2.9.3 --- docs/release-notes/version-2.9.md | 2 +- netbox/netbox/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 09456ae14..ef5c4326c 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -1,6 +1,6 @@ # NetBox v2.9 -## v2.9.3 (FUTURE) +## v2.9.3 (2020-09-04) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index bfffe7135..c48db1493 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -16,7 +16,7 @@ from django.core.validators import URLValidator # Environment setup # -VERSION = '2.9.3-dev' +VERSION = '2.9.3' # Hostname HOSTNAME = platform.node() From 08b9eedcec42e4c95c0de7d5d6f4c9659d6ddd0f Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 4 Sep 2020 15:46:39 -0400 Subject: [PATCH 46/73] Correct changelog for #5095 --- docs/release-notes/version-2.9.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index ef5c4326c..a3d500094 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -21,7 +21,7 @@ * [#5089](https://github.com/netbox-community/netbox/issues/5089) - Redirect to device view after editing component * [#5090](https://github.com/netbox-community/netbox/issues/5090) - Fix status display for console/power/interface connections * [#5091](https://github.com/netbox-community/netbox/issues/5091) - Avoid KeyError when handling invalid table preferences -* [#5095](https://github.com/netbox-community/netbox/issues/5095) - Avoid KeyError when handling invalid table preferences +* [#5095](https://github.com/netbox-community/netbox/issues/5095) - Show assigned prefixes in VLANs list --- From 0c8d45f679806b21939f60700a8a70d47064ef0e Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 4 Sep 2020 15:57:28 -0400 Subject: [PATCH 47/73] 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 c48db1493..8a8c47c75 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -16,7 +16,7 @@ from django.core.validators import URLValidator # Environment setup # -VERSION = '2.9.3' +VERSION = '2.9.4-dev' # Hostname HOSTNAME = platform.node() From 695e9ec5d7ce3915cf6caf8f4131b5dc1d116747 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 9 Sep 2020 09:52:57 -0400 Subject: [PATCH 48/73] Fixes #5111: Allow use of tuples when specifying ObjectVar query_params --- docs/release-notes/version-2.9.md | 8 ++++++++ netbox/utilities/forms/widgets.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index a3d500094..3d68b10ba 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -1,5 +1,13 @@ # NetBox v2.9 +## v2.9.4 (FUTURE) + +### Bug Fixes + +* [#5111](https://github.com/netbox-community/netbox/issues/5111) - Allow use of tuples when specifying ObjectVar `query_params` + +--- + ## v2.9.3 (2020-09-04) ### Enhancements diff --git a/netbox/utilities/forms/widgets.py b/netbox/utilities/forms/widgets.py index 9996f7d11..cd6fb0fbb 100644 --- a/netbox/utilities/forms/widgets.py +++ b/netbox/utilities/forms/widgets.py @@ -141,7 +141,7 @@ class APISelect(SelectWithDisabled): key = f'data-query-param-{name}' values = json.loads(self.attrs.get(key, '[]')) - if type(value) is list: + if type(value) in (list, tuple): values.extend([str(v) for v in value]) else: values.append(str(value)) From 150965046269b5d0f2145f7bf8447ba2e35e6ed1 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 9 Sep 2020 10:00:50 -0400 Subject: [PATCH 49/73] Closes #5107: Add note about dropping backward compatibility for old REDIS configuration format --- docs/release-notes/version-2.9.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 3d68b10ba..dbafa21ac 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -129,6 +129,7 @@ Two new REST API endpoints have been added to facilitate the retrieval and manip * If using NetBox's built-in remote authentication backend, update `REMOTE_AUTH_BACKEND` to `'netbox.authentication.RemoteUserBackend'`, as the authentication class has moved. * If using LDAP authentication, set `REMOTE_AUTH_BACKEND` to `'netbox.authentication.LDAPBackend'`. (LDAP configuration parameters in `ldap_config.py` remain unchanged.) * `REMOTE_AUTH_DEFAULT_PERMISSIONS` now takes a dictionary rather than a list. This is a mapping of permission names to a dictionary of constraining attributes, or `None`. For example, `['dcim.add_site', 'dcim.change_site']` would become `{'dcim.add_site': None, 'dcim.change_site': None}`. +* Backward compatibility for the old `webhooks` Redis queue name has been dropped. Ensure that your `REDIS` configuration parameter specifies both the `tasks` and `caching` databases. ### REST API Changes From c891f43b144c82e8d7891b57ca113d5f8f1f156a Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 9 Sep 2020 10:29:17 -0400 Subject: [PATCH 50/73] Fixes #5050: Fix potential failure on 0016_replicate_interfaces schema migration from old release --- docs/release-notes/version-2.9.md | 1 + netbox/virtualization/migrations/0016_replicate_interfaces.py | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index dbafa21ac..a38e945f6 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -4,6 +4,7 @@ ### Bug Fixes +* [#5050](https://github.com/netbox-community/netbox/issues/5050) - Fix potential failure on `0016_replicate_interfaces` schema migration from old release * [#5111](https://github.com/netbox-community/netbox/issues/5111) - Allow use of tuples when specifying ObjectVar `query_params` --- diff --git a/netbox/virtualization/migrations/0016_replicate_interfaces.py b/netbox/virtualization/migrations/0016_replicate_interfaces.py index a9c474083..585f5b80c 100644 --- a/netbox/virtualization/migrations/0016_replicate_interfaces.py +++ b/netbox/virtualization/migrations/0016_replicate_interfaces.py @@ -83,6 +83,7 @@ def replicate_interfaces(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ + ('dcim', '0082_3569_interface_fields'), ('ipam', '0037_ipaddress_assignment'), ('virtualization', '0015_vminterface'), ] From 47a6fc19cab1a3f53f80855e1f6fa9288fc8cbaf Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 9 Sep 2020 11:47:21 -0400 Subject: [PATCH 51/73] Fixes #5109: Fix representation of custom choice field values for webhook data --- docs/release-notes/version-2.9.md | 1 + netbox/extras/api/customfields.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index a38e945f6..19789149b 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -5,6 +5,7 @@ ### Bug Fixes * [#5050](https://github.com/netbox-community/netbox/issues/5050) - Fix potential failure on `0016_replicate_interfaces` schema migration from old release +* [#5109](https://github.com/netbox-community/netbox/issues/5109) - Fix representation of custom choice field values for webhook data * [#5111](https://github.com/netbox-community/netbox/issues/5111) - Allow use of tuples when specifying ObjectVar `query_params` --- diff --git a/netbox/extras/api/customfields.py b/netbox/extras/api/customfields.py index f096fb4a6..ba59e529a 100644 --- a/netbox/extras/api/customfields.py +++ b/netbox/extras/api/customfields.py @@ -158,7 +158,7 @@ class CustomFieldModelSerializer(ValidatedModelSerializer): instance.custom_fields = {} for field in custom_fields: value = instance.cf.get(field.name) - if field.type == CustomFieldTypeChoices.TYPE_SELECT and value: + if field.type == CustomFieldTypeChoices.TYPE_SELECT and type(value) is CustomFieldChoice: instance.custom_fields[field.name] = CustomFieldChoiceSerializer(value).data else: instance.custom_fields[field.name] = value From 4466458076b4cfd1b3d97a234d7f34ef9e191e8c Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 9 Sep 2020 13:43:10 -0400 Subject: [PATCH 52/73] Fixes #5118: Specifying an empty list of tags should clear assigned tags (REST API) --- docs/release-notes/version-2.9.md | 1 + netbox/extras/api/serializers.py | 16 +++++++++++----- netbox/extras/tests/test_tags.py | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 19789149b..33f372f47 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -7,6 +7,7 @@ * [#5050](https://github.com/netbox-community/netbox/issues/5050) - Fix potential failure on `0016_replicate_interfaces` schema migration from old release * [#5109](https://github.com/netbox-community/netbox/issues/5109) - Fix representation of custom choice field values for webhook data * [#5111](https://github.com/netbox-community/netbox/issues/5111) - Allow use of tuples when specifying ObjectVar `query_params` +* [#5118](https://github.com/netbox-community/netbox/issues/5118) - Specifying an empty list of tags should clear assigned tags (REST API) --- diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index aa8f6ba69..3cc2d1991 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -101,24 +101,30 @@ class TaggedObjectSerializer(serializers.Serializer): tags = NestedTagSerializer(many=True, required=False) def create(self, validated_data): - tags = validated_data.pop('tags', []) + tags = validated_data.pop('tags', None) instance = super().create(validated_data) - return self._save_tags(instance, tags) + if tags is not None: + return self._save_tags(instance, tags) + return instance def update(self, instance, validated_data): - tags = validated_data.pop('tags', []) + tags = validated_data.pop('tags', None) # Cache tags on instance for change logging - instance._tags = tags + instance._tags = tags or [] instance = super().update(instance, validated_data) - return self._save_tags(instance, tags) + if tags is not None: + return self._save_tags(instance, tags) + return instance def _save_tags(self, instance, tags): if tags: instance.tags.set(*[t.name for t in tags]) + else: + instance.tags.clear() return instance diff --git a/netbox/extras/tests/test_tags.py b/netbox/extras/tests/test_tags.py index 694cd77d9..39aae49dc 100644 --- a/netbox/extras/tests/test_tags.py +++ b/netbox/extras/tests/test_tags.py @@ -59,3 +59,21 @@ class TaggedItemTest(APITestCase): sorted([t.name for t in site.tags.all()]), sorted(["Foo", "Bar", "New Tag"]) ) + + def test_clear_tagged_item(self): + site = Site.objects.create( + name='Test Site', + slug='test-site' + ) + site.tags.add("Foo", "Bar", "Baz") + data = { + 'tags': [] + } + self.add_permissions('dcim.change_site') + url = reverse('dcim-api:site-detail', kwargs={'pk': site.pk}) + + response = self.client.patch(url, data, format='json', **self.header) + self.assertHttpStatus(response, status.HTTP_200_OK) + self.assertEqual(len(response.data['tags']), 0) + site = Site.objects.get(pk=response.data['id']) + self.assertEqual(len(site.tags.all()), 0) From c5e82a389545ae5516577e452ddd9cb32fc0a185 Mon Sep 17 00:00:00 2001 From: John Anderson Date: Thu, 10 Sep 2020 17:43:41 -0400 Subject: [PATCH 53/73] fixes #5108 - correct the runreport management command to work with JobResults model --- .../extras/management/commands/runreport.py | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/netbox/extras/management/commands/runreport.py b/netbox/extras/management/commands/runreport.py index efc789021..b751118e0 100644 --- a/netbox/extras/management/commands/runreport.py +++ b/netbox/extras/management/commands/runreport.py @@ -1,7 +1,12 @@ +import time + +from django.contrib.contenttypes.models import ContentType from django.core.management.base import BaseCommand from django.utils import timezone -from extras.reports import get_reports +from extras.choices import JobResultStatusChoices +from extras.models import JobResult +from extras.reports import get_reports, run_report class Command(BaseCommand): @@ -24,11 +29,29 @@ class Command(BaseCommand): self.stdout.write( "[{:%H:%M:%S}] Running {}...".format(timezone.now(), report.full_name) ) - report.run() + + report_content_type = ContentType.objects.get(app_label='extras', model='report') + job_result = JobResult.enqueue_job( + run_report, + report.full_name, + report_content_type, + None + ) + + # Wait on the job to finish + while job_result.status not in JobResultStatusChoices.TERMINAL_STATE_CHOICES: + time.sleep(1) + job_result = JobResult.objects.get(pk=job_result.pk) # Report on success/failure - status = self.style.ERROR('FAILED') if report.failed else self.style.SUCCESS('SUCCESS') - for test_name, attrs in report.result.data.items(): + if job_result.status == JobResultStatusChoices.STATUS_FAILED: + status = self.style.ERROR('FAILED') + elif job_result == JobResultStatusChoices.STATUS_ERRORED: + status = self.style.ERROR('ERRORED') + else: + status = self.style.SUCCESS('SUCCESS') + + for test_name, attrs in job_result.data.items(): self.stdout.write( "\t{}: {} success, {} info, {} warning, {} failure".format( test_name, attrs['success'], attrs['info'], attrs['warning'], attrs['failure'] @@ -37,6 +60,9 @@ class Command(BaseCommand): self.stdout.write( "[{:%H:%M:%S}] {}: {}".format(timezone.now(), report.full_name, status) ) + self.stdout.write( + "[{:%H:%M:%S}] {}: Duration {}".format(timezone.now(), report.full_name, job_result.duration) + ) # Wrap things up self.stdout.write( From b1b63513e79d6b253492edbadab5e92c217f4e41 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 14 Sep 2020 10:41:04 -0400 Subject: [PATCH 54/73] Changelog for #5108 --- docs/release-notes/version-2.9.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 33f372f47..d469e4c0f 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -6,6 +6,7 @@ * [#5050](https://github.com/netbox-community/netbox/issues/5050) - Fix potential failure on `0016_replicate_interfaces` schema migration from old release * [#5109](https://github.com/netbox-community/netbox/issues/5109) - Fix representation of custom choice field values for webhook data +* [#5108](https://github.com/netbox-community/netbox/issues/5108) - Fix execution of reports via CLI * [#5111](https://github.com/netbox-community/netbox/issues/5111) - Allow use of tuples when specifying ObjectVar `query_params` * [#5118](https://github.com/netbox-community/netbox/issues/5118) - Specifying an empty list of tags should clear assigned tags (REST API) From df6ad680ce300733157cb100f7627d45b1cb4db4 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 14 Sep 2020 14:22:21 -0400 Subject: [PATCH 55/73] Closes #1755: Toggle order in which rack elevations are displayed --- docs/release-notes/version-2.9.md | 4 ++++ netbox/dcim/views.py | 6 ++++++ netbox/templates/dcim/rack_elevation_list.html | 12 +++++++++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index d469e4c0f..093dc34a7 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -2,6 +2,10 @@ ## v2.9.4 (FUTURE) +### Enhancements + +* [#1755](https://github.com/netbox-community/netbox/issues/1755) - Toggle order in which rack elevations are displayed + ### Bug Fixes * [#5050](https://github.com/netbox-community/netbox/issues/5050) - Fix potential failure on `0016_replicate_interfaces` schema migration from old release diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 9f4dcc90e..ab84ba64b 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -310,6 +310,11 @@ class RackElevationListView(ObjectListView): racks = filters.RackFilterSet(request.GET, self.queryset).qs total_count = racks.count() + # Determine ordering + reverse = bool(request.GET.get('reverse', False)) + if reverse: + racks = racks.reverse() + # Pagination per_page = request.GET.get('per_page', settings.PAGINATE_COUNT) page_number = request.GET.get('page', 1) @@ -330,6 +335,7 @@ class RackElevationListView(ObjectListView): 'paginator': paginator, 'page': page, 'total_count': total_count, + 'reverse': reverse, 'rack_face': rack_face, 'filter_form': forms.RackElevationFilterForm(request.GET), }) diff --git a/netbox/templates/dcim/rack_elevation_list.html b/netbox/templates/dcim/rack_elevation_list.html index e4949eb17..c39bcae75 100644 --- a/netbox/templates/dcim/rack_elevation_list.html +++ b/netbox/templates/dcim/rack_elevation_list.html @@ -3,12 +3,18 @@ {% load static %} {% block content %} -
    +

    {% block title %}Rack Elevations{% endblock %}

    From 03b207d1542e8ede4fd29035bb41b640f4d018d9 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 16 Sep 2020 11:10:30 -0400 Subject: [PATCH 56/73] Fixes #5105: Validation should fail when reassigning a primary IP from device to VM --- docs/release-notes/version-2.9.md | 1 + netbox/ipam/forms.py | 13 ++++--------- netbox/ipam/models.py | 22 +++++----------------- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 093dc34a7..6d4f56ed8 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -9,6 +9,7 @@ ### Bug Fixes * [#5050](https://github.com/netbox-community/netbox/issues/5050) - Fix potential failure on `0016_replicate_interfaces` schema migration from old release +* [#5105](https://github.com/netbox-community/netbox/issues/5105) - Validation should fail when reassigning a primary IP from device to VM * [#5109](https://github.com/netbox-community/netbox/issues/5109) - Fix representation of custom choice field values for webhook data * [#5108](https://github.com/netbox-community/netbox/issues/5108) - Fix execution of reports via CLI * [#5111](https://github.com/netbox-community/netbox/issues/5111) - Allow use of tuples when specifying ObjectVar `query_params` diff --git a/netbox/ipam/forms.py b/netbox/ipam/forms.py index 1e8e9038a..75a4caf10 100644 --- a/netbox/ipam/forms.py +++ b/netbox/ipam/forms.py @@ -641,11 +641,11 @@ class IPAddressForm(BootstrapMixin, TenancyForm, ReturnURLForm, CustomFieldModel self.initial['primary_for_parent'] = True def clean(self): - super().clean() # Cannot select both a device interface and a VM interface if self.cleaned_data.get('interface') and self.cleaned_data.get('vminterface'): raise forms.ValidationError("Cannot select both a device interface and a virtual machine interface") + self.instance.assigned_object = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface') # Primary IP assignment is only available if an interface has been assigned. interface = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface') @@ -655,26 +655,21 @@ class IPAddressForm(BootstrapMixin, TenancyForm, ReturnURLForm, CustomFieldModel ) def save(self, *args, **kwargs): - - # Set assigned object - interface = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface') - if interface: - self.instance.assigned_object = interface - ipaddress = super().save(*args, **kwargs) # Assign/clear this IPAddress as the primary for the associated Device/VirtualMachine. + interface = self.instance.assigned_object if interface and self.cleaned_data['primary_for_parent']: if ipaddress.address.version == 4: interface.parent.primary_ip4 = ipaddress else: - interface.primary_ip6 = ipaddress + interface.parent.primary_ip6 = ipaddress interface.parent.save() elif interface and ipaddress.address.version == 4 and interface.parent.primary_ip4 == ipaddress: interface.parent.primary_ip4 = None interface.parent.save() elif interface and ipaddress.address.version == 6 and interface.parent.primary_ip6 == ipaddress: - interface.parent.primary_ip4 = None + interface.parent.primary_ip6 = None interface.parent.save() return ipaddress diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index 832e09330..c7955bcfa 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -726,30 +726,18 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel): }) # Check for primary IP assignment that doesn't match the assigned device/VM - if self.pk and type(self.assigned_object) is Interface: + if self.pk: device = Device.objects.filter(Q(primary_ip4=self) | Q(primary_ip6=self)).first() if device: - if self.assigned_object is None: + if getattr(self.assigned_object, 'device', None) != device: raise ValidationError({ - 'interface': f"IP address is primary for device {device} but not assigned to an interface" + 'interface': f"IP address is primary for device {device} but not assigned to it!" }) - elif self.assigned_object.device != device: - raise ValidationError({ - 'interface': f"IP address is primary for device {device} but assigned to " - f"{self.assigned_object.device} ({self.assigned_object})" - }) - elif self.pk and type(self.assigned_object) is VMInterface: vm = VirtualMachine.objects.filter(Q(primary_ip4=self) | Q(primary_ip6=self)).first() if vm: - if self.assigned_object is None: + if getattr(self.assigned_object, 'virtual_machine', None) != vm: raise ValidationError({ - 'vminterface': f"IP address is primary for virtual machine {vm} but not assigned to an " - f"interface" - }) - elif self.assigned_object.virtual_machine != vm: - raise ValidationError({ - 'vminterface': f"IP address is primary for virtual machine {vm} but assigned to " - f"{self.assigned_object.virtual_machine} ({self.assigned_object})" + 'vminterface': f"IP address is primary for virtual machine {vm} but not assigned to it!" }) # Validate IP status selection From 9d30712fb26503092e2ecd261c348f908213580b Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 16 Sep 2020 11:20:00 -0400 Subject: [PATCH 57/73] Changelog for #5133 (fixed in #5105) --- docs/release-notes/version-2.9.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 6d4f56ed8..55c66cb6a 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -14,6 +14,7 @@ * [#5108](https://github.com/netbox-community/netbox/issues/5108) - Fix execution of reports via CLI * [#5111](https://github.com/netbox-community/netbox/issues/5111) - Allow use of tuples when specifying ObjectVar `query_params` * [#5118](https://github.com/netbox-community/netbox/issues/5118) - Specifying an empty list of tags should clear assigned tags (REST API) +* [#5133](https://github.com/netbox-community/netbox/issues/5133) - Fix disassociation of an IP address from a VM interface --- From 4d9da4a1f8c261e4aa6dae04a3cbcfb20a443c1f Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 16 Sep 2020 12:44:49 -0400 Subject: [PATCH 58/73] Closes #5134: Display full hierarchy in breadcrumbs for sites/racks --- docs/release-notes/version-2.9.md | 1 + netbox/templates/dcim/device.html | 15 +++++++-------- netbox/templates/dcim/rack.html | 11 ++++++++++- netbox/templates/dcim/site.html | 4 ++-- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 55c66cb6a..fd7a99ff0 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -5,6 +5,7 @@ ### Enhancements * [#1755](https://github.com/netbox-community/netbox/issues/1755) - Toggle order in which rack elevations are displayed +* [#5134](https://github.com/netbox-community/netbox/issues/5134) - Display full hierarchy in breadcrumbs for sites/racks ### Bug Fixes diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html index e97893c30..34d28179b 100644 --- a/netbox/templates/dcim/device.html +++ b/netbox/templates/dcim/device.html @@ -11,11 +11,8 @@
    @@ -87,7 +93,10 @@ Group {% if rack.group %} - {{ rack.group }} + {% for group in rack.group.get_ancestors %} + {{ group }} + {% endfor %} + {{ rack.group }} {% else %} None {% endif %} diff --git a/netbox/templates/dcim/site.html b/netbox/templates/dcim/site.html index d6c21bf92..f5823f721 100644 --- a/netbox/templates/dcim/site.html +++ b/netbox/templates/dcim/site.html @@ -12,7 +12,7 @@