Multi-interface management, topology view, performance tuning, precompiled CSS
- Interface model with per-interface subnet/port/keys; import/adopt existing wg-quick configs (key-less imported peers, optional key rotation), cascade delete - Split wireguard.py into a package (keys via cryptography X25519, status, addressing, conf parse/render, sync, host tuning) - ECharts horizontal topology view (interface -> peers -> site subnets) - Advanced options: MTU, MSS clamping, FwMark/Table, custom PostUp/PostDown, per-peer keepalive override - Runtime settings (sample interval/retention, online threshold, UI refresh) with traffic sample pruning; host tuning (UDP buffers, backlog, GRO forwarding) - Precompiled Tailwind CSS replacing Play CDN runtime (fixes FOUC); stable table layout and diffed polling renders - Host network mode in compose; NAT/isolation iptables moved into app sync Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
parent
192960ad3e
commit
1b227c2470
+59
-8
@@ -1,7 +1,7 @@
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from sqlalchemy import Boolean, DateTime, Integer, String
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String, UniqueConstraint
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from .db import Base
|
||||
|
||||
@@ -10,15 +10,51 @@ def utcnow() -> datetime:
|
||||
return datetime.now(timezone.utc)
|
||||
|
||||
|
||||
class Peer(Base):
|
||||
__tablename__ = "peers"
|
||||
class Interface(Base):
|
||||
__tablename__ = "interfaces"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
name: Mapped[str] = mapped_column(String(64), unique=True)
|
||||
public_key: Mapped[str] = mapped_column(String(64), unique=True)
|
||||
name: Mapped[str] = mapped_column(String(15), unique=True)
|
||||
subnet: Mapped[str] = mapped_column(String(64))
|
||||
listen_port: Mapped[int] = mapped_column(Integer, unique=True)
|
||||
host: Mapped[str] = mapped_column(String(256))
|
||||
dns: Mapped[str] = mapped_column(String(128), default="1.1.1.1")
|
||||
allowed_ips: Mapped[str] = mapped_column(String(512), default="0.0.0.0/0, ::/0")
|
||||
persistent_keepalive: Mapped[int] = mapped_column(Integer, default=25)
|
||||
peer_isolation: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
mtu: Mapped[int] = mapped_column(Integer, default=0)
|
||||
mss_clamp: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
fwmark: Mapped[str] = mapped_column(String(32), default="")
|
||||
route_table: Mapped[str] = mapped_column(String(32), default="")
|
||||
post_up: Mapped[str] = mapped_column(String(2048), default="")
|
||||
post_down: Mapped[str] = mapped_column(String(2048), default="")
|
||||
enabled: Mapped[bool] = mapped_column(Boolean, default=True)
|
||||
private_key_enc: Mapped[str] = mapped_column(String(256))
|
||||
preshared_key_enc: Mapped[str] = mapped_column(String(256))
|
||||
address: Mapped[str] = mapped_column(String(64), unique=True)
|
||||
public_key: Mapped[str] = mapped_column(String(64), unique=True)
|
||||
imported: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow)
|
||||
|
||||
peers: Mapped[list["Peer"]] = relationship(
|
||||
back_populates="interface", cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
|
||||
class Peer(Base):
|
||||
__tablename__ = "peers"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("interface_id", "name", name="uq_peer_iface_name"),
|
||||
UniqueConstraint("interface_id", "address", name="uq_peer_iface_address"),
|
||||
)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
interface_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("interfaces.id", ondelete="CASCADE"), index=True
|
||||
)
|
||||
name: Mapped[str] = mapped_column(String(64))
|
||||
public_key: Mapped[str] = mapped_column(String(64), unique=True)
|
||||
private_key_enc: Mapped[str] = mapped_column(String(256), default="")
|
||||
preshared_key_enc: Mapped[str] = mapped_column(String(256), default="")
|
||||
address: Mapped[str] = mapped_column(String(64))
|
||||
enabled: Mapped[bool] = mapped_column(Boolean, default=True)
|
||||
expires_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow)
|
||||
@@ -26,12 +62,15 @@ class Peer(Base):
|
||||
dns: Mapped[str] = mapped_column(String(128), default="")
|
||||
extra_allowed_ips: Mapped[str] = mapped_column(String(512), default="")
|
||||
client_allowed_ips: Mapped[str] = mapped_column(String(512), default="")
|
||||
persistent_keepalive: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
quota_bytes: Mapped[int] = mapped_column(Integer, default=0)
|
||||
cum_rx: Mapped[int] = mapped_column(Integer, default=0)
|
||||
cum_tx: Mapped[int] = mapped_column(Integer, default=0)
|
||||
last_rx: Mapped[int] = mapped_column(Integer, default=0)
|
||||
last_tx: Mapped[int] = mapped_column(Integer, default=0)
|
||||
|
||||
interface: Mapped[Interface] = relationship(back_populates="peers")
|
||||
|
||||
@property
|
||||
def cum_total(self) -> int:
|
||||
return self.cum_rx + self.cum_tx
|
||||
@@ -40,11 +79,23 @@ class Peer(Base):
|
||||
def over_quota(self) -> bool:
|
||||
return self.quota_bytes > 0 and self.cum_total >= self.quota_bytes
|
||||
|
||||
@property
|
||||
def has_private_key(self) -> bool:
|
||||
return bool(self.private_key_enc)
|
||||
|
||||
|
||||
class AppSetting(Base):
|
||||
__tablename__ = "app_settings"
|
||||
|
||||
key: Mapped[str] = mapped_column(String(64), primary_key=True)
|
||||
value: Mapped[str] = mapped_column(String(256), default="")
|
||||
|
||||
|
||||
class TrafficSample(Base):
|
||||
__tablename__ = "traffic_samples"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
interface_name: Mapped[str] = mapped_column(String(15), default="", index=True)
|
||||
peer_public_key: Mapped[str] = mapped_column(String(64), index=True)
|
||||
rx_bytes: Mapped[int] = mapped_column(Integer, default=0)
|
||||
tx_bytes: Mapped[int] = mapped_column(Integer, default=0)
|
||||
|
||||
Reference in New Issue
Block a user