From c21ec2139d5f675777b9dcfde258398525e02fe9 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 23 Feb 2024 10:15:14 -0500 Subject: [PATCH 01/23] Delete obsolete file --- netbox/vpn/admin.py | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 netbox/vpn/admin.py diff --git a/netbox/vpn/admin.py b/netbox/vpn/admin.py deleted file mode 100644 index 8c38f3f3d..000000000 --- a/netbox/vpn/admin.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.contrib import admin - -# Register your models here. From 17ec264f3a0936e1157585133b075cac27f47647 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Fri, 23 Feb 2024 23:53:08 +0530 Subject: [PATCH 02/23] added display on virtual disk api #15241 --- netbox/virtualization/api/serializers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/virtualization/api/serializers.py b/netbox/virtualization/api/serializers.py index 1dcb413ec..34e4037e9 100644 --- a/netbox/virtualization/api/serializers.py +++ b/netbox/virtualization/api/serializers.py @@ -172,6 +172,6 @@ class VirtualDiskSerializer(NetBoxModelSerializer): class Meta: model = VirtualDisk fields = [ - 'id', 'url', 'virtual_machine', 'name', 'description', 'size', 'tags', 'custom_fields', 'created', - 'last_updated', + 'id', 'url', 'display', 'virtual_machine', 'name', 'description', 'size', 'tags', 'custom_fields', + 'created', 'last_updated', ] From edb7d24b458b60fa82b16bc37e79f37821e3685f Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Fri, 23 Feb 2024 12:54:47 -0800 Subject: [PATCH 03/23] Added installed_module on NestedModuleBaySerializer (#15245) * added installed_module on NestedModuleBaySerializer #15243 * Update test --------- Co-authored-by: Jeremy Stretch --- netbox/dcim/api/nested_serializers.py | 4 ++-- netbox/dcim/api/serializers.py | 3 +-- netbox/dcim/tests/test_api.py | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/netbox/dcim/api/nested_serializers.py b/netbox/dcim/api/nested_serializers.py index c8440612d..419d9b175 100644 --- a/netbox/dcim/api/nested_serializers.py +++ b/netbox/dcim/api/nested_serializers.py @@ -414,11 +414,11 @@ class NestedFrontPortSerializer(WritableNestedSerializer): class NestedModuleBaySerializer(WritableNestedSerializer): url = serializers.HyperlinkedIdentityField(view_name='dcim-api:modulebay-detail') - module = NestedModuleSerializer(required=False, read_only=True, allow_null=True) + installed_module = ModuleBayNestedModuleSerializer(required=False, allow_null=True) class Meta: model = models.ModuleBay - fields = ['id', 'url', 'display', 'module', 'name'] + fields = ['id', 'url', 'display', 'installed_module', 'name'] class NestedDeviceBaySerializer(WritableNestedSerializer): diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index f8541f013..ab3177de5 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -1039,8 +1039,7 @@ class ModuleBaySerializer(NetBoxModelSerializer): model = ModuleBay fields = [ 'id', 'url', 'display', 'device', 'name', 'installed_module', 'label', 'position', 'description', 'tags', - 'custom_fields', - 'created', 'last_updated', + 'custom_fields', 'created', 'last_updated', ] diff --git a/netbox/dcim/tests/test_api.py b/netbox/dcim/tests/test_api.py index d02422c6f..b0670fdff 100644 --- a/netbox/dcim/tests/test_api.py +++ b/netbox/dcim/tests/test_api.py @@ -1755,7 +1755,7 @@ class RearPortTest(APIViewTestCases.APIViewTestCase): class ModuleBayTest(APIViewTestCases.APIViewTestCase): model = ModuleBay - brief_fields = ['display', 'id', 'module', 'name', 'url'] + brief_fields = ['display', 'id', 'installed_module', 'name', 'url'] bulk_update_data = { 'description': 'New description', } From 55ef24d56d6d45fa40f766d22ca8f21ed75b2558 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 29 Feb 2024 14:54:41 -0500 Subject: [PATCH 04/23] Fixes #15316: Fix selection of 3DES encryption for IKE & IPSec proposals --- netbox/vpn/choices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/vpn/choices.py b/netbox/vpn/choices.py index c4ae67619..4aa97f615 100644 --- a/netbox/vpn/choices.py +++ b/netbox/vpn/choices.py @@ -124,7 +124,7 @@ class EncryptionAlgorithmChoices(ChoiceSet): (ENCRYPTION_AES256_CBC, '256-bit AES (CBC)'), (ENCRYPTION_AES256_GCM, '256-bit AES (GCM)'), (ENCRYPTION_3DES, '3DES'), - (ENCRYPTION_3DES, 'DES'), + (ENCRYPTION_DES, 'DES'), ) From 8afbb4421bc0f58734ad44dca8052652ae73802a Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 27 Feb 2024 09:36:12 -0800 Subject: [PATCH 05/23] 15232 fix inventory item template permission --- netbox/dcim/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 2a2fe39e3..d0e92ff56 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1079,7 +1079,7 @@ class DeviceTypeInventoryItemsView(DeviceTypeComponentsView): tab = ViewTab( label=_('Inventory Items'), badge=lambda obj: obj.inventory_item_template_count, - permission='dcim.view_invenotryitemtemplate', + permission='dcim.view_inventoryitemtemplate', weight=590, hide_if_empty=True ) From c45acf0a7c38cd8d04e38895baaf8765b53a5e32 Mon Sep 17 00:00:00 2001 From: Jeff Gehlbach Date: Fri, 23 Feb 2024 15:56:14 -0500 Subject: [PATCH 06/23] Fixes: Use systemctl enable --now shortcut in docs #15249 --- docs/installation/1-postgresql.md | 3 +-- docs/installation/2-redis.md | 3 +-- docs/installation/4-gunicorn.md | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/docs/installation/1-postgresql.md b/docs/installation/1-postgresql.md index 184fc26d2..9d30f4514 100644 --- a/docs/installation/1-postgresql.md +++ b/docs/installation/1-postgresql.md @@ -31,8 +31,7 @@ This section entails the installation and configuration of a local PostgreSQL da Once PostgreSQL has been installed, start the service and enable it to run at boot: ```no-highlight - sudo systemctl start postgresql - sudo systemctl enable postgresql + sudo systemctl enable --now postgresql ``` Before continuing, verify that you have installed PostgreSQL 12 or later: diff --git a/docs/installation/2-redis.md b/docs/installation/2-redis.md index 7c364947e..2756a1ab0 100644 --- a/docs/installation/2-redis.md +++ b/docs/installation/2-redis.md @@ -14,8 +14,7 @@ ```no-highlight sudo yum install -y redis - sudo systemctl start redis - sudo systemctl enable redis + sudo systemctl enable --now redis ``` Before continuing, verify that your installed version of Redis is at least v4.0: diff --git a/docs/installation/4-gunicorn.md b/docs/installation/4-gunicorn.md index e31c48466..1e8d49453 100644 --- a/docs/installation/4-gunicorn.md +++ b/docs/installation/4-gunicorn.md @@ -27,8 +27,7 @@ sudo systemctl daemon-reload Then, start the `netbox` and `netbox-rq` services and enable them to initiate at boot time: ```no-highlight -sudo systemctl start netbox netbox-rq -sudo systemctl enable netbox netbox-rq +sudo systemctl enable --now netbox netbox-rq ``` You can use the command `systemctl status netbox` to verify that the WSGI service is running: From bdcf4c4154bcfc73f3c09c7f8cbc558af22e125c Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 29 Feb 2024 16:03:54 -0500 Subject: [PATCH 07/23] Fixes #15220: Move IP mask validation logic from form to model --- netbox/ipam/forms/model_forms.py | 14 -------------- netbox/ipam/models/ip.py | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/netbox/ipam/forms/model_forms.py b/netbox/ipam/forms/model_forms.py index c7e3f92a3..71aa32d52 100644 --- a/netbox/ipam/forms/model_forms.py +++ b/netbox/ipam/forms/model_forms.py @@ -367,20 +367,6 @@ class IPAddressForm(TenancyForm, NetBoxModelForm): 'primary_for_parent', _("Only IP addresses assigned to an interface can be designated as primary IPs.") ) - # Do not allow assigning a network ID or broadcast address to an interface. - if interface and (address := self.cleaned_data.get('address')): - if address.ip == address.network: - msg = _("{ip} is a network ID, which may not be assigned to an interface.").format(ip=address.ip) - if address.version == 4 and address.prefixlen not in (31, 32): - raise ValidationError(msg) - if address.version == 6 and address.prefixlen not in (127, 128): - raise ValidationError(msg) - if address.version == 4 and address.ip == address.broadcast and address.prefixlen not in (31, 32): - msg = _("{ip} is a broadcast address, which may not be assigned to an interface.").format( - ip=address.ip - ) - raise ValidationError(msg) - def save(self, *args, **kwargs): ipaddress = super().save(*args, **kwargs) diff --git a/netbox/ipam/models/ip.py b/netbox/ipam/models/ip.py index 76fae2990..ca9592d6e 100644 --- a/netbox/ipam/models/ip.py +++ b/netbox/ipam/models/ip.py @@ -844,6 +844,25 @@ class IPAddress(PrimaryModel): 'address': _("Cannot create IP address with /0 mask.") }) + # Do not allow assigning a network ID or broadcast address to an interface. + if self.assigned_object: + if self.address.ip == self.address.network: + msg = _("{ip} is a network ID, which may not be assigned to an interface.").format( + ip=self.address.ip + ) + if self.address.version == 4 and self.address.prefixlen not in (31, 32): + raise ValidationError(msg) + if self.address.version == 6 and self.address.prefixlen not in (127, 128): + raise ValidationError(msg) + if ( + self.address.version == 4 and self.address.ip == self.address.broadcast and + self.address.prefixlen not in (31, 32) + ): + msg = _("{ip} is a broadcast address, which may not be assigned to an interface.").format( + ip=self.address.ip + ) + raise ValidationError(msg) + # Enforce unique IP space (if applicable) if (self.vrf is None and get_config().ENFORCE_GLOBAL_UNIQUE) or (self.vrf and self.vrf.enforce_unique): duplicate_ips = self.get_duplicates() From 6629c941483704c5092bc20d564ad9527a83908d Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 8 Mar 2024 16:48:39 -0500 Subject: [PATCH 08/23] Closes #15297: Linkify platform column in device & virtual machine tables --- docs/release-notes/version-3.7.md | 4 ++++ netbox/dcim/tables/devices.py | 6 +++++- netbox/virtualization/tables/virtualmachines.py | 10 +++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/release-notes/version-3.7.md b/docs/release-notes/version-3.7.md index 21e7489c3..097cd70e5 100644 --- a/docs/release-notes/version-3.7.md +++ b/docs/release-notes/version-3.7.md @@ -2,6 +2,10 @@ ## v3.7.4 (FUTURE) +### Enhancements + +* [#15297](https://github.com/netbox-community/netbox/issues/15297) - Linkify platform column in device & virtual machine tables + --- ## v3.7.3 (2024-02-21) diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index d4c9641b6..98dcfcb3c 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -210,6 +210,10 @@ class DeviceTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable): linkify=True, verbose_name=_('Type') ) + platform = tables.Column( + linkify=True, + verbose_name=_('Platform') + ) primary_ip = tables.Column( linkify=True, order_by=('primary_ip4', 'primary_ip6'), @@ -294,7 +298,7 @@ class DeviceTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable): model = models.Device fields = ( 'pk', 'id', 'name', 'status', 'tenant', 'tenant_group', 'role', 'manufacturer', 'device_type', - 'platform', 'serial', 'asset_tag', 'region', 'site_group', 'site', 'location', 'rack', 'parent_device', + 'serial', 'asset_tag', 'region', 'site_group', 'site', 'location', 'rack', 'parent_device', 'device_bay_position', 'position', 'face', 'latitude', 'longitude', 'airflow', 'primary_ip', 'primary_ip4', 'primary_ip6', 'oob_ip', 'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'description', 'config_template', 'comments', 'contacts', 'tags', 'created', 'last_updated', diff --git a/netbox/virtualization/tables/virtualmachines.py b/netbox/virtualization/tables/virtualmachines.py index 632e6878a..36030baee 100644 --- a/netbox/virtualization/tables/virtualmachines.py +++ b/netbox/virtualization/tables/virtualmachines.py @@ -64,6 +64,10 @@ class VirtualMachineTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable) role = columns.ColoredLabelColumn( verbose_name=_('Role'), ) + platform = tables.Column( + linkify=True, + verbose_name=_('Platform') + ) comments = columns.MarkdownColumn( verbose_name=_('Comments'), ) @@ -97,9 +101,9 @@ class VirtualMachineTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable) class Meta(NetBoxTable.Meta): model = VirtualMachine fields = ( - 'pk', 'id', 'name', 'status', 'site', 'cluster', 'device', 'role', 'tenant', 'tenant_group', 'platform', - 'vcpus', 'memory', 'disk', 'primary_ip4', 'primary_ip6', 'primary_ip', 'description', 'comments', - 'config_template', 'contacts', 'tags', 'created', 'last_updated', + 'pk', 'id', 'name', 'status', 'site', 'cluster', 'device', 'role', 'tenant', 'tenant_group', 'vcpus', + 'memory', 'disk', 'primary_ip4', 'primary_ip6', 'primary_ip', 'description', 'comments', 'config_template', + 'contacts', 'tags', 'created', 'last_updated', ) default_columns = ( 'pk', 'name', 'status', 'site', 'cluster', 'role', 'tenant', 'vcpus', 'memory', 'disk', 'primary_ip', From 8bb49d229692fbc9e33edb4733a0d1d20f82ff37 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 8 Mar 2024 16:58:04 -0500 Subject: [PATCH 09/23] Closes #15291: Add tunnel termination buttons to VM interfaces table --- docs/release-notes/version-3.7.md | 1 + netbox/virtualization/tables/virtualmachines.py | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/docs/release-notes/version-3.7.md b/docs/release-notes/version-3.7.md index 097cd70e5..846a7a115 100644 --- a/docs/release-notes/version-3.7.md +++ b/docs/release-notes/version-3.7.md @@ -4,6 +4,7 @@ ### Enhancements +* [#15291](https://github.com/netbox-community/netbox/issues/15291) - Add tunnel termination buttons to VM interfaces table * [#15297](https://github.com/netbox-community/netbox/issues/15297) - Linkify platform column in device & virtual machine tables --- diff --git a/netbox/virtualization/tables/virtualmachines.py b/netbox/virtualization/tables/virtualmachines.py index 36030baee..ba5360a62 100644 --- a/netbox/virtualization/tables/virtualmachines.py +++ b/netbox/virtualization/tables/virtualmachines.py @@ -33,6 +33,15 @@ VMINTERFACE_BUTTONS = """ {% endif %} +{% if perms.vpn.add_tunnel and not record.tunnel_termination %} + + + +{% elif perms.vpn.delete_tunneltermination and record.tunnel_termination %} + + + +{% endif %} """ From eeb732d96e18c9c897db849f469e77b9924ac04a Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 8 Mar 2024 17:03:18 -0500 Subject: [PATCH 10/23] Fixes #15336: Correct label for recurring scheduled jobs --- docs/release-notes/version-3.7.md | 4 ++++ netbox/templates/core/job.html | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.7.md b/docs/release-notes/version-3.7.md index 846a7a115..fd39b9255 100644 --- a/docs/release-notes/version-3.7.md +++ b/docs/release-notes/version-3.7.md @@ -7,6 +7,10 @@ * [#15291](https://github.com/netbox-community/netbox/issues/15291) - Add tunnel termination buttons to VM interfaces table * [#15297](https://github.com/netbox-community/netbox/issues/15297) - Linkify platform column in device & virtual machine tables +### Bug Fixes + +* [#15336](https://github.com/netbox-community/netbox/issues/15336) - Correct label for recurring scheduled jobs + --- ## v3.7.3 (2024-02-21) diff --git a/netbox/templates/core/job.html b/netbox/templates/core/job.html index deb651739..14c7815c0 100644 --- a/netbox/templates/core/job.html +++ b/netbox/templates/core/job.html @@ -63,7 +63,7 @@ {{ object.scheduled|annotated_date|placeholder }} {% if object.interval %} - ({% blocktrans with interval=object.interval %}every {{ interval }} seconds{% endblocktrans %}) + ({% blocktrans with interval=object.interval %}every {{ interval }} minutes{% endblocktrans %}) {% endif %} From de622801f107b320ae934938895c2e6b8cdb4b2a Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 8 Mar 2024 17:05:10 -0500 Subject: [PATCH 11/23] Changelog for #15220, #15232, #15241, #15243, #15316 --- docs/release-notes/version-3.7.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/release-notes/version-3.7.md b/docs/release-notes/version-3.7.md index fd39b9255..17a3bf9cc 100644 --- a/docs/release-notes/version-3.7.md +++ b/docs/release-notes/version-3.7.md @@ -9,6 +9,11 @@ ### Bug Fixes +* [#15220](https://github.com/netbox-community/netbox/issues/15220) - Fix validation check when bulk editing the mask length of IP addresses +* [#15232](https://github.com/netbox-community/netbox/issues/15232) - Permit user with sufficient permissions to assign an inventory item to a device type +* [#15241](https://github.com/netbox-community/netbox/issues/15241) - Restore missing `display` field on VirtualDisk serialization in REST API +* [#15243](https://github.com/netbox-community/netbox/issues/15243) - Correct representation of installed module when listing module bays using REST API brief mode +* [#15316](https://github.com/netbox-community/netbox/issues/15316) - Fix selection of 3DES encryption for IKE & IPSec proposals * [#15336](https://github.com/netbox-community/netbox/issues/15336) - Correct label for recurring scheduled jobs --- From f0e137133f9cea63e9ddd6101196bf41e83a20ca Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Mon, 4 Mar 2024 23:18:38 +0800 Subject: [PATCH 12/23] Fixes: #14832 Extend GraphQL FHRPGroupType with IPAddressesMixin --- netbox/ipam/graphql/types.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netbox/ipam/graphql/types.py b/netbox/ipam/graphql/types.py index b4350f9f2..d19837fd1 100644 --- a/netbox/ipam/graphql/types.py +++ b/netbox/ipam/graphql/types.py @@ -1,6 +1,7 @@ import graphene from ipam import filtersets, models +from .mixins import IPAddressesMixin from netbox.graphql.scalars import BigInt from netbox.graphql.types import BaseObjectType, OrganizationalObjectType, NetBoxObjectType @@ -71,7 +72,7 @@ class AggregateType(NetBoxObjectType, BaseIPAddressFamilyType): filterset_class = filtersets.AggregateFilterSet -class FHRPGroupType(NetBoxObjectType): +class FHRPGroupType(NetBoxObjectType, IPAddressesMixin): class Meta: model = models.FHRPGroup From 1ff4e1287fec67721e8446707f32eecb224ed9e3 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Mon, 11 Mar 2024 09:50:10 -0500 Subject: [PATCH 13/23] Fixes: #13722 - Correct range expansion code when a numeric set is used (#15301) * Fixes: #13722 - Correct range expansion code when a numeric set is used * Correct to my own suggestion * Clean up logic * Simplify range detection --------- Co-authored-by: Jeremy Stretch --- netbox/utilities/forms/utils.py | 43 ++++++++++++++++------------ netbox/utilities/tests/test_forms.py | 11 ++++++- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/netbox/utilities/forms/utils.py b/netbox/utilities/forms/utils.py index 689fbebbf..0429fe571 100644 --- a/netbox/utilities/forms/utils.py +++ b/netbox/utilities/forms/utils.py @@ -51,36 +51,43 @@ def parse_alphanumeric_range(string): '0-3,a-d' => [0, 1, 2, 3, a, b, c, d] """ values = [] - for dash_range in string.split(','): + for value in string.split(','): + if '-' not in value: + # Item is not a range + values.append(value) + continue + + # Find the range's beginning & end values try: - begin, end = dash_range.split('-') + begin, end = value.split('-') vals = begin + end # Break out of loop if there's an invalid pattern to return an error if (not (vals.isdigit() or vals.isalpha())) or (vals.isalpha() and not (vals.isupper() or vals.islower())): return [] except ValueError: - begin, end = dash_range, dash_range + raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=value)) + + # Numeric range if begin.isdigit() and end.isdigit(): if int(begin) >= int(end): - raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=dash_range)) - + raise forms.ValidationError( + _('Invalid range: Ending value ({end}) must be greater than beginning value ({begin}).').format( + begin=begin, end=end + ) + ) for n in list(range(int(begin), int(end) + 1)): values.append(n) + + # Alphanumeric range else: - # Value-based - if begin == end: - values.append(begin) - # Range-based - else: - # Not a valid range (more than a single character) - if not len(begin) == len(end) == 1: - raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=dash_range)) + # Not a valid range (more than a single character) + if not len(begin) == len(end) == 1: + raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=value)) + if ord(begin) >= ord(end): + raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=value)) + for n in list(range(ord(begin), ord(end) + 1)): + values.append(chr(n)) - if ord(begin) >= ord(end): - raise forms.ValidationError(_('Range "{value}" is invalid.').format(value=dash_range)) - - for n in list(range(ord(begin), ord(end) + 1)): - values.append(chr(n)) return values diff --git a/netbox/utilities/tests/test_forms.py b/netbox/utilities/tests/test_forms.py index d014d4bbd..aab9af870 100644 --- a/netbox/utilities/tests/test_forms.py +++ b/netbox/utilities/tests/test_forms.py @@ -191,7 +191,16 @@ class ExpandAlphanumeric(TestCase): self.assertEqual(sorted(expand_alphanumeric_pattern(input)), output) - def test_set(self): + def test_set_numeric(self): + input = 'r[1,2]a' + output = sorted([ + 'r1a', + 'r2a', + ]) + + self.assertEqual(sorted(expand_alphanumeric_pattern(input)), output) + + def test_set_alpha(self): input = '[r,t]1a' output = sorted([ 'r1a', From 51b2bcf264723f1752438b0448049ba50f9feb87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markku=20Leini=C3=B6?= Date: Sun, 10 Mar 2024 13:41:27 +0200 Subject: [PATCH 14/23] Closes #14206: Add FC SFP types --- netbox/dcim/choices.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index 2ba24e0aa..b00784265 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -889,7 +889,10 @@ class InterfaceTypeChoices(ChoiceSet): TYPE_8GFC_SFP_PLUS = '8gfc-sfpp' TYPE_16GFC_SFP_PLUS = '16gfc-sfpp' TYPE_32GFC_SFP28 = '32gfc-sfp28' + TYPE_32GFC_SFP_PLUS = '32gfc-sfpp' TYPE_64GFC_QSFP_PLUS = '64gfc-qsfpp' + TYPE_64GFC_SFP_DD = '64gfc-sfpdd' + TYPE_64GFC_SFP_PLUS = '64gfc-sfpp' TYPE_128GFC_QSFP28 = '128gfc-qsfp28' # InfiniBand @@ -1058,7 +1061,10 @@ class InterfaceTypeChoices(ChoiceSet): (TYPE_8GFC_SFP_PLUS, 'SFP+ (8GFC)'), (TYPE_16GFC_SFP_PLUS, 'SFP+ (16GFC)'), (TYPE_32GFC_SFP28, 'SFP28 (32GFC)'), + (TYPE_32GFC_SFP_PLUS, 'SFP+ (32GFC)'), (TYPE_64GFC_QSFP_PLUS, 'QSFP+ (64GFC)'), + (TYPE_64GFC_SFP_DD, 'SFP-DD (64GFC)'), + (TYPE_64GFC_SFP_PLUS, 'SFP+ (64GFC)'), (TYPE_128GFC_QSFP28, 'QSFP28 (128GFC)'), ) ), From eca2a7758485bc0e62a6a63706ab50890364bf53 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 12 Mar 2024 10:51:29 -0400 Subject: [PATCH 15/23] Closes #14459: Update coverage report --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed8c65b7d..11125ae4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,4 +84,4 @@ jobs: run: coverage run --source="netbox/" netbox/manage.py test netbox/ --parallel - name: Show coverage report - run: coverage report --skip-covered --omit *migrations* + run: coverage report --skip-covered --omit '*/migrations/*,*/tests/*' From 44f7ab09701b39d6a526f09c86945c5764a313c0 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 12 Mar 2024 10:57:14 -0400 Subject: [PATCH 16/23] Add NetBox Enterprise deployment type --- .github/ISSUE_TEMPLATE/bug_report.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index b0b8c02ad..1776f6cf4 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -17,8 +17,9 @@ body: How are you running NetBox? (For issues with the Docker image, please go to the [netbox-docker](https://github.com/netbox-community/netbox-docker) repo.) options: - - Self-hosted - NetBox Cloud + - NetBox Enterprise + - Self-hosted validations: required: true - type: input From 8fe3f5e3fd62e88f7c473c95f4036c97a663f0e1 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 12 Mar 2024 10:38:21 -0400 Subject: [PATCH 17/23] Closes #14366: Enable custom links on ConfigContexts and ConfigTemplates --- netbox/extras/models/configs.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netbox/extras/models/configs.py b/netbox/extras/models/configs.py index 425c1386a..910803e16 100644 --- a/netbox/extras/models/configs.py +++ b/netbox/extras/models/configs.py @@ -11,7 +11,7 @@ from extras.querysets import ConfigContextQuerySet from netbox.config import get_config from netbox.registry import registry from netbox.models import ChangeLoggedModel -from netbox.models.features import CloningMixin, ExportTemplatesMixin, SyncedDataMixin, TagsMixin +from netbox.models.features import CloningMixin, CustomLinksMixin, ExportTemplatesMixin, SyncedDataMixin, TagsMixin from utilities.jinja2 import ConfigTemplateLoader from utilities.utils import deepmerge @@ -26,7 +26,7 @@ __all__ = ( # Config contexts # -class ConfigContext(SyncedDataMixin, CloningMixin, ChangeLoggedModel): +class ConfigContext(SyncedDataMixin, CloningMixin, CustomLinksMixin, ChangeLoggedModel): """ A ConfigContext represents a set of arbitrary data available to any Device or VirtualMachine matching its assigned qualifiers (region, site, etc.). For example, the data stored in a ConfigContext assigned to site A and tenant B @@ -210,7 +210,7 @@ class ConfigContextModel(models.Model): # Config templates # -class ConfigTemplate(SyncedDataMixin, ExportTemplatesMixin, TagsMixin, ChangeLoggedModel): +class ConfigTemplate(SyncedDataMixin, CustomLinksMixin, ExportTemplatesMixin, TagsMixin, ChangeLoggedModel): name = models.CharField( verbose_name=_('name'), max_length=100 From 7350950e8874bff4f3657596891216cde01010af Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 13 Mar 2024 15:11:28 -0400 Subject: [PATCH 18/23] Fixes #15347: Fix querying virtual machine contacts via GraphQL --- netbox/extras/graphql/mixins.py | 1 + netbox/virtualization/graphql/types.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/netbox/extras/graphql/mixins.py b/netbox/extras/graphql/mixins.py index 7045575fb..68fba5ee6 100644 --- a/netbox/extras/graphql/mixins.py +++ b/netbox/extras/graphql/mixins.py @@ -7,6 +7,7 @@ from extras.models import ObjectChange __all__ = ( 'ChangelogMixin', 'ConfigContextMixin', + 'ContactsMixin', 'CustomFieldsMixin', 'ImageAttachmentsMixin', 'JournalEntriesMixin', diff --git a/netbox/virtualization/graphql/types.py b/netbox/virtualization/graphql/types.py index 9b97e1dc9..30429be69 100644 --- a/netbox/virtualization/graphql/types.py +++ b/netbox/virtualization/graphql/types.py @@ -1,5 +1,5 @@ from dcim.graphql.types import ComponentObjectType -from extras.graphql.mixins import ConfigContextMixin +from extras.graphql.mixins import ConfigContextMixin, ContactsMixin from ipam.graphql.mixins import IPAddressesMixin, VLANGroupsMixin from netbox.graphql.types import OrganizationalObjectType, NetBoxObjectType from virtualization import filtersets, models @@ -38,7 +38,7 @@ class ClusterTypeType(OrganizationalObjectType): filterset_class = filtersets.ClusterTypeFilterSet -class VirtualMachineType(ConfigContextMixin, NetBoxObjectType): +class VirtualMachineType(ConfigContextMixin, ContactsMixin, NetBoxObjectType): class Meta: model = models.VirtualMachine From 7ac21690e5c04a9b163f507a70c2a6929a2a0a4d Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 13 Mar 2024 15:05:04 -0400 Subject: [PATCH 19/23] Fixes #15356: Fix assignment of front & rear images to device types via REST API --- netbox/dcim/api/serializers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index ab3177de5..053b3e9ea 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -326,8 +326,8 @@ class DeviceTypeSerializer(NetBoxModelSerializer): airflow = ChoiceField(choices=DeviceAirflowChoices, allow_blank=True, required=False, allow_null=True) weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False, allow_null=True) device_count = serializers.IntegerField(read_only=True) - front_image = serializers.URLField(allow_null=True, required=False) - rear_image = serializers.URLField(allow_null=True, required=False) + front_image = serializers.ImageField(required=False, allow_null=True) + rear_image = serializers.ImageField(required=False, allow_null=True) # Counter fields console_port_template_count = serializers.IntegerField(read_only=True) From 8bdbb49a276b569b6ea6444dbecda32e3205a3be Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 13 Mar 2024 15:18:25 -0400 Subject: [PATCH 20/23] Fixes #15322: Add description field to YAML export for device & module types --- netbox/dcim/models/devices.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/models/devices.py b/netbox/dcim/models/devices.py index f9e8ba213..2a1269a8d 100644 --- a/netbox/dcim/models/devices.py +++ b/netbox/dcim/models/devices.py @@ -229,15 +229,16 @@ class DeviceType(ImageAttachmentsMixin, PrimaryModel, WeightMixin): 'manufacturer': self.manufacturer.name, 'model': self.model, 'slug': self.slug, + 'description': self.description, 'default_platform': self.default_platform.name if self.default_platform else None, 'part_number': self.part_number, 'u_height': float(self.u_height), 'is_full_depth': self.is_full_depth, 'subdevice_role': self.subdevice_role, 'airflow': self.airflow, - 'comments': self.comments, 'weight': float(self.weight) if self.weight is not None else None, 'weight_unit': self.weight_unit, + 'comments': self.comments, } # Component templates @@ -415,9 +416,10 @@ class ModuleType(ImageAttachmentsMixin, PrimaryModel, WeightMixin): 'manufacturer': self.manufacturer.name, 'model': self.model, 'part_number': self.part_number, - 'comments': self.comments, + 'description': self.description, 'weight': float(self.weight) if self.weight is not None else None, 'weight_unit': self.weight_unit, + 'comments': self.comments, } # Component templates From df7905d257e4a3f798a50a662930f05933be6d5e Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 13 Mar 2024 19:15:35 -0400 Subject: [PATCH 21/23] Changelog for #13722, #14206, #14366, #14832, #15322, #15347, #15356 --- docs/release-notes/version-3.7.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/release-notes/version-3.7.md b/docs/release-notes/version-3.7.md index 17a3bf9cc..db6e697f0 100644 --- a/docs/release-notes/version-3.7.md +++ b/docs/release-notes/version-3.7.md @@ -4,17 +4,24 @@ ### Enhancements +* [#14206](https://github.com/netbox-community/netbox/issues/14206) - Add additional FibreChannel SFP+ interface types +* [#14366](https://github.com/netbox-community/netbox/issues/14366) - Enable custom links for config contexts & templates * [#15291](https://github.com/netbox-community/netbox/issues/15291) - Add tunnel termination buttons to VM interfaces table * [#15297](https://github.com/netbox-community/netbox/issues/15297) - Linkify platform column in device & virtual machine tables ### Bug Fixes +* [#13722](https://github.com/netbox-community/netbox/issues/13722) - Fix range expansion for comma-separated numerical values +* [#14832](https://github.com/netbox-community/netbox/issues/14832) - Enable querying IP addresses for an FHRP group via GraphQL * [#15220](https://github.com/netbox-community/netbox/issues/15220) - Fix validation check when bulk editing the mask length of IP addresses * [#15232](https://github.com/netbox-community/netbox/issues/15232) - Permit user with sufficient permissions to assign an inventory item to a device type * [#15241](https://github.com/netbox-community/netbox/issues/15241) - Restore missing `display` field on VirtualDisk serialization in REST API * [#15243](https://github.com/netbox-community/netbox/issues/15243) - Correct representation of installed module when listing module bays using REST API brief mode * [#15316](https://github.com/netbox-community/netbox/issues/15316) - Fix selection of 3DES encryption for IKE & IPSec proposals +* [#15322](https://github.com/netbox-community/netbox/issues/15322) - Add description field to YAML export for device & module types * [#15336](https://github.com/netbox-community/netbox/issues/15336) - Correct label for recurring scheduled jobs +* [#15347](https://github.com/netbox-community/netbox/issues/15347) - Fix querying virtual machine contacts via GraphQL +* [#15356](https://github.com/netbox-community/netbox/issues/15356) - Fix assignment of front & rear images to device types via REST API --- From 06bdfdc9e899ac28f1b61df2a647df1436c41596 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 13 Mar 2024 19:23:51 -0400 Subject: [PATCH 22/23] Release v3.7.4 --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yaml | 2 +- base_requirements.txt | 2 +- contrib/generated_schema.json | 3 +++ docs/release-notes/version-3.7.md | 2 +- netbox/netbox/settings.py | 2 +- requirements.txt | 10 +++++----- 7 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 1776f6cf4..612d01d89 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -26,7 +26,7 @@ body: attributes: label: NetBox Version description: What version of NetBox are you currently running? - placeholder: v3.7.3 + placeholder: v3.7.4 validations: required: true - type: dropdown diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index bc99999c0..8eb47180d 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -14,7 +14,7 @@ body: attributes: label: NetBox version description: What version of NetBox are you currently running? - placeholder: v3.7.3 + placeholder: v3.7.4 validations: required: true - type: dropdown diff --git a/base_requirements.txt b/base_requirements.txt index de885eeb2..642450cf8 100644 --- a/base_requirements.txt +++ b/base_requirements.txt @@ -101,7 +101,7 @@ markdown-include mkdocs-material # Introspection for embedded code -# https://github.com/mkdocstrings/mkdocstrings/blob/master/CHANGELOG.md +# https://github.com/mkdocstrings/mkdocstrings/blob/main/CHANGELOG.md mkdocstrings[python-legacy] # Library for manipulating IP prefixes and addresses diff --git a/contrib/generated_schema.json b/contrib/generated_schema.json index 5e8507798..1164f2e48 100644 --- a/contrib/generated_schema.json +++ b/contrib/generated_schema.json @@ -384,7 +384,10 @@ "8gfc-sfpp", "16gfc-sfpp", "32gfc-sfp28", + "32gfc-sfpp", "64gfc-qsfpp", + "64gfc-sfpdd", + "64gfc-sfpp", "128gfc-qsfp28", "infiniband-sdr", "infiniband-ddr", diff --git a/docs/release-notes/version-3.7.md b/docs/release-notes/version-3.7.md index db6e697f0..fd61218e5 100644 --- a/docs/release-notes/version-3.7.md +++ b/docs/release-notes/version-3.7.md @@ -1,6 +1,6 @@ # NetBox v3.7 -## v3.7.4 (FUTURE) +## v3.7.4 (2024-03-13) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 52b085b33..007164a6d 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -28,7 +28,7 @@ from netbox.plugins import PluginConfig # Environment setup # -VERSION = '3.7.4-dev' +VERSION = '3.7.4' # Hostname HOSTNAME = platform.node() diff --git a/requirements.txt b/requirements.txt index 5218657f2..39922c9b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ bleach==6.1.0 -Django==4.2.10 +Django==4.2.11 django-cors-headers==4.3.1 django-debug-toolbar==4.3.0 -django-filter==23.5 +django-filter==24.1 django-graphiql-debug-toolbar==0.2.0 django-mptt==0.14.0 django-pglocks==1.0.4 @@ -15,14 +15,14 @@ django-tables2==2.7.0 django-timezone-field==6.1.0 djangorestframework==3.14.0 drf-spectacular==0.27.1 -drf-spectacular-sidecar==2024.2.1 +drf-spectacular-sidecar==2024.3.4 feedparser==6.0.11 graphene-django==3.0.0 gunicorn==21.2.0 Jinja2==3.1.3 Markdown==3.5.2 -mkdocs-material==9.5.10 -mkdocstrings[python-legacy]==0.24.0 +mkdocs-material==9.5.13 +mkdocstrings[python-legacy]==0.24.1 netaddr==1.2.1 Pillow==10.2.0 psycopg[binary,pool]==3.1.18 From 4adb44f60d91fec19c800ea0e03800e2eb338f06 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 13 Mar 2024 19:37:28 -0400 Subject: [PATCH 23/23] PRVB --- docs/release-notes/version-3.7.md | 4 ++++ netbox/netbox/settings.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.7.md b/docs/release-notes/version-3.7.md index fd61218e5..9724c4488 100644 --- a/docs/release-notes/version-3.7.md +++ b/docs/release-notes/version-3.7.md @@ -1,5 +1,9 @@ # NetBox v3.7 +## v3.7.5 (FUTURE) + +--- + ## v3.7.4 (2024-03-13) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 007164a6d..e662561ee 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -28,7 +28,7 @@ from netbox.plugins import PluginConfig # Environment setup # -VERSION = '3.7.4' +VERSION = '3.7.5-dev' # Hostname HOSTNAME = platform.node()