mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Add dynamic config JOBRESULT_RETENTION
and cleanup functionality to the housekeeping script
This commit is contained in:
@ -4,6 +4,7 @@ NetBox includes a `housekeeping` management command that should be run nightly.
|
|||||||
|
|
||||||
* Clearing expired authentication sessions from the database
|
* Clearing expired authentication sessions from the database
|
||||||
* Deleting changelog records older than the configured [retention time](../configuration/dynamic-settings.md#changelog_retention)
|
* Deleting changelog records older than the configured [retention time](../configuration/dynamic-settings.md#changelog_retention)
|
||||||
|
* Deleting job result records older than the configured [retention time](../configuration/dynamic-settings.md#jobresult_retention)
|
||||||
|
|
||||||
This command can be invoked directly, or by using the shell script provided at `/opt/netbox/contrib/netbox-housekeeping.sh`. This script can be linked from your cron scheduler's daily jobs directory (e.g. `/etc/cron.daily`) or referenced directly within the cron configuration file.
|
This command can be invoked directly, or by using the shell script provided at `/opt/netbox/contrib/netbox-housekeeping.sh`. This script can be linked from your cron scheduler's daily jobs directory (e.g. `/etc/cron.daily`) or referenced directly within the cron configuration file.
|
||||||
|
|
||||||
|
@ -43,6 +43,18 @@ changes in the database indefinitely.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## JOBRESULT_RETENTION
|
||||||
|
|
||||||
|
Default: 0
|
||||||
|
|
||||||
|
The number of days to retain job results (scripts and reports). Set this to `0` to retain
|
||||||
|
job results in the database indefinitely.
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
If enabling indefinite job results retention, it is recommended to periodically delete old entries. Otherwise, the database may eventually exceed capacity.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## CUSTOM_VALIDATORS
|
## CUSTOM_VALIDATORS
|
||||||
|
|
||||||
This is a mapping of models to [custom validators](../customization/custom-validation.md) that have been defined locally to enforce custom validation logic. An example is provided below:
|
This is a mapping of models to [custom validators](../customization/custom-validation.md) that have been defined locally to enforce custom validation logic. An example is provided below:
|
||||||
|
@ -40,7 +40,7 @@ class ConfigRevisionAdmin(admin.ModelAdmin):
|
|||||||
'fields': ('DEFAULT_USER_PREFERENCES',),
|
'fields': ('DEFAULT_USER_PREFERENCES',),
|
||||||
}),
|
}),
|
||||||
('Miscellaneous', {
|
('Miscellaneous', {
|
||||||
'fields': ('MAINTENANCE_MODE', 'GRAPHQL_ENABLED', 'CHANGELOG_RETENTION', 'MAPS_URL'),
|
'fields': ('MAINTENANCE_MODE', 'GRAPHQL_ENABLED', 'CHANGELOG_RETENTION', 'JOBRESULT_RETENTION', 'MAPS_URL'),
|
||||||
}),
|
}),
|
||||||
('Config Revision', {
|
('Config Revision', {
|
||||||
'fields': ('comment',),
|
'fields': ('comment',),
|
||||||
|
@ -9,6 +9,7 @@ from django.db import DEFAULT_DB_ALIAS
|
|||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from packaging import version
|
from packaging import version
|
||||||
|
|
||||||
|
from extras.models import JobResult
|
||||||
from extras.models import ObjectChange
|
from extras.models import ObjectChange
|
||||||
from netbox.config import Config
|
from netbox.config import Config
|
||||||
|
|
||||||
@ -63,6 +64,33 @@ class Command(BaseCommand):
|
|||||||
f"\tSkipping: No retention period specified (CHANGELOG_RETENTION = {config.CHANGELOG_RETENTION})"
|
f"\tSkipping: No retention period specified (CHANGELOG_RETENTION = {config.CHANGELOG_RETENTION})"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Delete expired JobResults
|
||||||
|
if options['verbosity']:
|
||||||
|
self.stdout.write("[*] Checking for expired jobresult records")
|
||||||
|
if config.JOBRESULT_RETENTION:
|
||||||
|
cutoff = timezone.now() - timedelta(days=config.JOBRESULT_RETENTION)
|
||||||
|
if options['verbosity'] >= 2:
|
||||||
|
self.stdout.write(f"\tRetention period: {config.JOBRESULT_RETENTION} days")
|
||||||
|
self.stdout.write(f"\tCut-off time: {cutoff}")
|
||||||
|
expired_records = JobResult.objects.filter(created__lt=cutoff).count()
|
||||||
|
if expired_records:
|
||||||
|
if options['verbosity']:
|
||||||
|
self.stdout.write(
|
||||||
|
f"\tDeleting {expired_records} expired records... ",
|
||||||
|
self.style.WARNING,
|
||||||
|
ending=""
|
||||||
|
)
|
||||||
|
self.stdout.flush()
|
||||||
|
JobResult.objects.filter(created__lt=cutoff)._raw_delete(using=DEFAULT_DB_ALIAS)
|
||||||
|
if options['verbosity']:
|
||||||
|
self.stdout.write("Done.", self.style.SUCCESS)
|
||||||
|
elif options['verbosity']:
|
||||||
|
self.stdout.write("\tNo expired records found.", self.style.SUCCESS)
|
||||||
|
elif options['verbosity']:
|
||||||
|
self.stdout.write(
|
||||||
|
f"\tSkipping: No retention period specified (JOBRESULT_RETENTION = {config.JOBRESULT_RETENTION})"
|
||||||
|
)
|
||||||
|
|
||||||
# Check for new releases (if enabled)
|
# Check for new releases (if enabled)
|
||||||
if options['verbosity']:
|
if options['verbosity']:
|
||||||
self.stdout.write("[*] Checking for latest release")
|
self.stdout.write("[*] Checking for latest release")
|
||||||
|
@ -187,6 +187,13 @@ PARAMS = (
|
|||||||
description="Days to retain changelog history (set to zero for unlimited)",
|
description="Days to retain changelog history (set to zero for unlimited)",
|
||||||
field=forms.IntegerField
|
field=forms.IntegerField
|
||||||
),
|
),
|
||||||
|
ConfigParam(
|
||||||
|
name='JOBRESULT_RETENTION',
|
||||||
|
label='Job result retention',
|
||||||
|
default=0,
|
||||||
|
description="Days to retain job result history (set to zero for unlimited)",
|
||||||
|
field=forms.IntegerField
|
||||||
|
),
|
||||||
ConfigParam(
|
ConfigParam(
|
||||||
name='MAPS_URL',
|
name='MAPS_URL',
|
||||||
label='Maps URL',
|
label='Maps URL',
|
||||||
|
Reference in New Issue
Block a user