Files
OutFleet/vpn/tasks.py

123 lines
4.8 KiB
Python
Raw Normal View History

2024-10-20 21:57:12 +00:00
import logging
2024-10-21 13:22:03 +00:00
from celery import group, shared_task
2025-07-20 22:30:04 +03:00
from celery.exceptions import Retry
2024-10-20 21:57:12 +00:00
logger = logging.getLogger(__name__)
class TaskFailedException(Exception):
def __init__(self, message=""):
self.message = message
super().__init__(f"{self.message}")
2025-07-20 22:30:04 +03:00
@shared_task(name="sync_all_servers", bind=True, autoretry_for=(Exception,), retry_kwargs={'max_retries': 3, 'countdown': 60})
def sync_all_users(self):
2024-10-21 13:22:03 +00:00
from vpn.server_plugins import Server
servers = Server.objects.all()
2025-07-20 22:30:04 +03:00
if not servers.exists():
logger.warning("No servers found for synchronization")
return "No servers to sync"
2024-10-21 13:22:03 +00:00
tasks = group(sync_users.s(server.id) for server in servers)
result = tasks.apply_async()
2025-07-20 22:30:04 +03:00
return f"Initiated sync for {servers.count()} servers"
2024-10-21 13:22:03 +00:00
2025-07-20 22:30:04 +03:00
@shared_task(name="sync_all_users_on_server", bind=True, autoretry_for=(Exception,), retry_kwargs={'max_retries': 3, 'countdown': 60})
def sync_users(self, server_id):
from vpn.server_plugins import Server
2024-10-21 13:22:03 +00:00
try:
server = Server.objects.get(id=server_id)
2025-07-20 22:30:04 +03:00
logger.info(f"Starting user sync for server {server.name}")
sync_result = server.sync_users()
if sync_result:
2024-10-28 17:15:49 +00:00
logger.info(f"Successfully synced users for server {server.name}")
return f"Successfully synced users for server {server.name}"
2025-07-20 22:30:04 +03:00
else:
raise TaskFailedException(f"Sync failed for server {server.name}")
except Server.DoesNotExist:
logger.error(f"Server with id {server_id} not found")
raise TaskFailedException(f"Server with id {server_id} not found")
2024-10-21 13:22:03 +00:00
except Exception as e:
2025-07-20 22:30:04 +03:00
logger.error(f"Error syncing users for server id {server_id}: {e}")
if self.request.retries < 3:
logger.info(f"Retrying sync for server id {server_id} (attempt {self.request.retries + 1})")
raise self.retry(countdown=60)
raise TaskFailedException(f"Error syncing users for server id {server_id}: {e}")
2024-10-21 13:22:03 +00:00
2025-07-20 22:30:04 +03:00
@shared_task(name="sync_server_info", bind=True, autoretry_for=(Exception,), retry_kwargs={'max_retries': 3, 'countdown': 30})
def sync_server(self, id):
2024-10-20 21:57:12 +00:00
from vpn.server_plugins import Server
2025-07-20 22:30:04 +03:00
try:
server = Server.objects.get(id=id)
logger.info(f"Starting server info sync for {server.name}")
sync_result = server.sync()
return {"status": sync_result, "server": server.name}
except Server.DoesNotExist:
logger.error(f"Server with id {id} not found")
return {"error": f"Server with id {id} not found"}
except Exception as e:
logger.error(f"Error syncing server info for id {id}: {e}")
if self.request.retries < 3:
logger.info(f"Retrying server sync for id {id} (attempt {self.request.retries + 1})")
raise self.retry(countdown=30)
return {"error": f"Error syncing server info: {e}"}
2024-10-20 21:57:12 +00:00
2025-07-20 22:30:04 +03:00
@shared_task(name="sync_user_on_server", bind=True, autoretry_for=(Exception,), retry_kwargs={'max_retries': 5, 'countdown': 30})
def sync_user(self, user_id, server_id):
2024-10-20 21:57:12 +00:00
from .models import User, ACL
from vpn.server_plugins import Server
errors = {}
result = {}
2025-07-20 22:30:04 +03:00
2024-10-21 13:22:03 +00:00
try:
2025-07-20 22:30:04 +03:00
user = User.objects.get(id=user_id)
server = Server.objects.get(id=server_id)
logger.info(f"Syncing user {user.username} on server {server.name}")
# Check if ACL exists
acl_exists = ACL.objects.filter(user=user, server=server).exists()
if acl_exists:
# User should exist on server
2024-10-21 13:22:03 +00:00
result[server.name] = server.add_user(user)
2025-07-20 22:30:04 +03:00
logger.info(f"Added/updated user {user.username} on server {server.name}")
2024-10-21 13:22:03 +00:00
else:
2025-07-20 22:30:04 +03:00
# User should be removed from server
2024-10-21 13:22:03 +00:00
result[server.name] = server.delete_user(user)
2025-07-20 22:30:04 +03:00
logger.info(f"Removed user {user.username} from server {server.name}")
except User.DoesNotExist:
error_msg = f"User with id {user_id} not found"
logger.error(error_msg)
errors["user"] = error_msg
except Server.DoesNotExist:
error_msg = f"Server with id {server_id} not found"
logger.error(error_msg)
errors["server"] = error_msg
2024-10-21 13:22:03 +00:00
except Exception as e:
2025-07-20 22:30:04 +03:00
error_msg = f"Error syncing user {user_id} on server {server_id}: {e}"
logger.error(error_msg)
errors[f"server_{server_id}"] = error_msg
# Retry on failure unless it's a permanent error
if self.request.retries < 5:
logger.info(f"Retrying user sync for user {user_id} on server {server_id} (attempt {self.request.retries + 1})")
raise self.retry(countdown=30)
if errors:
raise TaskFailedException(message=f"Errors during task: {errors}")
return result