From 99f4b2cf95861b22ce5a690bb20549a6e4f0d232 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 d43d5a6cb6035baaef3141f5a810dea1277cdfbd 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 b19734004a49b7a0c8653f6d0f134a450ab6f33a 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 3d8a3a2204ab7e413933f17f6dfb75838d2279ed 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 9cbe3ff5517ee904cb97716d29c4f1686aabeee2 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 d54bf5f75eef3b93ab0641a527576eed0a8eb7de 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 c249cd4ffd07d0d05f40f9bb1421ec76c2f5cae6 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 1fba4b7e32f18e643f6483068062c71a2019c807 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 cc433388f5811823913bcf0e310d0af3f05a710d 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 7c48e3632db052924c80213fc07faa8d3059fe7c 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 18a691482def587bfc65759d5a4569923a5010af 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 e849d2827684f061b3fc4702a4c93f1a78353676 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 3d0882856fd393c3feaa0b40227505894160b5da 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 a2203da1c6fa674a55d3071a287094d70cb1c502 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 92df40a6a012a82b02eae73a4b43b97e5907f26e 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 14d2a499420aa1fd28508311781c769adfbab4d1 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 f67369a9a9fa283469c80ed3a18cef2d03f31036 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 3e49745257bcb67b3091e63f1342c1a3cb19f856 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 ae349d4424b853f7bdf2858de1970a9d3e40df3a 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()