From 09bb86d31a08d0cf1ff5b2805b88f839c469ff0e Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Tue, 24 Mar 2026 16:00:58 -0300 Subject: [PATCH] Add export_configs management command for WireGuard and Caddy configurations --- dns/functions.py | 5 ++- .../0005_dnsfilterlist_list_format.py | 20 +++++++++++ dns/models.py | 9 +++++ dns/views.py | 36 +++++++++++++++++-- templates/dns/static_host_list.html | 20 ++++++++--- 5 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 dns/migrations/0005_dnsfilterlist_list_format.py diff --git a/dns/functions.py b/dns/functions.py index 00ddff0..e9d7002 100644 --- a/dns/functions.py +++ b/dns/functions.py @@ -134,6 +134,9 @@ bind-interfaces dnsmasq_config += '\n' for dns_list in dns_lists: file_path = os.path.join("/etc/dnsmasq/", f"{dns_list.uuid}.conf") - dnsmasq_config += f'addn-hosts={file_path}\n' + if dns_list.list_format == 'hosts': + dnsmasq_config += f'addn-hosts={file_path}\n' + elif dns_list.list_format == 'dnsmasq': + dnsmasq_config += f'conf-file={file_path}\n' return dnsmasq_config diff --git a/dns/migrations/0005_dnsfilterlist_list_format.py b/dns/migrations/0005_dnsfilterlist_list_format.py new file mode 100644 index 0000000..eba9b45 --- /dev/null +++ b/dns/migrations/0005_dnsfilterlist_list_format.py @@ -0,0 +1,20 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dns', '0004_dnsfilterlist_recommended'), + ] + + operations = [ + migrations.AddField( + model_name='dnsfilterlist', + name='list_format', + field=models.CharField( + choices=[('', 'Unknown'), ('hosts', 'Hosts'), ('dnsmasq', 'Dnsmasq'), ('unsupported', 'Unsupported')], + default='', + max_length=15, + ), + ), + ] diff --git a/dns/models.py b/dns/models.py index bf2d5c6..990a42a 100644 --- a/dns/models.py +++ b/dns/models.py @@ -1,6 +1,7 @@ import uuid from django.db import models +from django.utils.translation import gettext_lazy as _ class DNSSettings(models.Model): @@ -27,6 +28,13 @@ class StaticHost(models.Model): class DNSFilterList(models.Model): + LIST_FORMAT_CHOICES = [ + ('', _('Unknown')), + ('hosts', 'Hosts'), + ('dnsmasq', 'Dnsmasq'), + ('unsupported', _('Unsupported')), + ] + name = models.SlugField(max_length=100, unique=True) description = models.CharField(max_length=100) enabled = models.BooleanField(default=False) @@ -34,6 +42,7 @@ class DNSFilterList(models.Model): last_updated = models.DateTimeField(blank=True, null=True) host_count = models.IntegerField(default=0) recommended = models.BooleanField(default=False) + list_format = models.CharField(max_length=15, choices=LIST_FORMAT_CHOICES, default='') created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) diff --git a/dns/views.py b/dns/views.py index ad97645..192c516 100644 --- a/dns/views.py +++ b/dns/views.py @@ -1,5 +1,6 @@ import hashlib import os +import re import requests from django.conf import settings @@ -17,6 +18,20 @@ from .models import DNSFilterList, DNSSettings from .models import StaticHost +def detect_list_format(content): + for line in content.splitlines(): + line = line.strip() + if not line or line.startswith('#'): + continue + if line.startswith(('local=/', 'address=/', 'server=/', 'conf-file=')): + return 'dnsmasq' + parts = line.split() + if len(parts) >= 2 and re.match(r'^[\d\.]+$|^[0-9a-fA-F:]+$', parts[0]): + return 'hosts' + return 'unsupported' + return '' + + def export_dns_configuration(): dnsmasq_config = generate_dnsmasq_config() with open(settings.DNS_CONFIG_FILE, 'w') as f: @@ -172,7 +187,9 @@ def view_manage_filter_list(request): form = DNSFilterListForm(request.POST or None, instance=filter_list) if form.is_valid(): - form.save() + saved = form.save(commit=False) + saved.list_format = '' + saved.save() dns_settings.pending_changes = True dns_settings.save() messages.success(request, _('DNS Filter List saved successfully')) @@ -244,6 +261,17 @@ def view_update_dns_list(request): dns_settings.pending_changes = True dns_settings.save() + # Detect list format from content. + detected_format = detect_list_format(content) + dns_list.list_format = detected_format + + # If unsupported format, disable the list. + if detected_format == 'unsupported' and dns_list.enabled: + dns_list.enabled = False + dns_settings.pending_changes = True + dns_settings.save() + messages.warning(request, _('DNS Filter List disabled | Unsupported format detected')) + # Count the number of valid host entries (ignoring empty lines and lines starting with '#'). host_count = sum(1 for line in content.splitlines() if line.strip() and not line.strip().startswith('#')) dns_list.host_count = host_count @@ -268,7 +296,11 @@ def view_toggle_dns_list(request): file_path = os.path.join("/etc/dnsmasq/", f"{dns_list.uuid}.conf") if request.GET.get('action') == 'enable': - if dns_list.host_count > 0 and os.path.exists(file_path): + if dns_list.list_format == 'unsupported': + messages.error(request, _('DNS Filter List not enabled | Unsupported format')) + elif dns_list.list_format == '': + messages.error(request, _('DNS Filter List not enabled | List has not been downloaded yet')) + elif dns_list.host_count > 0 and os.path.exists(file_path): dns_list.enabled = True dns_list.save() export_dns_configuration() diff --git a/templates/dns/static_host_list.html b/templates/dns/static_host_list.html index 7efcc41..5f006ad 100644 --- a/templates/dns/static_host_list.html +++ b/templates/dns/static_host_list.html @@ -67,11 +67,12 @@ {% trans 'Name' %} {% trans 'Description' %} + {% trans 'Format' %} {% trans 'Hosts' %} {% trans 'Last Update' %} - {% trans 'Status' %} - {% trans 'Update' %} - {% trans 'Edit' %} + + + @@ -83,8 +84,17 @@ {% endif %} {{ filter_list.name }} {{ filter_list.description }} + + {% if filter_list.list_format == 'unsupported' %} + {% trans 'Unsupported' %} + {% elif filter_list.list_format == '' %} + {% trans 'Unknown' %} + {% else %} + {{ filter_list.list_format }} + {% endif %} + {{ filter_list.host_count }} - {{ filter_list.last_updated|default_if_none:"" }} + {{ filter_list.last_updated|date:"d/m/y H:i"|default_if_none:"" }} {% if filter_list.enabled %} @@ -103,7 +113,7 @@ {% endfor %} {% else %} - + {% endif %}