diff --git a/api/views.py b/api/views.py index 733c927..f64b8ae 100644 --- a/api/views.py +++ b/api/views.py @@ -1,8 +1,13 @@ from django.http import JsonResponse from django.views.decorators.http import require_http_methods from django.contrib.auth.decorators import login_required +from django.conf import settings +from django.utils import timezone +from wireguard.models import WebadminSettings +import requests import subprocess + @login_required @require_http_methods(["GET"]) def wireguard_status(request): @@ -53,3 +58,38 @@ def wireguard_status(request): output[interface][peer][key] = value return JsonResponse(output) + + +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=6): + try: + version = settings.WIREGUARD_WEBADMIN_VERSION / 10000 + url = f'https://updates.eth0.com.br/api/check_updates/?app=wireguard_webadmin&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.WIREGUARD_WEBADMIN_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}) diff --git a/cron/Dockerfile-cron b/cron/Dockerfile-cron new file mode 100644 index 0000000..a965478 --- /dev/null +++ b/cron/Dockerfile-cron @@ -0,0 +1,16 @@ +FROM ubuntu:latest + +# Instalar cron +RUN apt-get update && apt-get install -y cron curl + +# Adicionar seus scripts de cron +COPY cron_tasks /etc/cron.d/cron_tasks + +# Dar permissões apropriadas +RUN chmod 0644 /etc/cron.d/cron_tasks + +# Criar um arquivo de log para armazenar os resultados do cron +RUN touch /var/log/cron.log + +# Executar o cron em primeiro plano +CMD cron -f diff --git a/cron/cron_tasks b/cron/cron_tasks new file mode 100644 index 0000000..04302cb --- /dev/null +++ b/cron/cron_tasks @@ -0,0 +1 @@ +* * * * * root /usr/bin/curl -s http://wireguard-webadmin:8000/api/cron_check_updates/ >> /var/log/cron.log 2>&1 diff --git a/docker-compose-no-nginx-dev.yml b/docker-compose-no-nginx-dev.yml index 922b459..08ba9e1 100644 --- a/docker-compose-no-nginx-dev.yml +++ b/docker-compose-no-nginx-dev.yml @@ -27,6 +27,13 @@ services: - net.ipv4.ip_forward=1 command: /bin/bash /app/init.sh + wireguard-webadmin-cron: + build: + context: ./cron + dockerfile: Dockerfile-cron + depends_on: + - wireguard-webadmin + volumes: static_volume: wireguard: diff --git a/docker-compose-no-nginx.yml b/docker-compose-no-nginx.yml index 830932b..58ebc1c 100644 --- a/docker-compose-no-nginx.yml +++ b/docker-compose-no-nginx.yml @@ -26,6 +26,13 @@ services: - net.ipv4.ip_forward=1 command: /bin/bash /app/init.sh + wireguard-webadmin-cron: + build: + context: ./cron + dockerfile: Dockerfile-cron + depends_on: + - wireguard-webadmin + volumes: static_volume: wireguard: diff --git a/docker-compose.yml b/docker-compose.yml index 337c683..73c392b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,6 +26,13 @@ services: - net.ipv4.ip_forward=1 command: /bin/bash /app/init.sh + wireguard-webadmin-cron: + build: + context: ./cron + dockerfile: Dockerfile-cron + depends_on: + - wireguard-webadmin + nginx: container_name: wireguard-webadmin-nginx restart: unless-stopped diff --git a/entrypoint.sh b/entrypoint.sh index 7d5a3bb..c2ed734 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -14,8 +14,8 @@ fi cat > /app/wireguard_webadmin/production_settings.py < +{% load custom_tags %} +{% tag_webadmin_version as webadmin_version %} +
@@ -165,7 +168,34 @@
+ + + + + + + + +
{% if pending_changes_warning %} @@ -190,9 +220,9 @@
- wireguard-webadmin + {% if webadmin_version.update_available %}Update Available{% else %}wireguard-webadmin {% endif %}
- Version 0.9.0 + Version {{ webadmin_version.current_version }}
@@ -259,8 +289,53 @@ {% endif %} {% endcomment %} -{% include "template_messages.html" %} + + +{% include "template_messages.html" %} {% block custom_page_scripts %} diff --git a/templates/wireguard/welcome.html b/templates/wireguard/welcome.html index 1b7e2d3..8a1a924 100644 --- a/templates/wireguard/welcome.html +++ b/templates/wireguard/welcome.html @@ -9,7 +9,7 @@ diff --git a/wireguard/admin.py b/wireguard/admin.py index ef6c0ed..56a2b79 100644 --- a/wireguard/admin.py +++ b/wireguard/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from .models import WireGuardInstance, Peer, PeerAllowedIP +from .models import WireGuardInstance, Peer, PeerAllowedIP, WebadminSettings class WireGuardInstanceAdmin(admin.ModelAdmin): @@ -20,4 +20,11 @@ class PeerAllowedIPAdmin(admin.ModelAdmin): list_display = ('peer', 'priority', 'allowed_ip', 'netmask', 'created', 'updated', 'uuid') search_fields = ('peer', 'priority', 'allowed_ip', 'netmask', 'created', 'updated', 'uuid') -admin.site.register(PeerAllowedIP, PeerAllowedIPAdmin) \ No newline at end of file +admin.site.register(PeerAllowedIP, PeerAllowedIPAdmin) + + +class WebadminSettingsAdmin(admin.ModelAdmin): + list_display = ('current_version', 'latest_version', 'update_available', 'created', 'updated', 'uuid') + search_fields = ('current_version', 'latest_version', 'update_available', 'created', 'updated', 'uuid') + +#admin.site.register(WebadminSettings, WebadminSettingsAdmin) \ No newline at end of file diff --git a/wireguard/migrations/0008_wireguardinstance_dns_primary_and_more.py b/wireguard/migrations/0008_wireguardinstance_dns_primary_and_more.py index 75e0269..732c07c 100644 --- a/wireguard/migrations/0008_wireguardinstance_dns_primary_and_more.py +++ b/wireguard/migrations/0008_wireguardinstance_dns_primary_and_more.py @@ -13,12 +13,12 @@ class Migration(migrations.Migration): migrations.AddField( model_name='wireguardinstance', name='dns_primary', - field=models.GenericIPAddressField(default='1.1.1.1', protocol='IPv4', unique=True), + field=models.GenericIPAddressField(default='1.1.1.1', protocol='IPv4', unique=False), ), migrations.AddField( model_name='wireguardinstance', name='dns_secondary', - field=models.GenericIPAddressField(blank=True, default='1.0.0.1', null=True, protocol='IPv4', unique=True), + field=models.GenericIPAddressField(blank=True, default='1.0.0.1', null=True, protocol='IPv4', unique=False), ), migrations.AddField( model_name='wireguardinstance', diff --git a/wireguard/migrations/0009_webadminsettings.py b/wireguard/migrations/0009_webadminsettings.py new file mode 100644 index 0000000..ccd0e2f --- /dev/null +++ b/wireguard/migrations/0009_webadminsettings.py @@ -0,0 +1,28 @@ +# Generated by Django 5.0.1 on 2024-02-22 17:54 + +import uuid +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wireguard', '0008_wireguardinstance_dns_primary_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='WebadminSettings', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('webadmin_settings', models.CharField(max_length=20, unique=True)), + ('update_available', models.BooleanField(default=False)), + ('current_version', models.DecimalField(decimal_places=4, default=0, max_digits=8)), + ('latest_version', models.DecimalField(decimal_places=4, default=0, max_digits=8)), + ('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/wireguard/migrations/0010_remove_webadminsettings_webadmin_settings.py b/wireguard/migrations/0010_remove_webadminsettings_webadmin_settings.py new file mode 100644 index 0000000..271cf0a --- /dev/null +++ b/wireguard/migrations/0010_remove_webadminsettings_webadmin_settings.py @@ -0,0 +1,17 @@ +# Generated by Django 5.0.1 on 2024-02-22 18:03 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('wireguard', '0009_webadminsettings'), + ] + + operations = [ + migrations.RemoveField( + model_name='webadminsettings', + name='webadmin_settings', + ), + ] diff --git a/wireguard/migrations/0011_webadminsettings_name.py b/wireguard/migrations/0011_webadminsettings_name.py new file mode 100644 index 0000000..ab6c83b --- /dev/null +++ b/wireguard/migrations/0011_webadminsettings_name.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.1 on 2024-02-22 18:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wireguard', '0010_remove_webadminsettings_webadmin_settings'), + ] + + operations = [ + migrations.AddField( + model_name='webadminsettings', + name='name', + field=models.CharField(default='webadmin_settings', max_length=20, unique=True), + ), + ] diff --git a/wireguard/migrations/0012_remove_webadminsettings_current_version_and_more.py b/wireguard/migrations/0012_remove_webadminsettings_current_version_and_more.py new file mode 100644 index 0000000..eae7d9d --- /dev/null +++ b/wireguard/migrations/0012_remove_webadminsettings_current_version_and_more.py @@ -0,0 +1,21 @@ +# Generated by Django 5.0.1 on 2024-02-22 19:02 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('wireguard', '0011_webadminsettings_name'), + ] + + operations = [ + migrations.RemoveField( + model_name='webadminsettings', + name='current_version', + ), + migrations.RemoveField( + model_name='webadminsettings', + name='latest_version', + ), + ] diff --git a/wireguard/migrations/0013_webadminsettings_current_version_and_more.py b/wireguard/migrations/0013_webadminsettings_current_version_and_more.py new file mode 100644 index 0000000..c7520a0 --- /dev/null +++ b/wireguard/migrations/0013_webadminsettings_current_version_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 5.0.1 on 2024-02-22 19:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wireguard', '0012_remove_webadminsettings_current_version_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='webadminsettings', + name='current_version', + field=models.PositiveIntegerField(default=0), + ), + migrations.AddField( + model_name='webadminsettings', + name='latest_version', + field=models.PositiveIntegerField(default=0), + ), + ] diff --git a/wireguard/migrations/0014_alter_wireguardinstance_dns_primary_and_more.py b/wireguard/migrations/0014_alter_wireguardinstance_dns_primary_and_more.py new file mode 100644 index 0000000..29d920e --- /dev/null +++ b/wireguard/migrations/0014_alter_wireguardinstance_dns_primary_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 5.0.1 on 2024-02-23 15:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wireguard', '0013_webadminsettings_current_version_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='wireguardinstance', + name='dns_primary', + field=models.GenericIPAddressField(default='1.1.1.1', protocol='IPv4'), + ), + migrations.AlterField( + model_name='wireguardinstance', + name='dns_secondary', + field=models.GenericIPAddressField(blank=True, default='1.0.0.1', null=True, protocol='IPv4'), + ), + ] diff --git a/wireguard/models.py b/wireguard/models.py index a9b1a23..2b3818e 100644 --- a/wireguard/models.py +++ b/wireguard/models.py @@ -29,6 +29,21 @@ NETMASK_CHOICES = ( ) +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 + + class WireGuardInstance(models.Model): name = models.CharField(max_length=100, blank=True, null=True) instance_id = models.PositiveIntegerField(unique=True, default=0) @@ -41,8 +56,8 @@ class WireGuardInstance(models.Model): post_up = models.TextField(blank=True, null=True) post_down = models.TextField(blank=True, null=True) peer_list_refresh_interval = models.IntegerField(default=20) - dns_primary = models.GenericIPAddressField(unique=True, protocol='IPv4', default='1.1.1.1') - dns_secondary = models.GenericIPAddressField(unique=True, protocol='IPv4', default='1.0.0.1', blank=True, null=True) + dns_primary = models.GenericIPAddressField(unique=False, protocol='IPv4', default='1.1.1.1') + dns_secondary = models.GenericIPAddressField(unique=False, protocol='IPv4', default='1.0.0.1', blank=True, null=True) pending_changes = models.BooleanField(default=True) created = models.DateTimeField(auto_now_add=True) diff --git a/wireguard/views.py b/wireguard/views.py index 62a1f5e..c6f66b3 100644 --- a/wireguard/views.py +++ b/wireguard/views.py @@ -1,11 +1,13 @@ +from decimal import Decimal, ROUND_DOWN from django.shortcuts import render, get_object_or_404, redirect from user_manager.models import UserAcl from wireguard.forms import WireGuardInstanceForm -from .models import WireGuardInstance +from .models import WireGuardInstance, WebadminSettings from django.contrib.auth.decorators import login_required from django.contrib import messages from django.db import models +from django.conf import settings import os import subprocess @@ -67,8 +69,7 @@ def generate_instance_defaults(): @login_required def view_welcome(request): page_title = 'Welcome' - breadcrumb = {'level2': {'title': 'Place holder', 'href': '/blabla'}} - context = {'page_title': page_title, 'breadcrumb': breadcrumb} + context = {'page_title': page_title} return render(request, 'wireguard/welcome.html', context) diff --git a/wireguard_tools/templatetags/__init__.py b/wireguard_tools/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/wireguard_tools/templatetags/custom_tags.py b/wireguard_tools/templatetags/custom_tags.py new file mode 100644 index 0000000..cf309a0 --- /dev/null +++ b/wireguard_tools/templatetags/custom_tags.py @@ -0,0 +1,18 @@ +from django import template +from django.conf import settings +from wireguard.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.WIREGUARD_WEBADMIN_VERSION: + webadmin_settings.current_version = settings.WIREGUARD_WEBADMIN_VERSION + webadmin_settings.save() + return { + 'current_version': settings.WIREGUARD_WEBADMIN_VERSION / 10000, + 'latest_version': webadmin_settings.latest_version / 10000, + 'update_available': webadmin_settings.update_available, + } + \ No newline at end of file diff --git a/wireguard_webadmin/settings.py b/wireguard_webadmin/settings.py index c96b745..be2152f 100644 --- a/wireguard_webadmin/settings.py +++ b/wireguard_webadmin/settings.py @@ -38,6 +38,7 @@ INSTALLED_APPS = [ 'django.contrib.staticfiles', 'wireguard', 'user_manager', + 'wireguard_tools', ] MIDDLEWARE = [ @@ -127,4 +128,6 @@ STATICFILES_DIRS = [ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +WIREGUARD_WEBADMIN_VERSION = 9000 + from wireguard_webadmin.production_settings import * \ No newline at end of file diff --git a/wireguard_webadmin/urls.py b/wireguard_webadmin/urls.py index 88dcbb9..1af802f 100644 --- a/wireguard_webadmin/urls.py +++ b/wireguard_webadmin/urls.py @@ -22,7 +22,7 @@ from console.views import view_console from user_manager.views import view_user_list, view_manage_user from accounts.views import view_create_first_user, view_login, view_logout from wireguard_tools.views import export_wireguard_configs, download_config_or_qrcode, restart_wireguard_interfaces -from api.views import wireguard_status +from api.views import wireguard_status, cron_check_updates urlpatterns = [ @@ -43,5 +43,6 @@ urlpatterns = [ path('accounts/login/', view_login, name='login'), path('accounts/logout/', view_logout, name='logout'), path('api/wireguard_status/', wireguard_status, name='api_wireguard_status'), + path('api/cron_check_updates/', cron_check_updates, name='cron_check_updates'), ]