Fix HAProxy 2.6 compatibility for default backend
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 37s
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 37s
- Replace http-response set-body (HAProxy 2.8+) with local server approach - Add separate Flask server on port 8080 to serve default page - Update default backend template to use local server instead of inline HTML - Maintain all customization features via environment variables - Fix JavaScript error handling for domains API response
This commit is contained in:
parent
27f3f8959b
commit
fac6cef0db
BIN
__pycache__/haproxy_manager.cpython-310.pyc
Normal file
BIN
__pycache__/haproxy_manager.cpython-310.pyc
Normal file
Binary file not shown.
@ -286,6 +286,17 @@ def add_domain():
|
|||||||
def index():
|
def index():
|
||||||
return render_template('index.html')
|
return render_template('index.html')
|
||||||
|
|
||||||
|
@app.route('/default-page')
|
||||||
|
def default_page():
|
||||||
|
"""Serve the default page for unmatched domains"""
|
||||||
|
admin_email = os.environ.get('HAPROXY_ADMIN_EMAIL', 'admin@example.com')
|
||||||
|
|
||||||
|
return render_template('default_page.html',
|
||||||
|
page_title=os.environ.get('HAPROXY_DEFAULT_PAGE_TITLE', 'Site Not Configured'),
|
||||||
|
main_message=os.environ.get('HAPROXY_DEFAULT_MAIN_MESSAGE', 'This domain has not been configured yet. Please contact your system administrator to set up this website.'),
|
||||||
|
secondary_message=os.environ.get('HAPROXY_DEFAULT_SECONDARY_MESSAGE', 'If you believe this is an error, please check the domain name and try again.')
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/api/ssl', methods=['POST'])
|
@app.route('/api/ssl', methods=['POST'])
|
||||||
@require_api_key
|
@require_api_key
|
||||||
def request_ssl():
|
def request_ssl():
|
||||||
@ -789,18 +800,7 @@ def generate_config():
|
|||||||
config_parts.append(letsencrypt_backend)
|
config_parts.append(letsencrypt_backend)
|
||||||
# Add Default Backend
|
# Add Default Backend
|
||||||
try:
|
try:
|
||||||
# Render the default page template with customizable content
|
default_backend = template_env.get_template('hap_default_backend.tpl').render()
|
||||||
default_page_template = template_env.get_template('default_page.html')
|
|
||||||
default_page_content = default_page_template.render(
|
|
||||||
page_title=os.environ.get('HAPROXY_DEFAULT_PAGE_TITLE', 'Site Not Configured'),
|
|
||||||
main_message=os.environ.get('HAPROXY_DEFAULT_MAIN_MESSAGE', 'This domain has not been configured yet. Please contact your system administrator to set up this website.'),
|
|
||||||
secondary_message=os.environ.get('HAPROXY_DEFAULT_SECONDARY_MESSAGE', 'If you believe this is an error, please check the domain name and try again.')
|
|
||||||
)
|
|
||||||
default_page_content = default_page_content.replace('"', '\\"').replace('\n', '\\n')
|
|
||||||
|
|
||||||
default_backend = template_env.get_template('hap_default_backend.tpl').render(
|
|
||||||
default_page_content=default_page_content
|
|
||||||
)
|
|
||||||
config_parts.append(default_backend)
|
config_parts.append(default_backend)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error generating default backend: {e}")
|
logger.error(f"Error generating default backend: {e}")
|
||||||
@ -809,8 +809,7 @@ def generate_config():
|
|||||||
backend default-backend
|
backend default-backend
|
||||||
mode http
|
mode http
|
||||||
option http-server-close
|
option http-server-close
|
||||||
http-response set-header Content-Type text/html
|
server default-page 127.0.0.1:8080'''
|
||||||
http-response set-body "<!DOCTYPE html><html><head><title>Site Not Configured</title></head><body><h1>Site Not Configured</h1><p>This domain has not been configured yet.</p></body></html>"'''
|
|
||||||
config_parts.append(fallback_backend)
|
config_parts.append(fallback_backend)
|
||||||
# Add Backends
|
# Add Backends
|
||||||
config_parts.append('\n' .join(config_backends) + '\n')
|
config_parts.append('\n' .join(config_backends) + '\n')
|
||||||
@ -898,4 +897,32 @@ if __name__ == '__main__':
|
|||||||
generate_self_signed_cert(SSL_CERTS_DIR)
|
generate_self_signed_cert(SSL_CERTS_DIR)
|
||||||
start_haproxy()
|
start_haproxy()
|
||||||
certbot_register()
|
certbot_register()
|
||||||
|
|
||||||
|
# Run Flask app on port 8000 for API and port 8080 for default page
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
|
def run_default_page_server():
|
||||||
|
"""Run a separate Flask app on port 8080 for the default page"""
|
||||||
|
from flask import Flask, render_template
|
||||||
|
default_app = Flask(__name__)
|
||||||
|
default_app.template_folder = 'templates'
|
||||||
|
|
||||||
|
@default_app.route('/')
|
||||||
|
def default_page():
|
||||||
|
"""Serve the default page for unmatched domains"""
|
||||||
|
admin_email = os.environ.get('HAPROXY_ADMIN_EMAIL', 'admin@example.com')
|
||||||
|
|
||||||
|
return render_template('default_page.html',
|
||||||
|
page_title=os.environ.get('HAPROXY_DEFAULT_PAGE_TITLE', 'Site Not Configured'),
|
||||||
|
main_message=os.environ.get('HAPROXY_DEFAULT_MAIN_MESSAGE', 'This domain has not been configured yet. Please contact your system administrator to set up this website.'),
|
||||||
|
secondary_message=os.environ.get('HAPROXY_DEFAULT_SECONDARY_MESSAGE', 'If you believe this is an error, please check the domain name and try again.')
|
||||||
|
)
|
||||||
|
|
||||||
|
default_app.run(host='0.0.0.0', port=8080)
|
||||||
|
|
||||||
|
# Start the default page server in a separate thread
|
||||||
|
default_server_thread = Thread(target=run_default_page_server, daemon=True)
|
||||||
|
default_server_thread.start()
|
||||||
|
|
||||||
|
# Run the main API server
|
||||||
app.run(host='0.0.0.0', port=8000)
|
app.run(host='0.0.0.0', port=8000)
|
||||||
|
@ -7,6 +7,5 @@ backend default-backend
|
|||||||
http-request set-header X-Forwarded-For %[src]
|
http-request set-header X-Forwarded-For %[src]
|
||||||
http-request set-header X-Real-IP %[src]
|
http-request set-header X-Real-IP %[src]
|
||||||
|
|
||||||
# Serve the default page HTML response
|
# Serve the default page HTML response using a local server
|
||||||
http-response set-header Content-Type text/html
|
server default-page 127.0.0.1:8080
|
||||||
http-response set-body "{{ default_page_content }}"
|
|
@ -346,16 +346,34 @@
|
|||||||
|
|
||||||
function loadDomains() {
|
function loadDomains() {
|
||||||
fetch('/api/domains')
|
fetch('/api/domains')
|
||||||
.then(response => response.json())
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
.then(domains => {
|
.then(domains => {
|
||||||
const domainList = document.getElementById('domainList');
|
const domainList = document.getElementById('domainList');
|
||||||
domainList.innerHTML = '';
|
domainList.innerHTML = '';
|
||||||
|
|
||||||
|
// Ensure domains is an array
|
||||||
|
if (!Array.isArray(domains)) {
|
||||||
|
console.error('Expected array of domains, got:', typeof domains, domains);
|
||||||
|
showStatus('Error: Invalid response format from server', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domains.length === 0) {
|
||||||
|
domainList.innerHTML = '<div class="domain-list-item"><p>No domains configured yet. Add your first domain above.</p></div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
domains.forEach(domain => {
|
domains.forEach(domain => {
|
||||||
const domainDiv = document.createElement('div');
|
const domainDiv = document.createElement('div');
|
||||||
domainDiv.className = 'domain-list-item';
|
domainDiv.className = 'domain-list-item';
|
||||||
domainDiv.innerHTML = `
|
domainDiv.innerHTML = `
|
||||||
<h3>${domain.domain}</h3>
|
<h3>${domain.domain}</h3>
|
||||||
<p>Backend: ${domain.backend_name}</p>
|
<p>Backend: ${domain.backend_name || 'Not configured'}</p>
|
||||||
<p>SSL: ${domain.ssl_enabled ? 'Enabled' : 'Disabled'}</p>
|
<p>SSL: ${domain.ssl_enabled ? 'Enabled' : 'Disabled'}</p>
|
||||||
<button onclick="requestSSL('${domain.domain}')" class="ssl-btn">
|
<button onclick="requestSSL('${domain.domain}')" class="ssl-btn">
|
||||||
${domain.ssl_enabled ? 'Renew SSL' : 'Enable SSL'}
|
${domain.ssl_enabled ? 'Renew SSL' : 'Enable SSL'}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user