mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-25 01:48:38 -06:00
Merge branch 'develop' into feature
This commit is contained in:
commit
e3f5062583
8
.github/workflows/stale.yml
vendored
8
.github/workflows/stale.yml
vendored
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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',
|
||||||
|
@ -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):
|
||||||
|
@ -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
netbox/ipam/signals.py
Normal file
21
netbox/ipam/signals.py
Normal file
@ -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()
|
@ -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(),
|
||||||
|
Loading…
Reference in New Issue
Block a user