diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 6ee058e89..419af2c7a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -17,7 +17,7 @@ body: What version of NetBox are you currently running? (If you don't have access to the most recent NetBox release, consider testing on our [demo instance](https://demo.netbox.dev/) before opening a bug report to see if your issue has already been addressed.) - placeholder: v2.11.5 + placeholder: v2.11.6 validations: required: true - type: dropdown diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index c18fc3a1a..80cad1a52 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: v2.11.5 + placeholder: v2.11.6 validations: required: true - type: dropdown diff --git a/docs/release-notes/version-2.11.md b/docs/release-notes/version-2.11.md index db773e2bd..f010e5d1b 100644 --- a/docs/release-notes/version-2.11.md +++ b/docs/release-notes/version-2.11.md @@ -1,5 +1,29 @@ # NetBox v2.11 +## v2.11.7 (FUTURE) + +### Enhancements + +* [#6455](https://github.com/netbox-community/netbox/issues/6455) - Permit /32 IPv4 and /128 IPv6 prefixes +* [#6493](https://github.com/netbox-community/netbox/issues/6493) - Show change log diff for non-atomic (pre-2.11) changes + +### Bug Fixes + +* [#6553](https://github.com/netbox-community/netbox/issues/6553) - ProviderNetwork search should match on name +* [#6562](https://github.com/netbox-community/netbox/issues/6562) - Disable ordering of secrets by assigned object +* [#6563](https://github.com/netbox-community/netbox/issues/6563) - Fix filtering by location for cable connection forms +* [#6584](https://github.com/netbox-community/netbox/issues/6584) - Fix ordering of nested inventory items + +--- + +## v2.11.6 (2021-06-04) + +### Bug Fixes + +* [#6544](https://github.com/netbox-community/netbox/issues/6544) - Fix migration error when upgrading with VRF(s) defined + +--- + ## v2.11.5 (2021-06-04) **NOTE:** This release includes a database migration that calculates and annotates prefix depth. It may impose a noticeable delay on the upgrade process: Users should anticipate roughly one minute of delay per 100 thousand prefixes being updated. diff --git a/netbox/circuits/filtersets.py b/netbox/circuits/filtersets.py index 066178685..15bc5a8b3 100644 --- a/netbox/circuits/filtersets.py +++ b/netbox/circuits/filtersets.py @@ -104,6 +104,7 @@ class ProviderNetworkFilterSet(PrimaryModelFilterSet): if not value.strip(): return queryset return queryset.filter( + Q(name__icontains=value) | Q(description__icontains=value) | Q(comments__icontains=value) ).distinct() diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 572814872..c98c52db9 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -4031,6 +4031,7 @@ class ConnectCableToDeviceForm(BootstrapMixin, CustomFieldModelForm): required=False, query_params={ 'site_id': '$termination_b_site', + 'location_id': '$termination_b_location', 'rack_id': '$termination_b_rack', } ) diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index 013bfa1ce..8ac53aee6 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -709,7 +709,7 @@ class InventoryItemTable(DeviceComponentTable): ) cable = None # Override DeviceComponentTable - class Meta(DeviceComponentTable.Meta): + class Meta(BaseTable.Meta): model = InventoryItem fields = ( 'pk', 'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description', @@ -730,7 +730,7 @@ class DeviceInventoryItemTable(InventoryItemTable): buttons=('edit', 'delete') ) - class Meta(DeviceComponentTable.Meta): + class Meta(BaseTable.Meta): model = InventoryItem fields = ( 'pk', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description', 'discovered', diff --git a/netbox/extras/views.py b/netbox/extras/views.py index 3f86c98d2..5316cfbec 100644 --- a/netbox/extras/views.py +++ b/netbox/extras/views.py @@ -202,15 +202,22 @@ class ObjectChangeView(generic.ObjectView): next_change = objectchanges.filter(time__gt=instance.time).order_by('time').first() prev_change = objectchanges.filter(time__lt=instance.time).order_by('-time').first() - if instance.prechange_data and instance.postchange_data: + if not instance.prechange_data and instance.action in ['update', 'delete'] and prev_change: + non_atomic_change = True + prechange_data = prev_change.postchange_data + else: + non_atomic_change = False + prechange_data = instance.prechange_data + + if prechange_data and instance.postchange_data: diff_added = shallow_compare_dict( - instance.prechange_data or dict(), + prechange_data or dict(), instance.postchange_data or dict(), exclude=['last_updated'], ) diff_removed = { - x: instance.prechange_data.get(x) for x in diff_added - } if instance.prechange_data else {} + x: prechange_data.get(x) for x in diff_added + } if prechange_data else {} else: diff_added = None diff_removed = None @@ -221,7 +228,8 @@ class ObjectChangeView(generic.ObjectView): 'next_change': next_change, 'prev_change': prev_change, 'related_changes_table': related_changes_table, - 'related_changes_count': related_changes.count() + 'related_changes_count': related_changes.count(), + 'non_atomic_change': non_atomic_change } diff --git a/netbox/ipam/management/commands/rebuild_prefixes.py b/netbox/ipam/management/commands/rebuild_prefixes.py index 5d614b834..f84ff3ea4 100644 --- a/netbox/ipam/management/commands/rebuild_prefixes.py +++ b/netbox/ipam/management/commands/rebuild_prefixes.py @@ -22,6 +22,6 @@ class Command(BaseCommand): for vrf in VRF.objects.all(): vrf_count = Prefix.objects.filter(vrf=vrf).count() self.stdout.write(f'VRF {vrf}: {vrf_count} prefixes...') - rebuild_prefixes(vrf) + rebuild_prefixes(vrf.pk) self.stdout.write(self.style.SUCCESS('Finished.')) diff --git a/netbox/ipam/migrations/0048_prefix_populate_depth_children.py b/netbox/ipam/migrations/0048_prefix_populate_depth_children.py index 279f899f6..5ec448ee1 100644 --- a/netbox/ipam/migrations/0048_prefix_populate_depth_children.py +++ b/netbox/ipam/migrations/0048_prefix_populate_depth_children.py @@ -20,7 +20,7 @@ def populate_prefix_hierarchy(apps, schema_editor): # Iterate through all VRFs, rebuilding each for vrf in VRF.objects.all(): - rebuild_prefixes(vrf) + rebuild_prefixes(vrf.pk) class Migration(migrations.Migration): diff --git a/netbox/ipam/models/ip.py b/netbox/ipam/models/ip.py index d6b274bbb..40fa4ad42 100644 --- a/netbox/ipam/models/ip.py +++ b/netbox/ipam/models/ip.py @@ -311,16 +311,6 @@ class Prefix(PrimaryModel): 'prefix': "Cannot create prefix with /0 mask." }) - # Disallow host masks - if self.prefix.version == 4 and self.prefix.prefixlen == 32: - raise ValidationError({ - 'prefix': "Cannot create host addresses (/32) as prefixes. Create an IPv4 address instead." - }) - elif self.prefix.version == 6 and self.prefix.prefixlen == 128: - raise ValidationError({ - 'prefix': "Cannot create host addresses (/128) as prefixes. Create an IPv6 address instead." - }) - # Enforce unique IP space (if applicable) if (self.vrf is None and settings.ENFORCE_GLOBAL_UNIQUE) or (self.vrf and self.vrf.enforce_unique): duplicate_prefixes = self.get_duplicates() @@ -431,8 +421,8 @@ class Prefix(PrimaryModel): child_ips = netaddr.IPSet([ip.address.ip for ip in self.get_child_ips()]) available_ips = prefix - child_ips - # IPv6, pool, or IPv4 /31 sets are fully usable - if self.family == 6 or self.is_pool or self.prefix.prefixlen == 31: + # IPv6, pool, or IPv4 /31-/32 sets are fully usable + if self.family == 6 or self.is_pool or (self.family == 4 and self.prefix.prefixlen >= 31): return available_ips # For "normal" IPv4 prefixes, omit first and last addresses diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 8de6e9b1c..919b09b79 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -522,7 +522,7 @@ class IPAddressView(generic.ObjectView): # Parent prefixes table parent_prefixes = Prefix.objects.restrict(request.user, 'view').filter( vrf=instance.vrf, - prefix__net_contains=str(instance.address.ip) + prefix__net_contains_or_equals=str(instance.address.ip) ).prefetch_related( 'site', 'role' ) diff --git a/netbox/templates/extras/objectchange.html b/netbox/templates/extras/objectchange.html index caffd80b0..a8619e8fe 100644 --- a/netbox/templates/extras/objectchange.html +++ b/netbox/templates/extras/objectchange.html @@ -129,6 +129,8 @@ {{ k }}: {{ v|render_json }} {% endspaceless %}{% endfor %} + {% elif non_atomic_change %} + Warning: Comparing non-atomic change to previous change record ({{ prev_change.pk }}) {% else %} None {% endif %} diff --git a/netbox/utilities/tables.py b/netbox/utilities/tables.py index 1e39dc3cd..2103e7e11 100644 --- a/netbox/utilities/tables.py +++ b/netbox/utilities/tables.py @@ -349,8 +349,11 @@ class MPTTColumn(tables.TemplateColumn): """ Display a nested hierarchy for MPTT-enabled models. """ - template_code = """{% for i in record.get_ancestors %}{% endfor %}""" \ - """{{ record.name }}""" + template_code = """ + {% load helpers %} + {% for i in record.level|as_range %}{% endfor %} + {{ record.name }} + """ def __init__(self, *args, **kwargs): super().__init__(