Router availability display and history

This commit is contained in:
Eduardo Silva 2024-04-11 14:44:39 -03:00
parent 23c4090ec1
commit 1f5bbf1608
8 changed files with 116 additions and 4 deletions

View file

@ -1,3 +1,11 @@
from django.contrib import admin from django.contrib import admin
from .models import RouterDownTime
# Register your models here.
class RouterDownTimeAdmin(admin.ModelAdmin):
list_display = ('router', 'start_time', 'end_time', 'total_down_time', 'updated', 'created', 'uuid')
search_fields = ('router', 'start_time', 'end_time', 'total_down_time', 'updated', 'created', 'uuid')
readonly_fields = ('updated', 'created', 'uuid')
admin.site.register(RouterDownTime, RouterDownTimeAdmin)

View file

@ -7,8 +7,13 @@ class RouterDownTime(models.Model):
router = models.ForeignKey(Router, on_delete=models.CASCADE) router = models.ForeignKey(Router, on_delete=models.CASCADE)
start_time = models.DateTimeField(blank=True, null=True) start_time = models.DateTimeField(blank=True, null=True)
end_time = models.DateTimeField(blank=True, null=True) end_time = models.DateTimeField(blank=True, null=True)
total_down_time = models.IntegerField(default=0) # minutes total_down_time = models.IntegerField(default=0) # seconds
updated = models.DateTimeField(auto_now=True) updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
uuid = models.UUIDField(unique=True, editable=False, default=uuid.uuid4) uuid = models.UUIDField(unique=True, editable=False, default=uuid.uuid4)
def save(self, *args, **kwargs):
if self.end_time:
self.total_down_time = int((self.end_time - self.start_time).total_seconds())
super().save(*args, **kwargs)

View file

@ -1,4 +1,6 @@
from django.shortcuts import render from django.shortcuts import render
from monitoring.models import RouterDownTime
from router_manager.models import Router from router_manager.models import Router
from django.http import JsonResponse from django.http import JsonResponse
from django.utils import timezone from django.utils import timezone
@ -40,6 +42,10 @@ def view_export_router_list(request):
def view_update_router_status(request): def view_update_router_status(request):
router = Router.objects.get(uuid=request.GET.get('uuid')) router = Router.objects.get(uuid=request.GET.get('uuid'))
new_status = request.GET.get('status') new_status = request.GET.get('status')
if router.routerstatus.status_online:
current_status = 'online'
else:
current_status = 'offline'
if new_status not in ['online', 'offline']: if new_status not in ['online', 'offline']:
return JsonResponse({'status': 'error', 'error_message': 'Invalid status'}, status=400) return JsonResponse({'status': 'error', 'error_message': 'Invalid status'}, status=400)
if new_status == 'online': if new_status == 'online':
@ -47,6 +53,23 @@ def view_update_router_status(request):
else: else:
router.routerstatus.status_online = False router.routerstatus.status_online = False
router.routerstatus.save() router.routerstatus.save()
if current_status != new_status:
if new_status == 'online':
router.routerstatus.status_online = True
downtime = RouterDownTime.objects.filter(router=router, end_time=None).first()
if downtime:
downtime.end_time = timezone.now()
downtime.save()
else:
router.routerstatus.status_online = False
downtime = RouterDownTime.objects.create(router=router, start_time=timezone.now())
router.routerstatus.last_status_change = timezone.now()
router.routerstatus.save()
if downtime:
RouterDownTime.objects.filter(router=router, end_time=None).exclude(uuid=downtime.uuid).delete()
webadmin_settings, _ = WebadminSettings.objects.get_or_create(name='webadmin_settings') webadmin_settings, _ = WebadminSettings.objects.get_or_create(name='webadmin_settings')
webadmin_settings.monitoring_last_run = timezone.now() webadmin_settings.monitoring_last_run = timezone.now()
webadmin_settings.save() webadmin_settings.save()

View file

@ -1,10 +1,12 @@
from django.contrib import messages from django.contrib import messages
from django.db.models import Sum
from django.utils import timezone from django.utils import timezone
from django.shortcuts import render, get_object_or_404, redirect from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from backup.models import BackupProfile from backup.models import BackupProfile
from backup_data.models import RouterBackup from backup_data.models import RouterBackup
from monitoring.models import RouterDownTime
from routerfleet_tools.models import WebadminSettings from routerfleet_tools.models import WebadminSettings
from .models import Router, RouterGroup, RouterStatus, SSHKey, BackupSchedule from .models import Router, RouterGroup, RouterStatus, SSHKey, BackupSchedule
from .forms import RouterForm, RouterGroupForm, SSHKeyForm from .forms import RouterForm, RouterGroupForm, SSHKeyForm
@ -34,11 +36,29 @@ def view_router_list(request):
return render(request, 'router_manager/router_list.html', context=context) 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() @login_required()
def view_router_details(request): def view_router_details(request):
router = get_object_or_404(Router, uuid=request.GET.get('uuid')) router = get_object_or_404(Router, uuid=request.GET.get('uuid'))
router_status, _ = RouterStatus.objects.get_or_create(router=router) router_status, _ = RouterStatus.objects.get_or_create(router=router)
router_backup_list = router.routerbackup_set.all().order_by('-created') router_backup_list = router.routerbackup_set.all().order_by('-created')
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 router_status.backup_lock:
if not router_backup_list.filter(success=False, error=False).exists(): if not router_backup_list.filter(success=False, error=False).exists():
router_status.backup_lock = None router_status.backup_lock = None
@ -50,6 +70,9 @@ def view_router_details(request):
'router_status': router_status, 'router_status': router_status,
'router_backup_list': router_backup_list, 'router_backup_list': router_backup_list,
'page_title': 'Router Details', 'page_title': 'Router Details',
'offline_time_last_week': downtime_last_week,
'last_week_availability': last_week_availability,
} }

View file

@ -140,6 +140,6 @@ STATICFILES_DIRS = [
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
MEDIA_ROOT = '/var/lib/routerfleet/' MEDIA_ROOT = '/var/lib/routerfleet/'
ROUTERFLEET_VERSION = 7007 ROUTERFLEET_VERSION = 7008
from routerfleet.production_settings import * from routerfleet.production_settings import *

View file

@ -4,7 +4,7 @@ from dashboard.views import view_dashboard, view_status
from integration_manager.views import view_wireguard_webadmin_launcher, view_manage_wireguard_integration, view_launch_wireguard_webadmin from integration_manager.views import view_wireguard_webadmin_launcher, view_manage_wireguard_integration, view_launch_wireguard_webadmin
from user_manager.views import view_manage_user, view_user_list from user_manager.views import view_manage_user, view_user_list
from accounts.views import view_login, view_logout, view_create_first_user from accounts.views import view_login, view_logout, view_create_first_user
from router_manager.views import view_router_list, view_manage_router, view_router_group_list, view_ssh_key_list, view_manage_router_group, view_manage_sshkey, view_router_details, view_create_instant_backup_task from router_manager.views import view_router_list, view_manage_router, view_router_group_list, view_ssh_key_list, view_manage_router_group, view_manage_sshkey, view_router_details, view_create_instant_backup_task, view_router_availability
from backup.views import view_backup_profile_list, view_manage_backup_profile, view_backup_list, view_backup_details, view_debug_run_backups, view_compare_backups, view_backup_download, view_backup_delete from backup.views import view_backup_profile_list, view_manage_backup_profile, view_backup_list, view_backup_details, view_debug_run_backups, view_compare_backups, view_backup_download, view_backup_delete
from monitoring.views import view_export_router_list, view_update_router_status, view_router_config_timestamp from monitoring.views import view_export_router_list, view_update_router_status, view_router_config_timestamp
from backup_data.views import view_generate_backup_schedule, view_create_backup_tasks, view_perform_backup_tasks, view_housekeeping from backup_data.views import view_generate_backup_schedule, view_create_backup_tasks, view_perform_backup_tasks, view_housekeeping
@ -24,6 +24,7 @@ urlpatterns = [
path('router/list/', view_router_list, name='router_list'), path('router/list/', view_router_list, name='router_list'),
path('router/manage/', view_manage_router, name='manage_router'), path('router/manage/', view_manage_router, name='manage_router'),
path('router/details/', view_router_details, name='router_details'), path('router/details/', view_router_details, name='router_details'),
path('router/availability/', view_router_availability, name='router_availability'),
path('router/group_list/', view_router_group_list, name='router_group_list'), path('router/group_list/', view_router_group_list, name='router_group_list'),
path('router/ssh_keys/', view_ssh_key_list, name='ssh_keys_list'), path('router/ssh_keys/', view_ssh_key_list, name='ssh_keys_list'),
path('router/manage_group/', view_manage_router_group, name='manage_router_group'), path('router/manage_group/', view_manage_router_group, name='manage_router_group'),

View file

@ -0,0 +1,42 @@
{% extends 'base.html' %}
{% block content %}
<div class='row'>
<div class='col-xl-6'>
<div class="card card-primary card-outline">
<div class="card-header">
<h3 class="card-title">
Availabiliy for
<a href="/router/details/?uuid={{ router.uuid }}" >
{{ router.name }}
</a>
</h3>
</div>
<div class="card-body row">
<div class="col-lg-12">
<table class="table">
<thead>
<tr>
<th>Start Time</th>
<th>End Time</th>
<th>Duration</th>
</tr>
</thead>
<tbody>
{% for downtime in downtime_list %}
<tr>
<td>{{ downtime.start_time }}</td>
<td>{{ downtime.end_time }}</td>
<td>{{ downtime.total_down_time }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -60,6 +60,16 @@
{% endif %} {% endif %}
</span> </span>
</li> </li>
{% if router.monitoring %}
<li class="list-group-item">
<b>Availability (last 7 days)</b>
<span class="float-right">
<a href="/router/availability/?uuid={{ router.uuid }}">
{{ last_week_availability }}%
</a>
</span>
</li>
{% endif %}
<li class="list-group-item"> <li class="list-group-item">
<b>Router Type</b> <b>Router Type</b>
<span class="float-right">{{ router.get_router_type_display }}</span> <span class="float-right">{{ router.get_router_type_display }}</span>