diff --git a/vpn/admin.py b/vpn/admin.py index dafd997..910946e 100644 --- a/vpn/admin.py +++ b/vpn/admin.py @@ -53,24 +53,6 @@ class TaskExecutionLogAdmin(admin.ModelAdmin): # This action doesn't require selected items try: from vpn.tasks import sync_all_users - from datetime import timedelta - from django.utils import timezone - - # Check if sync is already running (last 10 minutes) - recent_cutoff = timezone.now() - timedelta(minutes=10) - running_syncs = TaskExecutionLog.objects.filter( - created_at__gte=recent_cutoff, - task_name='sync_all_servers', - status='STARTED' - ) - - if running_syncs.exists(): - self.message_user( - request, - 'Synchronization is already running. Please wait for completion.', - level=messages.WARNING - ) - return # Start the sync task task = sync_all_users.delay() @@ -140,7 +122,7 @@ class TaskExecutionLogAdmin(admin.ModelAdmin): return False def changelist_view(self, request, extra_context=None): - """Override to handle actions that don't require item selection and add sync status""" + """Override to handle actions that don't require item selection""" # Handle actions that don't require selection if 'action' in request.POST: action = request.POST['action'] @@ -150,36 +132,6 @@ class TaskExecutionLogAdmin(admin.ModelAdmin): # Return redirect to prevent AttributeError return redirect(request.get_full_path()) - # Add sync status and controls to the changelist - extra_context = extra_context or {} - - # Add sync statistics - from datetime import timedelta - from django.utils import timezone - - # Get recent sync tasks (last 24 hours) - recent_cutoff = timezone.now() - timedelta(hours=24) - recent_syncs = TaskExecutionLog.objects.filter( - created_at__gte=recent_cutoff, - task_name='sync_all_servers' - ) - - total_recent = recent_syncs.count() - successful_recent = recent_syncs.filter(status='SUCCESS').count() - failed_recent = recent_syncs.filter(status='FAILURE').count() - running_recent = recent_syncs.filter(status='STARTED').count() - - # Check if sync is currently running - currently_running = recent_syncs.filter(status='STARTED').exists() - - extra_context.update({ - 'total_recent_syncs': total_recent, - 'successful_recent_syncs': successful_recent, - 'failed_recent_syncs': failed_recent, - 'running_recent_syncs': running_recent, - 'sync_currently_running': currently_running, - }) - return super().changelist_view(request, extra_context) diff --git a/vpn/migrations/0002_taskexecutionlog.py b/vpn/migrations/0002_taskexecutionlog.py new file mode 100644 index 0000000..d9cba00 --- /dev/null +++ b/vpn/migrations/0002_taskexecutionlog.py @@ -0,0 +1,51 @@ +# Generated manually to fix migration issue + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('vpn', '0001_initial'), + ] + + operations = [ + migrations.RunSQL( + "DROP TABLE IF EXISTS vpn_taskexecutionlog CASCADE;", + reverse_sql="-- No reverse operation" + ), + migrations.CreateModel( + name='TaskExecutionLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('task_id', models.CharField(help_text='Celery task ID', max_length=255)), + ('task_name', models.CharField(help_text='Task name', max_length=100)), + ('action', models.CharField(help_text='Action performed', max_length=100)), + ('status', models.CharField(choices=[('STARTED', 'Started'), ('SUCCESS', 'Success'), ('FAILURE', 'Failure'), ('RETRY', 'Retry')], default='STARTED', max_length=20)), + ('message', models.TextField(help_text='Detailed execution message')), + ('execution_time', models.FloatField(blank=True, help_text='Execution time in seconds', null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('server', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vpn.server')), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vpn.user')), + ], + options={ + 'verbose_name': 'Task Execution Log', + 'verbose_name_plural': 'Task Execution Logs', + 'ordering': ['-created_at'], + }, + ), + # Create indexes with safe SQL to avoid conflicts + migrations.RunSQL( + "CREATE INDEX IF NOT EXISTS vpn_taskexec_task_id_idx ON vpn_taskexecutionlog (task_id);", + reverse_sql="DROP INDEX IF EXISTS vpn_taskexec_task_id_idx;" + ), + migrations.RunSQL( + "CREATE INDEX IF NOT EXISTS vpn_taskexec_created_idx ON vpn_taskexecutionlog (created_at);", + reverse_sql="DROP INDEX IF EXISTS vpn_taskexec_created_idx;" + ), + migrations.RunSQL( + "CREATE INDEX IF NOT EXISTS vpn_taskexec_status_idx ON vpn_taskexecutionlog (status);", + reverse_sql="DROP INDEX IF EXISTS vpn_taskexec_status_idx;" + ), + ] diff --git a/vpn/templates/admin/vpn/taskexecutionlog/change_list.html b/vpn/templates/admin/vpn/taskexecutionlog/change_list.html index 3b97342..b4eec6f 100644 --- a/vpn/templates/admin/vpn/taskexecutionlog/change_list.html +++ b/vpn/templates/admin/vpn/taskexecutionlog/change_list.html @@ -3,49 +3,14 @@ {% block content_title %}
- 💡 Use the "Trigger full sync" action to manually synchronize all servers with current ACL settings. -
- {% if sync_currently_running %} - - ⚠️ Sync already running - wait for completion - - {% endif %} -+ 💡 Use the "Trigger full sync" action to manually synchronize all servers with current ACL settings. +