197 lines
6.4 KiB
Python
197 lines
6.4 KiB
Python
import asyncio
|
||
|
||
import asyncpg
|
||
from py3xui import AsyncApi
|
||
|
||
from utils.client import add_client, delete_client, extend_client_key
|
||
from config import ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL, TOTAL_GB
|
||
from utils.database import get_servers_from_db
|
||
from logger import logger
|
||
|
||
|
||
async def create_key_on_cluster(cluster_id, tg_id, client_id, email, expiry_timestamp):
|
||
try:
|
||
tasks = []
|
||
servers = await get_servers_from_db()
|
||
cluster = servers.get(cluster_id)
|
||
|
||
if not cluster:
|
||
raise ValueError(f"Кластер с ID {cluster_id} не найден.")
|
||
|
||
for server_info in cluster:
|
||
xui = AsyncApi(
|
||
server_info["api_url"],
|
||
username=ADMIN_USERNAME,
|
||
password=ADMIN_PASSWORD,
|
||
)
|
||
|
||
inbound_id = server_info.get("inbound_id")
|
||
if not inbound_id:
|
||
logger.warning(
|
||
f"INBOUND_ID отсутствует для сервера {server_info.get('server_name', 'unknown')}. Пропуск."
|
||
)
|
||
continue
|
||
|
||
conn = await asyncpg.connect(DATABASE_URL)
|
||
existing_key = await conn.fetchrow("SELECT 1 FROM keys WHERE email = $1", email)
|
||
|
||
if existing_key:
|
||
raise ValueError(f"Email {email} уже существует в базе данных.")
|
||
|
||
tasks.append(
|
||
add_client(
|
||
xui,
|
||
client_id,
|
||
email,
|
||
tg_id,
|
||
limit_ip=1,
|
||
total_gb=TOTAL_GB,
|
||
expiry_time=expiry_timestamp,
|
||
enable=True,
|
||
flow="xtls-rprx-vision",
|
||
inbound_id=int(inbound_id),
|
||
)
|
||
)
|
||
await conn.close()
|
||
|
||
await asyncio.gather(*tasks)
|
||
|
||
except Exception as e:
|
||
logger.error(f"Ошибка при создании ключа: {e}")
|
||
raise e
|
||
|
||
|
||
async def renew_key_in_cluster(cluster_id, email, client_id, new_expiry_time, total_gb):
|
||
try:
|
||
servers = await get_servers_from_db()
|
||
cluster = servers.get(cluster_id)
|
||
|
||
if not cluster:
|
||
raise ValueError(f"Кластер с ID {cluster_id} не найден.")
|
||
|
||
tasks = []
|
||
for server_info in cluster:
|
||
xui = AsyncApi(
|
||
server_info["api_url"],
|
||
username=ADMIN_USERNAME,
|
||
password=ADMIN_PASSWORD,
|
||
)
|
||
|
||
inbound_id = server_info.get("inbound_id")
|
||
if not inbound_id:
|
||
logger.warning(
|
||
f"INBOUND_ID отсутствует для сервера {server_info.get('server_name', 'unknown')}. Пропуск."
|
||
)
|
||
continue
|
||
|
||
tasks.append(
|
||
extend_client_key(
|
||
xui,
|
||
int(inbound_id),
|
||
email,
|
||
new_expiry_time,
|
||
client_id,
|
||
total_gb,
|
||
)
|
||
)
|
||
|
||
await asyncio.gather(*tasks)
|
||
|
||
except Exception as e:
|
||
logger.error(f"Не удалось продлить ключ {client_id} в кластере {cluster_id}: {e}")
|
||
raise e
|
||
|
||
|
||
async def delete_key_from_db(client_id, session):
|
||
try:
|
||
await session.execute("DELETE FROM keys WHERE client_id = $1", client_id)
|
||
except Exception as e:
|
||
logger.error(f"Ошибка при удалении ключа {client_id} из базы данных: {e}")
|
||
|
||
|
||
async def delete_key_from_cluster(cluster_id, email, client_id):
|
||
"""Удаление ключа с серверов в кластере"""
|
||
try:
|
||
servers = await get_servers_from_db()
|
||
cluster = servers.get(cluster_id)
|
||
|
||
if not cluster:
|
||
raise ValueError(f"Кластер с ID {cluster_id} не найден.")
|
||
|
||
tasks = []
|
||
for server_info in cluster:
|
||
xui = AsyncApi(
|
||
server_info["api_url"],
|
||
username=ADMIN_USERNAME,
|
||
password=ADMIN_PASSWORD,
|
||
)
|
||
|
||
inbound_id = server_info.get("inbound_id")
|
||
if not inbound_id:
|
||
logger.warning(
|
||
f"INBOUND_ID отсутствует для сервера {server_info.get('server_name', 'unknown')}. Пропуск."
|
||
)
|
||
continue
|
||
|
||
tasks.append(
|
||
delete_client(
|
||
xui,
|
||
int(inbound_id),
|
||
email,
|
||
client_id,
|
||
)
|
||
)
|
||
|
||
await asyncio.gather(*tasks)
|
||
|
||
except Exception as e:
|
||
logger.error(f"Не удалось удалить ключ {client_id} в кластере {cluster_id}: {e}")
|
||
raise e
|
||
|
||
|
||
async def update_key_on_cluster(tg_id, client_id, email, expiry_time, cluster_id):
|
||
try:
|
||
servers = await get_servers_from_db()
|
||
cluster = servers.get(cluster_id)
|
||
|
||
if not cluster:
|
||
raise ValueError(f"Кластер с ID {cluster_id} не найден.")
|
||
|
||
tasks = []
|
||
for server_info in cluster:
|
||
xui = AsyncApi(
|
||
server_info["api_url"],
|
||
username=ADMIN_USERNAME,
|
||
password=ADMIN_PASSWORD,
|
||
)
|
||
|
||
inbound_id = server_info.get("inbound_id")
|
||
if not inbound_id:
|
||
logger.warning(
|
||
f"INBOUND_ID отсутствует для сервера {server_info.get('server_name', 'unknown')}. Пропуск."
|
||
)
|
||
continue
|
||
|
||
tasks.append(
|
||
add_client(
|
||
xui,
|
||
client_id,
|
||
email,
|
||
tg_id,
|
||
limit_ip=1,
|
||
total_gb=TOTAL_GB,
|
||
expiry_time=expiry_time,
|
||
enable=True,
|
||
flow="xtls-rprx-vision",
|
||
inbound_id=int(inbound_id),
|
||
)
|
||
)
|
||
|
||
await asyncio.gather(*tasks)
|
||
|
||
logger.info(f"Ключ успешно обновлен для {client_id} на всех серверах в кластере {cluster_id}")
|
||
|
||
except Exception as e:
|
||
logger.error(f"Ошибка при обновлении ключа на серверах кластера {cluster_id} для {client_id}: {e}")
|
||
raise e
|