From 899ccad2967b3625a49fd52d5826ed4317489afc Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 3 Jan 2023 16:30:17 -0500 Subject: [PATCH 01/46] PRVB --- docs/release-notes/version-3.4.md | 4 ++++ netbox/netbox/settings.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.4.md b/docs/release-notes/version-3.4.md index e8f3e2bba..3abb894df 100644 --- a/docs/release-notes/version-3.4.md +++ b/docs/release-notes/version-3.4.md @@ -1,5 +1,9 @@ # NetBox v3.4 +## v3.4.3 (FUTURE) + +--- + ## v3.4.2 (2023-01-03) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 0ad211416..e47a7fe91 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -24,7 +24,7 @@ from netbox.constants import RQ_QUEUE_DEFAULT, RQ_QUEUE_HIGH, RQ_QUEUE_LOW # Environment setup # -VERSION = '3.4.2' +VERSION = '3.4.3-dev' # Hostname HOSTNAME = platform.node() From e401f4de1cc27117e444393ebb4628e9f8d3a0c2 Mon Sep 17 00:00:00 2001 From: kkthxbye-code Date: Thu, 5 Jan 2023 11:42:28 +0100 Subject: [PATCH 02/46] Fix exception when scheduling a job in the past --- netbox/extras/forms/scripts.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/netbox/extras/forms/scripts.py b/netbox/extras/forms/scripts.py index 58388e247..e61bb111d 100644 --- a/netbox/extras/forms/scripts.py +++ b/netbox/extras/forms/scripts.py @@ -48,9 +48,7 @@ class ScriptForm(BootstrapMixin, forms.Form): def clean__schedule_at(self): scheduled_time = self.cleaned_data['_schedule_at'] if scheduled_time and scheduled_time < timezone.now(): - raise forms.ValidationError({ - '_schedule_at': _('Scheduled time must be in the future.') - }) + raise forms.ValidationError(_('Scheduled time must be in the future.')) return scheduled_time From 819ac9d69ab4f7f6b20c86333154a92f0cc8eebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Arnauts?= Date: Thu, 5 Jan 2023 20:25:15 +0100 Subject: [PATCH 03/46] #11150: Add a filter for device.primary_ip4 and primary_ip6 (#11382) * Closes #11150: Add a filter for device.primary_ip4 and primary_ip6 * Tweaked tests to query for multiple IDs Co-authored-by: jeremystretch --- netbox/dcim/filtersets.py | 12 +++++++++++- netbox/dcim/tests/test_filtersets.py | 22 ++++++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index 2360fc4aa..534d8e411 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -3,7 +3,7 @@ from django.contrib.auth.models import User from django.utils.translation import gettext as _ from extras.filtersets import LocalConfigContextFilterSet -from ipam.models import ASN, VRF +from ipam.models import ASN, IPAddress, VRF from netbox.filtersets import ( BaseFilterSet, ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet, ) @@ -958,6 +958,16 @@ class DeviceFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilter method='_device_bays', label=_('Has device bays'), ) + primary_ip4_id = django_filters.ModelMultipleChoiceFilter( + field_name='primary_ip4', + queryset=IPAddress.objects.all(), + label=_('Primary IPv4 (ID)'), + ) + primary_ip6_id = django_filters.ModelMultipleChoiceFilter( + field_name='primary_ip6', + queryset=IPAddress.objects.all(), + label=_('Primary IPv6 (ID)'), + ) class Meta: model = Device diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index 874e3474c..6fb3feb11 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -1626,10 +1626,14 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): ipaddresses = ( IPAddress(address='192.0.2.1/24', assigned_object=interfaces[0]), IPAddress(address='192.0.2.2/24', assigned_object=interfaces[1]), + IPAddress(address='192.0.2.3/24', assigned_object=None), + IPAddress(address='2001:db8::1/64', assigned_object=interfaces[0]), + IPAddress(address='2001:db8::2/64', assigned_object=interfaces[1]), + IPAddress(address='2001:db8::3/64', assigned_object=None), ) IPAddress.objects.bulk_create(ipaddresses) - Device.objects.filter(pk=devices[0].pk).update(primary_ip4=ipaddresses[0]) - Device.objects.filter(pk=devices[1].pk).update(primary_ip4=ipaddresses[1]) + Device.objects.filter(pk=devices[0].pk).update(primary_ip4=ipaddresses[0], primary_ip6=ipaddresses[3]) + Device.objects.filter(pk=devices[1].pk).update(primary_ip4=ipaddresses[1], primary_ip6=ipaddresses[4]) # VirtualChassis assignment for filtering virtual_chassis = VirtualChassis.objects.create(master=devices[0]) @@ -1761,6 +1765,20 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'has_primary_ip': 'false'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + def test_primary_ip4(self): + addresses = IPAddress.objects.filter(address__family=4) + params = {'primary_ip4_id': [addresses[0].pk, addresses[1].pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'primary_ip4_id': [addresses[2].pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0) + + def test_primary_ip6(self): + addresses = IPAddress.objects.filter(address__family=6) + params = {'primary_ip6_id': [addresses[0].pk, addresses[1].pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'primary_ip6_id': [addresses[2].pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0) + def test_virtual_chassis_id(self): params = {'virtual_chassis_id': [VirtualChassis.objects.first().pk]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) From b16bf800825e325efb4607895f58a088d5f6bc75 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Thu, 5 Jan 2023 21:42:14 +0100 Subject: [PATCH 04/46] NetBox should always be referred to as NetBox [DATALAD RUNCMD] === Do not change lines below === { "chain": [], "cmd": "git ls-files -z . | xargs --null -I '()' find './()' -type f -not -name 'style-guide.md' -print0 | xargs --null sed --in-place --regexp-extended 's/\\bNetbox\\b/NetBox/g;'", "exit": 0, "extra_inputs": [], "inputs": [], "outputs": [], "pwd": "." } ^^^ Do not change lines above ^^^ --- README.md | 2 +- contrib/gunicorn.py | 2 +- docs/reference/markdown.md | 4 ++-- netbox/extras/management/commands/runscript.py | 2 +- netbox/project-static/styles/netbox.scss | 2 +- netbox/templates/base/layout.html | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 654b290ee..f44ce725f 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ employed by thousands of organizations around the world. ## About NetBox -![Screenshot of Netbox UI](docs/media/screenshots/netbox-ui.png "NetBox UI") +![Screenshot of NetBox UI](docs/media/screenshots/netbox-ui.png "NetBox UI") Myriad infrastructure components can be modeled in NetBox, including: diff --git a/contrib/gunicorn.py b/contrib/gunicorn.py index 363dbc2ff..89d6943b4 100644 --- a/contrib/gunicorn.py +++ b/contrib/gunicorn.py @@ -1,4 +1,4 @@ -# The IP address (typically localhost) and port that the Netbox WSGI process should listen on +# The IP address (typically localhost) and port that the NetBox WSGI process should listen on bind = '127.0.0.1:8001' # Number of gunicorn workers to spawn. This should typically be 2n+1, where diff --git a/docs/reference/markdown.md b/docs/reference/markdown.md index 896d5dcf7..7f280686d 100644 --- a/docs/reference/markdown.md +++ b/docs/reference/markdown.md @@ -168,7 +168,7 @@ Some text to show that the reference links can follow later. ## Images ``` -Here's the Netbox logo (hover to see the title text): +Here's the NetBox logo (hover to see the title text): Inline-style: ![alt text](/static/netbox_logo.png "Logo Title Text 1") @@ -179,7 +179,7 @@ Reference-style: [logo]: /static/netbox_logo.png "Logo Title Text 2" ``` -Here's the Netbox logo (hover to see the title text): +Here's the NetBox logo (hover to see the title text): Inline-style: ![alt text](/static/netbox_logo.png "Logo Title Text 1") diff --git a/netbox/extras/management/commands/runscript.py b/netbox/extras/management/commands/runscript.py index 2296ce1ff..ae49d53be 100644 --- a/netbox/extras/management/commands/runscript.py +++ b/netbox/extras/management/commands/runscript.py @@ -20,7 +20,7 @@ from utilities.utils import NetBoxFakeRequest class Command(BaseCommand): - help = "Run a script in Netbox" + help = "Run a script in NetBox" def add_arguments(self, parser): parser.add_argument( diff --git a/netbox/project-static/styles/netbox.scss b/netbox/project-static/styles/netbox.scss index 8ff224172..e486bc7db 100644 --- a/netbox/project-static/styles/netbox.scss +++ b/netbox/project-static/styles/netbox.scss @@ -1,4 +1,4 @@ -// Netbox-specific Styles and Overrides. +// NetBox-specific Styles and Overrides. @use 'sass:map'; @use 'sass:math'; diff --git a/netbox/templates/base/layout.html b/netbox/templates/base/layout.html index e060110fb..2fc6d0d98 100644 --- a/netbox/templates/base/layout.html +++ b/netbox/templates/base/layout.html @@ -21,7 +21,7 @@ Blocks: {# Body #}
- {# Netbox Logo, only visible when printing #} + {# NetBox Logo, only visible when printing #}
NetBox logo
From 81068420f76a8575886178afa1b87d7d6106d1cb Mon Sep 17 00:00:00 2001 From: Patrick Kerwood Date: Thu, 11 Aug 2022 21:41:32 +0200 Subject: [PATCH 05/46] feat: added setting redis certificate authority path --- netbox/netbox/configuration_example.py | 4 ++++ netbox/netbox/settings.py | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/netbox/netbox/configuration_example.py b/netbox/netbox/configuration_example.py index 262b52d4f..14fcde022 100644 --- a/netbox/netbox/configuration_example.py +++ b/netbox/netbox/configuration_example.py @@ -38,6 +38,8 @@ REDIS = { # Set this to True to skip TLS certificate verification # This can expose the connection to attacks, be careful # 'INSECURE_SKIP_TLS_VERIFY': False, + # Set a path to a certificate authority, typically used with a self signed certificate. + # 'CA_CERT_PATH': '/etc/ssl/certs/ca.crt', }, 'caching': { 'HOST': 'localhost', @@ -52,6 +54,8 @@ REDIS = { # Set this to True to skip TLS certificate verification # This can expose the connection to attacks, be careful # 'INSECURE_SKIP_TLS_VERIFY': False, + # Set a path to a certificate authority, typically used with a self signed certificate. + # 'CA_CERT_PATH': '/etc/ssl/certs/ca.crt', } } diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index e47a7fe91..1b47520be 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -235,6 +235,7 @@ TASKS_REDIS_PASSWORD = TASKS_REDIS.get('PASSWORD', '') TASKS_REDIS_DATABASE = TASKS_REDIS.get('DATABASE', 0) TASKS_REDIS_SSL = TASKS_REDIS.get('SSL', False) TASKS_REDIS_SKIP_TLS_VERIFY = TASKS_REDIS.get('INSECURE_SKIP_TLS_VERIFY', False) +TASKS_REDIS_CA_CERT_PATH = TASKS_REDIS.get('CA_CERT_PATH', False) # Caching if 'caching' not in REDIS: @@ -251,6 +252,7 @@ CACHING_REDIS_SENTINELS = REDIS['caching'].get('SENTINELS', []) CACHING_REDIS_SENTINEL_SERVICE = REDIS['caching'].get('SENTINEL_SERVICE', 'default') CACHING_REDIS_PROTO = 'rediss' if REDIS['caching'].get('SSL', False) else 'redis' CACHING_REDIS_SKIP_TLS_VERIFY = REDIS['caching'].get('INSECURE_SKIP_TLS_VERIFY', False) +CACHING_REDIS_CA_CERT_PATH = REDIS['caching'].get('CA_CERT_PATH', False) CACHES = { 'default': { @@ -262,6 +264,8 @@ CACHES = { } } } + + if CACHING_REDIS_SENTINELS: DJANGO_REDIS_CONNECTION_FACTORY = 'django_redis.pool.SentinelConnectionFactory' CACHES['default']['LOCATION'] = f'{CACHING_REDIS_PROTO}://{CACHING_REDIS_SENTINEL_SERVICE}/{CACHING_REDIS_DATABASE}' @@ -270,7 +274,9 @@ if CACHING_REDIS_SENTINELS: if CACHING_REDIS_SKIP_TLS_VERIFY: CACHES['default']['OPTIONS'].setdefault('CONNECTION_POOL_KWARGS', {}) CACHES['default']['OPTIONS']['CONNECTION_POOL_KWARGS']['ssl_cert_reqs'] = False - +if CACHING_REDIS_CA_CERT_PATH: + CACHES['default']['OPTIONS'].setdefault('CONNECTION_POOL_KWARGS', {}) + CACHES['default']['OPTIONS']['CONNECTION_POOL_KWARGS']['ssl_ca_certs'] = CACHING_REDIS_CA_CERT_PATH # # Sessions @@ -648,6 +654,10 @@ RQ_PARAMS.update({ 'DEFAULT_TIMEOUT': RQ_DEFAULT_TIMEOUT, }) +if TASKS_REDIS_CA_CERT_PATH: + RQ_PARAMS.setdefault('REDIS_CLIENT_KWARGS', {}) + RQ_PARAMS['REDIS_CLIENT_KWARGS']['ssl_ca_certs'] = TASKS_REDIS_CA_CERT_PATH + RQ_QUEUES = { RQ_QUEUE_HIGH: RQ_PARAMS, RQ_QUEUE_DEFAULT: RQ_PARAMS, From 9a688858d500bbb74fb18d60c80f43d14f638d9a Mon Sep 17 00:00:00 2001 From: "Daniel W. Anner" Date: Thu, 5 Jan 2023 16:26:26 -0500 Subject: [PATCH 06/46] #11371 - Add various 100Mb Interface Types (#11377) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added 100base-fx (aka fast ethernet over fiber optic) * Added 100BASE-T1 (single pair fast ethernet) as well as 100BASE‑LFX (fast ethernet over fiber, non standard) * Update choices.py Updated the placing of the 100base-fx and lfx choices * Update netbox/dcim/choices.py Co-authored-by: Jeremy Stretch --- netbox/dcim/choices.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index 32dbbb62a..bcc3b404b 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -785,7 +785,10 @@ class InterfaceTypeChoices(ChoiceSet): TYPE_LAG = 'lag' # Ethernet + TYPE_100ME_FX = '100base-fx' + TYPE_100ME_LFX = '100base-lfx' TYPE_100ME_FIXED = '100base-tx' + TYPE_100ME_T1 = '100base-t1' TYPE_1GE_FIXED = '1000base-t' TYPE_1GE_GBIC = '1000base-x-gbic' TYPE_1GE_SFP = '1000base-x-sfp' @@ -918,7 +921,10 @@ class InterfaceTypeChoices(ChoiceSet): ( 'Ethernet (fixed)', ( + (TYPE_100ME_FX, '100BASE-FX (10/100ME FIBER)'), + (TYPE_100ME_LFX, '100BASE-LFX (10/100ME FIBER)'), (TYPE_100ME_FIXED, '100BASE-TX (10/100ME)'), + (TYPE_100ME_T1, '100BASE-T1 (10/100ME Single Pair)'), (TYPE_1GE_FIXED, '1000BASE-T (1GE)'), (TYPE_2GE_FIXED, '2.5GBASE-T (2.5GE)'), (TYPE_5GE_FIXED, '5GBASE-T (5GE)'), From 53c4eb242a9a0b05d6f0729da357bceebd12ae81 Mon Sep 17 00:00:00 2001 From: Renato Almeida de Oliveira Date: Thu, 5 Jan 2023 18:26:48 -0300 Subject: [PATCH 07/46] Add ExportTemplatesMixin to JournalEntry model (#11251) * Add ExportTemplatesMixin to JournalEntry model * Move mixin ahead of base class Co-authored-by: Jeremy Stretch --- netbox/extras/models/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index 699baa11b..607c5d4a0 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -514,7 +514,7 @@ class ImageAttachment(WebhooksMixin, ChangeLoggedModel): return objectchange -class JournalEntry(CustomFieldsMixin, CustomLinksMixin, TagsMixin, WebhooksMixin, ChangeLoggedModel): +class JournalEntry(CustomFieldsMixin, CustomLinksMixin, TagsMixin, WebhooksMixin, ExportTemplatesMixin, ChangeLoggedModel): """ A historical remark concerning an object; collectively, these form an object's journal. The journal is used to preserve historical context around an object, and complements NetBox's built-in change logging. For example, you From c55b2ea5c1f97d0cfdaae92f64211ad72f1842da Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 5 Jan 2023 16:29:17 -0500 Subject: [PATCH 08/46] Changelog for #9996, #11150, #11245, #11371, #11403 --- docs/release-notes/version-3.4.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/release-notes/version-3.4.md b/docs/release-notes/version-3.4.md index 3abb894df..84882dd58 100644 --- a/docs/release-notes/version-3.4.md +++ b/docs/release-notes/version-3.4.md @@ -2,6 +2,17 @@ ## v3.4.3 (FUTURE) +### Enhancements + +* [#9996](https://github.com/netbox-community/netbox/issues/9996) - Introduce `CA_CERT_PATH` parameter to define SSL CA path for Redis servers +* [#11150](https://github.com/netbox-community/netbox/issues/11150) - Add primary IPv4/v6 address filters for devices +* [#11245](https://github.com/netbox-community/netbox/issues/11245) - Enable export templates for journal entries +* [#11371](https://github.com/netbox-community/netbox/issues/11371) - Introduce additional 100M Ethernet interface types + +### Bug Fixes + +* [#11403](https://github.com/netbox-community/netbox/issues/11403) - Fix exception when scheduling a job in the past + --- ## v3.4.2 (2023-01-03) From 05319c589dca247cee08ce63e14fedbfb59b7cbd Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 5 Jan 2023 16:38:29 -0500 Subject: [PATCH 09/46] Closes #11406: Correct example JSON --- docs/models/extras/savedfilter.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/models/extras/savedfilter.md b/docs/models/extras/savedfilter.md index 68278403e..c03a8b0c2 100644 --- a/docs/models/extras/savedfilter.md +++ b/docs/models/extras/savedfilter.md @@ -40,8 +40,8 @@ is represented in JSON as ```json { - 'tag': ['alpha', 'bravo'], - 'status': 'active', - 'region_id': 51 + "tag": ["alpha", "bravo"], + "status": "active", + "region_id": 51 } ``` From 8c161ecbb96db2fd0239a7493aca024e58e55441 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 6 Jan 2023 09:42:13 -0500 Subject: [PATCH 10/46] Fixes #11384: Correct current time display on script & report forms --- docs/release-notes/version-3.4.md | 1 + netbox/extras/forms/reports.py | 3 ++- netbox/extras/forms/scripts.py | 4 ++-- netbox/utilities/utils.py | 9 +++++++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/release-notes/version-3.4.md b/docs/release-notes/version-3.4.md index 84882dd58..79f57a90c 100644 --- a/docs/release-notes/version-3.4.md +++ b/docs/release-notes/version-3.4.md @@ -11,6 +11,7 @@ ### Bug Fixes +* [#11384](https://github.com/netbox-community/netbox/issues/11384) - Correct current time display on script & report forms * [#11403](https://github.com/netbox-community/netbox/issues/11403) - Fix exception when scheduling a job in the past --- diff --git a/netbox/extras/forms/reports.py b/netbox/extras/forms/reports.py index 338d05fa3..d2ec01006 100644 --- a/netbox/extras/forms/reports.py +++ b/netbox/extras/forms/reports.py @@ -3,6 +3,7 @@ from django.utils import timezone from django.utils.translation import gettext as _ from utilities.forms import BootstrapMixin, DateTimePicker, SelectDurationWidget +from utilities.utils import local_now __all__ = ( 'ReportForm', @@ -35,5 +36,5 @@ class ReportForm(BootstrapMixin, forms.Form): super().__init__(*args, **kwargs) # Annotate the current system time for reference - now = timezone.now().strftime('%Y-%m-%d %H:%M:%S') + now = local_now().strftime('%Y-%m-%d %H:%M:%S') self.fields['schedule_at'].help_text += f' (current time: {now})' diff --git a/netbox/extras/forms/scripts.py b/netbox/extras/forms/scripts.py index e61bb111d..79dc8c869 100644 --- a/netbox/extras/forms/scripts.py +++ b/netbox/extras/forms/scripts.py @@ -1,8 +1,8 @@ from django import forms -from django.utils import timezone from django.utils.translation import gettext as _ from utilities.forms import BootstrapMixin, DateTimePicker, SelectDurationWidget +from utilities.utils import local_now __all__ = ( 'ScriptForm', @@ -34,7 +34,7 @@ class ScriptForm(BootstrapMixin, forms.Form): super().__init__(*args, **kwargs) # Annotate the current system time for reference - now = timezone.now().strftime('%Y-%m-%d %H:%M:%S') + now = local_now().strftime('%Y-%m-%d %H:%M:%S') self.fields['_schedule_at'].help_text += f' (current time: {now})' # Move _commit and _schedule_at to the end of the form diff --git a/netbox/utilities/utils.py b/netbox/utilities/utils.py index f635fc728..38a974036 100644 --- a/netbox/utilities/utils.py +++ b/netbox/utilities/utils.py @@ -12,6 +12,8 @@ from django.db.models import Count, OuterRef, Subquery from django.db.models.functions import Coalesce from django.http import QueryDict from django.utils.html import escape +from django.utils import timezone +from django.utils.timezone import localtime from jinja2.sandbox import SandboxedEnvironment from mptt.models import MPTTModel @@ -527,3 +529,10 @@ def highlight_string(value, highlight, trim_pre=None, trim_post=None, trim_place post = post[:trim_post] + trim_placeholder return f'{escape(pre)}{escape(match)}{escape(post)}' + + +def local_now(): + """ + Return the current date & time in the system timezone. + """ + return localtime(timezone.now()) From 271fd13641a8847b8051bbb34a7f16603efc9ef1 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Thu, 5 Jan 2023 22:49:11 +0100 Subject: [PATCH 11/46] Add summary release notes for v3.4 --- docs/release-notes/index.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/release-notes/index.md b/docs/release-notes/index.md index 8a6a86174..6262ef92c 100644 --- a/docs/release-notes/index.md +++ b/docs/release-notes/index.md @@ -10,6 +10,16 @@ Minor releases are published in April, August, and December of each calendar yea This page contains a history of all major and minor releases since NetBox v2.0. For more detail on a specific patch release, please see the release notes page for that specific minor release. +#### [Version 3.4](./version-3.4.md) (December 2022) + +* New Global Search ([#10560](https://github.com/netbox-community/netbox/issues/10560)) +* Virtual Device Contexts ([#7854](https://github.com/netbox-community/netbox/issues/7854)) +* Saved Filters ([#9623](https://github.com/netbox-community/netbox/issues/9623)) +* JSON/YAML Bulk Imports ([#4347](https://github.com/netbox-community/netbox/issues/4347)) +* Update Existing Objects via Bulk Import ([#7961](https://github.com/netbox-community/netbox/issues/7961)) +* Scheduled Reports & Scripts ([#8366](https://github.com/netbox-community/netbox/issues/8366)) +* API for Staged Changes ([#10851](https://github.com/netbox-community/netbox/issues/10851)) + #### [Version 3.3](./version-3.3.md) (August 2022) * Multi-object Cable Terminations ([#9102](https://github.com/netbox-community/netbox/issues/9102)) From 96d2b4d5ef7ad9f03538e0da0dfcd60d4696429b Mon Sep 17 00:00:00 2001 From: Arthur Hanson Date: Fri, 6 Jan 2023 07:15:43 -0800 Subject: [PATCH 12/46] 11340 cable termination setter (#11341) * 11340 update _terminations_modified only if modified * 11340 update _terminations_modified only if modified --- netbox/dcim/models/cables.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/models/cables.py b/netbox/dcim/models/cables.py index 48c1f92db..406231ef5 100644 --- a/netbox/dcim/models/cables.py +++ b/netbox/dcim/models/cables.py @@ -119,7 +119,8 @@ class Cable(PrimaryModel): @a_terminations.setter def a_terminations(self, value): - self._terminations_modified = True + if not self.pk or self.a_terminations != list(value): + self._terminations_modified = True self._a_terminations = value @property @@ -133,7 +134,8 @@ class Cable(PrimaryModel): @b_terminations.setter def b_terminations(self, value): - self._terminations_modified = True + if not self.pk or self.b_terminations != list(value): + self._terminations_modified = True self._b_terminations = value def clean(self): From d45e5718ead974731e5dac495c8da5e185caa51b Mon Sep 17 00:00:00 2001 From: kkthxbye-code Date: Mon, 19 Dec 2022 08:59:21 +0100 Subject: [PATCH 13/46] Return no terminations if the cable is unsaved --- netbox/dcim/models/cables.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/netbox/dcim/models/cables.py b/netbox/dcim/models/cables.py index 406231ef5..6fd99d18a 100644 --- a/netbox/dcim/models/cables.py +++ b/netbox/dcim/models/cables.py @@ -112,6 +112,10 @@ class Cable(PrimaryModel): def a_terminations(self): if hasattr(self, '_a_terminations'): return self._a_terminations + + if not self.pk: + return [] + # Query self.terminations.all() to leverage cached results return [ ct.termination for ct in self.terminations.all() if ct.cable_end == CableEndChoices.SIDE_A @@ -127,6 +131,10 @@ class Cable(PrimaryModel): def b_terminations(self): if hasattr(self, '_b_terminations'): return self._b_terminations + + if not self.pk: + return [] + # Query self.terminations.all() to leverage cached results return [ ct.termination for ct in self.terminations.all() if ct.cable_end == CableEndChoices.SIDE_B From 1969afbd0e190a6a09ad0815e5c469d9251f2b44 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 6 Jan 2023 21:11:29 +0100 Subject: [PATCH 14/46] Closes #10486: Add buttons to edit cables (#11414) * Added buttons to edit cables * Revert change that did not address this branch * Consolidated buttons * moved back trace button / added permission checks * reverted disabled trace button --- netbox/dcim/tables/template_code.py | 182 +++++++++++++++--- .../circuits/inc/circuit_termination.html | 5 + 2 files changed, 159 insertions(+), 28 deletions(-) diff --git a/netbox/dcim/tables/template_code.py b/netbox/dcim/tables/template_code.py index dd0581ddc..d390871c4 100644 --- a/netbox/dcim/tables/template_code.py +++ b/netbox/dcim/tables/template_code.py @@ -115,10 +115,28 @@ CONSOLEPORT_BUTTONS = """ {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} - {% if perms.dcim.delete_cable %} - - - + {% if perms.dcim.change_cable or perms.dcim.delete_cable %} + + + + {% endif %} {% elif perms.dcim.add_cable %} @@ -147,10 +165,28 @@ CONSOLESERVERPORT_BUTTONS = """ {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} - {% if perms.dcim.delete_cable %} - - - + {% if perms.dcim.change_cable or perms.dcim.delete_cable %} + + + + {% endif %} {% elif perms.dcim.add_cable %} @@ -179,10 +215,28 @@ POWERPORT_BUTTONS = """ {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} - {% if perms.dcim.delete_cable %} - - - + {% if perms.dcim.change_cable or perms.dcim.delete_cable %} + + + + {% endif %} {% elif perms.dcim.add_cable %} @@ -210,10 +264,28 @@ POWEROUTLET_BUTTONS = """ {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} - {% if perms.dcim.delete_cable %} - - - + {% if perms.dcim.change_cable or perms.dcim.delete_cable %} + + + + {% endif %} {% elif perms.dcim.add_cable %} @@ -258,10 +330,28 @@ INTERFACE_BUTTONS = """ {% endif %} {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} - {% if perms.dcim.delete_cable %} - - - + {% if perms.dcim.change_cable or perms.dcim.delete_cable %} + + + + {% endif %} {% elif record.wireless_link %} {% if perms.wireless.delete_wirelesslink %} @@ -303,10 +393,28 @@ FRONTPORT_BUTTONS = """ {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} - {% if perms.dcim.delete_cable %} - - - + {% if perms.dcim.change_cable or perms.dcim.delete_cable %} + + + + {% endif %} {% elif perms.dcim.add_cable %} @@ -340,10 +448,28 @@ REARPORT_BUTTONS = """ {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} - {% if perms.dcim.delete_cable %} - - - + {% if perms.dcim.change_cable or perms.dcim.delete_cable %} + + + + {% endif %} {% elif perms.dcim.add_cable %} diff --git a/netbox/templates/circuits/inc/circuit_termination.html b/netbox/templates/circuits/inc/circuit_termination.html index 160ff940f..12c63bd34 100644 --- a/netbox/templates/circuits/inc/circuit_termination.html +++ b/netbox/templates/circuits/inc/circuit_termination.html @@ -57,6 +57,11 @@ Trace + {% if perms.dcim.change_cable %} + + Edit + + {% endif %} {% if perms.dcim.delete_cable %} Disconnect From dd843684af74ab62bce1db273f59c9f0827dbc07 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 6 Jan 2023 16:10:30 -0500 Subject: [PATCH 15/46] Fixes #11379: Fix TypeError exception when bulk editing custom date fields --- netbox/netbox/views/generic/bulk_views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index 75416f097..ab3e8f100 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -494,7 +494,7 @@ class BulkEditView(GetReturnURLMixin, BaseMultiObjectView): return get_permission_for_model(self.queryset.model, 'change') def _update_objects(self, form, request): - custom_fields = getattr(form, 'custom_fields', []) + custom_fields = getattr(form, 'custom_fields', {}) standard_fields = [ field for field in form.fields if field not in list(custom_fields) + ['pk'] ] @@ -532,13 +532,13 @@ class BulkEditView(GetReturnURLMixin, BaseMultiObjectView): setattr(obj, name, form.cleaned_data[name]) # Update custom fields - for name in custom_fields: + for name, customfield in custom_fields.items(): assert name.startswith('cf_') cf_name = name[3:] # Strip cf_ prefix if name in form.nullable_fields and name in nullified_fields: obj.custom_field_data[cf_name] = None elif name in form.changed_data: - obj.custom_field_data[cf_name] = form.fields[name].prepare_value(form.cleaned_data[name]) + obj.custom_field_data[cf_name] = customfield.serialize(form.cleaned_data[name]) obj.full_clean() obj.save() From d7c38a522597e98151c81ba92627e2e0168ad68c Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 6 Jan 2023 16:25:41 -0500 Subject: [PATCH 16/46] Changelog for #10486, #11210, #11340, #11379 --- docs/release-notes/version-3.4.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/release-notes/version-3.4.md b/docs/release-notes/version-3.4.md index 79f57a90c..a087e31b8 100644 --- a/docs/release-notes/version-3.4.md +++ b/docs/release-notes/version-3.4.md @@ -5,12 +5,16 @@ ### Enhancements * [#9996](https://github.com/netbox-community/netbox/issues/9996) - Introduce `CA_CERT_PATH` parameter to define SSL CA path for Redis servers +* [#10486](https://github.com/netbox-community/netbox/issues/10486) - Add a cable edit button for connected components in component lists * [#11150](https://github.com/netbox-community/netbox/issues/11150) - Add primary IPv4/v6 address filters for devices * [#11245](https://github.com/netbox-community/netbox/issues/11245) - Enable export templates for journal entries * [#11371](https://github.com/netbox-community/netbox/issues/11371) - Introduce additional 100M Ethernet interface types ### Bug Fixes +* [#11210](https://github.com/netbox-community/netbox/issues/11210) - Fix ValueError exception when attempting to bulk import cables attached to occupied terminations +* [#11340](https://github.com/netbox-community/netbox/issues/11340) - Avoid flagging cable termination changes erroneously +* [#11379](https://github.com/netbox-community/netbox/issues/11379) - Fix TypeError exception when bulk editing custom date fields * [#11384](https://github.com/netbox-community/netbox/issues/11384) - Correct current time display on script & report forms * [#11403](https://github.com/netbox-community/netbox/issues/11403) - Fix exception when scheduling a job in the past From 2d0fe8f6123f4a12b8d2da4ea936d51e55268ecf Mon Sep 17 00:00:00 2001 From: kkthxbye Date: Mon, 9 Jan 2023 07:45:12 +0100 Subject: [PATCH 17/46] Get the queue from QUEUE_MAPPINGS when deleting JobResults --- netbox/extras/models/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index 607c5d4a0..e608f81b1 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -634,7 +634,8 @@ class JobResult(models.Model): def delete(self, *args, **kwargs): super().delete(*args, **kwargs) - queue = django_rq.get_queue("default") + rq_queue_name = get_config().QUEUE_MAPPINGS.get(self.obj_type.name, RQ_QUEUE_DEFAULT) + queue = django_rq.get_queue(rq_queue_name) job = queue.fetch_job(str(self.job_id)) if job: From c5bc3dfc556cc54cb8a150d5d6249f9b4d90466c Mon Sep 17 00:00:00 2001 From: kkthxbye Date: Mon, 9 Jan 2023 14:22:49 +0100 Subject: [PATCH 18/46] Snapshot DeviceBay before populating/depopulating. --- netbox/dcim/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 115c16112..13222313c 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -2820,7 +2820,7 @@ class DeviceBayPopulateView(generic.ObjectEditView): form = forms.PopulateDeviceBayForm(device_bay, request.POST) if form.is_valid(): - + device_bay.snapshot() device_bay.installed_device = form.cleaned_data['installed_device'] device_bay.save() messages.success(request, "Added {} to {}.".format(device_bay.installed_device, device_bay)) @@ -2854,7 +2854,7 @@ class DeviceBayDepopulateView(generic.ObjectEditView): form = ConfirmationForm(request.POST) if form.is_valid(): - + device_bay.snapshot() removed_device = device_bay.installed_device device_bay.installed_device = None device_bay.save() From c5d4ede1539e32df1b904d85e3ab7f01e0548ab5 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 9 Jan 2023 10:57:13 -0500 Subject: [PATCH 19/46] Fixes #11402: Avoid LookupError exception when running scripts with commit disabled --- docs/release-notes/version-3.4.md | 1 + netbox/netbox/context.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.4.md b/docs/release-notes/version-3.4.md index a087e31b8..5a76a3dd4 100644 --- a/docs/release-notes/version-3.4.md +++ b/docs/release-notes/version-3.4.md @@ -16,6 +16,7 @@ * [#11340](https://github.com/netbox-community/netbox/issues/11340) - Avoid flagging cable termination changes erroneously * [#11379](https://github.com/netbox-community/netbox/issues/11379) - Fix TypeError exception when bulk editing custom date fields * [#11384](https://github.com/netbox-community/netbox/issues/11384) - Correct current time display on script & report forms +* [#11402](https://github.com/netbox-community/netbox/issues/11402) - Avoid LookupError exception when running scripts with commit disabled * [#11403](https://github.com/netbox-community/netbox/issues/11403) - Fix exception when scheduling a job in the past --- diff --git a/netbox/netbox/context.py b/netbox/netbox/context.py index b5e4dc28e..5461a4e94 100644 --- a/netbox/netbox/context.py +++ b/netbox/netbox/context.py @@ -7,4 +7,4 @@ __all__ = ( current_request = ContextVar('current_request', default=None) -webhooks_queue = ContextVar('webhooks_queue') +webhooks_queue = ContextVar('webhooks_queue', default=[]) From 7053ffc0ed96df5691fc1a9019fdc1ba5aa9cecd Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 9 Jan 2023 10:58:23 -0500 Subject: [PATCH 20/46] Changelog for #11438, #11444 --- docs/release-notes/version-3.4.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/release-notes/version-3.4.md b/docs/release-notes/version-3.4.md index 5a76a3dd4..e5b230018 100644 --- a/docs/release-notes/version-3.4.md +++ b/docs/release-notes/version-3.4.md @@ -18,6 +18,8 @@ * [#11384](https://github.com/netbox-community/netbox/issues/11384) - Correct current time display on script & report forms * [#11402](https://github.com/netbox-community/netbox/issues/11402) - Avoid LookupError exception when running scripts with commit disabled * [#11403](https://github.com/netbox-community/netbox/issues/11403) - Fix exception when scheduling a job in the past +* [#11438](https://github.com/netbox-community/netbox/issues/11438) - Fix deletion of scheduled job using non-default queues +* [#11444](https://github.com/netbox-community/netbox/issues/11444) - Adding/removing a device from a device bay should record a pre-change snapshot on the device bay --- From fdaa149fe1f1479d9db9ef8d1dad4c98fe48350f Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 10 Jan 2023 08:41:06 -0500 Subject: [PATCH 21/46] Refresh contributing guide --- CONTRIBUTING.md | 230 ++++++++++++++++-------------------------------- 1 file changed, 77 insertions(+), 153 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 47fca53d0..6fd01164e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,188 +1,112 @@ -## Getting Help +**Looking for help?** NetBox has a vast, active community of fellow users that may be able to provide assistance. Just [start a discussion](https://github.com/netbox-community/netbox/discussions/new) right here on GitHub! Or if you'd prefer to chat, join us live in the `#netbox` channel on the [NetDev Community Slack](https://netdev.chat/)! -If you encounter any issues installing or using NetBox, try one of the -following resources to get assistance. Please **do not** open a GitHub issue -except to report bugs or request features. +
+

+ :bug: Report a bug · + :bulb: Suggest a feature · + :arrow_heading_up: Submit a pull request +

+

+ :jigsaw: Create a plugin · + :rescue_worker_helmet: Become a maintainer · + :heart: Other ideas +

+
+

-### GitHub Discussions +Some general tips for engaging here on GitHub: -GitHub's discussions are the best place to get help or propose rough ideas for -new functionality. Their integration with GitHub allows for easily cross- -referencing and converting posts to issues as needed. There are several -categories for discussions: +* Register for a free [GitHub account](https://github.com/signup) if you haven't already. +* You can use [GitHub Markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax) for formatting text and adding images. +* To help mitigate notification spam, please avoid "bumping" issues with no activity. (To vote an issue up or down, use a :thumbsup: or :thumbsdown: reaction.) +* Please avoid pinging members with `@` unless they've previously expressed interest or involvement with that particular issue. -* **General** - General community discussion -* **Ideas** - Ideas for new functionality that isn't yet ready for a formal - feature request -* **Q&A** - Request help with installing or using NetBox +## :bug: Reporting Bugs -### Slack +* First, ensure that you're running the [latest stable version](https://github.com/netbox-community/netbox/releases) of NetBox. If you're running an older version, it's likely that the bug has already been fixed. -For real-time chat, you can join the **#netbox** Slack channel on [NetDev Community](https://netdev.chat/). -Unfortunately, the Slack channel does not provide long-term retention of chat -history, so try to avoid it for any discussions would benefit from being -preserved for future reference. +* Next, search our [issues list](https://github.com/netbox-community/netbox/issues?q=is%3Aissue) to see if the bug you've found has already been reported. If you come across a bug report that seems to match, please click "add a reaction" in the top right corner of the issue and add a thumbs up (:thumbsup:). This will help draw more attention to it. Any comments you can add to provide additional information or context would also be much appreciated. -## Reporting Bugs +* If you can't find any existing issues (open or closed) that seem to match yours, you're welcome to [submit a new bug report](https://github.com/netbox-community/netbox/issues/new?label=type%3A+bug&template=bug_report.yaml). Be sure to complete the entire report template, including detailed steps that someone triaging your issue can follow to confirm the reported behavior. (If we're not able to replicate the bug based on the information provided, we'll ask for additional detail.) -* First, ensure that you're running the [latest stable version](https://github.com/netbox-community/netbox/releases) -of NetBox. If you're running an older version, it's possible that the bug has -already been fixed. - -* Next, check the GitHub [issues list](https://github.com/netbox-community/netbox/issues) -to see if the bug you've found has already been reported. If you think you may -be experiencing a reported issue that hasn't already been resolved, please -click "add a reaction" in the top right corner of the issue and add a thumbs -up (+1). You might also want to add a comment describing how it's affecting your -installation. This will allow us to prioritize bugs based on how many users are -affected. - -* When submitting an issue, please be as descriptive as possible. Be sure to -provide all information request in the issue template, including: - - * The environment in which NetBox is running - * The exact steps that can be taken to reproduce the issue - * Expected and observed behavior - * Any error messages generated - * Screenshots (if applicable) - -* Please avoid prepending any sort of tag (e.g. "[Bug]") to the issue title. -The issue will be reviewed by a maintainer after submission and the appropriate -labels will be applied for categorization. - -* Keep in mind that we prioritize bugs based on their severity and how much -work is required to resolve them. It may take some time for someone to address -your issue. +* Some other tips to keep in mind: + * Error messages and screenshots are especially helpful. + * Don't prepend your issue title with a label like `[Bug]`; the proper label will be assigned automatically. + * Ensure that your reproduction instructions don't reference data in our [demo instance](https://demo.netbox.dev/), which gets rebuilt nightly. + * We appreciate your patience as bugs are prioritized by their severity, impact, and difficulty to resolve. * For more information on how bug reports are handled, please see our [issue intake policy](https://github.com/netbox-community/netbox/wiki/Issue-Intake-Policy). -## Feature Requests +## :bulb: Feature Requests -* First, check the GitHub [issues list](https://github.com/netbox-community/netbox/issues) -to see if the feature you're requesting is already listed. (Be sure to search -closed issues as well, since some feature requests have been rejected.) If the -feature you'd like to see has already been requested and is open, click "add a -reaction" in the top right corner of the issue and add a thumbs up (+1). This -ensures that the issue has a better chance of receiving attention. Also feel -free to add a comment with any additional justification for the feature. -(However, note that comments with no substance other than a "+1" will be -deleted. Please use GitHub's reactions feature to indicate your support.) +* First, check the GitHub [issues list](https://github.com/netbox-community/netbox/issues?q=is%3Aissue) to see if the feature you have in mind has already been proposed. If you happen to find an open feature request that matches your idea, click "add a reaction" in the top right corner of the issue and add a thumbs up (:thumbsup:). This ensures that the issue has a better chance of receiving attention. Also feel free to add a comment with any additional justification for the feature. -* Before filing a new feature request, consider raising your idea in a -[GitHub discussion](https://github.com/netbox-community/netbox/discussions) -first. Feedback you receive there will help validate and shape the proposed -feature before filing a formal issue. +* If you have a rough idea that's not quite ready for formal submission yet, start a [GitHub discussion](https://github.com/netbox-community/netbox/discussions) instead. This is a great way to test the viability and narrow down the scope of a new feature prior to submitting a formal proposal, and can serve to generate interest in your idea from other community members. -* Good feature requests are very narrowly defined. Be sure to thoroughly -describe the functionality and data model(s) being proposed. The more effort -you put into writing a feature request, the better its chance is of being -implemented. Overly broad feature requests will be closed. +* Once you're ready, submit a feature request [using this template](https://github.com/netbox-community/netbox/issues/new?label=type%3A+feature&template=feature_request.yaml). Be sure to provide sufficient context and detail to convey exactly what you're proposing and why. The stronger your use case, the better chance your proposal has of being accepted. -* When submitting a feature request on GitHub, be sure to include all -information requested by the issue template, including: +* Some other tips to keep in mind: + * Don't prepend your issue title with a label like `[Feature]`; the proper label will be assigned automatically. + * Try to anticipate any likely questions about your proposal and provide that information proactively. + * You're welcome to volunteer to implement your FR, but don't submit a pull request until it has been approved. - * A detailed description of the proposed functionality - * A use case for the feature; who would use it and what value it would add - to NetBox - * A rough description of changes necessary to the database schema (if - applicable) - * Any third-party libraries or other resources which would be involved +* For more information on how feature requests are handled, please see our [issue intake policy](https://github.com/netbox-community/netbox/wiki/Issue-Intake-Policy). -* Please avoid prepending any sort of tag (e.g. "[Feature]") to the issue -title. The issue will be reviewed by a moderator after submission and the -appropriate labels will be applied for categorization. +## :arrow_heading_up: Submitting Pull Requests -* For more information on how feature requests are handled, please see our -[issue intake policy](https://github.com/netbox-community/netbox/wiki/Issue-Intake-Policy). +* [Pull requests](https://docs.github.com/en/pull-requests) (a feature of GitHub) are used to propose changes to NetBox's code base. Our process generally goes like this: + * A user opens a new issue (bug report or feature request) + * A maintainer triages the issue and may mark it as needing an owner + * The issue's author can volunteer to own it, or someone else can + * A maintainer assigns the issue to whomever volunteers + * The issue owner submits a pull request that will resolve the issue + * A maintainer reviews and merges the pull request, closing the issue -## Submitting Pull Requests +* It's very important that you not submit a pull request until a relevant issue has been opened **and** assigned to you. Otherwise, you risk wasting time on work that may ultimately not be needed. -* If you're interested in contributing to NetBox, be sure to check out our -[getting started](https://docs.netbox.dev/en/stable/development/getting-started/) -documentation for tips on setting up your development environment. +* New pull requests should generally be based off of the `develop` branch, rather than `master`. The `develop` branch is used for ongoing development, while `master` is used for tracking stable releases. (If you're developing for an upcoming minor release, use `feature` instead.) -* Be sure to open an issue and wait for it to be assigned to you **before** -starting work on a pull request, and discuss your idea with the NetBox -maintainers before beginning work. This will help prevent wasting time on -proposed changes that we might not be able to accept. When suggesting a new -feature, also make sure it won't conflict with any work that's already in -progress. +* In most cases, it is not necessary to add a changelog entry: A maintainer will take care of this when the PR is merged. (This helps avoid merge conflicts resulting from multiple PRs being submitted simultaneously.) -* Once you've opened or identified an issue you'd like to work on, ask that it -be assigned to you so that others are aware it's being worked on. If it meets -the acceptance criteria, a maintainer will then mark the issue as "accepted" -and assign it to you. (Note that GitHub requires that a user first comment on -an issue before it can be assigned to that user.) - -* Any pull request which does not relate to an **assigned** issue will be -closed. - -* All new functionality must include relevant tests where applicable. - -* When submitting a pull request, please be sure to work off of the `develop` -branch, rather than `master`. The `develop` branch is used for ongoing -development, while `master` is used for tagging stable releases. (If you're -developing for the next minor release, use `feature` instead.) - -* In most cases, it is not necessary to add a changelog entry: A maintainer will -take care of this when the PR is merged. (This helps avoid merge conflicts -resulting from multiple PRs being submitted simultaneously.) - -* All code submissions should meet the following criteria (CI will enforce -these checks): - - * Python syntax is valid - * All tests pass when run with `./manage.py test` - * PEP 8 compliance is enforced, with the exception that lines may be +* All code submissions should meet the following criteria (CI will enforce these checks): + * Python syntax is valid + * All tests pass when run with `./manage.py test` + * PEP 8 compliance is enforced, with the exception that lines may be greater than 80 characters in length -## Commenting +* Some other tips to keep in mind: + * If you'd like to volunteer for someone else's issue, please post a comment on that issue letting us know. (This will allow the maintainers to assign it to you.) + * Check out our [developer docs](https://docs.netbox.dev/en/stable/development/getting-started/) for tips on setting up your development environment. + * All new functionality must include relevant tests where applicable. -Only comment on an issue if you are sharing a relevant idea or constructive -feedback. **Do not** comment on an issue just to show your support (give the -top post a :+1: instead) or to ask for an update. Doing so generates -unnecessary noise in the discussion, and is especially annoying for people who -have subscribed to updates for the issue. Any comments without substance -relevant to the discussion will be deleted. +## :jigsaw: Creating Plugins -## Issue Lifecycle +Do you have an idea for something you'd like to build in NetBox, but might not be right for the core project? NetBox includes a powerful and extensive [plugins framework](https://docs.netbox.dev/en/stable/plugins/) that enables users to develop their own custom data models and integrations. -New issues are handled according to our [issue intake policy](https://github.com/netbox-community/netbox/wiki/Issue-Intake-Policy). -Maintainers will assign label(s) and/or close new issues as the policy -dictates. This helps ensure a productive development environment and avoid -accumulating a large backlog of work. +Check out our [plugin development tutorial](https://github.com/netbox-community/netbox-plugin-tutorial) to get started! -The core maintainers group has chosen to make use of GitHub's [Stale bot](https://github.com/apps/stale) -to aid in issue management. +## :rescue_worker_helmet: Become a Maintainer -* Issues will be marked as stale after 60 days of no activity. -* If the stable label is not removed in the following 30 days, the issue will - be closed automatically. -* Any issue bearing one of the following labels will be exempt from all Stale - bot actions: - * `status: accepted` - * `status: blocked` - * `status: needs milestone` +We're always looking for motivated individuals to join the maintainers team and help drvie NetBox's long-term development. Some of our most sought-after skills include: -It is natural that some new issues get more attention than others. The stale -bot helps bring renewed attention to potentially valuable issues that may have -been overlooked. **Do not** comment on a stale issue merely to "bump" it in an -effort to circumvent the bot: This will result in the immediate closure of the -issue, and you may be barred from participating in future discussions. +* Python development with a strong focus on the [Django](https://www.djangoproject.com/) framework +* Javascript & TypeScript proficiency +* A knack for web application design (HTML & CSS) +* Familiarity with git and software development best practices +* Excellent attention to detail +* Working experience in the field of network operations & engineering -## Maintainer Guidance +We generally ask that maintainers dedicate around four hours of work to the project each week on average, which includes both hands-on development and project management tasks such as issue triage. Maintainers are also encouraged (but not required) to attend our bi-weekly Zoom call to catch up on recent items. -* Maintainers are expected to contribute at least four hours per week to the - project on average. This can be employer-sponsored or individual time, with - the understanding that all contributions are submitted under the Apache 2.0 - license and that your employer may not make claim to any contributions. - Contributions include code work, issue management, and community support. All - development must be in accordance with our [development guidance](https://docs.netbox.dev/en/stable/development/). +Many maintainers petition their employer to grant some of their paid time to work on NetBox. In doing so, your employer becomes eligible to be featured as a [NetBox sponsor](https://github.com/netbox-community/netbox/wiki/Sponsorship). -* Maintainers are expected to attend (where feasible) our biweekly ~30-minute - sync to review agenda items. This meeting provides opportunity to present and - discuss pressing topics. Meetings are held as virtual audio/video conferences. +Interested? You can contact our lead maintainer, Jeremy Stretch, at jeremy@netbox.dev or on the [NetDev Community Slack](https://netdev.chat/). We'd love to have you on the team! -* Maintainers with no substantial recorded activity in a 60-day period will be - removed from the project. +## :heart: Other Ways to Contribute + +You don't have to be a developer to contribute to NetBox: There are plenty of other ways you can add value to the community! Below are just a few examples: + +* Help answer questions and provide feedback in our [GitHub discussions](https://github.com/netbox-community/netbox/discussions) and on [Slack](https://netdev.chat/). +* Write a blog article or record a YouTube video demonstrating how NetBox is used at your organization. +* Help grow our [library of device & module type definitions](https://github.com/netbox-community/devicetype-library). From 7fe57d6d3d113842cb91fc7bd5b56e5db8e551a6 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 10 Jan 2023 15:47:33 -0500 Subject: [PATCH 22/46] Add items to contributing guide --- CONTRIBUTING.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6fd01164e..6b71fb515 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,6 +33,7 @@ Some general tips for engaging here on GitHub: * Error messages and screenshots are especially helpful. * Don't prepend your issue title with a label like `[Bug]`; the proper label will be assigned automatically. * Ensure that your reproduction instructions don't reference data in our [demo instance](https://demo.netbox.dev/), which gets rebuilt nightly. + * Verify that you have GitHub notifications enabled and are subscribed to your issue after submitting. * We appreciate your patience as bugs are prioritized by their severity, impact, and difficulty to resolve. * For more information on how bug reports are handled, please see our [issue @@ -49,6 +50,7 @@ intake policy](https://github.com/netbox-community/netbox/wiki/Issue-Intake-Poli * Some other tips to keep in mind: * Don't prepend your issue title with a label like `[Feature]`; the proper label will be assigned automatically. * Try to anticipate any likely questions about your proposal and provide that information proactively. + * Verify that you have GitHub notifications enabled and are subscribed to your issue after submitting. * You're welcome to volunteer to implement your FR, but don't submit a pull request until it has been approved. * For more information on how feature requests are handled, please see our [issue intake policy](https://github.com/netbox-community/netbox/wiki/Issue-Intake-Policy). @@ -88,9 +90,10 @@ Check out our [plugin development tutorial](https://github.com/netbox-community/ ## :rescue_worker_helmet: Become a Maintainer -We're always looking for motivated individuals to join the maintainers team and help drvie NetBox's long-term development. Some of our most sought-after skills include: +We're always looking for motivated individuals to join the maintainers team and help drive NetBox's long-term development. Some of our most sought-after skills include: * Python development with a strong focus on the [Django](https://www.djangoproject.com/) framework +* Expertise working with PostgreSQL databases * Javascript & TypeScript proficiency * A knack for web application design (HTML & CSS) * Familiarity with git and software development best practices From af396678d64942bc56f4649646937e255a2d28fa Mon Sep 17 00:00:00 2001 From: Jonathan Senecal Date: Wed, 11 Jan 2023 09:45:28 -0500 Subject: [PATCH 23/46] Update ipaddress.md Missing `ipam` before `IPAddress.status` --- docs/models/ipam/ipaddress.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/models/ipam/ipaddress.md b/docs/models/ipam/ipaddress.md index ecfdc4b96..6c6e025f8 100644 --- a/docs/models/ipam/ipaddress.md +++ b/docs/models/ipam/ipaddress.md @@ -23,7 +23,7 @@ The IPv4 or IPv6 address and mask, in CIDR notation (e.g. `192.0.2.0/24`). The operational status of the IP address. !!! tip - Additional statuses may be defined by setting `IPAddress.status` under the [`FIELD_CHOICES`](../../configuration/data-validation.md#field_choices) configuration parameter. + Additional statuses may be defined by setting `ipam.IPAddress.status` under the [`FIELD_CHOICES`](../../configuration/data-validation.md#field_choices) configuration parameter. ### Role From ad83318ef8f80fe7d02a8b659f669e16fb1cca53 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 11 Jan 2023 14:42:25 -0500 Subject: [PATCH 24/46] Fixes #10201: Fix AssertionError exception when removing some terminations from an existing cable --- docs/release-notes/version-3.4.md | 1 + netbox/dcim/signals.py | 3 ++ netbox/dcim/tests/test_cablepaths.py | 41 ++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/docs/release-notes/version-3.4.md b/docs/release-notes/version-3.4.md index e5b230018..83e7751aa 100644 --- a/docs/release-notes/version-3.4.md +++ b/docs/release-notes/version-3.4.md @@ -12,6 +12,7 @@ ### Bug Fixes +* [#10201](https://github.com/netbox-community/netbox/issues/10201) - Fix AssertionError exception when removing some terminations from an existing cable * [#11210](https://github.com/netbox-community/netbox/issues/11210) - Fix ValueError exception when attempting to bulk import cables attached to occupied terminations * [#11340](https://github.com/netbox-community/netbox/issues/11340) - Avoid flagging cable termination changes erroneously * [#11379](https://github.com/netbox-community/netbox/issues/11379) - Fix TypeError exception when bulk editing custom date fields diff --git a/netbox/dcim/signals.py b/netbox/dcim/signals.py index 522bb76c0..7ef08d2cc 100644 --- a/netbox/dcim/signals.py +++ b/netbox/dcim/signals.py @@ -124,6 +124,9 @@ def nullify_connected_endpoints(instance, **kwargs): model.objects.filter(pk=instance.termination_id).update(cable=None, cable_end='') for cablepath in CablePath.objects.filter(_nodes__contains=instance.cable): + # Remove the deleted CableTermination if it's one of the path's originating nodes + if instance.termination in cablepath.origins: + cablepath.origins.remove(instance.termination) cablepath.retrace() diff --git a/netbox/dcim/tests/test_cablepaths.py b/netbox/dcim/tests/test_cablepaths.py index 50a707bc6..3367a3efe 100644 --- a/netbox/dcim/tests/test_cablepaths.py +++ b/netbox/dcim/tests/test_cablepaths.py @@ -1804,3 +1804,44 @@ class CablePathTestCase(TestCase): is_active=True ) self.assertEqual(CablePath.objects.count(), 2) + + def test_303_remove_termination_from_existing_cable(self): + """ + [IF1] --C1-- [IF2] + [IF3] + """ + interface1 = Interface.objects.create(device=self.device, name='Interface 1') + interface2 = Interface.objects.create(device=self.device, name='Interface 2') + interface3 = Interface.objects.create(device=self.device, name='Interface 3') + + # Create cables 1 + cable1 = Cable( + a_terminations=[interface1], + b_terminations=[interface2, interface3] + ) + cable1.save() + self.assertPathExists( + (interface1, cable1, [interface2, interface3]), + is_complete=True, + is_active=True + ) + self.assertPathExists( + ([interface2, interface3], cable1, interface1), + is_complete=True, + is_active=True + ) + + # Remove the termination to interface 3 + cable1 = Cable.objects.first() + cable1.b_terminations = [interface2] + cable1.save() + self.assertPathExists( + (interface1, cable1, interface2), + is_complete=True, + is_active=True + ) + self.assertPathExists( + (interface2, cable1, interface1), + is_complete=True, + is_active=True + ) From abccd68b507f410eff0d93f52a9a68cb6ae11d54 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 6 Jan 2023 08:51:26 -0800 Subject: [PATCH 25/46] 11416 fix circuit termination deletion --- netbox/dcim/models/cables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/models/cables.py b/netbox/dcim/models/cables.py index 6fd99d18a..062734355 100644 --- a/netbox/dcim/models/cables.py +++ b/netbox/dcim/models/cables.py @@ -537,7 +537,7 @@ class CablePath(models.Model): # Step 5: Record the far-end termination object(s) path.append([ - object_to_path_node(t) for t in remote_terminations + object_to_path_node(t) for t in remote_terminations if t is not None ]) # Step 6: Determine the "next hop" terminations, if applicable From 0fb1db6ed7be0d1365d3306e377bc3fc285d2de7 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 12 Jan 2023 09:05:55 -0500 Subject: [PATCH 26/46] Fixes #11467: Correct count on interfaces tab when viewing a VC master device --- docs/release-notes/version-3.4.md | 1 + netbox/dcim/views.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.4.md b/docs/release-notes/version-3.4.md index 83e7751aa..b524176cf 100644 --- a/docs/release-notes/version-3.4.md +++ b/docs/release-notes/version-3.4.md @@ -21,6 +21,7 @@ * [#11403](https://github.com/netbox-community/netbox/issues/11403) - Fix exception when scheduling a job in the past * [#11438](https://github.com/netbox-community/netbox/issues/11438) - Fix deletion of scheduled job using non-default queues * [#11444](https://github.com/netbox-community/netbox/issues/11444) - Adding/removing a device from a device bay should record a pre-change snapshot on the device bay +* [#11467](https://github.com/netbox-community/netbox/issues/11467) - Correct count on interfaces tab when viewing a VC master device --- diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 13222313c..794d58d1e 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1949,7 +1949,7 @@ class DeviceInterfacesView(DeviceComponentsView): template_name = 'dcim/device/interfaces.html' tab = ViewTab( label=_('Interfaces'), - badge=lambda obj: obj.interfaces.count(), + badge=lambda obj: obj.vc_interfaces().count(), permission='dcim.view_interface', weight=520, hide_if_empty=True From efc7ad190e20ef48c7eb0998205e2178cb3c4699 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 12 Jan 2023 09:37:52 -0500 Subject: [PATCH 27/46] Changelog for #11416 --- docs/release-notes/version-3.4.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/version-3.4.md b/docs/release-notes/version-3.4.md index b524176cf..f0ce62b92 100644 --- a/docs/release-notes/version-3.4.md +++ b/docs/release-notes/version-3.4.md @@ -19,6 +19,7 @@ * [#11384](https://github.com/netbox-community/netbox/issues/11384) - Correct current time display on script & report forms * [#11402](https://github.com/netbox-community/netbox/issues/11402) - Avoid LookupError exception when running scripts with commit disabled * [#11403](https://github.com/netbox-community/netbox/issues/11403) - Fix exception when scheduling a job in the past +* [#11416](https://github.com/netbox-community/netbox/issues/11416) - Avoid AttributeError exception when deleting a cabled circuit termination * [#11438](https://github.com/netbox-community/netbox/issues/11438) - Fix deletion of scheduled job using non-default queues * [#11444](https://github.com/netbox-community/netbox/issues/11444) - Adding/removing a device from a device bay should record a pre-change snapshot on the device bay * [#11467](https://github.com/netbox-community/netbox/issues/11467) - Correct count on interfaces tab when viewing a VC master device From 1bb6032b95e11e70e9b20e16421a2554bde220cd Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 13 Jan 2023 08:23:57 -0500 Subject: [PATCH 28/46] Fixes #11483: Apply configured formatting to custom date fields --- docs/release-notes/version-3.4.md | 1 + netbox/utilities/templates/builtins/customfield_value.html | 3 +++ 2 files changed, 4 insertions(+) diff --git a/docs/release-notes/version-3.4.md b/docs/release-notes/version-3.4.md index f0ce62b92..f4be8190d 100644 --- a/docs/release-notes/version-3.4.md +++ b/docs/release-notes/version-3.4.md @@ -23,6 +23,7 @@ * [#11438](https://github.com/netbox-community/netbox/issues/11438) - Fix deletion of scheduled job using non-default queues * [#11444](https://github.com/netbox-community/netbox/issues/11444) - Adding/removing a device from a device bay should record a pre-change snapshot on the device bay * [#11467](https://github.com/netbox-community/netbox/issues/11467) - Correct count on interfaces tab when viewing a VC master device +* [#11483](https://github.com/netbox-community/netbox/issues/11483) - Apply configured formatting to custom date fields --- diff --git a/netbox/utilities/templates/builtins/customfield_value.html b/netbox/utilities/templates/builtins/customfield_value.html index ff93a5168..b3bccd716 100644 --- a/netbox/utilities/templates/builtins/customfield_value.html +++ b/netbox/utilities/templates/builtins/customfield_value.html @@ -1,3 +1,4 @@ +{% load helpers %} {% if customfield.type == 'integer' and value is not None %} {{ value }} {% elif customfield.type == 'longtext' and value %} @@ -6,6 +7,8 @@ {% checkmark value true="True" %} {% elif customfield.type == 'boolean' and value == False %} {% checkmark value false="False" %} +{% elif customfield.type == 'date' and value %} + {{ value|annotated_date }} {% elif customfield.type == 'url' and value %} {{ value|truncatechars:70 }} {% elif customfield.type == 'json' and value %} From 8620695afa3f37c391314af09dc2a78c006d4c1a Mon Sep 17 00:00:00 2001 From: kkthxbye-code Date: Fri, 13 Jan 2023 22:12:12 +0100 Subject: [PATCH 29/46] Check for the extras.run_script permission when running scripts via. the API --- netbox/extras/api/views.py | 4 ++++ netbox/extras/tests/test_api.py | 1 + 2 files changed, 5 insertions(+) diff --git a/netbox/extras/api/views.py b/netbox/extras/api/views.py index 56bc8567d..1423824cd 100644 --- a/netbox/extras/api/views.py +++ b/netbox/extras/api/views.py @@ -318,6 +318,10 @@ class ScriptViewSet(ViewSet): """ Run a Script identified as ".