chore: интерфесы бота
This commit is contained in:
1 parent
5f53cadf89
commit
6d322f36a9
42 files changed
+1731
-111
No files matched your search
@@ -1,5 +1,7 @@
|
||||
from django.contrib.auth.base_user import BaseUserManager
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.db import models
|
||||
from serverus import Host
|
||||
|
||||
|
||||
class UserManager(BaseUserManager):
|
||||
@@ -46,3 +48,92 @@ class User(AbstractUser):
|
||||
|
||||
def email_user(self, *args, **kwargs):
|
||||
raise NotImplementedError('User has no email')
|
||||
|
||||
|
||||
class Point(models.Model):
|
||||
"""Точка доступа: кластер из сервера с панелью 3x-ui и сервера маскировки перед ним.
|
||||
|
||||
Клиенты подключаются к серверу маскировки, он перенаправляет трафик на панель и скрывает ее адрес.
|
||||
"""
|
||||
|
||||
CF_WARP = 'cf_warp'
|
||||
|
||||
class Status(models.TextChoices):
|
||||
INSTALLING = 'installing', 'устанавливается'
|
||||
READY = 'ready', 'активен'
|
||||
ERROR = 'error', 'ошибка'
|
||||
RELEASING = 'releasing', 'возвращается'
|
||||
|
||||
owner = models.ForeignKey('Telegram.User', on_delete=models.PROTECT, related_name='points')
|
||||
name = models.CharField(max_length=64, unique=True)
|
||||
status = models.CharField(max_length=16, choices=Status.choices, default=Status.INSTALLING)
|
||||
error = models.TextField(blank=True)
|
||||
|
||||
domain = models.CharField(max_length=253, blank=True)
|
||||
cloudflare = models.BooleanField(default=False, help_text='Домен спрятан за Cloudflare')
|
||||
outbound_proxy = models.CharField(
|
||||
max_length=512, blank=True, help_text=f'protocol://user:password@host:port или {CF_WARP}',
|
||||
)
|
||||
|
||||
panel_username = models.CharField(max_length=64)
|
||||
panel_password = models.CharField(max_length=128)
|
||||
panel_port = models.PositiveIntegerField()
|
||||
panel_path = models.CharField(max_length=64)
|
||||
panel_api_token = models.CharField(max_length=255, blank=True)
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'точка доступа'
|
||||
verbose_name_plural = 'точки доступа'
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@property
|
||||
def is_busy(self) -> bool:
|
||||
return self.status in (self.Status.INSTALLING, self.Status.RELEASING)
|
||||
|
||||
def server(self, role: str) -> 'Server':
|
||||
return self.servers.get(role=role)
|
||||
|
||||
@property
|
||||
def panel(self) -> 'Server':
|
||||
return self.server(Server.Role.PANEL)
|
||||
|
||||
@property
|
||||
def mask(self) -> 'Server':
|
||||
return self.server(Server.Role.MASK)
|
||||
|
||||
|
||||
class Server(models.Model):
|
||||
"""Сервер под управлением системы. Поля ssh отражают текущее состояние сервера."""
|
||||
|
||||
class Role(models.TextChoices):
|
||||
PANEL = 'panel', 'панель'
|
||||
MASK = 'mask', 'маскировка'
|
||||
|
||||
point = models.ForeignKey(Point, on_delete=models.CASCADE, related_name='servers')
|
||||
role = models.CharField(max_length=8, choices=Role.choices)
|
||||
address = models.GenericIPAddressField(unique=True)
|
||||
ssh_port = models.PositiveIntegerField(default=22)
|
||||
root_password = models.CharField(max_length=128, help_text='Текущий пароль root')
|
||||
private_key = models.TextField(blank=True)
|
||||
public_key = models.TextField(blank=True)
|
||||
known_hosts = models.TextField(blank=True, help_text='Отпечаток ssh сервера. Сбрасывается после переустановки ОС')
|
||||
uname = models.CharField(max_length=512, blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'сервер'
|
||||
verbose_name_plural = 'серверы'
|
||||
constraints = [models.UniqueConstraint(fields=['point', 'role'], name='app_server_role_unique')]
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.address} ({self.get_role_display()})'
|
||||
|
||||
def host(self) -> Host:
|
||||
return Host(self.address, port=self.ssh_port, private_key=self.private_key or None, known_hosts=self.known_hosts)
|
||||
|
||||
def reset_fingerprint(self):
|
||||
self.known_hosts = ''
|
||||
self.save(update_fields=['known_hosts'])
|
||||
Reference in new issue
Block a user