diff --git a/docs/administration/housekeeping.md b/docs/administration/housekeeping.md index bbb03dc27..1989e41c0 100644 --- a/docs/administration/housekeeping.md +++ b/docs/administration/housekeeping.md @@ -4,6 +4,7 @@ NetBox includes a `housekeeping` management command that should be run nightly. * Clearing expired authentication sessions from the database * 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. diff --git a/docs/configuration/dynamic-settings.md b/docs/configuration/dynamic-settings.md index 5649eb9be..4a12726ba 100644 --- a/docs/configuration/dynamic-settings.md +++ b/docs/configuration/dynamic-settings.md @@ -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 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: diff --git a/netbox/extras/admin.py b/netbox/extras/admin.py index 64c224cb1..28902c323 100644 --- a/netbox/extras/admin.py +++ b/netbox/extras/admin.py @@ -40,7 +40,7 @@ class ConfigRevisionAdmin(admin.ModelAdmin): 'fields': ('DEFAULT_USER_PREFERENCES',), }), ('Miscellaneous', { - 'fields': ('MAINTENANCE_MODE', 'GRAPHQL_ENABLED', 'CHANGELOG_RETENTION', 'MAPS_URL'), + 'fields': ('MAINTENANCE_MODE', 'GRAPHQL_ENABLED', 'CHANGELOG_RETENTION', 'JOBRESULT_RETENTION', 'MAPS_URL'), }), ('Config Revision', { 'fields': ('comment',), diff --git a/netbox/extras/management/commands/housekeeping.py b/netbox/extras/management/commands/housekeeping.py index 0607a16c2..51d50d7e1 100644 --- a/netbox/extras/management/commands/housekeeping.py +++ b/netbox/extras/management/commands/housekeeping.py @@ -9,6 +9,7 @@ from django.db import DEFAULT_DB_ALIAS from django.utils import timezone from packaging import version +from extras.models import JobResult from extras.models import ObjectChange from netbox.config import Config @@ -63,6 +64,33 @@ class Command(BaseCommand): 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) if options['verbosity']: self.stdout.write("[*] Checking for latest release") diff --git a/netbox/netbox/config/parameters.py b/netbox/netbox/config/parameters.py index 89de94674..9bbf45ceb 100644 --- a/netbox/netbox/config/parameters.py +++ b/netbox/netbox/config/parameters.py @@ -187,6 +187,13 @@ PARAMS = ( description="Days to retain changelog history (set to zero for unlimited)", 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( name='MAPS_URL', label='Maps URL',