From 839aadcf21c630d4d232cffe1cd38352ba43b299 Mon Sep 17 00:00:00 2001 From: Junwei Zhao Date: Mon, 11 May 2026 22:57:21 +1000 Subject: [PATCH] Update ban ip form --- links/mini_apps_views.py | 8 ---- links/views.py | 1 - nginxmon/templates/nginxmon/dashboard.html | 47 ++++++++++++++++++++++ nginxmon/urls.py | 3 ++ nginxmon/views.py | 41 +++++++++++++++++++ 5 files changed, 91 insertions(+), 9 deletions(-) diff --git a/links/mini_apps_views.py b/links/mini_apps_views.py index 594fe86..0bc2034 100644 --- a/links/mini_apps_views.py +++ b/links/mini_apps_views.py @@ -40,14 +40,6 @@ class MiniAppsListView(TemplateView): 'icon': 'fas fa-chart-line', 'color': '#27ae60' }, - { - 'name': 'Nginx IP Ban', - 'description': 'Manage the nginx ingress block list — view, add, and remove banned IPs and CIDR ranges directly from the Kubernetes ConfigMap.', - 'url': 'mini-apps-ip-ban', - 'thumbnail': 'https://images.unsplash.com/photo-1614064641938-3bbee52942c7?w=400&h=300&fit=crop', - 'icon': 'fas fa-ban', - 'color': '#e74c3c' - }, { 'name': 'Weather Dashboard', 'description': 'Real-time weather information with beautiful visualizations and forecasts.', diff --git a/links/views.py b/links/views.py index ef426e8..69f592d 100644 --- a/links/views.py +++ b/links/views.py @@ -90,7 +90,6 @@ class LinkListView(ListView): mini_apps = [ {'name': 'Image Gallery', 'description': 'Browse Images', 'url': 'mini-apps-image-gallery'}, {'name': 'TTS', 'description': 'Convert text to speech', 'url': 'mini-apps-tts'}, - {'name': 'IP Ban', 'description': 'Block IP addresses', 'url': 'mini-apps-ip-ban'}, ] context['mini_apps'] = [ {**app, 'color': random.choice(colors)} diff --git a/nginxmon/templates/nginxmon/dashboard.html b/nginxmon/templates/nginxmon/dashboard.html index 445e165..dcd6d4f 100644 --- a/nginxmon/templates/nginxmon/dashboard.html +++ b/nginxmon/templates/nginxmon/dashboard.html @@ -57,6 +57,10 @@ Detect Threats + New Alert Profile @@ -261,6 +265,49 @@ + + +
diff --git a/nginxmon/urls.py b/nginxmon/urls.py index 688b035..c17974e 100644 --- a/nginxmon/urls.py +++ b/nginxmon/urls.py @@ -20,6 +20,9 @@ urlpatterns = [ path('alert//dismiss/', views.DismissAlertView.as_view(), name='nginxmon-dismiss-alert'), path('ban//unban/', views.UnbanIPView.as_view(), name='nginxmon-unban'), + # Manual IP ban form + path('actions/ip-ban/', views.IPBanView.as_view(), name='nginxmon-ip-ban'), + # HTMX partials & APIs path('api/live-logs/', views.LiveLogsPartialView.as_view(), name='nginxmon-live-logs'), path('api/alerts/', views.AlertsPartialView.as_view(), name='nginxmon-alerts-partial'), diff --git a/nginxmon/views.py b/nginxmon/views.py index ef3e5f3..2283cb9 100644 --- a/nginxmon/views.py +++ b/nginxmon/views.py @@ -327,6 +327,47 @@ class UnbanIPView(View): return redirect('nginxmon-dashboard') +class IPBanView(View): + """Manual IP ban form — adds IPs/CIDRs to the k8s ConfigMap and creates BannedIP records.""" + + def post(self, request): + raw = request.POST.get('ips', '').strip() + if not raw: + messages.error(request, 'No IPs provided.') + return redirect('nginxmon-dashboard') + + new_ips = [ + ip.strip() + for part in raw.replace('\n', ',').split(',') + for ip in [part.strip()] + if ip + ] + + try: + from links.mini_apps_views import _read_blocked_ips, _write_blocked_ips + blocked = _read_blocked_ips() + added = 0 + for ip in new_ips: + if ip not in blocked: + blocked.append(ip) + added += 1 + BannedIP.objects.get_or_create( + ip=ip, + defaults=dict( + ban_source='manual', + reason='Manually banned from dashboard.', + request_count=NginxAccessLog.objects.filter(remote_addr=ip).count(), + ), + ) + _write_blocked_ips(blocked) + messages.success(request, f'Banned {added} new IP(s). Total blocked: {len(blocked)}.') + except Exception as exc: + logger.error('nginxmon IPBanView: %s', exc) + messages.error(request, f'Failed to ban IPs: {exc}') + + return redirect('nginxmon-dashboard') + + # ── Chart & ingest API ──────────────────────────────────────────────────────── class ChartDataView(View):