1
0
Fork 0

Refactor E2E tests and configuration format

- Replaced `easymapping` configuration with `containers` for better maintainability and clarity.
- Introduced `DockerComposeFixture` class in `utils.py` to manage Docker Compose lifecycle and smart build strategy.
- Enhanced YAML-to-environment variable conversion in `ContainerEnv` for dynamic configuration support.
- Updated HAProxy configurations and test fixtures to reflect the new format.
- Improved test coverage for YAML parsing, environment variable handling, and HAProxy config generation.
This commit is contained in:
Joao Gilberto Magalhaes 2026-02-13 11:44:26 -05:00
parent c125985150
commit 97845b8a52
22 changed files with 1042 additions and 442 deletions

View file

@ -79,13 +79,10 @@ stats:
password: password
port: 1936
easymapping:
- port: 443
containers:
"host1.local:443":
ip: ["container:8080"] # Can also be IP:PORT for external backends
ssl: true
hosts:
host1.local:
containers:
- container:8080 # Can also be IP:PORT for external backends
```
See `conf/` directory for complete examples.

View file

@ -15,17 +15,17 @@ stats:
customerrors: true # Optional (default false)
easymapping:
# HTTP - Redirect to HTTPS
- port: 80
redirect:
host1.local: https://host1.local
www.host1.local: https://host1.local
containers:
# HTTP - Redirect to HTTPS using redirect_ssl
"host1.local:80":
ip: ["container:8080"]
redirect_ssl: true
"www.host1.local:80":
ip: ["container:8080"]
redirect_ssl: true
# HTTPS - Serve application
- port: 443
"host1.local:443":
ip: ["container:8080"]
ssl: true
hosts:
host1.local:
containers:
- container:8080

View file

@ -35,54 +35,48 @@ stats:
customerrors: true
easymapping:
containers:
# HTTP Port 80
# Required for ACME HTTP-01 challenge and redirect
- port: 80
hosts:
# Domain with certbot enabled
example.com:
containers:
- webapp:8080
# Enable certbot for this domain
certbot: true
# Redirect HTTP to HTTPS after cert is issued
redirect_ssl: true
# Additional domain with certbot
app.example.com:
containers:
- app:3000
certbot: true
redirect_ssl: true
# Domain with certbot enabled
"example.com:80":
ip: ["webapp:8080"]
# Enable certbot for this domain
certbot: true
# Redirect HTTP to HTTPS after cert is issued
redirect_ssl: true
# Domain without certbot (uses custom certificate)
custom.example.com:
containers:
- custom-app:8080
# No certbot - expects certificate at /certs/haproxy/custom.example.com.pem
# Additional domain with certbot
"app.example.com:80":
ip: ["app:3000"]
certbot: true
redirect_ssl: true
# Domain without certbot (uses custom certificate)
"custom.example.com:80":
ip: ["custom-app:8080"]
# No certbot - expects certificate at /certs/haproxy/custom.example.com.pem
# HTTPS Port 443
# Serves HTTPS traffic with auto-generated certificates
- port: 443
"example.com:443":
ip: ["webapp:8080"]
ssl: true
hosts:
example.com:
containers:
- webapp:8080
# Certificate path (auto-generated by certbot)
# /certs/certbot/example.com/fullchain.pem
# Certificate path (auto-generated by certbot)
# /certs/certbot/example.com/fullchain.pem
app.example.com:
containers:
- app:3000
"app.example.com:443":
ip: ["app:3000"]
ssl: true
# Custom certificate example
custom.example.com:
containers:
- custom-app:8080
# Place your certificate at:
# /certs/haproxy/custom.example.com.pem
# Custom certificate example
"custom.example.com:443":
ip: ["custom-app:8080"]
ssl: true
# Place your certificate at:
# /certs/haproxy/custom.example.com.pem
# Multiple domains with different backends
# Certbot will request separate certificates for each domain

View file

@ -33,46 +33,39 @@ plugins:
- /config
status_code: 404 # Hide existence of these paths
easymapping:
- port: 80
hosts:
# Domain 1: Uses global deny_pages configuration
host1.local:
containers:
- webapp1:8080
# No plugins specified = uses global configuration
containers:
# Domain 1: Uses global deny_pages configuration
"host1.local:80":
ip: ["webapp1:8080"]
# No plugins specified = uses global configuration
# Domain 2: WordPress site with custom blocked paths
host2.local:
containers:
- wordpress:80
# Override global plugin configuration for this domain
plugins:
- deny_pages
plugin_config:
deny_pages:
paths:
- /wp-admin
- /wp-login.php
- /xmlrpc.php
- /wp-config.php
status_code: 403 # Return forbidden instead of 404
# Domain 2: WordPress site with custom blocked paths
"host2.local:80":
ip: ["wordpress:80"]
# Override global plugin configuration for this domain
plugins: [deny_pages]
plugin:
deny_pages:
paths:
- /wp-admin
- /wp-login.php
- /xmlrpc.php
- /wp-config.php
status_code: 403 # Return forbidden instead of 404
# Domain 3: Public site with stricter blocking
host3.local:
containers:
- publicsite:3000
plugins:
- deny_pages
plugin_config:
deny_pages:
paths:
- /admin
- /administrator
- /manager
- /phpmyadmin
- /.git
- /.env
- /config
- /backup
status_code: 404
# Domain 3: Public site with stricter blocking
"host3.local:80":
ip: ["publicsite:3000"]
plugins: [deny_pages]
plugin:
deny_pages:
paths:
- /admin
- /administrator
- /manager
- /phpmyadmin
- /.git
- /.env
- /config
- /backup
status_code: 404

View file

@ -32,55 +32,45 @@ stats:
customerrors: true
easymapping:
- port: 80
hosts:
# Public API with full JWT validation
api.local:
containers:
- api-server:8080
plugins:
- jwt_validator
plugin_config:
jwt_validator:
algorithm: RS256
issuer: https://auth.example.com/
audience: https://api.example.com
pubkey_path: /etc/haproxy/jwt_keys/api_pubkey.pem
containers:
# Public API with full JWT validation
"api.local:80":
ip: ["api-server:8080"]
plugins: [jwt_validator]
plugin:
jwt_validator:
algorithm: RS256
issuer: https://auth.example.com/
audience: https://api.example.com
pubkey_path: /etc/haproxy/jwt_keys/api_pubkey.pem
# Internal API - validate signature only (no issuer/audience check)
internal-api.local:
containers:
- internal-api:3000
plugins:
- jwt_validator
plugin_config:
jwt_validator:
algorithm: RS256
# No issuer/audience = skip those validations
pubkey_path: /etc/haproxy/jwt_keys/api_pubkey.pem
# Internal API - validate signature only (no issuer/audience check)
"internal-api.local:80":
ip: ["internal-api:3000"]
plugins: [jwt_validator]
plugin:
jwt_validator:
algorithm: RS256
# No issuer/audience = skip those validations
pubkey_path: /etc/haproxy/jwt_keys/api_pubkey.pem
# Admin API - different issuer and key
admin-api.local:
containers:
- admin-api:4000
plugins:
- jwt_validator
- deny_pages # Also block internal paths
plugin_config:
jwt_validator:
algorithm: RS256
issuer: https://admin-auth.example.com/
audience: https://admin.example.com
pubkey_path: /etc/haproxy/jwt_keys/admin_pubkey.pem
deny_pages:
paths:
- /internal
- /debug
status_code: 403
# Admin API - different issuer and key
"admin-api.local:80":
ip: ["admin-api:4000"]
plugins: [jwt_validator, deny_pages] # Also block internal paths
plugin:
jwt_validator:
algorithm: RS256
issuer: https://admin-auth.example.com/
audience: https://admin.example.com
pubkey_path: /etc/haproxy/jwt_keys/admin_pubkey.pem
deny_pages:
paths:
- /internal
- /debug
status_code: 403
# Public website - no JWT required
website.local:
containers:
- website:8080
# No plugins = public access
# Public website - no JWT required
"website.local:80":
ip: ["website:8080"]
# No plugins = public access

View file

@ -60,17 +60,70 @@
services:
haproxy:
image: byjg/easy-haproxy:5.0.0
image: byjg/easy-haproxy:local
build:
context: ../..
dockerfile: build/Dockerfile
volumes:
- ./conf/:/etc/haproxy/static/
- ./host1.local.pem:/certs/haproxy/host1.local.pem
- ../static/host1.local.pem:/certs/haproxy/host1.local.pem:ro
- ../docker/jwt_pubkey.pem:/etc/haproxy/jwt_keys/api_pubkey.pem:ro
- ../docker/jwt_pubkey.pem:/etc/haproxy/jwt_keys/admin_pubkey.pem:ro
- /var/run/docker.sock:/var/run/docker.sock
environment:
EASYHAPROXY_DISCOVER: static
HAPROXY_USERNAME: admin
HAPROXY_PASSWORD: password
ports:
- "80:80/tcp"
- "443:443/tcp"
- "1936:1936/tcp"
# Main container for basic tests
container:
image: byjg/static-httpserver
container_name: container
# Containers for deny-pages tests
webapp1:
image: byjg/static-httpserver
container_name: webapp1
environment:
TITLE: "WebApp 1"
wordpress:
image: byjg/static-httpserver
container_name: wordpress
environment:
TITLE: "WordPress Site"
publicsite:
image: byjg/static-httpserver
container_name: publicsite
environment:
TITLE: "Public Site"
# Containers for JWT validator tests
api-server:
image: byjg/static-httpserver
container_name: api-server
environment:
TITLE: "Protected API"
internal-api:
image: byjg/static-httpserver
container_name: internal-api
environment:
TITLE: "Internal API"
admin-api:
image: byjg/static-httpserver
container_name: admin-api
environment:
TITLE: "Admin API"
website:
image: byjg/static-httpserver
container_name: website
environment:
TITLE: "Public Website"