From 67cfcf3affeacf407679820fe55d185075521dc7 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sun, 22 Feb 2026 18:10:00 -0500 Subject: [PATCH] Add HAProxy monitoring dashboard features - Introduced a new `dashboard` frontend in HAProxy configuration to serve a real-time monitoring dashboard. - Added support for returning prebuilt `dashboard.html` for `/` or `/index.html` paths. - Updated test cases and expected outputs to accommodate the new frontend. --- .../assets/etc/easyhaproxy/www/dashboard.html | 103 ++++++++++++++++++ src/templates/haproxy.cfg.j2 | 8 ++ tests/conftest.py | 28 ++++- tests/expected/docker.txt | 8 ++ tests/expected/services-letsencrypt.txt | 8 ++ tests/expected/services-multiple-hosts.txt | 8 ++ tests/expected/ssl-loose.txt | 8 ++ tests/expected/static-cors.txt | 8 ++ tests/expected/static.txt | 8 ++ 9 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 deploy/docker/assets/etc/easyhaproxy/www/dashboard.html diff --git a/deploy/docker/assets/etc/easyhaproxy/www/dashboard.html b/deploy/docker/assets/etc/easyhaproxy/www/dashboard.html new file mode 100644 index 0000000..8e85bbc --- /dev/null +++ b/deploy/docker/assets/etc/easyhaproxy/www/dashboard.html @@ -0,0 +1,103 @@ + + + + + + + + HAProxy Monitor + + + + + +
+ + + \ No newline at end of file diff --git a/src/templates/haproxy.cfg.j2 b/src/templates/haproxy.cfg.j2 index 0096549..a4d113d 100644 --- a/src/templates/haproxy.cfg.j2 +++ b/src/templates/haproxy.cfg.j2 @@ -91,6 +91,14 @@ frontend stats backend srv_stats mode http server Local 127.0.0.1:{{ data_stats["port"] | default(1936) }} + +frontend dashboard + bind *:{{ (data_stats["port"] | default(1936) | int) + 10000 }} + mode http + acl is_index path / + acl is_index path /index.html + http-request return status 200 content-type "text/html" file /etc/easyhaproxy/www/dashboard.html if is_index + http-request return status 404 {% endif %} {% for o in data["easymapping"] -%} {% set mode = o["mode"] or "http" %} diff --git a/tests/conftest.py b/tests/conftest.py index 99c67ce..3babf7f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,20 +16,46 @@ _test_session_dir = tempfile.mkdtemp(prefix="pytest_easyhaproxy_") os.environ["EASYHAPROXY_BASE_PATH"] = _test_session_dir +_CONTAINER_ENV_VARS = [ + "HAPROXY_USERNAME", + "HAPROXY_PASSWORD", + "HAPROXY_STATS_PORT", + "HAPROXY_STATS_CORS_ORIGIN", + "HAPROXY_CUSTOMERRORS", + "EASYHAPROXY_SSL_MODE", + "EASYHAPROXY_LABEL_PREFIX", + "EASYHAPROXY_LOG_LEVEL", + "HAPROXY_LOG_LEVEL", + "CERTBOT_LOG_LEVEL", + "EASYHAPROXY_CERTBOT_EMAIL", + "EASYHAPROXY_CERTBOT_SERVER", + "EASYHAPROXY_CERTBOT_AUTOCONFIG", + "EASYHAPROXY_CERTBOT_EAB_KID", + "EASYHAPROXY_CERTBOT_EAB_HMAC_KEY", + "EASYHAPROXY_PLUGINS_ENABLED", + "EASYHAPROXY_PLUGINS_ABORT_ON_ERROR", +] + + @pytest.fixture(scope="function", autouse=True) def reset_consts(): """ - Reset Consts before and after each test. + Reset Consts and ContainerEnv environment variables before and after each test. This ensures: 1. Each test picks up the EASYHAPROXY_BASE_PATH environment variable 2. Tests don't get permission errors trying to write to /etc/easyhaproxy/ 3. Consts path cache is cleared between tests for isolation + 4. Environment variables set by ContainerEnv._yaml_to_env don't bleed across tests """ from functions import Consts Consts.reset() + for var in _CONTAINER_ENV_VARS: + os.environ.pop(var, None) yield Consts.reset() + for var in _CONTAINER_ENV_VARS: + os.environ.pop(var, None) def pytest_sessionfinish(session, exitstatus): diff --git a/tests/expected/docker.txt b/tests/expected/docker.txt index ab844fb..2c56560 100644 --- a/tests/expected/docker.txt +++ b/tests/expected/docker.txt @@ -37,6 +37,14 @@ backend srv_stats mode http server Local 127.0.0.1:1936 +frontend dashboard + bind *:11936 + mode http + acl is_index path / + acl is_index path /index.html + http-request return status 200 content-type "text/html" file /etc/easyhaproxy/www/dashboard.html if is_index + http-request return status 404 + frontend http_in_443 bind *:443 ssl crt /etc/easyhaproxy/certs/certbot/ alpn h2,http/1.1 crt /etc/easyhaproxy/certs/haproxy/ alpn h2,http/1.1 mode http diff --git a/tests/expected/services-letsencrypt.txt b/tests/expected/services-letsencrypt.txt index 4fb2db3..bbcc880 100644 --- a/tests/expected/services-letsencrypt.txt +++ b/tests/expected/services-letsencrypt.txt @@ -45,6 +45,14 @@ backend srv_stats mode http server Local 127.0.0.1:1936 +frontend dashboard + bind *:11936 + mode http + acl is_index path / + acl is_index path /index.html + http-request return status 200 content-type "text/html" file /etc/easyhaproxy/www/dashboard.html if is_index + http-request return status 404 + frontend http_in_80 bind *:80 mode http diff --git a/tests/expected/services-multiple-hosts.txt b/tests/expected/services-multiple-hosts.txt index c911670..de48d46 100644 --- a/tests/expected/services-multiple-hosts.txt +++ b/tests/expected/services-multiple-hosts.txt @@ -45,6 +45,14 @@ backend srv_stats mode http server Local 127.0.0.1:1937 +frontend dashboard + bind *:11937 + mode http + acl is_index path / + acl is_index path /index.html + http-request return status 200 content-type "text/html" file /etc/easyhaproxy/www/dashboard.html if is_index + http-request return status 404 + frontend http_in_19901 bind *:19901 mode http diff --git a/tests/expected/ssl-loose.txt b/tests/expected/ssl-loose.txt index faad621..0300fd0 100644 --- a/tests/expected/ssl-loose.txt +++ b/tests/expected/ssl-loose.txt @@ -35,6 +35,14 @@ backend srv_stats mode http server Local 127.0.0.1:1936 +frontend dashboard + bind *:11936 + mode http + acl is_index path / + acl is_index path /index.html + http-request return status 200 content-type "text/html" file /etc/easyhaproxy/www/dashboard.html if is_index + http-request return status 404 + backend certbot_backend mode http server certbot 127.0.0.1:2080 diff --git a/tests/expected/static-cors.txt b/tests/expected/static-cors.txt index c3cedf9..51c2743 100644 --- a/tests/expected/static-cors.txt +++ b/tests/expected/static-cors.txt @@ -52,6 +52,14 @@ backend srv_stats mode http server Local 127.0.0.1:1936 +frontend dashboard + bind *:11936 + mode http + acl is_index path / + acl is_index path /index.html + http-request return status 200 content-type "text/html" file /etc/easyhaproxy/www/dashboard.html if is_index + http-request return status 404 + frontend http_in_80 bind *:80 mode http diff --git a/tests/expected/static.txt b/tests/expected/static.txt index 4e5f722..0b53ab0 100644 --- a/tests/expected/static.txt +++ b/tests/expected/static.txt @@ -45,6 +45,14 @@ backend srv_stats mode http server Local 127.0.0.1:1936 +frontend dashboard + bind *:11936 + mode http + acl is_index path / + acl is_index path /index.html + http-request return status 200 content-type "text/html" file /etc/easyhaproxy/www/dashboard.html if is_index + http-request return status 404 + frontend http_in_443 bind *:443 ssl crt /etc/easyhaproxy/certs/certbot/ alpn h2,http/1.1 crt /etc/easyhaproxy/certs/haproxy/ alpn h2,http/1.1 mode http