new options

This commit is contained in:
Mateusz Gruszczyński
2025-11-03 12:17:32 +01:00
parent c7a09171e1
commit 2d53843f34
3 changed files with 120 additions and 161 deletions

View File

@@ -2,29 +2,84 @@ import os
HAPROXY_CFG = '/etc/haproxy/haproxy.cfg'
def is_frontend_exist(frontend_name, frontend_ip, frontend_port):
def sanitize_name(name):
"""Convert hostname/name to valid ACL name"""
return name.replace('.', '_').replace('-', '_').replace('/', '_').replace(':', '_')
def frontend_exists_at_port(frontend_ip, frontend_port):
"""Check if frontend already exists at specific port"""
if not os.path.exists(HAPROXY_CFG):
return None
try:
with open(HAPROXY_CFG, 'r') as f:
content = f.read()
lines = content.split('\n')
for i, line in enumerate(lines):
if line.strip().startswith('frontend'):
# Szukaj bind line
for j in range(i+1, min(i+10, len(lines))):
if lines[j].strip().startswith('bind'):
bind_info = lines[j].strip().split(' ', 1)[1]
if f"{frontend_ip}:{frontend_port}" in bind_info:
return line.strip().split(' ', 1)[1] # Zwróć nazwę frontendu
elif lines[j].strip().startswith('frontend') or lines[j].strip().startswith('backend'):
break
except Exception as e:
print(f"[HAPROXY_CONFIG] Error: {e}", flush=True)
return None
def add_acl_to_frontend(frontend_name, acl_name, hostname, backend_name):
"""Dodaj ACL i use_backend do istniejącego frontendu"""
if not os.path.exists(HAPROXY_CFG):
return False
try:
with open(HAPROXY_CFG, 'r') as haproxy_cfg:
frontend_found = False
for line in haproxy_cfg:
if line.strip().startswith('frontend'):
_, existing_frontend_name = line.strip().split(' ', 1)
if existing_frontend_name.strip() == frontend_name:
frontend_found = True
else:
frontend_found = False
elif frontend_found and line.strip().startswith('bind'):
_, bind_info = line.strip().split(' ', 1)
existing_ip, existing_port = bind_info.split(':', 1)
if existing_ip.strip() == frontend_ip and existing_port.strip() == frontend_port:
return True
with open(HAPROXY_CFG, 'r') as f:
lines = f.readlines()
# Znajdź frontend
frontend_idx = -1
for i, line in enumerate(lines):
if 'frontend' in line and frontend_name in line:
frontend_idx = i
break
if frontend_idx == -1:
return False
# Sprawdź czy ACL już istnieje
for line in lines[frontend_idx:]:
if acl_name in line and 'acl' in line:
return True # Już istnieje
if line.strip().startswith('backend'):
break
# Znajdź ostatnią linię ACL/use_backend w tym frontendzie
insert_idx = frontend_idx + 1
for i in range(frontend_idx + 1, len(lines)):
if lines[i].strip().startswith('backend'):
insert_idx = i
break
if 'use_backend' in lines[i] or 'default_backend' in lines[i]:
insert_idx = i + 1
# Wstaw ACL i use_backend
acl_line = f" acl {acl_name} hdr(host) -i {hostname}\n"
use_backend_line = f" use_backend {backend_name} if {acl_name}\n"
lines.insert(insert_idx, use_backend_line)
lines.insert(insert_idx, acl_line)
with open(HAPROXY_CFG, 'w') as f:
f.writelines(lines)
return True
except Exception as e:
print(f"[HAPROXY_CONFIG] Error checking frontend: {e}", flush=True)
return False
print(f"[HAPROXY_CONFIG] Error adding ACL: {e}", flush=True)
return False
def is_backend_exist(backend_name):
if not os.path.exists(HAPROXY_CFG):
@@ -75,85 +130,6 @@ def count_frontends_and_backends():
return frontend_count, backend_count, acl_count, layer7_count, layer4_count
def sanitize_name(name):
"""Convert hostname/name to valid ACL name"""
return name.replace('.', '_').replace('-', '_').replace('/', '_').replace(':', '_')
def frontend_exists_at_port(frontend_ip, frontend_port):
"""Check if frontend already exists at specific port"""
if not os.path.exists(HAPROXY_CFG):
return None
try:
with open(HAPROXY_CFG, 'r') as f:
content = f.read()
lines = content.split('\n')
for i, line in enumerate(lines):
if line.strip().startswith('frontend'):
frontend_name = line.strip().split(' ', 1)[1]
for j in range(i+1, min(i+10, len(lines))):
if lines[j].strip().startswith('bind'):
bind_info = lines[j].strip().split(' ', 1)[1]
if f"{frontend_ip}:{frontend_port}" in bind_info:
return frontend_name
elif lines[j].strip().startswith('frontend') or lines[j].strip().startswith('backend'):
break
except Exception as e:
print(f"[HAPROXY_CONFIG] Error: {e}", flush=True)
return None
def add_acl_to_frontend(frontend_name, acl_name, hostname, backend_name):
"""Dodaj ACL i use_backend do istniejącego frontendu"""
if not os.path.exists(HAPROXY_CFG):
return False
try:
with open(HAPROXY_CFG, 'r') as f:
content = f.read()
lines = content.split('\n')
frontend_idx = -1
for i, line in enumerate(lines):
if line.strip().startswith('frontend') and frontend_name in line:
frontend_idx = i
break
if frontend_idx == -1:
return False
insert_idx = -1
for i in range(frontend_idx + 1, len(lines)):
if lines[i].strip().startswith('backend'):
insert_idx = i
break
if 'use_backend' in lines[i] or 'default_backend' in lines[i]:
insert_idx = i
break
if insert_idx == -1:
insert_idx = len(lines) - 1
acl_line = f" acl {acl_name} hdr(host) -i {hostname}\n"
use_backend_line = f" use_backend {backend_name} if {acl_name}\n"
for line in lines[frontend_idx:insert_idx]:
if acl_name in line and 'acl' in line:
return True
lines.insert(insert_idx, use_backend_line)
lines.insert(insert_idx, acl_line)
with open(HAPROXY_CFG, 'w') as f:
f.write('\n'.join(lines))
return True
except Exception as e:
print(f"[HAPROXY_CONFIG] Error adding ACL: {e}", flush=True)
return False
def update_haproxy_config(frontend_name, frontend_ip, frontend_port, lb_method, protocol, backend_name,
backend_servers, health_check, health_check_tcp, health_check_link, sticky_session,
add_header, header_name, header_value, sticky_session_type, is_acl, acl_name,
@@ -182,11 +158,11 @@ def update_haproxy_config(frontend_name, frontend_ip, frontend_port, lb_method,
existing_frontend = frontend_exists_at_port(frontend_ip, frontend_port)
if existing_frontend:
# Frontend już istnieje - dodaj tylko backend i ACL
unique_backend_name = f"{backend_name}_{sanitize_name(frontend_hostname)}" if frontend_hostname else backend_name
# Frontend już istnieje - dodaj tylko backend + ACL
print(f"[HAPROXY] Found existing frontend '{existing_frontend}' at {frontend_ip}:{frontend_port}", flush=True)
# Utwórz backend
with open(HAPROXY_CFG, 'a') as haproxy_cfg:
# ===== BACKEND =====
haproxy_cfg.write(f"\nbackend {unique_backend_name}\n")
if not is_no_lb:
@@ -213,6 +189,7 @@ def update_haproxy_config(frontend_name, frontend_ip, frontend_port, lb_method,
if forward_for:
haproxy_cfg.write(f" option forwardfor\n")
# Add servers
for server_name, server_ip, server_port, maxconn in backend_servers:
maxconn_str = f" maxconn {maxconn}" if maxconn else ""
@@ -221,18 +198,22 @@ def update_haproxy_config(frontend_name, frontend_ip, frontend_port, lb_method,
else:
haproxy_cfg.write(f" server {server_name} {server_ip}:{server_port}{maxconn_str}\n")
# Dodaj ACL do istniejącego frontendu
acl_name_sanitized = f"is_{sanitize_name(frontend_hostname)}" if frontend_hostname else f"is_{unique_backend_name}"
add_acl_to_frontend(existing_frontend, acl_name_sanitized, frontend_hostname or 'localhost', unique_backend_name)
return f"Backend added to existing frontend {existing_frontend}"
return f"Backend added to existing frontend"
# ===== TWORZENIE NOWEGO FRONTENDU (GENERYCZNE NAZWY) =====
# Generuj generyczną nazwę frontendu
generic_frontend_name = f"https_frontend" if use_ssl else f"http_frontend"
generic_http_redirect_name = f"http_redirect_frontend"
print(f"[HAPROXY] Creating new frontend '{generic_frontend_name}' at {frontend_ip}:{frontend_port}", flush=True)
# ===== TWORZENIE NOWEGO FRONTENDU =====
with open(HAPROXY_CFG, 'a') as haproxy_cfg:
haproxy_cfg.write(f"\nfrontend {frontend_name}\n")
if is_frontend_exist(frontend_name, frontend_ip, frontend_port):
return "Frontend or Port already exists. Cannot add duplicate."
# ===== PRIMARY FRONTEND (GENERIC NAME) =====
haproxy_cfg.write(f"\nfrontend {generic_frontend_name}\n")
haproxy_cfg.write(f" bind {frontend_ip}:{frontend_port}")
if use_ssl:
@@ -240,7 +221,7 @@ def update_haproxy_config(frontend_name, frontend_ip, frontend_port, lb_method,
haproxy_cfg.write("\n")
# Headers ZARAZ PO BIND/CERT
# Headers zaraz po BIND/CERT
haproxy_cfg.write(f" http-request set-header X-Forwarded-For %[src]\n")
if use_ssl:
haproxy_cfg.write(f" http-request set-header X-Forwarded-Proto https\n")
@@ -249,7 +230,7 @@ def update_haproxy_config(frontend_name, frontend_ip, frontend_port, lb_method,
haproxy_cfg.write(f" mode {protocol}\n")
# ACL
# ACL dla pierwszego vhost
acl_name_sanitized = None
if frontend_hostname:
acl_name_sanitized = f"is_{sanitize_name(frontend_hostname)}"
@@ -331,17 +312,16 @@ def update_haproxy_config(frontend_name, frontend_ip, frontend_port, lb_method,
else:
haproxy_cfg.write(f" server {server_name} {server_ip}:{server_port}{maxconn_str}\n")
# ===== REDIRECT HTTP -> HTTPS =====
# ===== REDIRECT HTTP -> HTTPS (GENERIC NAME) =====
if backend_ssl_redirect and ssl_redirect_backend_name:
unique_redirect_backend_name = f"{ssl_redirect_backend_name}_redirect_{sanitize_name(frontend_hostname)}" if frontend_hostname else ssl_redirect_backend_name
# Check if HTTP frontend exists
# Check if HTTP redirect frontend exists
existing_http_frontend = frontend_exists_at_port(frontend_ip, ssl_redirect_port)
if not existing_http_frontend:
redirect_frontend_name = f"redirect_https_{sanitize_name(frontend_hostname)}" if frontend_hostname else f"redirect_https_{frontend_name}"
haproxy_cfg.write(f"\nfrontend {redirect_frontend_name}\n")
# Utwórz nowy HTTP redirect frontend (generic name)
haproxy_cfg.write(f"\nfrontend {generic_http_redirect_name}\n")
haproxy_cfg.write(f" bind {frontend_ip}:{ssl_redirect_port}\n")
haproxy_cfg.write(f" mode http\n")
@@ -352,6 +332,7 @@ def update_haproxy_config(frontend_name, frontend_ip, frontend_port, lb_method,
else:
haproxy_cfg.write(f" default_backend {unique_redirect_backend_name}\n")
else:
# Dodaj ACL do istniejącego HTTP frontendu
if frontend_hostname:
acl_name_redirect = f"is_{sanitize_name(frontend_hostname)}_redirect"
add_acl_to_frontend(existing_http_frontend, acl_name_redirect, frontend_hostname, unique_redirect_backend_name)