Extend admin UI to allow restoring previous config revisions

This commit is contained in:
jeremystretch
2021-10-27 14:05:49 -04:00
parent 77bd26d17f
commit 70f71e0f57
5 changed files with 100 additions and 5 deletions

View File

@@ -1,5 +1,10 @@
from django.contrib import admin
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.urls import path, reverse
from django.utils.html import format_html
from netbox.config import get_config, PARAMS
from .forms import ConfigRevisionForm
from .models import ConfigRevision, JobResult
@@ -33,7 +38,7 @@ class ConfigRevisionAdmin(admin.ModelAdmin):
})
]
form = ConfigRevisionForm
list_display = ('id', 'is_active', 'created', 'comment')
list_display = ('id', 'is_active', 'created', 'comment', 'restore_link')
ordering = ('-id',)
readonly_fields = ('data',)
@@ -47,6 +52,8 @@ class ConfigRevisionAdmin(admin.ModelAdmin):
return initial
# Permissions
def has_add_permission(self, request):
# Only superusers may modify the configuration.
return request.user.is_superuser
@@ -61,6 +68,58 @@ class ConfigRevisionAdmin(admin.ModelAdmin):
obj is None or not obj.is_active()
)
# List display methods
def restore_link(self, obj):
if obj.is_active():
return ''
return format_html(
'<a href="{url}" class="button">Restore</a>',
url=reverse('admin:extras_configrevision_restore', args=(obj.pk,))
)
restore_link.short_description = "Actions"
# URLs
def get_urls(self):
urls = [
path('<int:pk>/restore/', self.admin_site.admin_view(self.restore), name='extras_configrevision_restore'),
]
return urls + super().get_urls()
# Views
def restore(self, request, pk):
# Get the ConfigRevision being restored
candidate_config = get_object_or_404(ConfigRevision, pk=pk)
if request.method == 'POST':
candidate_config.activate()
self.message_user(request, f"Restored configuration revision #{pk}")
return redirect(reverse('admin:extras_configrevision_changelist'))
# Get the current ConfigRevision
config_version = get_config().version
current_config = ConfigRevision.objects.filter(pk=config_version).first()
params = []
for param in PARAMS:
params.append((
param.name,
current_config.data.get(param.name, None),
candidate_config.data.get(param.name, None)
))
context = self.admin_site.each_context(request)
context.update({
'object': candidate_config,
'params': params,
})
return TemplateResponse(request, 'admin/extras/configrevision/restore.html', context)
#
# Reports & scripts