Add Kubernetes integration tests for EasyHAProxy examples
- Introduced a suite of pytest-based integration tests for Kubernetes using `kind`. - Automated local installation of dependencies (`kind`, `kubectl`, and `helm`) when missing. - Implemented fixtures for Kubernetes resource management and TLS secrets. - Added end-to-end tests for HTTP and HTTPS ingress functionality.
This commit is contained in:
parent
5767e55dea
commit
90b01b1f13
18 changed files with 2978 additions and 24 deletions
|
|
@ -9,12 +9,28 @@ Configuration:
|
|||
- algorithm: JWT signing algorithm (default: RS256)
|
||||
- issuer: Expected JWT issuer (optional, set to "none"/"null" to skip validation)
|
||||
- audience: Expected JWT audience (optional, set to "none"/"null" to skip validation)
|
||||
- pubkey_path: Path to public key file (required if pubkey not provided)
|
||||
- pubkey: Public key content as base64-encoded string (required if pubkey_path not provided)
|
||||
- pubkey_path: Path to public key file in container (priority: 1)
|
||||
- pubkey: Public key content as base64-encoded string (priority: 2)
|
||||
- k8s_secret.pubkey: Kubernetes secret containing public key (priority: 3, Kubernetes only)
|
||||
- paths: List of paths that require JWT validation (optional, if not set ALL domain is protected)
|
||||
- only_paths: If true, only specified paths are accessible; if false (default), only specified paths require JWT validation
|
||||
- allow_anonymous: If true, allows requests without Authorization header (validates JWT if present); if false (default), requires Authorization header
|
||||
|
||||
Priority Order (first configured option wins):
|
||||
1. pubkey_path - Direct file path (explicit configuration)
|
||||
2. pubkey - Base64-encoded key content (inline configuration)
|
||||
3. k8s_secret.pubkey - Kubernetes secret name (processed by K8s processor into pubkey)
|
||||
|
||||
Kubernetes Secret Pattern (Kubernetes only):
|
||||
For Kubernetes deployments, you can load the public key from a Kubernetes Secret:
|
||||
|
||||
- Auto-detect key: easyhaproxy.plugin.jwt_validator.k8s_secret.pubkey: "secret_name"
|
||||
- Explicit key: easyhaproxy.plugin.jwt_validator.k8s_secret.pubkey: "secret_name/key_name"
|
||||
|
||||
See documentation for details:
|
||||
- General k8s_secret pattern: docs/kubernetes.md#loading-plugin-configuration-from-kubernetes-secrets
|
||||
- JWT Validator with Secrets: docs/Plugins/jwt-validator.md#kubernetes-with-secrets-recommended
|
||||
|
||||
Path Validation Logic:
|
||||
- No paths configured: ALL requests to the domain require JWT validation (default behavior)
|
||||
- Paths configured + only_paths=false: Only specified paths require JWT validation, others pass through
|
||||
|
|
@ -46,6 +62,16 @@ Example Container Label:
|
|||
easyhaproxy.http.plugin.jwt_validator.paths: /api/admin,/api/sensitive
|
||||
easyhaproxy.http.plugin.jwt_validator.only_paths: true
|
||||
|
||||
Example Kubernetes Annotations:
|
||||
# Using k8s_secret pattern (recommended for Kubernetes):
|
||||
easyhaproxy.plugin.jwt_validator.k8s_secret.pubkey: "my-jwt-secret"
|
||||
easyhaproxy.plugin.jwt_validator.algorithm: "RS256"
|
||||
easyhaproxy.plugin.jwt_validator.issuer: "https://auth.example.com/"
|
||||
easyhaproxy.plugin.jwt_validator.audience: "https://api.example.com"
|
||||
|
||||
# Using inline pubkey (for testing):
|
||||
easyhaproxy.plugin.jwt_validator.pubkey: "LS0tLS1CRUdJTi..."
|
||||
|
||||
HAProxy Config Generated:
|
||||
# JWT Validator - Validate JWT tokens
|
||||
http-request deny content-type 'text/html' string 'Missing Authorization HTTP header' unless { req.hdr(authorization) -m found }
|
||||
|
|
@ -74,7 +100,7 @@ import sys
|
|||
# Add parent directory to path for imports
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from functions import logger_easyhaproxy
|
||||
from functions import Consts, logger_easyhaproxy
|
||||
from plugins import PluginContext, PluginInterface, PluginResult, PluginType
|
||||
|
||||
|
||||
|
|
@ -178,7 +204,7 @@ class JwtValidatorPlugin(PluginInterface):
|
|||
elif self.pubkey:
|
||||
# Generate path for pubkey based on domain
|
||||
domain_safe = context.domain.replace(".", "_").replace(":", "_")
|
||||
pubkey_file = f"/etc/haproxy/jwt_keys/{domain_safe}_pubkey.pem"
|
||||
pubkey_file = f"{Consts.jwt_keys}/{domain_safe}_pubkey.pem"
|
||||
else:
|
||||
logger_easyhaproxy.warning(f"JWT validator plugin for {context.domain}: No pubkey or pubkey_path configured")
|
||||
return PluginResult()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue