diff --git a/dashboard/views.py b/dashboard/views.py index 5e8a5ce..3117d3a 100644 --- a/dashboard/views.py +++ b/dashboard/views.py @@ -1,6 +1,32 @@ from django.shortcuts import render from django.contrib.auth.decorators import login_required +from backup.models import BackupProfile +from backup_data.models import RouterBackup +from router_manager.models import Router, RouterGroup, RouterStatus, BackupSchedule, SSHKey +from integration_manager.models import ExternalIntegration +from user_manager.models import User +from django.conf import settings +from django.utils import timezone +from datetime import timedelta +import os +import shutil + + +def get_directory_statistics(directory_path): + total, used, free = shutil.disk_usage(directory_path) + # Convert to GB + total = total // (2 ** 30) + used = used // (2 ** 30) + free = free // (2 ** 30) + usage_percentage = (used / total) * 100 + + return { + "total_gb": total, + "used_gb": used, + "free_gb": free, + "usage_percentage": round(usage_percentage, 2) + } @login_required def view_dashboard(request): @@ -10,5 +36,18 @@ def view_dashboard(request): @login_required def view_status(request): - context = {'page_title': 'Welcome to routerfleet'} + settings.MEDIA_ROOT + context = { + 'page_title': 'Welcome to routerfleet', + 'media_root_stats': get_directory_statistics(settings.MEDIA_ROOT), + 'queue': RouterBackup.objects.filter(success=False, error=False).count(), + 'success_backup_last_24h': RouterBackup.objects.filter(success=True, created__gte=timezone.now() - timedelta(days=1)).count(), + 'error_backup_last_24h': RouterBackup.objects.filter(error=True, created__gte=timezone.now() - timedelta(days=1)).count(), + 'router_count': Router.objects.filter(enabled=True).count(), + 'router_online_count': RouterStatus.objects.filter(status_online=True, router__monitoring=True).count(), + 'router_offline_count': RouterStatus.objects.filter(status_online=False, router__monitoring=True).count(), + 'router_not_monitored_count': Router.objects.filter(enabled=True, monitoring=False).count(), + 'routerfleet_version': settings.ROUTERFLEET_VERSION, + } + return render(request, 'dashboard/status.html', context=context) diff --git a/routerfleet/settings.py b/routerfleet/settings.py index 533647c..d5f7758 100644 --- a/routerfleet/settings.py +++ b/routerfleet/settings.py @@ -46,6 +46,7 @@ INSTALLED_APPS = [ 'backup', 'backup_data', 'integration_manager', + 'routerfleet_tools' ] MIDDLEWARE = [ @@ -139,3 +140,4 @@ STATICFILES_DIRS = [ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' MEDIA_ROOT = '/var/lib/routerfleet/' +ROUTERFLEET_VERSION = 7002 diff --git a/routerfleet/urls.py b/routerfleet/urls.py index 8b9658f..b76f289 100644 --- a/routerfleet/urls.py +++ b/routerfleet/urls.py @@ -8,6 +8,7 @@ from router_manager.views import view_router_list, view_manage_router, view_rout 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 from backup_data.views import view_generate_backup_schedule, view_create_backup_tasks, view_perform_backup_tasks, view_housekeeping +from routerfleet_tools.views import cron_check_updates urlpatterns = [ @@ -41,6 +42,7 @@ urlpatterns = [ path('cron/create_backup_tasks/', view_create_backup_tasks, name='create_backup_tasks'), path('cron/perform_backup_tasks/', view_perform_backup_tasks, name='perform_backup_tasks'), path('cron/housekeeping/', view_housekeeping, name='housekeeping'), + path('cron/check_updates/', cron_check_updates, name='check_updates'), path('wireguard_webadmin/', view_wireguard_webadmin_launcher, name='wireguard_webadmin_launcher'), path('wireguard_webadmin/manage/', view_manage_wireguard_integration, name='manage_wireguard_integration'), path('wireguard_webadmin/launch/', view_launch_wireguard_webadmin, name='launch_wireguard_webadmin') diff --git a/routerfleet_tools/__init__.py b/routerfleet_tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/routerfleet_tools/admin.py b/routerfleet_tools/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/routerfleet_tools/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/routerfleet_tools/apps.py b/routerfleet_tools/apps.py new file mode 100644 index 0000000..057dbf9 --- /dev/null +++ b/routerfleet_tools/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class RouterfleetToolsConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'routerfleet_tools' diff --git a/routerfleet_tools/migrations/0001_initial.py b/routerfleet_tools/migrations/0001_initial.py new file mode 100644 index 0000000..4c6e1c2 --- /dev/null +++ b/routerfleet_tools/migrations/0001_initial.py @@ -0,0 +1,29 @@ +# Generated by Django 5.0.3 on 2024-04-04 16:49 + +import uuid +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='WebadminSettings', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(default='webadmin_settings', max_length=20, unique=True)), + ('update_available', models.BooleanField(default=False)), + ('current_version', models.PositiveIntegerField(default=0)), + ('latest_version', models.PositiveIntegerField(default=0)), + ('last_checked', models.DateTimeField(blank=True, null=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('created', models.DateTimeField(auto_now_add=True)), + ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ], + ), + ] diff --git a/routerfleet_tools/migrations/__init__.py b/routerfleet_tools/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/routerfleet_tools/models.py b/routerfleet_tools/models.py new file mode 100644 index 0000000..eef0360 --- /dev/null +++ b/routerfleet_tools/models.py @@ -0,0 +1,16 @@ +from django.db import models +import uuid + +class WebadminSettings(models.Model): + name = models.CharField(default='webadmin_settings', max_length=20, unique=True) + update_available = models.BooleanField(default=False) + current_version = models.PositiveIntegerField(default=0) + latest_version = models.PositiveIntegerField(default=0) + last_checked = models.DateTimeField(blank=True, null=True) + + updated = models.DateTimeField(auto_now=True) + created = models.DateTimeField(auto_now_add=True) + uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) + + def __str__(self): + return self.name diff --git a/routerfleet_tools/templatetags/__init__.py b/routerfleet_tools/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/routerfleet_tools/templatetags/custom_tags.py b/routerfleet_tools/templatetags/custom_tags.py new file mode 100644 index 0000000..adfcec8 --- /dev/null +++ b/routerfleet_tools/templatetags/custom_tags.py @@ -0,0 +1,21 @@ +from django import template +from django.conf import settings +from routerfleet_tools.models import WebadminSettings + +register = template.Library() + + +@register.simple_tag +def tag_webadmin_version(): + webadmin_settings, settings_created = WebadminSettings.objects.get_or_create(name='webadmin_settings') + if webadmin_settings.current_version != settings.ROUTERFLEET_VERSION: + webadmin_settings.current_version = settings.ROUTERFLEET_VERSION + webadmin_settings.save() + if webadmin_settings.current_version == webadmin_settings.latest_version: + webadmin_settings.update_available = False + webadmin_settings.save() + return { + 'current_version': settings.ROUTERFLEET_VERSION / 10000, + 'latest_version': webadmin_settings.latest_version / 10000, + 'update_available': webadmin_settings.update_available, + } diff --git a/routerfleet_tools/tests.py b/routerfleet_tools/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/routerfleet_tools/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/routerfleet_tools/views.py b/routerfleet_tools/views.py new file mode 100644 index 0000000..b2f9d9e --- /dev/null +++ b/routerfleet_tools/views.py @@ -0,0 +1,42 @@ +from django.shortcuts import render, Http404 +from .models import WebadminSettings +from django.http import JsonResponse +from django.conf import settings +from django.utils import timezone +import requests + + +def cron_check_updates(request): + webadmin_settings, webadmin_settings_created = WebadminSettings.objects.get_or_create(name='webadmin_settings') + + if webadmin_settings.last_checked is None or timezone.now() - webadmin_settings.last_checked > timezone.timedelta( + hours=1): + try: + version = settings.ROUTERFLEET_VERSION / 10000 + url = f'https://updates.eth0.com.br/api/check_updates/?app=routerfleet&version={version}' + response = requests.get(url) + response.raise_for_status() + data = response.json() + + if 'update_available' in data: + webadmin_settings.update_available = data['update_available'] + + if data['update_available']: + webadmin_settings.latest_version = float(data['current_version']) * 10000 + + webadmin_settings.last_checked = timezone.now() + webadmin_settings.save() + + response_data = { + 'update_available': webadmin_settings.update_available, + 'latest_version': webadmin_settings.latest_version, + 'current_version': settings.ROUTERFLEET_VERSION, + } + return JsonResponse(response_data) + + except Exception as e: + webadmin_settings.update_available = False + webadmin_settings.save() + return JsonResponse({'update_available': False}) + + return JsonResponse({'update_available': webadmin_settings.update_available}) \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index 6d279f0..7f9860f 100644 --- a/templates/base.html +++ b/templates/base.html @@ -36,7 +36,8 @@ {% block page_custom_head %}{% endblock%} - +{% load custom_tags %} +{% tag_webadmin_version as webadmin_version %}
Item | +Value | +
---|---|
+ + Used storage (binary backup) + + | ++ {{ media_root_stats.usage_percentage }}% + | +
+ + Backup Queue + + | ++ {{ queue }} + | +
+ + Successful backups (24h) + + | ++ {{ success_backup_last_24h }} + | +
+ + Failed backups (24h) + + | ++ {{ error_backup_last_24h }} + | +
+ + Routers + + | ++ {{ router_count }} + | +
+ + Online Routers + + | ++ {{ router_online_count }} + | +
+ + Offline Routers + + | ++ {{ router_offline_count }} + | +
+ + Not monitored Routers + + | ++ {{ router_not_monitored_count }} + | +
+ + Router Fleet Version + + | ++ {{ webadmin_version.current_version }} + | +
This status page is just a placeholder, it will be improved in next versions
+Greetings! I'm thrilled to introduce you to RouterFleet, a newly launched open source project aimed at revolutionizing the way we manage backups for routers and network equipment. I've dedicated countless hours to developing a system that simplifies and secures network management tasks, specifically tailored for those who manage a fleet of devices.
+ +At this initial stage, RouterFleet's compatibility is focused on Mikrotik devices. My commitment to you is to not only enhance the system for these devices but also to expand our compatibility list based on the community's needs. Your feedback and requests are crucial for guiding the future development of RouterFleet.
+ +Being at the forefront of RouterFleet, I am on a continuous journey to improve and evolve the platform. You can expect regular updates featuring new functionalities, performance enhancements, and bug fixes. To make the most out of RouterFleet, I recommend keeping your system up to date with the latest releases.
+ +As RouterFleet is an open source project, I warmly invite you to join the journey—whether it's through contributing code, providing feedback, or sharing your network management experiences. Every bit of support helps in building a robust community around RouterFleet. For more information, updates, and to get involved, please visit our GitHub page.
+ +Your support and involvement are what will shape the future of RouterFleet!
+ +