2024-03-17 17:24:56 -03:00
|
|
|
from django.contrib.auth.decorators import login_required
|
2024-04-01 12:36:50 -03:00
|
|
|
from django.http import JsonResponse, HttpResponse, FileResponse
|
|
|
|
from django.shortcuts import render, get_object_or_404, redirect, Http404
|
2024-03-17 17:24:56 -03:00
|
|
|
from django.contrib import messages
|
2024-03-20 16:59:34 -03:00
|
|
|
|
2024-04-05 22:11:08 -03:00
|
|
|
from routerfleet_tools.models import WebadminSettings
|
2024-03-20 16:59:34 -03:00
|
|
|
from routerlib.backup_functions import perform_backup
|
2024-03-17 17:24:56 -03:00
|
|
|
from .models import BackupProfile
|
|
|
|
from .forms import BackupProfileForm
|
2024-04-02 16:56:35 -03:00
|
|
|
from router_manager.models import Router, BackupSchedule
|
2024-03-17 19:11:59 -03:00
|
|
|
from backup_data.models import RouterBackup
|
2024-03-28 19:30:31 -03:00
|
|
|
import difflib
|
|
|
|
import unicodedata
|
2024-04-01 12:36:50 -03:00
|
|
|
from routerlib.functions import gen_backup_name, get_router_backup_file_extension
|
2024-04-04 11:18:46 -03:00
|
|
|
from django.conf import settings
|
|
|
|
from user_manager.models import UserAcl
|
2024-04-07 16:50:19 -03:00
|
|
|
from django.utils import timezone
|
2024-03-17 10:43:19 -03:00
|
|
|
|
2024-03-17 17:24:56 -03:00
|
|
|
|
|
|
|
@login_required()
|
|
|
|
def view_backup_profile_list(request):
|
2024-04-02 16:56:35 -03:00
|
|
|
default_backup_profile, _ = BackupProfile.objects.get_or_create(name='default')
|
2024-03-17 17:24:56 -03:00
|
|
|
context = {
|
|
|
|
'backup_profile_list': BackupProfile.objects.all().order_by('name'),
|
|
|
|
'page_title': 'Backup Profiles'
|
|
|
|
}
|
|
|
|
return render(request, 'backup/backup_profile_list.html', context)
|
|
|
|
|
|
|
|
|
|
|
|
@login_required()
|
|
|
|
def view_manage_backup_profile(request):
|
2024-04-04 11:18:46 -03:00
|
|
|
if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=40).exists():
|
|
|
|
return render(request, 'access_denied.html', {'page_title': 'Access Denied'})
|
2024-03-17 17:24:56 -03:00
|
|
|
if request.GET.get('uuid'):
|
|
|
|
backup_profile = get_object_or_404(BackupProfile, uuid=request.GET.get('uuid'))
|
|
|
|
if request.GET.get('action') == 'delete':
|
|
|
|
if request.GET.get('confirmation') == 'delete':
|
2024-04-02 16:56:35 -03:00
|
|
|
if backup_profile.name == 'default':
|
|
|
|
messages.warning(request, 'Backup profile not deleted|Default profile cannot be deleted')
|
2024-03-17 17:24:56 -03:00
|
|
|
return redirect('backup_profile_list')
|
|
|
|
else:
|
2024-04-02 16:56:35 -03:00
|
|
|
if Router.objects.filter(backup_profile=backup_profile).exists():
|
|
|
|
messages.warning(request, 'Backup profile in use|Backup profile is in use and cannot be deleted')
|
|
|
|
return redirect('backup_profile_list')
|
|
|
|
else:
|
|
|
|
backup_profile.delete()
|
|
|
|
messages.success(request, 'Backup profile deleted successfully')
|
2024-03-17 17:24:56 -03:00
|
|
|
return redirect('backup_profile_list')
|
|
|
|
else:
|
|
|
|
messages.warning(request, 'Backup profile not deleted|Invalid confirmation')
|
|
|
|
return redirect('backup_profile_list')
|
|
|
|
else:
|
|
|
|
backup_profile = None
|
|
|
|
|
|
|
|
form = BackupProfileForm(request.POST or None, instance=backup_profile)
|
|
|
|
if form.is_valid():
|
2024-04-02 16:56:35 -03:00
|
|
|
form.instance.profile_error_information = ''
|
2024-03-17 17:24:56 -03:00
|
|
|
form.save()
|
2024-04-02 16:56:35 -03:00
|
|
|
BackupSchedule.objects.filter(router__backup_profile=form.instance).delete()
|
2024-03-17 17:24:56 -03:00
|
|
|
messages.success(request, 'Backup Profile saved successfully')
|
|
|
|
return redirect('backup_profile_list')
|
|
|
|
|
|
|
|
context = {
|
|
|
|
'form': form,
|
|
|
|
'page_title': 'Manage Backup Profile',
|
|
|
|
'instance': backup_profile
|
|
|
|
}
|
|
|
|
return render(request, 'backup/backup_profile_form.html', context=context)
|
2024-03-17 19:11:59 -03:00
|
|
|
|
|
|
|
|
|
|
|
@login_required()
|
|
|
|
def view_backup_list(request):
|
|
|
|
backup_list = RouterBackup.objects.all().order_by('-created')
|
|
|
|
if request.GET.get('type') == 'queue':
|
|
|
|
backup_list = backup_list.filter(error=False, success=False).order_by('next_retry')
|
|
|
|
view_type = 'queue'
|
|
|
|
elif request.GET.get('type') == 'errors':
|
|
|
|
backup_list = backup_list.filter(error=True).order_by('-created')
|
|
|
|
view_type = 'errors'
|
|
|
|
else:
|
|
|
|
backup_list = backup_list.filter(success=True).order_by('-created')
|
|
|
|
view_type = 'success'
|
|
|
|
|
|
|
|
context = {
|
|
|
|
'backup_list': backup_list,
|
|
|
|
'page_title': 'Backup List',
|
|
|
|
'view_type': view_type
|
|
|
|
}
|
|
|
|
return render(request, 'backup/backup_list.html', context)
|
|
|
|
|
|
|
|
|
|
|
|
@login_required()
|
|
|
|
def view_backup_details(request):
|
2024-04-04 11:18:46 -03:00
|
|
|
if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=20).exists():
|
|
|
|
return render(request, 'access_denied.html', {'page_title': 'Access Denied'})
|
2024-03-17 19:11:59 -03:00
|
|
|
backup = get_object_or_404(RouterBackup, uuid=request.GET.get('uuid'))
|
2024-04-07 16:50:19 -03:00
|
|
|
if request.GET.get('action') == 'anticipate':
|
|
|
|
if not backup.success and not backup.error:
|
|
|
|
backup.next_retry = timezone.now()
|
|
|
|
backup.save()
|
|
|
|
messages.success(request, 'Backup task anticipated|Backup task will be retried shortly')
|
|
|
|
else:
|
|
|
|
messages.warning(request, 'Backup task not anticipated|Task is already completed')
|
|
|
|
return redirect(f'/backup/backup_details/?uuid={backup.uuid}')
|
2024-03-28 19:30:31 -03:00
|
|
|
hash_list = [backup.backup_text_hash]
|
|
|
|
backup_list = []
|
|
|
|
for backup_item in RouterBackup.objects.filter(router=backup.router, success=True).order_by('-created'):
|
|
|
|
if backup_item.backup_text_hash and backup_item.backup_text_hash not in hash_list:
|
|
|
|
hash_list.append(backup_item.backup_text_hash)
|
|
|
|
backup_list.append(backup_item)
|
2024-04-05 22:11:08 -03:00
|
|
|
webadmin_settings, _ = WebadminSettings.objects.get_or_create(name='webadmin_settings')
|
2024-03-17 19:11:59 -03:00
|
|
|
context = {
|
|
|
|
'backup': backup,
|
2024-03-28 19:30:31 -03:00
|
|
|
'backup_list': backup_list,
|
2024-04-05 22:11:08 -03:00
|
|
|
'page_title': 'Backup Details',
|
2024-04-07 16:50:19 -03:00
|
|
|
'webadmin_settings': webadmin_settings,
|
|
|
|
'now': timezone.now(),
|
|
|
|
'5_minutes_ago': timezone.now() - timezone.timedelta(minutes=5),
|
2024-03-17 19:11:59 -03:00
|
|
|
}
|
2024-03-20 16:59:34 -03:00
|
|
|
return render(request, 'backup/backup_details.html', context)
|
|
|
|
|
|
|
|
|
2024-03-28 19:30:31 -03:00
|
|
|
def normalize_text(text):
|
|
|
|
text = unicodedata.normalize('NFC', text)
|
|
|
|
text = text.replace('\r\n', '\n')
|
|
|
|
text = text.replace('\r', '')
|
|
|
|
text = '\n'.join([line.rstrip() for line in text.splitlines()])
|
|
|
|
return text
|
|
|
|
|
|
|
|
|
2024-04-04 11:18:46 -03:00
|
|
|
@login_required()
|
2024-03-28 19:30:31 -03:00
|
|
|
def view_compare_backups(request):
|
2024-04-04 11:18:46 -03:00
|
|
|
if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=20).exists():
|
|
|
|
return render(request, 'access_denied.html', {'page_title': 'Access Denied'})
|
2024-03-28 19:30:31 -03:00
|
|
|
backup1 = get_object_or_404(RouterBackup, uuid=request.GET.get('uuid'))
|
|
|
|
backup2 = get_object_or_404(RouterBackup, uuid=request.GET.get('compare_uuid'))
|
|
|
|
if request.GET.get('display') == 'all':
|
|
|
|
show_lines = 100000
|
|
|
|
show_all = True
|
|
|
|
else:
|
|
|
|
show_lines = 3
|
|
|
|
show_all = False
|
|
|
|
|
|
|
|
diff = difflib.unified_diff(normalize_text(backup1.backup_text).splitlines(keepends=True),
|
|
|
|
normalize_text(backup2.backup_text).splitlines(keepends=True),
|
|
|
|
fromfile=backup1.backup_text_hash[:16] + '...',
|
|
|
|
tofile=backup2.backup_text_hash[:16] + '...',
|
|
|
|
lineterm='', n=show_lines)
|
|
|
|
diff_str = '\n'.join(list(diff))
|
|
|
|
|
|
|
|
context = {
|
|
|
|
'backup1': backup1,
|
|
|
|
'backup2': backup2,
|
|
|
|
'diff_str': diff_str,
|
|
|
|
'page_title': 'Compare Backups',
|
|
|
|
'show_all': show_all
|
|
|
|
}
|
|
|
|
|
|
|
|
return render(request, 'backup/compare_backups.html', context)
|
|
|
|
|
|
|
|
|
2024-03-20 16:59:34 -03:00
|
|
|
def view_debug_run_backups(request):
|
|
|
|
data = {
|
|
|
|
'backup_count': 0,
|
|
|
|
}
|
2024-04-04 11:18:46 -03:00
|
|
|
if settings.DEBUG:
|
|
|
|
for backup in RouterBackup.objects.filter(success=False, error=False):
|
|
|
|
data['backup_count'] += 1
|
|
|
|
perform_backup(backup)
|
|
|
|
else:
|
|
|
|
data['error'] = 'Debug mode is not enabled'
|
2024-03-28 19:30:31 -03:00
|
|
|
return JsonResponse(data)
|
2024-04-01 12:36:50 -03:00
|
|
|
|
|
|
|
|
|
|
|
@login_required()
|
|
|
|
def view_backup_download(request):
|
2024-04-04 11:18:46 -03:00
|
|
|
if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=20).exists():
|
|
|
|
return render(request, 'access_denied.html', {'page_title': 'Access Denied'})
|
2024-04-01 12:36:50 -03:00
|
|
|
backup = get_object_or_404(RouterBackup, uuid=request.GET.get('uuid'))
|
|
|
|
if request.GET.get('type') == 'text':
|
|
|
|
response = HttpResponse(backup.backup_text, content_type='text/plain')
|
|
|
|
if backup.backup_text_filename:
|
|
|
|
filename = backup.backup_text_filename
|
|
|
|
else:
|
|
|
|
filename = gen_backup_name(backup)
|
|
|
|
filename += f'.missing_backup_name.{get_router_backup_file_extension(backup.router.router_type)["text"]}'
|
|
|
|
print(filename)
|
|
|
|
response['Content-Disposition'] = f'attachment; filename={filename}'
|
|
|
|
return response
|
|
|
|
elif request.GET.get('type') == 'binary':
|
|
|
|
response = FileResponse(backup.backup_binary, as_attachment=True)
|
|
|
|
return response
|
|
|
|
else:
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
|
|
|
|
@login_required()
|
|
|
|
def view_backup_delete(request):
|
2024-04-04 11:18:46 -03:00
|
|
|
if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=30).exists():
|
|
|
|
return render(request, 'access_denied.html', {'page_title': 'Access Denied'})
|
2024-04-01 12:36:50 -03:00
|
|
|
backup = get_object_or_404(RouterBackup, uuid=request.GET.get('uuid'))
|
2024-04-07 16:50:19 -03:00
|
|
|
router = backup.router
|
2024-04-01 12:36:50 -03:00
|
|
|
redirect_url = f'/router/details/?uuid={backup.router.uuid}'
|
|
|
|
if request.GET.get('confirmation') == f'delete{backup.id}':
|
|
|
|
backup.delete()
|
|
|
|
messages.success(request, 'Backup deleted successfully')
|
2024-04-07 16:50:19 -03:00
|
|
|
if router.routerstatus.backup_lock:
|
|
|
|
if not RouterBackup.objects.filter(router=router, success=False, error=False).exists():
|
|
|
|
router.routerstatus.backup_lock = None
|
|
|
|
router.routerstatus.save()
|
2024-04-01 12:36:50 -03:00
|
|
|
return redirect(redirect_url)
|
|
|
|
else:
|
|
|
|
messages.warning(request, 'Backup not deleted|Invalid confirmation')
|
|
|
|
return redirect(f'/backup/backup_details/?uuid={backup.uuid}')
|