diff --git a/wgrrd/__init__.py b/wgrrd/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/wgrrd/admin.py b/wgrrd/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/wgrrd/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/wgrrd/apps.py b/wgrrd/apps.py new file mode 100644 index 0000000..63223d1 --- /dev/null +++ b/wgrrd/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class WgrrdConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'wgrrd' diff --git a/wgrrd/migrations/__init__.py b/wgrrd/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/wgrrd/models.py b/wgrrd/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/wgrrd/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/wgrrd/tests.py b/wgrrd/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/wgrrd/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/wgrrd/views.py b/wgrrd/views.py new file mode 100644 index 0000000..d402b1a --- /dev/null +++ b/wgrrd/views.py @@ -0,0 +1,84 @@ +import subprocess + +from django.contrib.auth.decorators import login_required +from django.core.exceptions import PermissionDenied +from django.http import Http404, HttpResponse +from django.shortcuts import render, get_object_or_404 + +from user_manager.models import UserAcl +from wgwadmlibrary.tools import user_has_access_to_peer +from wireguard.models import Peer, WireGuardInstance + +import base64 +import tempfile +import os + + +@login_required +def view_rrd_graph(request): + user_acl = get_object_or_404(UserAcl, user=request.user) + peer = None + instance = None + if request.GET.get('peer'): + peer = get_object_or_404(Peer, uuid=request.GET.get('peer')) + if not user_has_access_to_peer(user_acl, peer): + raise PermissionDenied + graph_type = 'peer' + rrd_filename = base64.urlsafe_b64encode(peer.public_key.encode()).decode().replace('=', '') + rrd_file_path = f'/rrd_data/peers/{rrd_filename}.rrd' + elif request.GET.get('instance'): + wireguard_instance = get_object_or_404(WireGuardInstance, uuid=request.GET.get('instance')) + graph_type = 'instance' + rrd_file_path = f'/rrd_data/wginstances/wg{wireguard_instance.instance_id}.rrd' + else: + raise Http404 + + if not os.path.exists(rrd_file_path): + raise Http404 + + with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as tmp_file: + graph_file = tmp_file.name + #command = [ + # "rrdtool", "graph", graph_file, + # "--start", "-6h", + # "--title", "RRD Data Graph", + # "--vertical-label", "Value", + # f"DEF:txdata={rrd_file_path}:tx:AVERAGE", + # f"DEF:rxdata={rrd_file_path}:rx:AVERAGE", + # "LINE1:txdata#FF0000:Transmitted", + # "LINE1:rxdata#0000FF:Received" + #] + command = [ + "rrdtool", "graph", graph_file, + "--start", "-6h", + "--title", "RRD Data Graph", + "--vertical-label", "Value", + f"DEF:txdata={rrd_file_path}:tx:AVERAGE", + f"DEF:rxdata={rrd_file_path}:rx:AVERAGE", + "CDEF:tx_mb=txdata,1048576,/", + "CDEF:rx_mb=rxdata,1048576,/", + "VDEF:tx_total=tx_mb,TOTAL", + "VDEF:rx_total=rx_mb,TOTAL", + "LINE1:txdata#FF0000:Transmitted", + "GPRINT:tx_total:Total Tx\\: %6.2lf MB", + "LINE1:rxdata#0000FF:Received", + "GPRINT:rx_total:Total Rx\\: %6.2lf MB" + ] + + try: + # Execute the command using subprocess + subprocess.run(command, check=True, stdout=subprocess.PIPE) + + # Open and read the generated image file + with open(graph_file, 'rb') as f: + image_data = f.read() + finally: + # Clean up the temporary file + os.remove(graph_file) + + # Return the image data as an HTTP response with PNG content type + return HttpResponse(image_data, content_type="image/png") + + + + diff --git a/wireguard_webadmin/urls.py b/wireguard_webadmin/urls.py index 5d4797a..525a59f 100644 --- a/wireguard_webadmin/urls.py +++ b/wireguard_webadmin/urls.py @@ -25,7 +25,7 @@ from wireguard_tools.views import export_wireguard_configs, download_config_or_q from api.views import wireguard_status, cron_check_updates, cron_update_peer_latest_handshake, routerfleet_get_user_token, routerfleet_authenticate_session from firewall.views import view_redirect_rule_list, manage_redirect_rule, view_firewall_rule_list, manage_firewall_rule, view_manage_firewall_settings, view_generate_iptables_script, view_reset_firewall, view_firewall_migration_required from dns.views import view_static_host_list, view_manage_static_host, view_manage_dns_settings, view_apply_dns_config - +from wgrrd.views import view_rrd_graph urlpatterns = [ # path('admin/', admin.site.urls), @@ -39,6 +39,7 @@ urlpatterns = [ path('peer/sort/', view_wireguard_peer_sort, name='wireguard_peer_sort'), path('peer/manage/', view_wireguard_peer_manage, name='wireguard_peer_manage'), path('peer/manage_ip_address/', view_manage_ip_address, name='manage_ip_address'), + path('rrd/graph/', view_rrd_graph, name='rrd_graph'), path('console/', view_console, name='console'), path('user/list/', view_user_list, name='user_list'), path('user/manage/', view_manage_user, name='manage_user'),