Files
haproxy-openmanager/backend/models/backend.py
T
Taylan Bakırcıoğlu b212fb92bc Add SSL Advanced Options support (Backend) - Part 1
FEATURE: Complete SSL Advanced Options implementation for frontend and backend server SSL

 DATABASE:
- Added SSL parameter columns to frontends table:
  * ssl_alpn, ssl_npn, ssl_ciphers, ssl_ciphersuites
  * ssl_min_ver, ssl_max_ver, ssl_strict_sni
- Added SSL parameter columns to backend_servers table:
  * ssl_sni, ssl_min_ver, ssl_max_ver, ssl_ciphers
- Migration functions: add_ssl_advanced_options_to_frontends() and add_ssl_advanced_options_to_servers()

 MODELS:
- FrontendConfig: Added 7 new SSL fields for bind parameters
- ServerConfig: Added 4 new SSL fields for server parameters
- AgentHeartbeat: Added system_info field (fixes HTTP 422 validation error)

 BULK IMPORT PARSER:
- Parse alpn, npn, ciphers, ciphersuites, ssl-min-ver, ssl-max-ver, strict-sni from bind lines
- Parse sni, ssl-min-ver, ssl-max-ver, ciphers from server lines
- Store parsed values in frontend/server objects
- User-friendly warnings about imported SSL parameters

 CONFIG GENERATOR:
- Generate bind lines with SSL advanced options: 'bind :443 ssl crt file.pem alpn h2,http/1.1 ciphers ...'
- Generate server lines with SSL advanced options: 'server s1 addr:port ssl sni hostname ssl-min-ver TLSv1.2'
- Support both NEW MODE (multiple certs) and OLD MODE (single cert)

USER IMPACT:
- Bulk import now correctly parses SSL configs with alpn/npn/ciphers
- SSL parameters preserved during import (not lost anymore)
- Agent heartbeat fixed (no more offline agents)
- Ready for UI implementation (next commit)

EXAMPLE USAGE:
Frontend: bind 0.0.0.0:8443 ssl crt cert1.pem crt cert2.pem alpn h2,http/1.1
Server: server s1 10.1.1.1:443 ssl verify required sni backend.example.com ssl-min-ver TLSv1.2

NEXT: Frontend UI components for editing these SSL options
2025-11-18 21:58:05 +03:00

94 lines
3.6 KiB
Python

from pydantic import BaseModel, validator
from typing import Optional, List
class ServerConfig(BaseModel):
server_name: str
server_address: str
server_port: int
weight: int = 100
max_connections: Optional[int] = None
check_enabled: bool = True
check_port: Optional[int] = None
backup_server: bool = False
ssl_enabled: bool = False
ssl_verify: Optional[str] = None
ssl_certificate_id: Optional[int] = None # SSL certificate for backend server
# SSL Advanced Options (server SSL parameters)
ssl_sni: Optional[str] = None # SNI hostname for backend SSL connections
ssl_min_ver: Optional[str] = None # Minimum TLS version (TLSv1.2, TLSv1.3)
ssl_max_ver: Optional[str] = None # Maximum TLS version
ssl_ciphers: Optional[str] = None # Cipher suite list for backend connections
cookie_value: Optional[str] = None
inter: Optional[int] = None
fall: Optional[int] = None
rise: Optional[int] = None
is_active: bool = True
class BackendConfig(BaseModel):
name: str
cluster_id: int
balance_method: str = 'roundrobin'
mode: str = 'http'
health_check_uri: Optional[str] = None
health_check_interval: Optional[int] = 2000
health_check_expected_status: Optional[int] = 200
fullconn: Optional[int] = None
cookie_name: Optional[str] = None
cookie_options: Optional[str] = None
default_server_inter: Optional[int] = None
default_server_fall: Optional[int] = None
default_server_rise: Optional[int] = None
request_headers: Optional[str] = None
response_headers: Optional[str] = None
timeout_connect: Optional[int] = 10000
timeout_server: Optional[int] = 60000
timeout_queue: Optional[int] = 60000
options: Optional[str] = None
servers: List[ServerConfig] = []
@validator('health_check_interval', 'timeout_connect', 'timeout_server', 'timeout_queue', 'fullconn')
def check_positive(cls, v):
if v is not None and v <= 0:
raise ValueError('Timeout, interval, and connection values must be positive')
return v
@validator('health_check_expected_status')
def check_http_status(cls, v):
if v is not None and (v < 100 or v > 599):
raise ValueError('HTTP status code must be between 100 and 599')
return v
class BackendConfigUpdate(BaseModel):
name: Optional[str] = None
balance_method: Optional[str] = None
mode: Optional[str] = None
health_check_uri: Optional[str] = None
health_check_interval: Optional[int] = None
health_check_expected_status: Optional[int] = None
fullconn: Optional[int] = None
cookie_name: Optional[str] = None
cookie_options: Optional[str] = None
default_server_inter: Optional[int] = None
default_server_fall: Optional[int] = None
default_server_rise: Optional[int] = None
request_headers: Optional[str] = None
response_headers: Optional[str] = None
timeout_connect: Optional[int] = None
timeout_server: Optional[int] = None
timeout_queue: Optional[int] = None
options: Optional[str] = None
servers: Optional[List[ServerConfig]] = None
@validator('health_check_interval', 'timeout_connect', 'timeout_server', 'timeout_queue', 'fullconn')
def check_positive_update(cls, v):
if v is not None and v <= 0:
raise ValueError('Timeout, interval, and connection values must be positive')
return v
@validator('health_check_expected_status')
def check_http_status_update(cls, v):
if v is not None and (v < 100 or v > 599):
raise ValueError('HTTP status code must be between 100 and 599')
return v