From 43914c9c1bab40471bc01e06d888e5c8b548d97d Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 12 Apr 2021 13:29:37 -0400 Subject: [PATCH 01/19] PRVB --- 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 d647c0a0e..233ee72c4 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.10.9' +VERSION = '2.10.10-dev' # Hostname HOSTNAME = platform.node() From 3ecd2d8a76b0c6b3f47d9a986240571b0229fc66 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 12 Apr 2021 13:53:38 -0400 Subject: [PATCH 02/19] Change stale issues management to GitHub Actions --- .github/stale.yml | 30 ------------------------------ .github/workflows/stale.yml | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 30 deletions(-) delete mode 100644 .github/stale.yml create mode 100644 .github/workflows/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index 92da07e6a..000000000 --- a/.github/stale.yml +++ /dev/null @@ -1,30 +0,0 @@ -# Configuration for Stale (https://github.com/apps/stale) - -# Number of days of inactivity before an issue becomes stale -daysUntilStale: 45 - -# Number of days of inactivity before a stale issue is closed -daysUntilClose: 15 - -# Issues with these labels will never be considered stale -exemptLabels: - - "status: accepted" - - "status: blocked" - - "status: needs milestone" - -# Label to use when marking an issue as stale -staleLabel: "pending closure" - -# Comment to post when marking an issue as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. NetBox - is governed by a small group of core maintainers which means not all opened - issues may receive direct feedback. Please see our [contributing guide](https://github.com/netbox-community/netbox/blob/develop/CONTRIBUTING.md). - -# Comment to post when closing a stale issue. Set to `false` to disable -closeComment: > - This issue has been automatically closed due to lack of activity. In an - effort to reduce noise, please do not comment any further. Note that the - core maintainers may elect to reopen this issue at a later date if deemed - necessary. diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 000000000..1cd85d867 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,34 @@ +name: 'Close stale issues and PRs' +on: + schedule: + - cron: '0 4 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + debug-only: true + close-issue-message: > + This issue has been automatically closed due to lack of activity. In an + effort to reduce noise, please do not comment any further. Note that the + core maintainers may elect to reopen this issue at a later date if deemed + necessary. + close-pr-message: > + This PR has been automatically closed due to lack of activity. + days-before-stale: 45 + days-before-close: 15 + exempt-issue-labels: "status: accepted,status: blocked,status: needs milestone" + remove-stale-when-updated: false + stale-issue-label: 'pending closure' + stale-issue-message: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. NetBox + is governed by a small group of core maintainers which means not all opened + issues may receive direct feedback. Please see our [contributing guide](https://github.com/netbox-community/netbox/blob/develop/CONTRIBUTING.md). + stale-pr-label: "pending closure" + stale-pr-message: > + This PR has been automatically marked as stale because it has not had + recent activity. It will be closed automatically if no further action is + taken. From 53da02f3a8730fed17a4dd00502080546ea5e7c5 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 12 Apr 2021 15:06:40 -0400 Subject: [PATCH 03/19] Removed the "Additional information" blocks from issue templates (no longer needed) --- .github/ISSUE_TEMPLATE/bug_report.yaml | 5 ----- .github/ISSUE_TEMPLATE/documentation_change.yaml | 5 ----- .github/ISSUE_TEMPLATE/feature_request.yaml | 5 ----- .github/ISSUE_TEMPLATE/housekeeping.yaml | 5 ----- 4 files changed, 20 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index a83e9b34e..a37c5dfb1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -56,8 +56,3 @@ body: placeholder: "A TypeError exception was raised" validations: required: true - - type: markdown - attributes: - value: | - ### Additional information - You can use the space below to provide any additional information or to attach files. diff --git a/.github/ISSUE_TEMPLATE/documentation_change.yaml b/.github/ISSUE_TEMPLATE/documentation_change.yaml index bff755719..b480e629a 100644 --- a/.github/ISSUE_TEMPLATE/documentation_change.yaml +++ b/.github/ISSUE_TEMPLATE/documentation_change.yaml @@ -33,8 +33,3 @@ body: description: "Describe the proposed changes and why they are necessary" validations: required: true - - type: markdown - attributes: - value: | - ### Additional information - You can use the space below to provide any additional information or to attach files. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index efa83b376..6282eedde 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -51,8 +51,3 @@ body: description: "List any new dependencies on external libraries or services that this new feature would introduce. For example, does the proposal require the installation of a new Python package? (Not all new features introduce new dependencies.)" - - type: markdown - attributes: - value: | - ### Additional information - You can use the space below to provide any additional information or to attach files. diff --git a/.github/ISSUE_TEMPLATE/housekeeping.yaml b/.github/ISSUE_TEMPLATE/housekeeping.yaml index 0f466aa24..778dca235 100644 --- a/.github/ISSUE_TEMPLATE/housekeeping.yaml +++ b/.github/ISSUE_TEMPLATE/housekeeping.yaml @@ -20,8 +20,3 @@ body: description: "Please provide justification for the proposed change(s)." validations: required: true - - type: markdown - attributes: - value: | - ### Additional information - You can use the space below to provide any additional information or to attach files. From 5ad4cd0c12f4e01d5f6a7e9d3d8ef2e7bb6ce400 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 12 Apr 2021 15:17:50 -0400 Subject: [PATCH 04/19] Fix link --- docs/rest-api/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rest-api/overview.md b/docs/rest-api/overview.md index 735e0713b..088286e22 100644 --- a/docs/rest-api/overview.md +++ b/docs/rest-api/overview.md @@ -387,7 +387,7 @@ curl -s -X GET http://netbox/api/ipam/ip-addresses/5618/ | jq '.' ### Creating a New Object -To create a new object, make a `POST` request to the model's _list_ endpoint with JSON data pertaining to the object being created. Note that a REST API token is required for all write operations; see the [authentication documentation](../authentication/index.md) for more information. Also be sure to set the `Content-Type` HTTP header to `application/json`. +To create a new object, make a `POST` request to the model's _list_ endpoint with JSON data pertaining to the object being created. Note that a REST API token is required for all write operations; see the [authentication documentation](authentication.md) for more information. Also be sure to set the `Content-Type` HTTP header to `application/json`. ```no-highlight curl -s -X POST \ From 04eefbe7111c1b13ae8db736e04dd93a082943e7 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 13 Apr 2021 11:46:14 -0400 Subject: [PATCH 05/19] Enable close-stale-issue action --- .github/workflows/stale.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 1cd85d867..8fc85ead6 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,4 +1,5 @@ -name: 'Close stale issues and PRs' +# close-stale-issues (https://github.com/marketplace/actions/close-stale-issues) +name: 'Close stale issues/PRs' on: schedule: - cron: '0 4 * * *' @@ -9,7 +10,6 @@ jobs: steps: - uses: actions/stale@v3 with: - debug-only: true close-issue-message: > This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the @@ -19,7 +19,7 @@ jobs: This PR has been automatically closed due to lack of activity. days-before-stale: 45 days-before-close: 15 - exempt-issue-labels: "status: accepted,status: blocked,status: needs milestone" + exempt-issue-labels: 'status: accepted,status: blocked,status: needs milestone' remove-stale-when-updated: false stale-issue-label: 'pending closure' stale-issue-message: > @@ -27,7 +27,7 @@ jobs: recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Please see our [contributing guide](https://github.com/netbox-community/netbox/blob/develop/CONTRIBUTING.md). - stale-pr-label: "pending closure" + stale-pr-label: 'pending closure' stale-pr-message: > This PR has been automatically marked as stale because it has not had recent activity. It will be closed automatically if no further action is From ccefadc053858186f68de3313e52d51005496b86 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 13 Apr 2021 11:52:32 -0400 Subject: [PATCH 06/19] Fixes #6144: Fix MAC address field display in VM interfaces search form --- docs/release-notes/version-2.10.md | 8 ++++++++ netbox/virtualization/forms.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index d2ce57484..2ea0b7bbf 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -1,5 +1,13 @@ # NetBox v2.10 +## v2.10.10 (FUTURE) + +### Bug Fixes + +* [#6144](https://github.com/netbox-community/netbox/issues/6144) - Fix MAC address field display in VM interfaces search form + +--- + ## v2.10.9 (2021-04-12) ### Enhancements diff --git a/netbox/virtualization/forms.py b/netbox/virtualization/forms.py index 20d0e4ad8..a3e6c4cf4 100644 --- a/netbox/virtualization/forms.py +++ b/netbox/virtualization/forms.py @@ -765,7 +765,7 @@ class VMInterfaceBulkRenameForm(BulkRenameForm): ) -class VMInterfaceFilterForm(forms.Form): +class VMInterfaceFilterForm(BootstrapMixin, forms.Form): model = VMInterface cluster_id = DynamicModelMultipleChoiceField( queryset=Cluster.objects.all(), From 98213054821212abde2a1f0804a4dcf124bf1549 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 13 Apr 2021 12:05:44 -0400 Subject: [PATCH 07/19] Fixes #6152: Fix custom field filtering for cables, virtual chassis --- docs/release-notes/version-2.10.md | 1 + netbox/dcim/filters.py | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 2ea0b7bbf..974eb00b0 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -5,6 +5,7 @@ ### Bug Fixes * [#6144](https://github.com/netbox-community/netbox/issues/6144) - Fix MAC address field display in VM interfaces search form +* [#6152](https://github.com/netbox-community/netbox/issues/6152) - Fix custom field filtering for cables, virtual chassis --- diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index 9c8a8a79a..dff552910 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -1,6 +1,5 @@ import django_filters from django.contrib.auth.models import User -from django.db.models import Count from extras.filters import CustomFieldModelFilterSet, LocalConfigContextFilterSet, CreatedUpdatedFilterSet from tenancy.filters import TenancyFilterSet @@ -1011,7 +1010,7 @@ class InventoryItemFilterSet(BaseFilterSet, DeviceComponentFilterSet): return queryset.filter(qs_filter) -class VirtualChassisFilterSet(BaseFilterSet): +class VirtualChassisFilterSet(BaseFilterSet, CustomFieldModelFilterSet): q = django_filters.CharFilter( method='search', label='Search', @@ -1078,7 +1077,7 @@ class VirtualChassisFilterSet(BaseFilterSet): return queryset.filter(qs_filter).distinct() -class CableFilterSet(BaseFilterSet): +class CableFilterSet(BaseFilterSet, CustomFieldModelFilterSet): q = django_filters.CharFilter( method='search', label='Search', From 3ce42008cf8cfc531b14b8170e9c793e461fd86d Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 13 Apr 2021 13:23:25 -0400 Subject: [PATCH 08/19] Fixes #5419: Update parent device/VM when deleting a primary IP --- docs/release-notes/version-2.10.md | 1 + netbox/ipam/apps.py | 3 +++ netbox/ipam/signals.py | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 netbox/ipam/signals.py diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 974eb00b0..2675bac5f 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -4,6 +4,7 @@ ### Bug Fixes +* [#5419](https://github.com/netbox-community/netbox/issues/5419) - Update parent device/VM when deleting a primary IP * [#6144](https://github.com/netbox-community/netbox/issues/6144) - Fix MAC address field display in VM interfaces search form * [#6152](https://github.com/netbox-community/netbox/issues/6152) - Fix custom field filtering for cables, virtual chassis diff --git a/netbox/ipam/apps.py b/netbox/ipam/apps.py index fd4af74b0..413c8c1bc 100644 --- a/netbox/ipam/apps.py +++ b/netbox/ipam/apps.py @@ -4,3 +4,6 @@ from django.apps import AppConfig class IPAMConfig(AppConfig): name = "ipam" verbose_name = "IPAM" + + def ready(self): + import ipam.signals diff --git a/netbox/ipam/signals.py b/netbox/ipam/signals.py new file mode 100644 index 000000000..a8fce8310 --- /dev/null +++ b/netbox/ipam/signals.py @@ -0,0 +1,21 @@ +from django.db.models.signals import pre_delete +from django.dispatch import receiver + +from dcim.models import Device +from virtualization.models import VirtualMachine +from .models import IPAddress + + +@receiver(pre_delete, sender=IPAddress) +def clear_primary_ip(instance, **kwargs): + """ + When an IPAddress is deleted, trigger save() on any Devices/VirtualMachines for which it + was a primary IP. + """ + field_name = f'primary_ip{instance.family}' + device = Device.objects.filter(**{field_name: instance}).first() + if device: + device.save() + virtualmachine = VirtualMachine.objects.filter(**{field_name: instance}).first() + if virtualmachine: + virtualmachine.save() From 79568fd65321f02795023d8e0fe3b72abfc90cd7 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 13 Apr 2021 13:48:22 -0400 Subject: [PATCH 09/19] Fixes #6056: Optimize change log cleanup --- docs/release-notes/version-2.10.md | 1 + netbox/extras/signals.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 2675bac5f..69db03724 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -5,6 +5,7 @@ ### Bug Fixes * [#5419](https://github.com/netbox-community/netbox/issues/5419) - Update parent device/VM when deleting a primary IP +* [#6056](https://github.com/netbox-community/netbox/issues/6056) - Optimize change log cleanup * [#6144](https://github.com/netbox-community/netbox/issues/6144) - Fix MAC address field display in VM interfaces search form * [#6152](https://github.com/netbox-community/netbox/issues/6152) - Fix custom field filtering for cables, virtual chassis diff --git a/netbox/extras/signals.py b/netbox/extras/signals.py index 0d6295e5b..9eeb4ce45 100644 --- a/netbox/extras/signals.py +++ b/netbox/extras/signals.py @@ -4,6 +4,7 @@ from datetime import timedelta from cacheops.signals import cache_invalidated, cache_read from django.conf import settings from django.contrib.contenttypes.models import ContentType +from django.db import DEFAULT_DB_ALIAS from django.db.models.signals import m2m_changed, pre_delete from django.utils import timezone from django_prometheus.models import model_deletes, model_inserts, model_updates @@ -52,7 +53,7 @@ def _handle_changed_object(request, sender, instance, **kwargs): # Housekeeping: 0.1% chance of clearing out expired ObjectChanges if settings.CHANGELOG_RETENTION and random.randint(1, 1000) == 1: cutoff = timezone.now() - timedelta(days=settings.CHANGELOG_RETENTION) - ObjectChange.objects.filter(time__lt=cutoff).delete() + ObjectChange.objects.filter(time__lt=cutoff)._raw_delete(using=DEFAULT_DB_ALIAS) def _handle_deleted_object(request, sender, instance, **kwargs): From cf72df00a4b19cf5acee49362ac41c528e5fa806 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 14 Apr 2021 10:21:07 -0400 Subject: [PATCH 10/19] Closes #6157: Support Markdown rendering for report logs --- docs/release-notes/version-2.10.md | 4 ++++ netbox/templates/extras/report_result.html | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 69db03724..8b1d367ef 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -2,6 +2,10 @@ ## v2.10.10 (FUTURE) +### Enhancements + +* [#6157](https://github.com/netbox-community/netbox/issues/6157) - Support Markdown rendering for report logs + ### Bug Fixes * [#5419](https://github.com/netbox-community/netbox/issues/5419) - Update parent device/VM when deleting a primary IP diff --git a/netbox/templates/extras/report_result.html b/netbox/templates/extras/report_result.html index 80715f2aa..3d01ca38e 100644 --- a/netbox/templates/extras/report_result.html +++ b/netbox/templates/extras/report_result.html @@ -66,9 +66,11 @@ {{ obj }} {% elif obj %} {{ obj }} + {% else %} + {% endif %} - {{ message }} + {{ message|render_markdown }} {% endfor %} {% endfor %} From f78345dd82c9ec053294f727598ef459dde55a2a Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 14 Apr 2021 10:38:54 -0400 Subject: [PATCH 11/19] Closes #6160: Add F connector port type --- docs/release-notes/version-2.10.md | 1 + netbox/dcim/choices.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 8b1d367ef..6fccdaf00 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -5,6 +5,7 @@ ### Enhancements * [#6157](https://github.com/netbox-community/netbox/issues/6157) - Support Markdown rendering for report logs +* [#6160](https://github.com/netbox-community/netbox/issues/6160) - Add F connector port type ### Bug Fixes diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index ee832b085..57f288531 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -881,6 +881,7 @@ class PortTypeChoices(ChoiceSet): TYPE_TERA1P = 'tera-1p' TYPE_110_PUNCH = '110-punch' TYPE_BNC = 'bnc' + TYPE_F = 'f' TYPE_MRJ21 = 'mrj21' TYPE_ST = 'st' TYPE_SC = 'sc' @@ -910,6 +911,7 @@ class PortTypeChoices(ChoiceSet): (TYPE_TERA1P, 'TERA 1P'), (TYPE_110_PUNCH, '110 Punch'), (TYPE_BNC, 'BNC'), + (TYPE_F, 'F Connector'), (TYPE_MRJ21, 'MRJ21'), ), ), From 64a23f966b38113d177b3e77b2a8b727c097cdec Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 14 Apr 2021 10:40:31 -0400 Subject: [PATCH 12/19] Closes #5980: Add Saf-D-Grid power port, outlet types --- docs/release-notes/version-2.10.md | 1 + netbox/dcim/choices.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 6fccdaf00..4ad08ea61 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -4,6 +4,7 @@ ### Enhancements +* [#5980](https://github.com/netbox-community/netbox/issues/5980) - Add Saf-D-Grid power port, outlet types * [#6157](https://github.com/netbox-community/netbox/issues/6157) - Support Markdown rendering for report logs * [#6160](https://github.com/netbox-community/netbox/issues/6160) - Add F connector port type diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index 57f288531..bd4ae1831 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -314,6 +314,8 @@ class PowerPortTypeChoices(ChoiceSet): TYPE_USB_MICRO_B = 'usb-micro-b' TYPE_USB_3_B = 'usb-3-b' TYPE_USB_3_MICROB = 'usb-3-micro-b' + # Proprietary + TYPE_SAF_D_GRID = 'saf-d-grid' CHOICES = ( ('IEC 60320', ( @@ -414,6 +416,9 @@ class PowerPortTypeChoices(ChoiceSet): (TYPE_USB_3_B, 'USB 3.0 Type B'), (TYPE_USB_3_MICROB, 'USB 3.0 Micro B'), )), + ('Proprietary', ( + (TYPE_SAF_D_GRID, 'Saf-D-Grid'), + )), ) @@ -509,6 +514,7 @@ class PowerOutletTypeChoices(ChoiceSet): TYPE_USB_C = 'usb-c' # Proprietary TYPE_HDOT_CX = 'hdot-cx' + TYPE_SAF_D_GRID = 'saf-d-grid' CHOICES = ( ('IEC 60320', ( @@ -604,6 +610,7 @@ class PowerOutletTypeChoices(ChoiceSet): )), ('Proprietary', ( (TYPE_HDOT_CX, 'HDOT Cx'), + (TYPE_SAF_D_GRID, 'Saf-D-Grid'), )), ) From 0a9c413b1b413008f8f9c3e4da0fc814a1006cb1 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 14 Apr 2021 10:44:15 -0400 Subject: [PATCH 13/19] Closes #5796: Add DC terminal power port, outlet types --- docs/release-notes/version-2.10.md | 1 + netbox/dcim/choices.py | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 4ad08ea61..83f9d5d25 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -4,6 +4,7 @@ ### Enhancements +* [#5796](https://github.com/netbox-community/netbox/issues/5796) - Add DC terminal power port, outlet types * [#5980](https://github.com/netbox-community/netbox/issues/5980) - Add Saf-D-Grid power port, outlet types * [#6157](https://github.com/netbox-community/netbox/issues/6157) - Support Markdown rendering for report logs * [#6160](https://github.com/netbox-community/netbox/issues/6160) - Add F connector port type diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index bd4ae1831..55b7539d1 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -314,6 +314,8 @@ class PowerPortTypeChoices(ChoiceSet): TYPE_USB_MICRO_B = 'usb-micro-b' TYPE_USB_3_B = 'usb-3-b' TYPE_USB_3_MICROB = 'usb-3-micro-b' + # Direct current (DC) + TYPE_DC = 'dc-terminal' # Proprietary TYPE_SAF_D_GRID = 'saf-d-grid' @@ -416,6 +418,9 @@ class PowerPortTypeChoices(ChoiceSet): (TYPE_USB_3_B, 'USB 3.0 Type B'), (TYPE_USB_3_MICROB, 'USB 3.0 Micro B'), )), + ('DC', ( + (TYPE_DC, 'DC Terminal'), + )), ('Proprietary', ( (TYPE_SAF_D_GRID, 'Saf-D-Grid'), )), @@ -512,6 +517,8 @@ class PowerOutletTypeChoices(ChoiceSet): TYPE_USB_A = 'usb-a' TYPE_USB_MICROB = 'usb-micro-b' TYPE_USB_C = 'usb-c' + # Direct current (DC) + TYPE_DC = 'dc-terminal' # Proprietary TYPE_HDOT_CX = 'hdot-cx' TYPE_SAF_D_GRID = 'saf-d-grid' @@ -608,6 +615,9 @@ class PowerOutletTypeChoices(ChoiceSet): (TYPE_USB_MICROB, 'USB Micro B'), (TYPE_USB_C, 'USB Type C'), )), + ('DC', ( + (TYPE_DC, 'DC Terminal'), + )), ('Proprietary', ( (TYPE_HDOT_CX, 'HDOT Cx'), (TYPE_SAF_D_GRID, 'Saf-D-Grid'), From 82d074589074be33af061edfe5a404f56f467356 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 14 Apr 2021 16:17:19 -0400 Subject: [PATCH 14/19] Fixes #6162: Fix choice field filters (multiple models) --- docs/release-notes/version-2.10.md | 1 + netbox/dcim/filters.py | 32 ++++++++++++++++++++++++ netbox/dcim/tests/test_filters.py | 40 ++++++++++++------------------ 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 83f9d5d25..9c41edd2c 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -15,6 +15,7 @@ * [#6056](https://github.com/netbox-community/netbox/issues/6056) - Optimize change log cleanup * [#6144](https://github.com/netbox-community/netbox/issues/6144) - Fix MAC address field display in VM interfaces search form * [#6152](https://github.com/netbox-community/netbox/issues/6152) - Fix custom field filtering for cables, virtual chassis +* [#6162](https://github.com/netbox-community/netbox/issues/6162) - Fix choice field filters (multiple models) --- diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index dff552910..ac6ecb272 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -446,6 +446,10 @@ class PowerPortTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): class PowerOutletTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): + feed_leg = django_filters.MultipleChoiceFilter( + choices=PowerOutletFeedLegChoices, + null_value=None + ) class Meta: model = PowerOutletTemplate @@ -453,6 +457,10 @@ class PowerOutletTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): class InterfaceTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): + type = django_filters.MultipleChoiceFilter( + choices=InterfaceTypeChoices, + null_value=None + ) class Meta: model = InterfaceTemplate @@ -460,6 +468,10 @@ class InterfaceTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): class FrontPortTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): + type = django_filters.MultipleChoiceFilter( + choices=PortTypeChoices, + null_value=None + ) class Meta: model = FrontPortTemplate @@ -467,6 +479,10 @@ class FrontPortTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): class RearPortTemplateFilterSet(BaseFilterSet, DeviceTypeComponentFilterSet): + type = django_filters.MultipleChoiceFilter( + choices=PortTypeChoices, + null_value=None + ) class Meta: model = RearPortTemplate @@ -817,6 +833,10 @@ class PowerOutletFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTermina choices=PowerOutletTypeChoices, null_value=None ) + feed_leg = django_filters.MultipleChoiceFilter( + choices=PowerOutletFeedLegChoices, + null_value=None + ) class Meta: model = PowerOutlet @@ -917,6 +937,10 @@ class InterfaceFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminati class FrontPortFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet): + type = django_filters.MultipleChoiceFilter( + choices=PortTypeChoices, + null_value=None + ) class Meta: model = FrontPort @@ -924,6 +948,10 @@ class FrontPortFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminati class RearPortFilterSet(BaseFilterSet, DeviceComponentFilterSet, CableTerminationFilterSet): + type = django_filters.MultipleChoiceFilter( + choices=PortTypeChoices, + null_value=None + ) class Meta: model = RearPort @@ -1301,6 +1329,10 @@ class PowerFeedFilterSet( queryset=Rack.objects.all(), label='Rack (ID)', ) + status = django_filters.MultipleChoiceFilter( + choices=PowerFeedStatusChoices, + null_value=None + ) tag = TagFilter() class Meta: diff --git a/netbox/dcim/tests/test_filters.py b/netbox/dcim/tests/test_filters.py index 02a44bbc1..f9ab32765 100644 --- a/netbox/dcim/tests/test_filters.py +++ b/netbox/dcim/tests/test_filters.py @@ -851,9 +851,8 @@ class PowerOutletTemplateTestCase(TestCase): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_feed_leg(self): - # TODO: Support filtering for multiple values - params = {'feed_leg': PowerOutletFeedLegChoices.FEED_LEG_A} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + params = {'feed_leg': [PowerOutletFeedLegChoices.FEED_LEG_A, PowerOutletFeedLegChoices.FEED_LEG_B]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) class InterfaceTemplateTestCase(TestCase): @@ -892,9 +891,8 @@ class InterfaceTemplateTestCase(TestCase): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_type(self): - # TODO: Support filtering for multiple values - params = {'type': InterfaceTypeChoices.TYPE_1GE_FIXED} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + params = {'type': [InterfaceTypeChoices.TYPE_1GE_FIXED, InterfaceTypeChoices.TYPE_1GE_GBIC]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_mgmt_only(self): params = {'mgmt_only': 'true'} @@ -946,9 +944,8 @@ class FrontPortTemplateTestCase(TestCase): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_type(self): - # TODO: Support filtering for multiple values - params = {'type': PortTypeChoices.TYPE_8P8C} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + params = {'type': [PortTypeChoices.TYPE_8P8C, PortTypeChoices.TYPE_110_PUNCH]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) class RearPortTemplateTestCase(TestCase): @@ -987,9 +984,8 @@ class RearPortTemplateTestCase(TestCase): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_type(self): - # TODO: Support filtering for multiple values - params = {'type': PortTypeChoices.TYPE_8P8C} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + params = {'type': [PortTypeChoices.TYPE_8P8C, PortTypeChoices.TYPE_110_PUNCH]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_positions(self): params = {'positions': [1, 2]} @@ -1824,9 +1820,8 @@ class PowerOutletTestCase(TestCase): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_feed_leg(self): - # TODO: Support filtering for multiple values - params = {'feed_leg': PowerOutletFeedLegChoices.FEED_LEG_A} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + params = {'feed_leg': [PowerOutletFeedLegChoices.FEED_LEG_A, PowerOutletFeedLegChoices.FEED_LEG_B]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_connected(self): params = {'connected': True} @@ -2063,9 +2058,8 @@ class FrontPortTestCase(TestCase): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_type(self): - # TODO: Test for multiple values - params = {'type': PortTypeChoices.TYPE_8P8C} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + params = {'type': [PortTypeChoices.TYPE_8P8C, PortTypeChoices.TYPE_110_PUNCH]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_description(self): params = {'description': ['First', 'Second']} @@ -2159,9 +2153,8 @@ class RearPortTestCase(TestCase): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_type(self): - # TODO: Test for multiple values - params = {'type': PortTypeChoices.TYPE_8P8C} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + params = {'type': [PortTypeChoices.TYPE_8P8C, PortTypeChoices.TYPE_110_PUNCH]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_positions(self): params = {'positions': [1, 2]} @@ -2732,9 +2725,8 @@ class PowerFeedTestCase(TestCase): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_status(self): - # TODO: Test for multiple values - params = {'status': PowerFeedStatusChoices.STATUS_ACTIVE} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + params = {'status': [PowerFeedStatusChoices.STATUS_ACTIVE, PowerFeedStatusChoices.STATUS_FAILED]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_type(self): params = {'type': PowerFeedTypeChoices.TYPE_PRIMARY} From 66b07a6be3801c95e390c5e46e36c2fe56390c32 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 15 Apr 2021 12:04:34 -0400 Subject: [PATCH 15/19] Fixes #5652: Update object data when renaming a custom field --- docs/release-notes/version-2.10.md | 1 + netbox/extras/models/customfields.py | 18 ++++++++++++++++ netbox/extras/signals.py | 11 +++++++++- netbox/extras/tests/test_customfields.py | 27 ++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 9c41edd2c..3755944dc 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -12,6 +12,7 @@ ### Bug Fixes * [#5419](https://github.com/netbox-community/netbox/issues/5419) - Update parent device/VM when deleting a primary IP +* [#5652](https://github.com/netbox-community/netbox/issues/5652) - Update object data when renaming a custom field * [#6056](https://github.com/netbox-community/netbox/issues/6056) - Optimize change log cleanup * [#6144](https://github.com/netbox-community/netbox/issues/6144) - Fix MAC address field display in VM interfaces search form * [#6152](https://github.com/netbox-community/netbox/issues/6152) - Fix custom field filtering for cables, virtual chassis diff --git a/netbox/extras/models/customfields.py b/netbox/extras/models/customfields.py index a69816d21..4f37d4870 100644 --- a/netbox/extras/models/customfields.py +++ b/netbox/extras/models/customfields.py @@ -162,6 +162,24 @@ class CustomField(models.Model): def __str__(self): return self.label or self.name.replace('_', ' ').capitalize() + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Cache instance's original name so we can check later whether it has changed + self._name = self.name + + def rename_object_data(self, old_name, new_name): + """ + Called when a CustomField has been renamed. Updates all assigned object data. + """ + for ct in self.content_types.all(): + model = ct.model_class() + params = {f'custom_field_data__{old_name}__isnull': False} + instances = model.objects.filter(**params) + for instance in instances: + instance.custom_field_data[new_name] = instance.custom_field_data.pop(old_name) + model.objects.bulk_update(instances, ['custom_field_data'], batch_size=100) + def remove_stale_data(self, content_types): """ Delete custom field data which is no longer relevant (either because the CustomField is diff --git a/netbox/extras/signals.py b/netbox/extras/signals.py index 9eeb4ce45..3556f6fe8 100644 --- a/netbox/extras/signals.py +++ b/netbox/extras/signals.py @@ -5,7 +5,7 @@ from cacheops.signals import cache_invalidated, cache_read from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.db import DEFAULT_DB_ALIAS -from django.db.models.signals import m2m_changed, pre_delete +from django.db.models.signals import m2m_changed, post_save, pre_delete from django.utils import timezone from django_prometheus.models import model_deletes, model_inserts, model_updates from prometheus_client import Counter @@ -86,6 +86,14 @@ def handle_cf_removed_obj_types(instance, action, pk_set, **kwargs): instance.remove_stale_data(ContentType.objects.filter(pk__in=pk_set)) +def handle_cf_renamed(instance, created, **kwargs): + """ + Handle the renaming of custom field data on objects when a CustomField is renamed. + """ + if not created and instance.name != instance._name: + instance.rename_object_data(old_name=instance._name, new_name=instance.name) + + def handle_cf_deleted(instance, **kwargs): """ Handle the cleanup of old custom field data when a CustomField is deleted. @@ -94,6 +102,7 @@ def handle_cf_deleted(instance, **kwargs): m2m_changed.connect(handle_cf_removed_obj_types, sender=CustomField.content_types.through) +post_save.connect(handle_cf_renamed, sender=CustomField) pre_delete.connect(handle_cf_deleted, sender=CustomField) diff --git a/netbox/extras/tests/test_customfields.py b/netbox/extras/tests/test_customfields.py index 4f7a67676..d1725ac9d 100644 --- a/netbox/extras/tests/test_customfields.py +++ b/netbox/extras/tests/test_customfields.py @@ -91,6 +91,33 @@ class CustomFieldTest(TestCase): # Delete the custom field cf.delete() + def test_rename_customfield(self): + obj_type = ContentType.objects.get_for_model(Site) + FIELD_DATA = 'abc' + + # Create a custom field + cf = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name='field1') + cf.save() + cf.content_types.set([obj_type]) + + # Assign custom field data to an object + site = Site.objects.create( + name='Site 1', + slug='site-1', + custom_field_data={'field1': FIELD_DATA} + ) + site.refresh_from_db() + self.assertEqual(site.custom_field_data['field1'], FIELD_DATA) + + # Rename the custom field + cf.name = 'field2' + cf.save() + + # Check that custom field data on the object has been updated + site.refresh_from_db() + self.assertNotIn('field1', site.custom_field_data) + self.assertEqual(site.custom_field_data['field2'], FIELD_DATA) + class CustomFieldManagerTest(TestCase): From 1c91305b2b860143a2155f0c91f0195c40379ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20N=C3=B6thlich?= Date: Thu, 15 Apr 2021 18:37:45 +0200 Subject: [PATCH 16/19] Fixes #6168: Add SFP56 interface type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Adrian Nöthlich --- netbox/dcim/choices.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index 55b7539d1..a33e268a3 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -662,6 +662,7 @@ class InterfaceTypeChoices(ChoiceSet): TYPE_10GE_XENPAK = '10gbase-x-xenpak' TYPE_10GE_X2 = '10gbase-x-x2' TYPE_25GE_SFP28 = '25gbase-x-sfp28' + TYPE_50GE_SFP56 = '50gbase-x-sfp56' TYPE_40GE_QSFP_PLUS = '40gbase-x-qsfpp' TYPE_50GE_QSFP28 = '50gbase-x-sfp28' TYPE_100GE_CFP = '100gbase-x-cfp' @@ -766,6 +767,7 @@ class InterfaceTypeChoices(ChoiceSet): (TYPE_10GE_XENPAK, 'XENPAK (10GE)'), (TYPE_10GE_X2, 'X2 (10GE)'), (TYPE_25GE_SFP28, 'SFP28 (25GE)'), + (TYPE_50GE_SFP56, 'SFP56 (50GE)'), (TYPE_40GE_QSFP_PLUS, 'QSFP+ (40GE)'), (TYPE_50GE_QSFP28, 'QSFP28 (50GE)'), (TYPE_100GE_CFP, 'CFP (100GE)'), From 9f61f83acb17f26d3305c418ab9526dbcd5a5a39 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 15 Apr 2021 13:26:19 -0400 Subject: [PATCH 17/19] Fixes #5643: Fix VLAN assignment when editing VM interfaces in bulk --- docs/release-notes/version-2.10.md | 1 + netbox/virtualization/forms.py | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 3755944dc..0e1e207fd 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -12,6 +12,7 @@ ### Bug Fixes * [#5419](https://github.com/netbox-community/netbox/issues/5419) - Update parent device/VM when deleting a primary IP +* [#5643](https://github.com/netbox-community/netbox/issues/5643) - Fix VLAN assignment when editing VM interfaces in bulk * [#5652](https://github.com/netbox-community/netbox/issues/5652) - Update object data when renaming a custom field * [#6056](https://github.com/netbox-community/netbox/issues/6056) - Optimize change log cleanup * [#6144](https://github.com/netbox-community/netbox/issues/6144) - Fix MAC address field display in VM interfaces search form diff --git a/netbox/virtualization/forms.py b/netbox/virtualization/forms.py index a3e6c4cf4..8d20b390a 100644 --- a/netbox/virtualization/forms.py +++ b/netbox/virtualization/forms.py @@ -756,6 +756,26 @@ class VMInterfaceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, BulkEditForm): # Add current site to VLANs query params self.fields['untagged_vlan'].widget.add_query_param('site_id', site.pk) self.fields['tagged_vlans'].widget.add_query_param('site_id', site.pk) + else: + # See 5643 + if 'pk' in self.initial: + site = None + interfaces = VMInterface.objects.filter(pk__in=self.initial['pk']).prefetch_related( + 'virtual_machine__cluster__site' + ) + + # Check interface sites. First interface should set site, further interfaces will either continue the + # loop or reset back to no site and break the loop. + for interface in interfaces: + if site is None: + site = interface.virtual_machine.cluster.site + elif interface.virtual_machine.cluster.site is not site: + site = None + break + + if site is not None: + self.fields['untagged_vlan'].widget.add_query_param('site_id', site.pk) + self.fields['tagged_vlans'].widget.add_query_param('site_id', site.pk) class VMInterfaceBulkRenameForm(BulkRenameForm): From 4ed1f242690485ded267ad4a7c5c18bbe3147779 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 15 Apr 2021 13:30:42 -0400 Subject: [PATCH 18/19] Changelog for #6168 --- docs/release-notes/version-2.10.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 0e1e207fd..4329c9916 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -8,6 +8,7 @@ * [#5980](https://github.com/netbox-community/netbox/issues/5980) - Add Saf-D-Grid power port, outlet types * [#6157](https://github.com/netbox-community/netbox/issues/6157) - Support Markdown rendering for report logs * [#6160](https://github.com/netbox-community/netbox/issues/6160) - Add F connector port type +* [#6168](https://github.com/netbox-community/netbox/issues/6168) - Add SFP56 50GE interface type ### Bug Fixes From 89d928b99062f927259d89355554649c5a03aaf6 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 15 Apr 2021 15:20:30 -0400 Subject: [PATCH 19/19] Release v2.10.10 --- docs/release-notes/version-2.10.md | 2 +- netbox/netbox/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 4329c9916..d356fc235 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -1,6 +1,6 @@ # NetBox v2.10 -## v2.10.10 (FUTURE) +## v2.10.10 (2021-04-15) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 233ee72c4..3c03651bf 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.10.10-dev' +VERSION = '2.10.10' # Hostname HOSTNAME = platform.node()