from django.contrib import messages from django.contrib.auth.decorators import login_required from django.db.models import Sum from django.http import JsonResponse from django.shortcuts import render, redirect, get_object_or_404 from django.utils import timezone from backup.models import BackupProfile from backup_data.models import RouterBackup from routerfleet_tools.models import WebadminSettings from routerlib.router_functions import update_router_information from user_manager.models import UserAcl from .forms import RouterForm, RouterGroupForm, SSHKeyForm from .models import Router, RouterGroup, RouterInformation, RouterStatus, SSHKey, BackupSchedule from django.conf import settings import json from urllib.parse import unquote @login_required def view_router_list(request): router_list = Router.objects.all().prefetch_related( 'routerstatus', 'routerinformation', 'backupschedule', 'routergroup_set' ).order_by('name') last_router_status_change = RouterStatus.objects.filter(last_status_change__isnull=False).order_by('-last_status_change').first() if last_router_status_change: last_status_change_timestamp = last_router_status_change.last_status_change.isoformat() else: last_status_change_timestamp = 0 default_backup_profile, default_backup_profile_created = BackupProfile.objects.get_or_create(name='default') filter_group = None if request.GET.get('filter_group'): if request.GET.get('filter_group') == 'all': pass else: filter_group = get_object_or_404(RouterGroup, uuid=request.GET.get('filter_group')) router_list = router_list.filter(routergroup=filter_group) if not filter_group and request.GET.get('filter_group') != 'all': filter_group = RouterGroup.objects.filter(default_group=True).first() # Parse the router_visible_columns cookie visible_columns = [] if 'router_visible_columns' in request.COOKIES: try: visible_columns = json.loads(unquote(request.COOKIES['router_visible_columns'])) except json.JSONDecodeError: # If the cookie is invalid, use default columns visible_columns = ["name", "type", "status", "backup", "groups"] else: # Default columns if cookie doesn't exist visible_columns = ["name", "type", "status", "backup", "groups"] context = { 'router_list': router_list, 'page_title': 'Router List', 'filter_group_list': RouterGroup.objects.all().order_by('name'), 'filter_group': filter_group, 'last_status_change_timestamp': last_status_change_timestamp, 'visible_columns': visible_columns, } return render(request, 'router_manager/router_list.html', context=context) @login_required() def view_router_availability(request): router = get_object_or_404(Router, uuid=request.GET.get('uuid')) data = { 'router': router, 'downtime_list': router.routerdowntime_set.all().order_by('-start_time'), } return render(request, 'router_manager/router_availability.html', context=data) @login_required() def view_router_details(request): router = get_object_or_404(Router, uuid=request.GET.get('uuid')) router_status, router_status_created = RouterStatus.objects.get_or_create(router=router) router_backup_list = router.routerbackup_set.all().order_by('-created') router_information = RouterInformation.objects.filter(router=router).first() downtime_last_week = router.routerdowntime_set.filter(start_time__gte=timezone.now() - timezone.timedelta(days=7)).aggregate(total=Sum('total_down_time'))['total'] if downtime_last_week is None: downtime_last_week = 0 total_last_week = 7 * 24 * 60 * 60 # total seconds in a week last_week_availability = round((total_last_week - downtime_last_week) / total_last_week * 100, 3) if downtime_last_week > 0 and last_week_availability == 100: last_week_availability = 99.999 if router_status.backup_lock: if not router_backup_list.filter(success=False, error=False).exists(): router_status.backup_lock = None router_status.save() messages.warning(request, 'Backup lock removed|Backup lock was removed as there are no active backup tasks') context = { 'router': router, 'router_information': router_information, 'router_status': router_status, 'router_backup_list': router_backup_list, 'page_title': 'Router Details', 'offline_time_last_week': downtime_last_week, 'last_week_availability': last_week_availability, } return render(request, 'router_manager/router_details.html', context=context) @login_required() def view_manage_router(request): if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=30).exists(): return render(request, 'access_denied.html', {'page_title': 'Access Denied'}) webadmin_settings, webadmin_settings_created = WebadminSettings.objects.get_or_create(name='webadmin_settings') if request.GET.get('uuid'): router = get_object_or_404(Router, uuid=request.GET.get('uuid')) if request.GET.get('action') == 'delete': if request.GET.get('confirmation') == 'delete': router.delete() messages.success(request, 'Router deleted successfully') webadmin_settings.router_config_last_updated = timezone.now() webadmin_settings.save() return redirect('router_list') else: messages.warning(request, 'Router not deleted|Invalid confirmation') return redirect('router_list') elif request.GET.get('action') == 'refresh_information': router_information, created = RouterInformation.objects.get_or_create(router=router) router_information.next_retry = timezone.now() router_information.retry_count = 0 router_information.success = False router_information.error = False router_information.error_message = '' router_information.save() messages.success(request, 'Router information will be updated shortly') return redirect('/router/details/?uuid=' + str(router.uuid)) else: router = None form = RouterForm(request.POST or None, instance=router) if form.is_valid(): form.save() messages.success(request, 'Router saved successfully|It may take a few minutes until monitoring starts for this router.') router_status, router_status_created = RouterStatus.objects.get_or_create(router=form.instance) BackupSchedule.objects.filter(router=form.instance).delete() if form.instance.router_type == 'monitoring': RouterInformation.objects.filter(router=form.instance).delete() webadmin_settings.router_config_last_updated = timezone.now() webadmin_settings.save() return redirect('router_list') context = { 'form': form, 'page_title': 'Manage Router', 'instance': router } return render(request, 'generic_form.html', context=context) @login_required() def view_router_group_list(request): context = { 'router_group_list': RouterGroup.objects.all().order_by('name'), 'page_title': 'Router Group List', } return render(request, 'router_manager/router_group_list.html', context=context) @login_required() def view_manage_router_group(request): if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=40).exists(): return render(request, 'access_denied.html', {'page_title': 'Access Denied'}) if request.GET.get('uuid'): router_group = get_object_or_404(RouterGroup, uuid=request.GET.get('uuid')) if request.GET.get('action') == 'delete': if request.GET.get('confirmation') == 'delete': router_group.delete() messages.success(request, 'Router Group deleted successfully') return redirect('router_group_list') else: messages.warning(request, 'Router Group not deleted|Invalid confirmation') return redirect('router_group_list') else: router_group = None form = RouterGroupForm(request.POST or None, instance=router_group) if form.is_valid(): form.save() messages.success(request, 'Router Group saved successfully') return redirect('router_group_list') context = { 'form': form, 'page_title': 'Manage Router Group', 'instance': router_group } return render(request, 'generic_form.html', context=context) @login_required() def view_ssh_key_list(request): context = { 'sshkey_list': SSHKey.objects.all().order_by('name'), 'page_title': 'SSH Key List', } return render(request, 'router_manager/sshkey_list.html', context=context) @login_required() def view_manage_sshkey(request): if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=40).exists(): return render(request, 'access_denied.html', {'page_title': 'Access Denied'}) if request.GET.get('uuid'): sshkey = get_object_or_404(SSHKey, uuid=request.GET.get('uuid')) if request.GET.get('action') == 'delete': if request.GET.get('confirmation') == 'delete': sshkey.delete() messages.success(request, 'SSH Key deleted successfully') return redirect('ssh_keys_list') else: messages.warning(request, 'SSH Key not deleted|Invalid confirmation') return redirect('ssh_keys_list') else: sshkey = None form = SSHKeyForm(request.POST or None, instance=sshkey) if form.is_valid(): form.save() messages.success(request, 'SSH Key saved successfully') return redirect('ssh_keys_list') context = { 'form': form, 'page_title': 'Manage SSH Key', 'instance': sshkey } return render(request, 'generic_form.html', context=context) def create_instant_backup(router): if RouterBackup.objects.filter(router=router, success=False, error=False).exists(): return 'Active router backup task already exists' if router.routerstatus.backup_lock: return 'Router backup is currently locked' if not router.backup_profile: return 'Router has no backup profile' router_backup = RouterBackup.objects.create( router=router, schedule_time=timezone.now(), schedule_type='instant' ) router.routerstatus.backup_lock = router_backup.schedule_time router.routerstatus.save() return None @login_required() def view_create_instant_backup_task(request): if not UserAcl.objects.filter(user=request.user, user_level__gte=20).exists(): return render(request, 'access_denied.html', {'page_title': 'Access Denied'}) router = get_object_or_404(Router, uuid=request.GET.get('uuid')) router_details_url = f'/router/details/?uuid={router.uuid}' error = create_instant_backup(router) if error: messages.warning(request, f'Backup task not created | {error}') else: messages.success(request, 'Backup task created successfully') return redirect(router_details_url) @login_required def view_create_instant_backup_multiple_routers(request): if request.method == 'POST': if not UserAcl.objects.filter(user=request.user, user_level__gte=20).exists(): return JsonResponse({'error': 'Permission denied.'}, status=403) uuids = request.POST.getlist('routers[]') if not uuids: return JsonResponse({'error': 'No routers selected.'}, status=400) results = [] for uuid in uuids: router = get_object_or_404(Router, uuid=uuid) error = create_instant_backup(router) results.append({'router': router.name, 'status': error}) return JsonResponse({'results': results}) return JsonResponse({'error': 'Invalid request method.'}, status=405) @login_required def view_manage_router_groups_multiple(request): if not UserAcl.objects.filter(user=request.user, user_level__gte=20).exists(): return render(request, 'access_denied.html', {'page_title': 'Access Denied'}) if request.method == 'POST': router_uuids = request.POST.getlist('router_uuids') add_group_uuid = request.POST.get('add_group') remove_group_uuid = request.POST.get('remove_group') if not router_uuids: messages.warning(request, 'No routers selected') return redirect('router_list') # Validate that the same group is not selected for both add and remove if add_group_uuid and remove_group_uuid and add_group_uuid == remove_group_uuid: messages.warning(request, 'Cannot add and remove from the same group') return redirect('router_list') routers = Router.objects.filter(uuid__in=router_uuids) # Process add to group if add_group_uuid: try: group = RouterGroup.objects.get(uuid=add_group_uuid) for router in routers: group.routers.add(router) messages.success(request, f'Added {routers.count()} router(s) to group {group.name}') except RouterGroup.DoesNotExist: messages.error(request, 'Group not found') # Process remove from group if remove_group_uuid: try: group = RouterGroup.objects.get(uuid=remove_group_uuid) for router in routers: group.routers.remove(router) messages.success(request, f'Removed {routers.count()} router(s) from group {group.name}') except RouterGroup.DoesNotExist: messages.error(request, 'Group not found') return redirect('router_list') # GET request - display form router_uuids = request.GET.getlist('routers[]') if not router_uuids: messages.warning(request, 'No routers selected') return redirect('router_list') routers = Router.objects.filter(uuid__in=router_uuids) groups = RouterGroup.objects.all().order_by('name') context = { 'routers': routers, 'groups': groups, 'page_title': 'Manage Router Groups', } return render(request, 'router_manager/manage_router_groups.html', context) def view_cron_update_router_information(request): data = {'status': 'success'} refresh_interval = 24 #hours router_list = Router.objects.filter(enabled=True).exclude(router_type='monitoring').exclude(routerstatus__status_online=False) router = router_list.filter(routerinformation__isnull=True).first() if not router: router = router_list.filter(routerinformation__next_retry__lt=timezone.now()).first() if not router: router = router_list.filter(routerinformation__last_retrieval__isnull=True).first() if not router: router = router_list.filter(routerinformation__last_retrieval__lt=timezone.now() - timezone.timedelta(hours=refresh_interval)).first() if router: router_information, created = RouterInformation.objects.get_or_create(router=router) success, error_message = update_router_information(router_information) if not success: data['status'] = 'error' data['message'] = 'Failed to update router' else: data['message'] = 'No routers need update' return JsonResponse(data)