Files
haproxy-dashboard/database/modelspy
Mateusz Gruszczyński addb21bc3e rewrite
2025-11-04 09:56:37 +01:00

171 lines
6.2 KiB
Plaintext

"""Database Models"""
from datetime import datetime
from database import db
from werkzeug.security import generate_password_hash, check_password_hash
import json
class User(db.Model):
"""User model for authentication"""
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False, index=True)
password_hash = db.Column(db.String(255), nullable=False)
is_admin = db.Column(db.Boolean, default=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
last_login = db.Column(db.DateTime)
def set_password(self, password):
"""Hash and set password"""
self.password_hash = generate_password_hash(password, method='pbkdf2:sha256')
def check_password(self, password):
"""Verify password"""
return check_password_hash(self.password_hash, password)
def __repr__(self):
return f'<User {self.username}>'
class Certificate(db.Model):
"""SSL Certificate storage"""
__tablename__ = 'certificates'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(200), nullable=False, unique=True, index=True)
cert_content = db.Column(db.Text, nullable=False) # Full PEM (cert + key combined)
cert_only = db.Column(db.Text) # Separate cert (for info)
key_only = db.Column(db.Text) # Separate key (for backup)
# Metadata
common_name = db.Column(db.String(255))
subject_alt_names = db.Column(db.Text) # JSON array
issued_at = db.Column(db.DateTime)
expires_at = db.Column(db.DateTime)
created_at = db.Column(db.DateTime, default=datetime.utcnow, index=True)
updated_at = db.Column(db.DateTime, onupdate=datetime.utcnow)
# Relationships
vhosts = db.relationship('VirtualHost', backref='certificate', lazy=True)
def get_san_list(self):
"""Get Subject Alternative Names as list"""
if self.subject_alt_names:
try:
return json.loads(self.subject_alt_names)
except:
return []
return []
def set_san_list(self, san_list):
"""Set Subject Alternative Names from list"""
self.subject_alt_names = json.dumps(san_list)
def __repr__(self):
return f'<Certificate {self.name}>'
class VirtualHost(db.Model):
"""Virtual Host / Proxy configuration"""
__tablename__ = 'virtual_hosts'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(200), nullable=False, unique=True, index=True)
hostname = db.Column(db.String(255), nullable=False)
description = db.Column(db.Text)
# ===== FRONTEND SETTINGS =====
frontend_ip = db.Column(db.String(50), default='0.0.0.0')
frontend_port = db.Column(db.Integer, default=443)
protocol = db.Column(db.String(10), default='http') # http or tcp
# ===== SSL SETTINGS =====
use_ssl = db.Column(db.Boolean, default=False)
certificate_id = db.Column(db.Integer, db.ForeignKey('certificates.id'))
ssl_redirect = db.Column(db.Boolean, default=False)
ssl_redirect_port = db.Column(db.Integer, default=80)
# ===== LOAD BALANCING =====
lb_method = db.Column(db.String(50), default='roundrobin') # roundrobin, leastconn, source, uri
# ===== SECURITY OPTIONS =====
dos_protection = db.Column(db.Boolean, default=False)
dos_ban_duration = db.Column(db.String(20), default='30m')
dos_limit_requests = db.Column(db.Integer, default=100)
sql_injection_check = db.Column(db.Boolean, default=False)
xss_check = db.Column(db.Boolean, default=False)
webshell_check = db.Column(db.Boolean, default=False)
# ===== HEADERS =====
add_custom_header = db.Column(db.Boolean, default=False)
custom_header_name = db.Column(db.String(200))
custom_header_value = db.Column(db.String(500))
del_server_header = db.Column(db.Boolean, default=False)
forward_for = db.Column(db.Boolean, default=True)
# ===== STATE =====
enabled = db.Column(db.Boolean, default=True, index=True)
# ===== TIMESTAMPS =====
created_at = db.Column(db.DateTime, default=datetime.utcnow, index=True)
updated_at = db.Column(db.DateTime, onupdate=datetime.utcnow)
# Relationships
backend_servers = db.relationship('BackendServer', backref='vhost',
lazy=True, cascade='all, delete-orphan')
def __repr__(self):
return f'<VirtualHost {self.name}>'
class BackendServer(db.Model):
"""Backend server for virtual host"""
__tablename__ = 'backend_servers'
id = db.Column(db.Integer, primary_key=True)
vhost_id = db.Column(db.Integer, db.ForeignKey('virtual_hosts.id'), nullable=False)
# Server info
name = db.Column(db.String(100), nullable=False)
ip_address = db.Column(db.String(50), nullable=False)
port = db.Column(db.Integer, nullable=False)
maxconn = db.Column(db.Integer)
weight = db.Column(db.Integer, default=1)
# Health check
health_check = db.Column(db.Boolean, default=False)
health_check_path = db.Column(db.String(200), default='/')
# State
enabled = db.Column(db.Boolean, default=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, onupdate=datetime.utcnow)
def __repr__(self):
return f'<BackendServer {self.name}:{self.port}>'
class ConfigHistory(db.Model):
"""History of HAProxy configuration changes"""
__tablename__ = 'config_history'
id = db.Column(db.Integer, primary_key=True)
config_content = db.Column(db.Text, nullable=False)
change_type = db.Column(db.String(50)) # vhost_create, vhost_edit, vhost_delete, manual_edit
vhost_id = db.Column(db.Integer, db.ForeignKey('virtual_hosts.id'))
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
description = db.Column(db.Text)
created_at = db.Column(db.DateTime, default=datetime.utcnow, index=True)
# Relationships
vhost = db.relationship('VirtualHost')
user = db.relationship('User')
def __repr__(self):
return f'<ConfigHistory {self.change_type} at {self.created_at}>'