Procházet zdrojové kódy

Merge branch 'develop' into feature

jeremystretch před 4 roky
rodič
revize
e3f5062583

+ 4 - 4
.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:
 on:
   schedule:
   schedule:
     - cron: '0 4 * * *'
     - cron: '0 4 * * *'
@@ -9,7 +10,6 @@ jobs:
     steps:
     steps:
       - uses: actions/stale@v3
       - uses: actions/stale@v3
         with:
         with:
-          debug-only: true
           close-issue-message: >
           close-issue-message: >
             This issue has been automatically closed due to lack of activity. In an
             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
             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.
             This PR has been automatically closed due to lack of activity.
           days-before-stale: 45
           days-before-stale: 45
           days-before-close: 15
           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
           remove-stale-when-updated: false
           stale-issue-label: 'pending closure'
           stale-issue-label: 'pending closure'
           stale-issue-message: >
           stale-issue-message: >
@@ -27,7 +27,7 @@ jobs:
             recent activity. It will be closed if no further activity occurs. NetBox
             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
             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).
             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: >
           stale-pr-message: >
             This PR has been automatically marked as stale because it has not had
             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
             recent activity. It will be closed automatically if no further action is

+ 11 - 0
docs/release-notes/version-2.10.md

@@ -1,5 +1,16 @@
 # NetBox v2.10
 # NetBox v2.10
 
 
+## v2.10.10 (FUTURE)
+
+### 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
+
+---
+
 ## v2.10.9 (2021-04-12)
 ## v2.10.9 (2021-04-12)
 
 
 ### Enhancements
 ### Enhancements

+ 2 - 2
netbox/dcim/filters.py

@@ -1093,7 +1093,7 @@ class InventoryItemFilterSet(BaseFilterSet, DeviceComponentFilterSet):
         return queryset.filter(qs_filter)
         return queryset.filter(qs_filter)
 
 
 
 
-class VirtualChassisFilterSet(BaseFilterSet):
+class VirtualChassisFilterSet(BaseFilterSet, CustomFieldModelFilterSet):
     q = django_filters.CharFilter(
     q = django_filters.CharFilter(
         method='search',
         method='search',
         label='Search',
         label='Search',
@@ -1173,7 +1173,7 @@ class VirtualChassisFilterSet(BaseFilterSet):
         return queryset.filter(qs_filter).distinct()
         return queryset.filter(qs_filter).distinct()
 
 
 
 
-class CableFilterSet(BaseFilterSet):
+class CableFilterSet(BaseFilterSet, CustomFieldModelFilterSet):
     q = django_filters.CharFilter(
     q = django_filters.CharFilter(
         method='search',
         method='search',
         label='Search',
         label='Search',

+ 2 - 1
netbox/extras/signals.py

@@ -4,6 +4,7 @@ from datetime import timedelta
 from cacheops.signals import cache_invalidated, cache_read
 from cacheops.signals import cache_invalidated, cache_read
 from django.conf import settings
 from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
 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, pre_delete
 from django.utils import timezone
 from django.utils import timezone
 from django_prometheus.models import model_deletes, model_inserts, model_updates
 from django_prometheus.models import model_deletes, model_inserts, model_updates
@@ -64,7 +65,7 @@ def _handle_changed_object(request, sender, instance, **kwargs):
     # Housekeeping: 0.1% chance of clearing out expired ObjectChanges
     # Housekeeping: 0.1% chance of clearing out expired ObjectChanges
     if settings.CHANGELOG_RETENTION and random.randint(1, 1000) == 1:
     if settings.CHANGELOG_RETENTION and random.randint(1, 1000) == 1:
         cutoff = timezone.now() - timedelta(days=settings.CHANGELOG_RETENTION)
         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):
 def _handle_deleted_object(request, sender, instance, **kwargs):

+ 3 - 0
netbox/ipam/apps.py

@@ -4,3 +4,6 @@ from django.apps import AppConfig
 class IPAMConfig(AppConfig):
 class IPAMConfig(AppConfig):
     name = "ipam"
     name = "ipam"
     verbose_name = "IPAM"
     verbose_name = "IPAM"
+
+    def ready(self):
+        import ipam.signals

+ 21 - 0
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()

+ 1 - 1
netbox/virtualization/forms.py

@@ -806,7 +806,7 @@ class VMInterfaceBulkRenameForm(BulkRenameForm):
     )
     )
 
 
 
 
-class VMInterfaceFilterForm(forms.Form):
+class VMInterfaceFilterForm(BootstrapMixin, forms.Form):
     model = VMInterface
     model = VMInterface
     cluster_id = DynamicModelMultipleChoiceField(
     cluster_id = DynamicModelMultipleChoiceField(
         queryset=Cluster.objects.all(),
         queryset=Cluster.objects.all(),