From e40e2550a618fbf2bf7d7227bc38889d08c45046 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 16 Nov 2022 11:34:45 -0500 Subject: [PATCH 01/28] PRVB --- docs/release-notes/version-3.3.md | 4 ++++ netbox/netbox/settings.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.3.md b/docs/release-notes/version-3.3.md index 4894690def..a46424df0b 100644 --- a/docs/release-notes/version-3.3.md +++ b/docs/release-notes/version-3.3.md @@ -1,5 +1,9 @@ # NetBox v3.3 +## v3.3.9 (FUTURE) + +--- + ## v3.3.8 (2022-11-16) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 46663f08c4..ff0551fffd 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -29,7 +29,7 @@ # Environment setup # -VERSION = '3.3.8' +VERSION = '3.3.9-dev' # Hostname HOSTNAME = platform.node() From eb591731ef3459f7a194fea6a69d8559452c3d49 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 17 Nov 2022 13:06:51 -0500 Subject: [PATCH 02/28] #10712: Remove pin for swagger-spec-validator (fixed in v3.0.3) --- requirements.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 8e89b47c5a..4504925f6c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -34,6 +34,3 @@ tzdata==2022.6 # Workaround for #7401 jsonschema==3.2.0 - -# Temporary fix for #10712 -swagger-spec-validator==2.7.6 From d3911e2a4cedc2d4182b13a74caa1d155f102f28 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 17 Nov 2022 15:13:37 -0500 Subject: [PATCH 03/28] Fixes #9878: Fix spurious error message when rendering REST API docs --- docs/release-notes/version-3.3.md | 4 ++++ netbox/utilities/custom_inspectors.py | 7 +++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/release-notes/version-3.3.md b/docs/release-notes/version-3.3.md index a46424df0b..8c0634e960 100644 --- a/docs/release-notes/version-3.3.md +++ b/docs/release-notes/version-3.3.md @@ -2,6 +2,10 @@ ## v3.3.9 (FUTURE) +### Bug Fixes + +* [#9878](https://github.com/netbox-community/netbox/issues/9878) - Fix spurious error message when rendering REST API docs + --- ## v3.3.8 (2022-11-16) diff --git a/netbox/utilities/custom_inspectors.py b/netbox/utilities/custom_inspectors.py index 258399e86d..d87613b20f 100644 --- a/netbox/utilities/custom_inspectors.py +++ b/netbox/utilities/custom_inspectors.py @@ -28,13 +28,12 @@ def get_request_serializer(self): serializer = super().get_request_serializer() if serializer is not None and self.method in self.implicit_body_methods: - writable_class = self.get_writable_class(serializer) - if writable_class is not None: + if writable_class := self.get_writable_class(serializer): if hasattr(serializer, 'child'): child_serializer = self.get_writable_class(serializer.child) - serializer = writable_class(child=child_serializer) + serializer = writable_class(context=serializer.context, child=child_serializer) else: - serializer = writable_class() + serializer = writable_class(context=serializer.context) return serializer def get_writable_class(self, serializer): From bd29d1581461f1b97cf0bcdaa10752d89e3ac0ae Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 17 Nov 2022 16:08:29 -0500 Subject: [PATCH 04/28] Fixes #10579: Mark cable traces terminating to a provider network as complete --- docs/release-notes/version-3.3.md | 1 + netbox/dcim/models/cables.py | 1 + netbox/dcim/tests/test_cablepaths.py | 1 + 3 files changed, 3 insertions(+) diff --git a/docs/release-notes/version-3.3.md b/docs/release-notes/version-3.3.md index 8c0634e960..46d4da7f2f 100644 --- a/docs/release-notes/version-3.3.md +++ b/docs/release-notes/version-3.3.md @@ -5,6 +5,7 @@ ### Bug Fixes * [#9878](https://github.com/netbox-community/netbox/issues/9878) - Fix spurious error message when rendering REST API docs +* [#10579](https://github.com/netbox-community/netbox/issues/10579) - Mark cable traces terminating to a provider network as complete --- diff --git a/netbox/dcim/models/cables.py b/netbox/dcim/models/cables.py index e05eb6d51a..4dd8d98a19 100644 --- a/netbox/dcim/models/cables.py +++ b/netbox/dcim/models/cables.py @@ -570,6 +570,7 @@ def from_origin(cls, terminations): [object_to_path_node(circuit_termination)], [object_to_path_node(circuit_termination.provider_network)], ]) + is_complete = True break elif circuit_termination.site and not circuit_termination.cable: # Circuit terminates to a Site diff --git a/netbox/dcim/tests/test_cablepaths.py b/netbox/dcim/tests/test_cablepaths.py index cfbbbc63b0..50a707bc62 100644 --- a/netbox/dcim/tests/test_cablepaths.py +++ b/netbox/dcim/tests/test_cablepaths.py @@ -1323,6 +1323,7 @@ def test_214_interface_to_providernetwork_via_circuit(self): is_active=True ) self.assertEqual(CablePath.objects.count(), 1) + self.assertTrue(CablePath.objects.first().is_complete) # Delete cable 1 cable1.delete() From cf55e9624154ee84c87968bf0798484e002d43a6 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 17 Nov 2022 16:30:54 -0500 Subject: [PATCH 05/28] Fixes #10721: Disable ordering by custom object field columns --- docs/release-notes/version-3.3.md | 1 + netbox/netbox/tables/columns.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/docs/release-notes/version-3.3.md b/docs/release-notes/version-3.3.md index 46d4da7f2f..ac047ee620 100644 --- a/docs/release-notes/version-3.3.md +++ b/docs/release-notes/version-3.3.md @@ -6,6 +6,7 @@ * [#9878](https://github.com/netbox-community/netbox/issues/9878) - Fix spurious error message when rendering REST API docs * [#10579](https://github.com/netbox-community/netbox/issues/10579) - Mark cable traces terminating to a provider network as complete +* [#10721](https://github.com/netbox-community/netbox/issues/10721) - Disable ordering by custom object field columns --- diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py index c7545192ae..81fdaa20f0 100644 --- a/netbox/netbox/tables/columns.py +++ b/netbox/netbox/tables/columns.py @@ -425,6 +425,12 @@ def __init__(self, customfield, *args, **kwargs): kwargs['accessor'] = Accessor(f'custom_field_data__{customfield.name}') if 'verbose_name' not in kwargs: kwargs['verbose_name'] = customfield.label or customfield.name + # We can't logically sort on FK values + if customfield.type in ( + CustomFieldTypeChoices.TYPE_OBJECT, + CustomFieldTypeChoices.TYPE_MULTIOBJECT + ): + kwargs['orderable'] = False super().__init__(*args, **kwargs) From 3a5914827b59620441bd5dbb51839ca860c0fecb Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 17 Nov 2022 21:04:55 -0500 Subject: [PATCH 06/28] Fixes #6389: Call snapshot() on object when processing deletions --- docs/release-notes/version-3.3.md | 1 + netbox/extras/signals.py | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/release-notes/version-3.3.md b/docs/release-notes/version-3.3.md index ac047ee620..7a7f0fdf9b 100644 --- a/docs/release-notes/version-3.3.md +++ b/docs/release-notes/version-3.3.md @@ -4,6 +4,7 @@ ### Bug Fixes +* [#6389](https://github.com/netbox-community/netbox/issues/6389) - Call `snapshot()` on object when processing deletions * [#9878](https://github.com/netbox-community/netbox/issues/9878) - Fix spurious error message when rendering REST API docs * [#10579](https://github.com/netbox-community/netbox/issues/10579) - Mark cable traces terminating to a provider network as complete * [#10721](https://github.com/netbox-community/netbox/issues/10721) - Disable ordering by custom object field columns diff --git a/netbox/extras/signals.py b/netbox/extras/signals.py index 31e0c126cf..4972d9e853 100644 --- a/netbox/extras/signals.py +++ b/netbox/extras/signals.py @@ -14,7 +14,6 @@ from .models import ConfigRevision, CustomField, ObjectChange from .webhooks import enqueue_object, get_snapshots, serialize_for_webhook - # # Change logging/webhooks # @@ -100,9 +99,6 @@ def handle_deleted_object(sender, instance, **kwargs): """ Fires when an object is deleted. """ - if not hasattr(instance, 'to_objectchange'): - return - # Get the current request, or bail if not set request = current_request.get() if request is None: @@ -110,6 +106,8 @@ def handle_deleted_object(sender, instance, **kwargs): # Record an ObjectChange if applicable if hasattr(instance, 'to_objectchange'): + if hasattr(instance, 'snapshot') and not getattr(instance, '_prechange_snapshot', None): + instance.snapshot() objectchange = instance.to_objectchange(ObjectChangeActionChoices.ACTION_DELETE) objectchange.user = request.user objectchange.request_id = request.id From dd2520d675c1fae1085383bccca0f5d824bd93d3 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Date: Fri, 18 Nov 2022 05:55:28 -0800 Subject: [PATCH 07/28] 10236 fix device detail for power-feed (#10961) * 10236 fix device detail for power-feed * 10236 optimize with statement --- netbox/templates/dcim/device.html | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html index b0cd76de48..19e7e6e3cf 100644 --- a/netbox/templates/dcim/device.html +++ b/netbox/templates/dcim/device.html @@ -247,10 +247,15 @@
Leg {{ leg.name }} {{ leg.outlet_count }} {{ leg.allocated }} - {{ powerfeed.available_power|divide:3 }}VA - {% with phase_available=powerfeed.available_power|divide:3 %} - {% utilization_graph leg.allocated|percentage:phase_available %} - {% endwith %} + {% if powerfeed.available_power %} + {% with phase_available=powerfeed.available_power|divide:3 %} + {{ phase_available }}VA + {% utilization_graph leg.allocated|percentage:phase_available %} + {% endwith %} + {% else %} + — + — + {% endif %} {% endfor %} {% endwith %} From de9646d0969e22a4de41615a21e0a2554521199e Mon Sep 17 00:00:00 2001 From: Arthur Hanson Date: Fri, 18 Nov 2022 05:57:57 -0800 Subject: [PATCH 08/28] 10653 log failed login attempts on INFO (#10843) * 10653 log failed login attempts on INFO * 10653 use signal to log failed login attempts * 10653 use signal to log failed login attempts * Update netbox/users/signals.py Co-authored-by: Jeremy Stretch * Update netbox/users/apps.py Co-authored-by: Jeremy Stretch Co-authored-by: Jeremy Stretch --- netbox/users/apps.py | 8 ++++++++ netbox/users/signals.py | 10 ++++++++++ netbox/users/views.py | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 netbox/users/apps.py create mode 100644 netbox/users/signals.py diff --git a/netbox/users/apps.py b/netbox/users/apps.py new file mode 100644 index 0000000000..b8d67f1c34 --- /dev/null +++ b/netbox/users/apps.py @@ -0,0 +1,8 @@ +from django.apps import AppConfig + + +class UsersConfig(AppConfig): + name = 'users' + + def ready(self): + import users.signals diff --git a/netbox/users/signals.py b/netbox/users/signals.py new file mode 100644 index 0000000000..8915af1dcd --- /dev/null +++ b/netbox/users/signals.py @@ -0,0 +1,10 @@ +import logging +from django.dispatch import receiver +from django.contrib.auth.signals import user_login_failed + + +@receiver(user_login_failed) +def log_user_login_failed(sender, credentials, request, **kwargs): + logger = logging.getLogger('netbox.auth.login') + username = credentials.get("username") + logger.info(f"Failed login attempt for username: {username}") diff --git a/netbox/users/views.py b/netbox/users/views.py index 33ef3fadd8..c688d6b4f2 100644 --- a/netbox/users/views.py +++ b/netbox/users/views.py @@ -106,7 +106,7 @@ def post(self, request): return self.redirect_to_next(request, logger) else: - logger.debug("Login form validation failed") + logger.debug(f"Login form validation failed for username: {form['username'].value()}") return render(request, self.template_name, { 'form': form, From c287641363593ed9ddfe01d8b108a2d17e55fdb6 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 18 Nov 2022 11:23:30 -0500 Subject: [PATCH 09/28] Changelog for #10236, #10653 --- docs/release-notes/version-3.3.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/release-notes/version-3.3.md b/docs/release-notes/version-3.3.md index 7a7f0fdf9b..0b84bf8da9 100644 --- a/docs/release-notes/version-3.3.md +++ b/docs/release-notes/version-3.3.md @@ -2,10 +2,15 @@ ## v3.3.9 (FUTURE) +### Enhancements + +* [#10653](https://github.com/netbox-community/netbox/issues/10653) - Ensure logging of failed login attempts + ### Bug Fixes * [#6389](https://github.com/netbox-community/netbox/issues/6389) - Call `snapshot()` on object when processing deletions * [#9878](https://github.com/netbox-community/netbox/issues/9878) - Fix spurious error message when rendering REST API docs +* [#10236](https://github.com/netbox-community/netbox/issues/10236) - Fix TypeError exception when viewing PDU configured for three-phase power * [#10579](https://github.com/netbox-community/netbox/issues/10579) - Mark cable traces terminating to a provider network as complete * [#10721](https://github.com/netbox-community/netbox/issues/10721) - Disable ordering by custom object field columns From 0885333b116640f6164f084a22b6c562d445881d Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 18 Nov 2022 11:24:14 -0500 Subject: [PATCH 10/28] Fixes #9223: Fix serialization of array field values in change log --- docs/release-notes/version-3.3.md | 1 + netbox/netbox/settings.py | 4 ++++ netbox/utilities/serializers/json.py | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 netbox/utilities/serializers/json.py diff --git a/docs/release-notes/version-3.3.md b/docs/release-notes/version-3.3.md index 0b84bf8da9..d99dc70996 100644 --- a/docs/release-notes/version-3.3.md +++ b/docs/release-notes/version-3.3.md @@ -9,6 +9,7 @@ ### Bug Fixes * [#6389](https://github.com/netbox-community/netbox/issues/6389) - Call `snapshot()` on object when processing deletions +* [#9223](https://github.com/netbox-community/netbox/issues/9223) - Fix serialization of array field values in change log * [#9878](https://github.com/netbox-community/netbox/issues/9878) - Fix spurious error message when rendering REST API docs * [#10236](https://github.com/netbox-community/netbox/issues/10236) - Fix TypeError exception when viewing PDU configured for three-phase power * [#10579](https://github.com/netbox-community/netbox/issues/10579) - Mark cable traces terminating to a provider network as complete diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index ff0551fffd..fa5480e19d 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -445,6 +445,10 @@ def _setting(name, default=None): f'/{BASE_PATH}metrics', ) +SERIALIZATION_MODULES = { + 'json': 'utilities.serializers.json', +} + # # Sentry diff --git a/netbox/utilities/serializers/json.py b/netbox/utilities/serializers/json.py new file mode 100644 index 0000000000..d2e682678b --- /dev/null +++ b/netbox/utilities/serializers/json.py @@ -0,0 +1,19 @@ +from django.contrib.postgres.fields import ArrayField +from django.core.serializers.json import Serializer as Serializer_ +from django.utils.encoding import is_protected_type + + +class Serializer(Serializer_): + """ + Custom extension of Django's JSON serializer to support ArrayFields (see + https://code.djangoproject.com/ticket/33974). + """ + def _value_from_field(self, obj, field): + value = field.value_from_object(obj) + + # Handle ArrayFields of protected types + if type(field) is ArrayField: + if not value or is_protected_type(value[0]): + return value + + return value if is_protected_type(value) else field.value_to_string(obj) From 3a89a676cdc8d27c0cf367546165107dda4714ae Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 17 Nov 2022 13:40:27 -0800 Subject: [PATCH 11/28] 10869 convert docstring to comment --- netbox/netbox/api/viewsets/__init__.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/netbox/netbox/api/viewsets/__init__.py b/netbox/netbox/api/viewsets/__init__.py index c50ad9ca6d..d6504282e0 100644 --- a/netbox/netbox/api/viewsets/__init__.py +++ b/netbox/netbox/api/viewsets/__init__.py @@ -137,9 +137,7 @@ def dispatch(self, request, *args, **kwargs): ) def list(self, request, *args, **kwargs): - """ - Overrides ListModelMixin to allow processing ExportTemplates. - """ + # Overrides ListModelMixin to allow processing ExportTemplates. if 'export' in request.GET: content_type = ContentType.objects.get_for_model(self.get_serializer_class().Meta.model) et = get_object_or_404(ExportTemplate, content_type=content_type, name=request.GET['export']) From 4e27e8d3dd2cbfe3279bda3631ca92a7facdd334 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 21 Nov 2022 09:44:08 -0500 Subject: [PATCH 12/28] Fixes #10969: Update cable paths ending at associated rear port when creating new front ports --- docs/release-notes/version-3.3.md | 1 + netbox/dcim/signals.py | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.3.md b/docs/release-notes/version-3.3.md index d99dc70996..a6dbdef19e 100644 --- a/docs/release-notes/version-3.3.md +++ b/docs/release-notes/version-3.3.md @@ -14,6 +14,7 @@ * [#10236](https://github.com/netbox-community/netbox/issues/10236) - Fix TypeError exception when viewing PDU configured for three-phase power * [#10579](https://github.com/netbox-community/netbox/issues/10579) - Mark cable traces terminating to a provider network as complete * [#10721](https://github.com/netbox-community/netbox/issues/10721) - Disable ordering by custom object field columns +* [#10969](https://github.com/netbox-community/netbox/issues/10969) - Update cable paths ending at associated rear port when creating new front ports --- diff --git a/netbox/dcim/signals.py b/netbox/dcim/signals.py index b990daf1aa..f223f9c5aa 100644 --- a/netbox/dcim/signals.py +++ b/netbox/dcim/signals.py @@ -4,7 +4,9 @@ from django.dispatch import receiver from .choices import CableEndChoices, LinkStatusChoices -from .models import Cable, CablePath, CableTermination, Device, PathEndpoint, PowerPanel, Rack, Location, VirtualChassis +from .models import ( + Cable, CablePath, CableTermination, Device, FrontPort, PathEndpoint, PowerPanel, Rack, Location, VirtualChassis, +) from .models.cables import trace_paths from .utils import create_cablepath, rebuild_paths @@ -123,3 +125,14 @@ def nullify_connected_endpoints(instance, **kwargs): for cablepath in CablePath.objects.filter(_nodes__contains=instance.cable): cablepath.retrace() + + +@receiver(post_save, sender=FrontPort) +def extend_rearport_cable_paths(instance, created, **kwargs): + """ + When a new FrontPort is created, add it to any CablePaths which end at its corresponding RearPort. + """ + if created: + rearport = instance.rear_port + for cablepath in CablePath.objects.filter(_nodes__contains=rearport): + cablepath.retrace() From 90f15b8d55e8de7747d7b3c18fbda895a08a0eda Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 21 Nov 2022 09:49:30 -0500 Subject: [PATCH 13/28] Fixes #10938: render_field template tag should respect label kwarg --- docs/release-notes/version-3.3.md | 1 + .../templates/form_helpers/render_field.html | 16 ++++++++-------- netbox/utilities/templatetags/form_helpers.py | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/release-notes/version-3.3.md b/docs/release-notes/version-3.3.md index a6dbdef19e..5f8856a69e 100644 --- a/docs/release-notes/version-3.3.md +++ b/docs/release-notes/version-3.3.md @@ -14,6 +14,7 @@ * [#10236](https://github.com/netbox-community/netbox/issues/10236) - Fix TypeError exception when viewing PDU configured for three-phase power * [#10579](https://github.com/netbox-community/netbox/issues/10579) - Mark cable traces terminating to a provider network as complete * [#10721](https://github.com/netbox-community/netbox/issues/10721) - Disable ordering by custom object field columns +* [#10938](https://github.com/netbox-community/netbox/issues/10938) - `render_field` template tag should respect `label` kwarg * [#10969](https://github.com/netbox-community/netbox/issues/10969) - Update cable paths ending at associated rear port when creating new front ports --- diff --git a/netbox/utilities/templates/form_helpers/render_field.html b/netbox/utilities/templates/form_helpers/render_field.html index 9f3779bfec..4c6c46ef08 100644 --- a/netbox/utilities/templates/form_helpers/render_field.html +++ b/netbox/utilities/templates/form_helpers/render_field.html @@ -8,7 +8,7 @@
{{ field }}
{% if field.help_text %} @@ -23,7 +23,7 @@ -{% elif field|widget_type == 'textarea' and not field.label %} +{% elif field|widget_type == 'textarea' and not label %}
{% if label %}