Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v4.1.1 #17478

Merged
merged 33 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
886d635
Update source translation strings
github-actions[bot] Sep 4, 2024
8cc0616
17354 fix import with custom-field (#17368)
arthanson Sep 4, 2024
5c33aa8
Fixes #17332: Restore pagination for object list dashboard widgets
jeremystretch Sep 4, 2024
7404cae
17353 make map buttons consistent (#17371)
arthanson Sep 4, 2024
2a1710b
Changelog for #17332, #17353, #17354, #17364
jeremystretch Sep 4, 2024
684cdda
Update source translation strings
github-actions[bot] Sep 5, 2024
ed1b8bc
16349 add warning to custom script docs
arthanson Sep 5, 2024
76ff329
Closes #17384: Reorder GitHub issue templates
jeremystretch Sep 5, 2024
16f74f7
Fixed view permissions for ObjectChange
peteeckel Sep 5, 2024
7ab2ebc
Disable Directory Browsing for Static file path in Apache2 config
marsteel Sep 6, 2024
aca693b
17066 fix put/patch for Script OpenAPI docs
arthanson Sep 5, 2024
43b9497
Closes #16926 Adds various USB cable types to front/rear ports and ca…
Brian-Chow Sep 9, 2024
0c2861e
Update source translation strings
github-actions[bot] Sep 10, 2024
93eea95
Add NEMA L22-20
amit177 Sep 6, 2024
81a1280
17414 allow single vlan in vlan group (#17418)
arthanson Sep 10, 2024
ce38484
Changelog for #16926, #17066, #17347, #17387, #17414
jeremystretch Sep 10, 2024
353db09
17422 update custom field group display tag (#17423)
arthanson Sep 10, 2024
ce372ce
Update source translation strings
github-actions[bot] Sep 11, 2024
89604ce
Add a step to the release checklist documentation for testing migrati…
bctiemann Sep 10, 2024
bf7b8b2
Fix migration dependencies for 3.7->4.1 path
bctiemann Sep 10, 2024
5f32b23
17410 only add debug middleware if DEBUG
arthanson Sep 9, 2024
213eb61
Fixes #17362: Fix unicity of VRF returned by filter_present_in_vrf fu…
pl0xym0r Sep 5, 2024
af5fb8f
Update source translation strings
github-actions[bot] Sep 12, 2024
c0d5d98
17457 Make NumericArrayFilter optional
arthanson Sep 11, 2024
ee7ac6f
17444 fix event rules jobs enqueue (#17458)
arthanson Sep 12, 2024
52299fa
17333 don't prefetch jobs on script api call
arthanson Sep 4, 2024
114b8a2
Fixes #17437: Fix exception when specifying a bridge relationship on …
jeremystretch Sep 12, 2024
5486e92
Ignore blocked PRs
jeremystretch Sep 12, 2024
5ce8b6b
Delete obsolete static resources
jeremystretch Sep 12, 2024
b3e4d3c
Remove markdown-include
jeremystretch Sep 12, 2024
84ea437
Updates for project NetBox (#17474)
transifex-integration[bot] Sep 12, 2024
1893568
Release v4.1.1
jeremystretch Sep 12, 2024
15a106b
Merge branch 'master' into develop
jeremystretch Sep 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ body:
attributes:
label: NetBox version
description: What version of NetBox are you currently running?
placeholder: v4.1.0
placeholder: v4.1.1
validations:
required: true
- type: dropdown
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ body:
attributes:
label: NetBox Version
description: What version of NetBox are you currently running?
placeholder: v4.1.0
placeholder: v4.1.1
validations:
required: true
- type: dropdown
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/close-stale-issues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ jobs:
This PR has been automatically closed due to lack of activity.
days-before-pr-stale: 15
days-before-pr-close: 15
exempt-pr-labels: 'status: blocked'
stale-pr-label: 'pending closure'
stale-pr-message: >
This PR has been automatically marked as stale because it has not had
Expand Down
4 changes: 0 additions & 4 deletions base_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,6 @@ Jinja2
# https://python-markdown.github.io/changelog/
Markdown

# File inclusion plugin for Python-Markdown
# https://github.com/cmacmackin/markdown-include
markdown-include

# MkDocs Material theme (for documentation build)
# https://squidfunk.github.io/mkdocs-material/changelog/
mkdocs-material
Expand Down
2 changes: 1 addition & 1 deletion contrib/apache.conf
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
Alias /static /opt/netbox/netbox/static

<Directory /opt/netbox/netbox/static>
Options Indexes FollowSymLinks MultiViews
Options FollowSymLinks MultiViews
AllowOverride None
Require all granted
</Directory>
Expand Down
18 changes: 18 additions & 0 deletions contrib/generated_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
"nema-l15-60p",
"nema-l21-20p",
"nema-l21-30p",
"nema-l22-20p",
"nema-l22-30p",
"cs6361c",
"cs6365c",
Expand Down Expand Up @@ -262,6 +263,7 @@
"nema-l15-60r",
"nema-l21-20r",
"nema-l21-30r",
"nema-l22-20r",
"nema-l22-30r",
"CS6360C",
"CS6364C",
Expand Down Expand Up @@ -518,6 +520,14 @@
"urm-p4",
"urm-p8",
"splice",
"usb-a",
"usb-b",
"usb-c",
"usb-mini-a",
"usb-mini-b",
"usb-micro-a",
"usb-micro-b",
"usb-micro-ab",
"other"
]
}
Expand Down Expand Up @@ -575,6 +585,14 @@
"urm-p4",
"urm-p8",
"splice",
"usb-a",
"usb-b",
"usb-c",
"usb-mini-a",
"usb-mini-b",
"usb-micro-a",
"usb-micro-b",
"usb-micro-ab",
"other"
]
}
Expand Down
3 changes: 3 additions & 0 deletions docs/customization/custom-scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ They can also be used as a mechanism for validating the integrity of data within

Custom scripts are Python code which exists outside the NetBox code base, so they can be updated and changed without interfering with the core NetBox installation. And because they're completely custom, there is no inherent limitation on what a script can accomplish.

!!! danger "Only install trusted scripts"
Custom scripts have unrestricted access to change anything in the databse and are inherently unsafe and should only be installed and run from trusted sources. You should also review and set permissions for who can run scripts if the script can modify any data.

## Writing Custom Scripts

All custom scripts must inherit from the `extras.scripts.Script` base class. This class provides the functionality necessary to generate forms and log activity.
Expand Down
4 changes: 4 additions & 0 deletions docs/development/release-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ mkdocs serve

Follow these instructions to perform a new installation of NetBox in a temporary environment. This process must not be automated: The goal of this step is to catch any errors or omissions in the documentation, and ensure that it is kept up-to-date for each release. Make any necessary changes to the documentation before proceeding with the release.

### Test Upgrade Paths

Upgrading from a previous version typically involves database migrations, which must work without errors. Supported upgrade paths include from one minor version to another within the same major version (i.e. 4.0 to 4.1), as well as from the latest patch version of the previous minor version (i.e. 3.7 to 4.0 or to 4.1). Prior to release, test all these supported paths by loading demo data from the source version and performing a `./manage.py migrate`.

### Merge the Release Branch

Submit a pull request to merge the `feature` branch into the `develop` branch in preparation for its release. Once it has been merged, continue with the section for patch releases below.
Expand Down
26 changes: 26 additions & 0 deletions docs/release-notes/version-4.1.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
# NetBox v4.1

## v4.1.1 (2024-09-12)

### Enhancements

* [#16926](https://github.com/netbox-community/netbox/issues/16926) - Add USB front & rear port types
* [#17347](https://github.com/netbox-community/netbox/issues/17347) - Add NEMA L22-20 power port & outlet types

### Bug Fixes

* [#17066](https://github.com/netbox-community/netbox/issues/17066) - Fix OpenAPI schema definition for custom scripts REST API endpoint
* [#17332](https://github.com/netbox-community/netbox/issues/17332) - Restore pagination for object list dashboard widgets
* [#17333](https://github.com/netbox-community/netbox/issues/17333) - Avoid prefetching all jobs when retrieving custom scripts via the REST API
* [#17353](https://github.com/netbox-community/netbox/issues/17353) - Fix styling of map buttons under site and device views
* [#17354](https://github.com/netbox-community/netbox/issues/17354) - Prevent object & multi-object custom fields from breaking bulk import forms
* [#17362](https://github.com/netbox-community/netbox/issues/17362) - Remove duplicate prefixes & IP addresses returned by the `present_in_vrf` query filter
* [#17364](https://github.com/netbox-community/netbox/issues/17364) - Fix rendering of Markdown tables inside object list dashboard widgets
* [#17387](https://github.com/netbox-community/netbox/issues/17387) - Fix display of the changelog tab for users with sufficient permission
* [#17410](https://github.com/netbox-community/netbox/issues/17410) - Enable debug toolbar middleware for `strawberry-django` only when `DEBUG` is true
* [#17414](https://github.com/netbox-community/netbox/issues/17414) - Fix support for declaring individual VLAN IDs within a VLAN group
* [#17431](https://github.com/netbox-community/netbox/issues/17431) - Fix database migration error when upgrading to v4.1 from v3.7 or earlier
* [#17437](https://github.com/netbox-community/netbox/issues/17437) - Fix exception when specifying a bridge relationship on an interface template
* [#17444](https://github.com/netbox-community/netbox/issues/17444) - Custom script fails to execute when triggered by an event rule
* [#17457](https://github.com/netbox-community/netbox/issues/17457) - GraphQL `service_list` filter should not require a port number

---

## v4.1.0 (2024-09-03)

### Breaking Changes
Expand Down
2 changes: 1 addition & 1 deletion netbox/dcim/api/serializers_/nested.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class NestedInterfaceTemplateSerializer(WritableNestedSerializer):

class Meta:
model = models.InterfaceTemplate
fields = ['id', 'url', 'display_url', 'display', 'name']
fields = ['id', 'url', 'display', 'name']


class NestedDeviceBaySerializer(WritableNestedSerializer):
Expand Down
27 changes: 27 additions & 0 deletions netbox/dcim/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ class PowerPortTypeChoices(ChoiceSet):
TYPE_NEMA_L1560P = 'nema-l15-60p'
TYPE_NEMA_L2120P = 'nema-l21-20p'
TYPE_NEMA_L2130P = 'nema-l21-30p'
TYPE_NEMA_L2220P = 'nema-l22-20p'
TYPE_NEMA_L2230P = 'nema-l22-30p'
# California style
TYPE_CS6361C = 'cs6361c'
Expand Down Expand Up @@ -517,6 +518,7 @@ class PowerPortTypeChoices(ChoiceSet):
(TYPE_NEMA_L1560P, 'NEMA L15-60P'),
(TYPE_NEMA_L2120P, 'NEMA L21-20P'),
(TYPE_NEMA_L2130P, 'NEMA L21-30P'),
(TYPE_NEMA_L2220P, 'NEMA L22-20P'),
(TYPE_NEMA_L2230P, 'NEMA L22-30P'),
)),
(_('California Style'), (
Expand Down Expand Up @@ -649,6 +651,7 @@ class PowerOutletTypeChoices(ChoiceSet):
TYPE_NEMA_L1560R = 'nema-l15-60r'
TYPE_NEMA_L2120R = 'nema-l21-20r'
TYPE_NEMA_L2130R = 'nema-l21-30r'
TYPE_NEMA_L2220R = 'nema-l22-20r'
TYPE_NEMA_L2230R = 'nema-l22-30r'
# California style
TYPE_CS6360C = 'CS6360C'
Expand Down Expand Up @@ -763,6 +766,7 @@ class PowerOutletTypeChoices(ChoiceSet):
(TYPE_NEMA_L1560R, 'NEMA L15-60R'),
(TYPE_NEMA_L2120R, 'NEMA L21-20R'),
(TYPE_NEMA_L2130R, 'NEMA L21-30R'),
(TYPE_NEMA_L2220R, 'NEMA L22-20R'),
(TYPE_NEMA_L2230R, 'NEMA L22-30R'),
)),
(_('California Style'), (
Expand Down Expand Up @@ -1347,6 +1351,14 @@ class PortTypeChoices(ChoiceSet):
TYPE_URM_P2 = 'urm-p2'
TYPE_URM_P4 = 'urm-p4'
TYPE_URM_P8 = 'urm-p8'
TYPE_USB_A = 'usb-a'
TYPE_USB_B = 'usb-b'
TYPE_USB_C = 'usb-c'
TYPE_USB_MINI_A = 'usb-mini-a'
TYPE_USB_MINI_B = 'usb-mini-b'
TYPE_USB_MICRO_A = 'usb-micro-a'
TYPE_USB_MICRO_B = 'usb-micro-b'
TYPE_USB_MICRO_AB = 'usb-micro-ab'
TYPE_OTHER = 'other'

CHOICES = (
Expand Down Expand Up @@ -1406,6 +1418,19 @@ class PortTypeChoices(ChoiceSet):
(TYPE_SPLICE, 'Splice'),
),
),
(
_('USB'),
(
(TYPE_USB_A, 'USB Type A'),
(TYPE_USB_B, 'USB Type B'),
(TYPE_USB_C, 'USB Type C'),
(TYPE_USB_MINI_A, 'USB Mini A'),
(TYPE_USB_MINI_B, 'USB Mini B'),
(TYPE_USB_MICRO_A, 'USB Micro A'),
(TYPE_USB_MICRO_B, 'USB Micro B'),
(TYPE_USB_MICRO_AB, 'USB Micro AB'),
),
),
(
_('Other'),
(
Expand Down Expand Up @@ -1444,6 +1469,7 @@ class CableTypeChoices(ChoiceSet):
TYPE_SMF_OS2 = 'smf-os2'
TYPE_AOC = 'aoc'
TYPE_POWER = 'power'
TYPE_USB = 'usb'

CHOICES = (
(
Expand Down Expand Up @@ -1476,6 +1502,7 @@ class CableTypeChoices(ChoiceSet):
(TYPE_AOC, 'Active Optical Cabling (AOC)'),
),
),
(TYPE_USB, _('USB')),
(TYPE_POWER, _('Power')),
)

Expand Down
4 changes: 2 additions & 2 deletions netbox/dcim/forms/model_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -975,8 +975,8 @@ class InterfaceTemplateForm(ModularComponentTemplateForm):
queryset=InterfaceTemplate.objects.all(),
required=False,
query_params={
'devicetype_id': '$device_type',
'moduletype_id': '$module_type',
'device_type_id': '$device_type',
'module_type_id': '$module_type',
}
)

Expand Down
7 changes: 6 additions & 1 deletion netbox/extras/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.shortcuts import get_object_or_404
from django.utils.module_loading import import_string
from django_rq.queues import get_connection
from drf_spectacular.utils import extend_schema, extend_schema_view
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied
Expand Down Expand Up @@ -229,9 +230,13 @@ def render(self, request, pk):
# Scripts
#

@extend_schema_view(
update=extend_schema(request=serializers.ScriptInputSerializer),
partial_update=extend_schema(request=serializers.ScriptInputSerializer),
)
class ScriptViewSet(ModelViewSet):
permission_classes = [IsAuthenticatedOrLoginNotRequired]
queryset = Script.objects.prefetch_related('jobs')
queryset = Script.objects.all()
serializer_class = serializers.ScriptSerializer
filterset_class = filtersets.ScriptFilterSet

Expand Down
30 changes: 18 additions & 12 deletions netbox/extras/models/customfields.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,23 +525,29 @@ def to_form_field(self, set_initial=True, enforce_required=True, enforce_visibil
elif self.type == CustomFieldTypeChoices.TYPE_OBJECT:
model = self.related_object_type.model_class()
field_class = CSVModelChoiceField if for_csv_import else DynamicModelChoiceField
field = field_class(
queryset=model.objects.all(),
required=required,
initial=initial,
query_params=self.related_object_filter
)
kwargs = {
'queryset': model.objects.all(),
'required': required,
'initial': initial,
}
if not for_csv_import:
kwargs['query_params'] = self.related_object_filter

field = field_class(**kwargs)

# Multiple objects
elif self.type == CustomFieldTypeChoices.TYPE_MULTIOBJECT:
model = self.related_object_type.model_class()
field_class = CSVModelMultipleChoiceField if for_csv_import else DynamicModelMultipleChoiceField
field = field_class(
queryset=model.objects.all(),
required=required,
initial=initial,
query_params=self.related_object_filter
)
kwargs = {
'queryset': model.objects.all(),
'required': required,
'initial': initial,
}
if not for_csv_import:
kwargs['query_params'] = self.related_object_filter

field = field_class(**kwargs)

# Text
else:
Expand Down
4 changes: 2 additions & 2 deletions netbox/ipam/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ def filter_present_in_vrf(self, queryset, name, vrf):
return queryset.filter(
Q(vrf=vrf) |
Q(vrf__export_targets__in=vrf.import_targets.all())
)
).distinct()


class IPRangeFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
Expand Down Expand Up @@ -738,7 +738,7 @@ def filter_present_in_vrf(self, queryset, name, vrf):
return queryset.filter(
Q(vrf=vrf) |
Q(vrf__export_targets__in=vrf.import_targets.all())
)
).distinct()

def filter_device(self, queryset, name, value):
devices = Device.objects.filter(**{'{}__in'.format(name): value})
Expand Down
2 changes: 1 addition & 1 deletion netbox/ipam/models/vlans.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def clean(self):
if self.vid_ranges and check_ranges_overlap(self.vid_ranges):
raise ValidationError({'vid_ranges': _("Ranges cannot overlap.")})
for vid_range in self.vid_ranges:
if vid_range.lower >= vid_range.upper:
if vid_range.lower > vid_range.upper:
raise ValidationError({
'vid_ranges': _(
"Maximum child VID must be greater than or equal to minimum child VID ({value})"
Expand Down
14 changes: 14 additions & 0 deletions netbox/ipam/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,3 +543,17 @@ def test_vid_validation(self):

vlan = VLAN(vid=109, name='VLAN 109', group=vlangroup)
vlan.full_clean()

def test_overlapping_vlan(self):
vlangroup = VLANGroup(
name='VLAN Group 1',
slug='vlan-group-1',
vid_ranges=string_to_ranges('2-4,3-5'),
)
with self.assertRaises(ValidationError):
vlangroup.full_clean()

# make sure single vlan range works
vlangroup.vid_ranges = string_to_ranges('2-2')
vlangroup.full_clean()
vlangroup.save()
2 changes: 1 addition & 1 deletion netbox/netbox/graphql/filter_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def map_strawberry_type(field):
pass
elif isinstance(field, NumericArrayFilter):
should_create_function = True
attr_type = int
attr_type = int | None
elif isinstance(field, TreeNodeMultipleChoiceFilter):
should_create_function = True
attr_type = List[str] | None
Expand Down
3 changes: 2 additions & 1 deletion netbox/netbox/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ def enqueue(cls, *args, **kwargs):
This method is a wrapper of `Job.enqueue()` using `handle()` as function callback. See its documentation for
parameters.
"""
return Job.enqueue(cls.handle, name=cls.name, *args, **kwargs)
name = kwargs.pop('name', None) or cls.name
return Job.enqueue(cls.handle, name=name, *args, **kwargs)

@classmethod
@advisory_lock(ADVISORY_LOCK_KEYS['job-schedules'])
Expand Down
8 changes: 7 additions & 1 deletion netbox/netbox/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,6 @@ def _setting(name, default=None):

# Middleware
MIDDLEWARE = [
"strawberry_django.middlewares.debug_toolbar.DebugToolbarMiddleware",
'corsheaders.middleware.CorsMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
Expand All @@ -431,6 +430,13 @@ def _setting(name, default=None):
'netbox.middleware.CoreMiddleware',
'netbox.middleware.MaintenanceModeMiddleware',
]

if DEBUG:
MIDDLEWARE = [
"strawberry_django.middlewares.debug_toolbar.DebugToolbarMiddleware",
*MIDDLEWARE,
]

if METRICS_ENABLED:
# If metrics are enabled, add the before & after Prometheus middleware
MIDDLEWARE = [
Expand Down
Loading