Add IP Whitelist Plugin and corresponding tests
- Introduced `IpWhitelistPlugin` (DOMAIN): Restricts access to specific IP addresses or CIDR ranges. - Added configuration options: `enabled`, `allowed_ips`, and `status_code`. - Updated `plugins.md` and `plugin-development.md` to document `IpWhitelistPlugin`. - Created fixtures for `services-with-ip-whitelist`. - Added extensive test cases for `IpWhitelistPlugin` to validate configuration and HAProxy output generation. - Ensured seamless integration into the plugin framework alongside other domain plugins.
This commit is contained in:
parent
91f8ff5d08
commit
57387f3e32
5 changed files with 1549 additions and 428 deletions
File diff suppressed because it is too large
Load diff
534
docs/plugins.md
534
docs/plugins.md
|
|
@ -2,42 +2,57 @@
|
|||
sidebar_position: 16
|
||||
---
|
||||
|
||||
# Plugins
|
||||
# Using Plugins
|
||||
|
||||
EasyHAProxy supports a flexible plugin system that allows you to extend HAProxy configuration with custom functionality. Plugins are automatically invoked during the discovery cycle and can inject HAProxy configuration directives or modify discovery data.
|
||||
EasyHAProxy supports a plugin system that extends HAProxy configuration with custom functionality. This guide explains how to use and configure plugins.
|
||||
|
||||
## What are Plugins?
|
||||
|
||||
Plugins automatically run during the discovery cycle and can:
|
||||
- Add HAProxy configuration directives
|
||||
- Perform maintenance tasks
|
||||
- Modify discovery data
|
||||
- Integrate with external services
|
||||
|
||||
## Plugin Types
|
||||
|
||||
### Global Plugins
|
||||
Global plugins execute **once per discovery cycle**, regardless of how many domains are discovered. They're ideal for:
|
||||
|
||||
Execute **once per discovery cycle** regardless of how many domains are discovered.
|
||||
|
||||
**Use cases:**
|
||||
- Cleanup tasks
|
||||
- Global monitoring
|
||||
- DNS updates
|
||||
- Log management
|
||||
|
||||
**Example:** `cleanup` plugin
|
||||
|
||||
### Domain Plugins
|
||||
Domain plugins execute **once for each discovered domain/host**. They're ideal for:
|
||||
|
||||
Execute **once for each discovered domain/host**.
|
||||
|
||||
**Use cases:**
|
||||
- Domain-specific configuration
|
||||
- IP restoration (e.g., Cloudflare)
|
||||
- IP restoration (Cloudflare)
|
||||
- Path blocking
|
||||
- Custom headers per domain
|
||||
|
||||
**Examples:** `cloudflare`, `deny_pages`
|
||||
|
||||
## Built-in Plugins
|
||||
|
||||
### Cloudflare (Domain Plugin)
|
||||
### Cloudflare Plugin (Domain)
|
||||
|
||||
Restores the original visitor IP address from Cloudflare's `CF-Connecting-IP` header when requests come through Cloudflare's CDN.
|
||||
Restores the original visitor IP address when requests come through Cloudflare's CDN.
|
||||
|
||||
**Configuration:**
|
||||
```yaml
|
||||
# /etc/haproxy/static/config.yaml
|
||||
plugins:
|
||||
cloudflare:
|
||||
enabled: true
|
||||
ip_list_path: /etc/haproxy/cloudflare_ips.lst
|
||||
```
|
||||
**Why use it:** Cloudflare replaces the visitor's IP with its own. This plugin restores the original IP from the `CF-Connecting-IP` header.
|
||||
|
||||
**Container Label:**
|
||||
**Configuration options:**
|
||||
- `enabled` - Enable/disable plugin (default: `true`)
|
||||
- `ip_list_path` - Path to Cloudflare IP list (default: `/etc/haproxy/cloudflare_ips.lst`)
|
||||
|
||||
**Enable via container label:**
|
||||
```yaml
|
||||
services:
|
||||
myapp:
|
||||
|
|
@ -46,101 +61,117 @@ services:
|
|||
easyhaproxy.http.plugins: cloudflare
|
||||
```
|
||||
|
||||
**Environment Variable:**
|
||||
```bash
|
||||
EASYHAPROXY_PLUGINS_ENABLED=cloudflare
|
||||
EASYHAPROXY_PLUGIN_CLOUDFLARE_IP_LIST_PATH=/etc/haproxy/cloudflare_ips.lst
|
||||
**Custom IP list path:**
|
||||
```yaml
|
||||
labels:
|
||||
easyhaproxy.http.plugins: cloudflare
|
||||
easyhaproxy.http.plugin.cloudflare.ip_list_path: /custom/path/cf_ips.lst
|
||||
```
|
||||
|
||||
### Cleanup (Global Plugin)
|
||||
**HAProxy config generated:**
|
||||
```
|
||||
# Cloudflare - Restore original visitor IP
|
||||
acl from_cloudflare src -f /etc/haproxy/cloudflare_ips.lst
|
||||
http-request set-header X-Forwarded-For %[req.hdr(CF-Connecting-IP)] if from_cloudflare
|
||||
```
|
||||
|
||||
**Required:** Download Cloudflare IP list from [Cloudflare documentation](https://support.cloudflare.com/hc/en-us/articles/200170786).
|
||||
|
||||
### Cleanup Plugin (Global)
|
||||
|
||||
Performs cleanup tasks during each discovery cycle, such as removing old temporary files.
|
||||
|
||||
**Configuration:**
|
||||
**Why use it:** Prevents disk space issues by automatically cleaning up temporary files created by EasyHAProxy.
|
||||
|
||||
**Configuration options:**
|
||||
- `enabled` - Enable/disable plugin (default: `true`)
|
||||
- `max_idle_time` - Maximum age in seconds before deleting files (default: `300`)
|
||||
- `cleanup_temp_files` - Enable temp file cleanup (default: `true`)
|
||||
|
||||
**Enable via YAML:**
|
||||
```yaml
|
||||
# /etc/haproxy/static/config.yaml
|
||||
plugins:
|
||||
cleanup:
|
||||
enabled: true
|
||||
max_idle_time: 300 # seconds
|
||||
cleanup_temp_files: true
|
||||
enabled: [cleanup]
|
||||
config:
|
||||
cleanup:
|
||||
max_idle_time: 600
|
||||
cleanup_temp_files: true
|
||||
```
|
||||
|
||||
**Environment Variable:**
|
||||
**Enable via environment variable:**
|
||||
```bash
|
||||
EASYHAPROXY_PLUGINS_ENABLED=cleanup
|
||||
EASYHAPROXY_PLUGIN_CLEANUP_MAX_IDLE_TIME=600
|
||||
```
|
||||
|
||||
### Deny Pages (Domain Plugin)
|
||||
### Deny Pages Plugin (Domain)
|
||||
|
||||
Blocks access to specific paths for a domain.
|
||||
Blocks access to specific paths for a domain, returning a configurable HTTP status code.
|
||||
|
||||
**Configuration:**
|
||||
```yaml
|
||||
# /etc/haproxy/static/config.yaml
|
||||
plugins:
|
||||
deny_pages:
|
||||
enabled: true
|
||||
paths: /admin,/private,/internal
|
||||
status_code: 403
|
||||
```
|
||||
**Why use it:** Protect admin panels, internal APIs, or debugging endpoints from public access.
|
||||
|
||||
**Container Label:**
|
||||
**Configuration options:**
|
||||
- `enabled` - Enable/disable plugin (default: `true`)
|
||||
- `paths` - Comma-separated list of paths to block (e.g., `/admin,/private`)
|
||||
- `status_code` - HTTP status code to return (default: `403`)
|
||||
|
||||
**Enable via container label:**
|
||||
```yaml
|
||||
services:
|
||||
myapp:
|
||||
webapp:
|
||||
labels:
|
||||
easyhaproxy.http.host: example.com
|
||||
easyhaproxy.http.plugins: deny_pages
|
||||
easyhaproxy.http.plugin.deny_pages.paths: /admin,/private
|
||||
easyhaproxy.http.plugin.deny_pages.status_code: 403
|
||||
easyhaproxy.http.plugin.deny_pages.paths: /admin,/private,/debug
|
||||
easyhaproxy.http.plugin.deny_pages.status_code: 404
|
||||
```
|
||||
|
||||
**HAProxy config generated:**
|
||||
```
|
||||
# Deny Pages - Block specific paths
|
||||
acl denied_path path_beg /admin /private /debug
|
||||
http-request deny deny_status 404 if denied_path
|
||||
```
|
||||
|
||||
### IP Whitelist Plugin (Domain)
|
||||
|
||||
Restricts access to a domain to only specific IP addresses or CIDR ranges.
|
||||
|
||||
**Why use it:** Restrict access to internal tools, admin panels, or staging environments to only trusted IP addresses.
|
||||
|
||||
**Configuration options:**
|
||||
- `enabled` - Enable/disable plugin (default: `true`)
|
||||
- `allowed_ips` - Comma-separated list of IPs/CIDR ranges to allow (e.g., `192.168.1.0/24,10.0.0.1`)
|
||||
- `status_code` - HTTP status code to return for blocked IPs (default: `403`)
|
||||
|
||||
**Enable via container label:**
|
||||
```yaml
|
||||
services:
|
||||
admin:
|
||||
labels:
|
||||
easyhaproxy.http.host: admin.example.com
|
||||
easyhaproxy.http.plugins: ip_whitelist
|
||||
easyhaproxy.http.plugin.ip_whitelist.allowed_ips: 192.168.1.0/24,10.0.0.5
|
||||
easyhaproxy.http.plugin.ip_whitelist.status_code: 403
|
||||
```
|
||||
|
||||
**HAProxy config generated:**
|
||||
```
|
||||
# IP Whitelist - Only allow specific IPs
|
||||
acl whitelisted_ip src 192.168.1.0/24 10.0.0.5
|
||||
http-request deny deny_status 403 if !whitelisted_ip
|
||||
```
|
||||
|
||||
**Important:** This blocks ALL IPs except those in the whitelist. Make sure to include your own IP!
|
||||
|
||||
## Configuration Methods
|
||||
|
||||
Plugins can be configured using three methods. Configuration from YAML takes precedence over environment variables.
|
||||
Plugins can be configured using three methods, listed in order of precedence (highest to lowest):
|
||||
|
||||
### 1. Static YAML Configuration
|
||||
### 1. Container Labels (Domain Plugins Only)
|
||||
|
||||
Configure plugins in `/etc/haproxy/static/config.yaml`:
|
||||
|
||||
```yaml
|
||||
plugins:
|
||||
# Global settings
|
||||
abort_on_error: false # Log and continue on plugin errors (default)
|
||||
|
||||
# Plugin-specific configuration
|
||||
cloudflare:
|
||||
enabled: true
|
||||
ip_list_path: /etc/haproxy/cloudflare_ips.lst
|
||||
|
||||
cleanup:
|
||||
enabled: true
|
||||
max_idle_time: 300
|
||||
|
||||
deny_pages:
|
||||
enabled: false # Disable globally, can still be enabled per domain
|
||||
```
|
||||
|
||||
### 2. Environment Variables
|
||||
|
||||
Configure plugins via environment variables:
|
||||
|
||||
```bash
|
||||
# Global settings
|
||||
EASYHAPROXY_PLUGINS_ABORT_ON_ERROR=false
|
||||
EASYHAPROXY_PLUGINS_ENABLED=cloudflare,cleanup
|
||||
|
||||
# Plugin-specific configuration
|
||||
EASYHAPROXY_PLUGIN_CLOUDFLARE_ENABLED=true
|
||||
EASYHAPROXY_PLUGIN_CLOUDFLARE_IP_LIST_PATH=/etc/haproxy/cloudflare_ips.lst
|
||||
EASYHAPROXY_PLUGIN_CLEANUP_MAX_IDLE_TIME=600
|
||||
```
|
||||
|
||||
### 3. Container Labels (Domain Plugins Only)
|
||||
|
||||
Enable domain plugins for specific containers:
|
||||
Enable and configure domain plugins for specific containers:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
|
|
@ -148,194 +179,239 @@ services:
|
|||
image: myapp:latest
|
||||
labels:
|
||||
easyhaproxy.http.host: example.com
|
||||
easyhaproxy.http.port: 80
|
||||
# Enable multiple plugins
|
||||
easyhaproxy.http.plugins: cloudflare,deny_pages
|
||||
# Configure deny_pages plugin
|
||||
easyhaproxy.http.plugin.deny_pages.paths: /admin,/api/internal
|
||||
easyhaproxy.http.plugin.deny_pages.status_code: 403
|
||||
```
|
||||
|
||||
**Label format:**
|
||||
- Enable plugins: `easyhaproxy.<definition>.plugins: plugin1,plugin2`
|
||||
- Configure plugin: `easyhaproxy.<definition>.plugin.<plugin_name>.<config_key>: value`
|
||||
|
||||
**Where `<definition>` is:** `http`, `https`, `tcp`, etc.
|
||||
|
||||
### 2. Static YAML Configuration
|
||||
|
||||
Configure plugins globally in `/etc/haproxy/static/config.yaml`:
|
||||
|
||||
```yaml
|
||||
plugins:
|
||||
# Global settings
|
||||
abort_on_error: false # Log and continue on errors (recommended)
|
||||
|
||||
# Enable global plugins
|
||||
enabled: [cleanup]
|
||||
|
||||
# Configure individual plugins
|
||||
config:
|
||||
cloudflare:
|
||||
enabled: true
|
||||
ip_list_path: /etc/haproxy/cloudflare_ips.lst
|
||||
|
||||
cleanup:
|
||||
enabled: true
|
||||
max_idle_time: 600
|
||||
|
||||
deny_pages:
|
||||
enabled: false # Disable globally, enable per-container via labels
|
||||
```
|
||||
|
||||
### 3. Environment Variables
|
||||
|
||||
Configure plugins via environment variables:
|
||||
|
||||
```bash
|
||||
# Global settings
|
||||
EASYHAPROXY_PLUGINS_ENABLED=cleanup
|
||||
EASYHAPROXY_PLUGINS_ABORT_ON_ERROR=false
|
||||
|
||||
# Plugin-specific configuration
|
||||
EASYHAPROXY_PLUGIN_CLEANUP_ENABLED=true
|
||||
EASYHAPROXY_PLUGIN_CLEANUP_MAX_IDLE_TIME=600
|
||||
EASYHAPROXY_PLUGIN_CLOUDFLARE_IP_LIST_PATH=/etc/haproxy/cloudflare_ips.lst
|
||||
```
|
||||
|
||||
**Variable format:**
|
||||
- Enable plugins: `EASYHAPROXY_PLUGINS_ENABLED=plugin1,plugin2`
|
||||
- Configure plugin: `EASYHAPROXY_PLUGIN_<PLUGIN_NAME>_<CONFIG_KEY>=value`
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
### Restrict Admin Panel to Office IPs
|
||||
|
||||
Protect admin panel by only allowing access from office network:
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
easyhaproxy.http.host: admin.example.com
|
||||
easyhaproxy.http.plugins: ip_whitelist
|
||||
easyhaproxy.http.plugin.ip_whitelist.allowed_ips: 203.0.113.0/24,198.51.100.42
|
||||
```
|
||||
|
||||
### Protect Admin Paths
|
||||
|
||||
Block access to WordPress admin and other sensitive paths:
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
easyhaproxy.http.host: wordpress.example.com
|
||||
easyhaproxy.http.plugins: deny_pages
|
||||
easyhaproxy.http.plugin.deny_pages.paths: /wp-admin,/wp-login.php,/.env
|
||||
easyhaproxy.http.plugin.deny_pages.status_code: 404
|
||||
```
|
||||
|
||||
### Cloudflare IP Restoration
|
||||
|
||||
Restore original visitor IPs for applications behind Cloudflare:
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
easyhaproxy.http.host: myapp.com
|
||||
easyhaproxy.http.plugins: cloudflare
|
||||
```
|
||||
|
||||
### Multiple Plugins Together
|
||||
|
||||
Combine multiple plugins for one domain:
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
easyhaproxy.http.host: secure-app.com
|
||||
easyhaproxy.http.plugins: cloudflare,deny_pages
|
||||
easyhaproxy.http.plugin.deny_pages.paths: /admin,/config
|
||||
easyhaproxy.http.plugin.deny_pages.status_code: 403
|
||||
```
|
||||
|
||||
### Automatic Cleanup
|
||||
|
||||
Keep your system clean with automatic temp file removal:
|
||||
|
||||
```yaml
|
||||
# /etc/haproxy/static/config.yaml
|
||||
plugins:
|
||||
enabled: [cleanup]
|
||||
config:
|
||||
cleanup:
|
||||
enabled: true
|
||||
max_idle_time: 3600 # 1 hour
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Log and Continue (Default)
|
||||
### Log and Continue (Recommended)
|
||||
|
||||
By default, plugin errors are logged as warnings and the discovery cycle continues:
|
||||
By default, plugin errors are logged as warnings and discovery continues:
|
||||
|
||||
```yaml
|
||||
plugins:
|
||||
abort_on_error: false # Default
|
||||
```
|
||||
|
||||
This ensures that a failing plugin doesn't prevent HAProxy configuration updates.
|
||||
**When to use:** Most situations. Ensures a failing plugin doesn't prevent HAProxy updates.
|
||||
|
||||
**Behavior:**
|
||||
- Plugin errors logged as warnings
|
||||
- Discovery cycle continues
|
||||
- Other plugins still execute
|
||||
- HAProxy config is generated without the failed plugin
|
||||
|
||||
### Abort on Error
|
||||
|
||||
For critical plugins, you can stop the discovery cycle on errors:
|
||||
Stop discovery cycle if any plugin fails:
|
||||
|
||||
```yaml
|
||||
plugins:
|
||||
abort_on_error: true
|
||||
```
|
||||
|
||||
With this setting, any plugin error will halt configuration generation and the previous HAProxy config remains active until the issue is resolved.
|
||||
**When to use:** Critical plugins where failure should halt deployment.
|
||||
|
||||
## Custom Plugins
|
||||
**Behavior:**
|
||||
- Plugin error stops discovery
|
||||
- Previous HAProxy config remains active
|
||||
- No configuration changes until issue is resolved
|
||||
|
||||
You can create custom plugins by placing Python files in `/etc/haproxy/plugins/`.
|
||||
## Troubleshooting
|
||||
|
||||
### Simple Custom Plugin Example
|
||||
### Enable Debug Logging
|
||||
|
||||
Create `/etc/haproxy/plugins/custom_header.py`:
|
||||
|
||||
```python
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from plugins import PluginInterface, PluginType, PluginContext, PluginResult
|
||||
|
||||
|
||||
class CustomHeaderPlugin(PluginInterface):
|
||||
def __init__(self):
|
||||
self.enabled = True
|
||||
self.header_name = "X-Custom-App"
|
||||
self.header_value = "EasyHAProxy"
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "custom_header"
|
||||
|
||||
@property
|
||||
def plugin_type(self) -> PluginType:
|
||||
return PluginType.DOMAIN
|
||||
|
||||
def configure(self, config: dict) -> None:
|
||||
if "enabled" in config:
|
||||
self.enabled = str(config["enabled"]).lower() in ["true", "1", "yes"]
|
||||
if "header_name" in config:
|
||||
self.header_name = config["header_name"]
|
||||
if "header_value" in config:
|
||||
self.header_value = config["header_value"]
|
||||
|
||||
def process(self, context: PluginContext) -> PluginResult:
|
||||
if not self.enabled:
|
||||
return PluginResult()
|
||||
|
||||
haproxy_config = f'http-request set-header {self.header_name} "{self.header_value}"'
|
||||
|
||||
return PluginResult(
|
||||
haproxy_config=haproxy_config,
|
||||
metadata={"domain": context.domain}
|
||||
)
|
||||
```
|
||||
|
||||
### Enable Your Custom Plugin
|
||||
|
||||
**YAML:**
|
||||
```yaml
|
||||
plugins:
|
||||
custom_header:
|
||||
enabled: true
|
||||
header_name: X-My-Header
|
||||
header_value: MyValue
|
||||
```
|
||||
|
||||
**Container Label:**
|
||||
```yaml
|
||||
labels:
|
||||
easyhaproxy.http.plugins: custom_header
|
||||
easyhaproxy.http.plugin.custom_header.header_value: CustomValue
|
||||
```
|
||||
|
||||
## Plugin Development
|
||||
|
||||
For detailed information on developing plugins, see the [Plugin Developer Guide](plugin-development.md).
|
||||
|
||||
Key points:
|
||||
- Plugins must inherit from `PluginInterface`
|
||||
- Implement required methods: `name`, `plugin_type`, `configure`, `process`
|
||||
- Return `PluginResult` with HAProxy config snippets
|
||||
- Use `loggerEasyHaproxy` for logging
|
||||
- Handle errors gracefully
|
||||
|
||||
## Use Cases
|
||||
|
||||
### 1. Cloudflare IP Restoration
|
||||
|
||||
Restore original visitor IPs when using Cloudflare:
|
||||
|
||||
```yaml
|
||||
plugins:
|
||||
cloudflare:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
Requires Cloudflare IP list at `/etc/haproxy/cloudflare_ips.lst`. See [Cloudflare documentation](https://support.cloudflare.com/hc/en-us/articles/200170786-Restoring-original-visitor-IPs).
|
||||
|
||||
### 2. Path Protection
|
||||
|
||||
Block sensitive paths from public access:
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
easyhaproxy.http.host: myapp.com
|
||||
easyhaproxy.http.plugins: deny_pages
|
||||
easyhaproxy.http.plugin.deny_pages.paths: /admin,/config,/debug
|
||||
```
|
||||
|
||||
### 3. Automatic Cleanup
|
||||
|
||||
Keep your system clean:
|
||||
|
||||
```yaml
|
||||
plugins:
|
||||
cleanup:
|
||||
enabled: true
|
||||
max_idle_time: 3600 # 1 hour
|
||||
```
|
||||
|
||||
### 4. Custom Authentication
|
||||
|
||||
Create a plugin to add basic auth:
|
||||
|
||||
```python
|
||||
def process(self, context: PluginContext) -> PluginResult:
|
||||
return PluginResult(
|
||||
haproxy_config="""http-request auth realm MyApp unless { http_auth(user_list) }"""
|
||||
)
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
Enable debug logging to see plugin execution:
|
||||
See detailed plugin execution information:
|
||||
|
||||
```bash
|
||||
EASYHAPROXY_LOG_LEVEL=DEBUG
|
||||
```
|
||||
|
||||
Look for log messages:
|
||||
**Look for:**
|
||||
```
|
||||
INFO: Loaded builtin plugin: cloudflare (domain)
|
||||
INFO: Loaded builtin plugin: cleanup (global)
|
||||
DEBUG: Executing domain plugin: cloudflare for domain: example.com
|
||||
DEBUG: Plugin cloudflare metadata: {'domain': 'example.com'}
|
||||
DEBUG: Plugin cloudflare metadata: {'domain': 'example.com', 'ip_list_path': '/etc/haproxy/cloudflare_ips.lst'}
|
||||
```
|
||||
|
||||
### Plugin Not Loading
|
||||
|
||||
**Check:**
|
||||
1. Plugin file exists in `/etc/haproxy/plugins/` or builtin directory
|
||||
2. Python syntax is valid
|
||||
3. Plugin class inherits from `PluginInterface`
|
||||
4. Check logs for load errors
|
||||
|
||||
### Plugin Not Executing
|
||||
|
||||
**For domain plugins:**
|
||||
1. Check container has label: `easyhaproxy.http.plugins: plugin_name`
|
||||
2. Verify plugin name is correct (case-sensitive)
|
||||
3. Enable debug logging
|
||||
|
||||
**For global plugins:**
|
||||
1. Check YAML config: `plugins.enabled: [plugin_name]`
|
||||
2. Or env var: `EASYHAPROXY_PLUGINS_ENABLED=plugin_name`
|
||||
3. Enable debug logging
|
||||
|
||||
### Configuration Not Applied
|
||||
|
||||
**Check precedence order:**
|
||||
1. Container labels (highest)
|
||||
2. YAML configuration
|
||||
3. Environment variables (lowest)
|
||||
|
||||
Container labels override YAML and env vars.
|
||||
|
||||
### Plugin Output Missing
|
||||
|
||||
**Verify:**
|
||||
1. Plugin is enabled (`enabled: true`)
|
||||
2. Plugin configuration is correct
|
||||
3. Plugin's `process()` method returns valid `PluginResult`
|
||||
4. Check debug logs for plugin execution
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Test plugins independently** before deploying to production
|
||||
2. **Use log-and-continue mode** unless a plugin is critical
|
||||
3. **Keep plugin logic simple** - one plugin should do one thing well
|
||||
4. **Document configuration options** in plugin docstrings
|
||||
5. **Handle errors gracefully** - return empty PluginResult on errors
|
||||
6. **Use sensible defaults** so plugins work out of the box
|
||||
1. **Start with log-and-continue mode** - Use `abort_on_error: false` until you're confident plugins are stable
|
||||
2. **Use container labels for domain-specific config** - Easier to manage per-service
|
||||
3. **Use YAML/env for global config** - Better for global plugins and defaults
|
||||
4. **Enable debug logging during testing** - Helps identify configuration issues
|
||||
5. **Test plugin changes in staging first** - Avoid production surprises
|
||||
6. **Keep plugin configurations simple** - Use defaults when possible
|
||||
|
||||
## Limitations
|
||||
|
||||
- Plugins are Python-only (no shell scripts)
|
||||
- Plugins cannot modify the HAProxy template structure
|
||||
- Domain plugins are executed for each domain, so keep them lightweight
|
||||
- Plugin errors in abort mode will halt configuration updates
|
||||
- Plugins must be written in Python
|
||||
- Domain plugins execute for each domain, so keep them lightweight
|
||||
- Plugins cannot modify the Jinja2 template structure directly
|
||||
- Plugin errors in abort mode prevent all configuration updates
|
||||
|
||||
## Creating Custom Plugins
|
||||
|
||||
To create your own plugins, see the [Plugin Developer Guide](plugin-development.md).
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Plugin Developer Guide](plugin-development.md)
|
||||
- [Container Labels](container-labels.md)
|
||||
- [Environment Variables](environment-variable.md)
|
||||
- [Static Configuration](static.md)
|
||||
- [Plugin Developer Guide](plugin-development.md) - Create custom plugins
|
||||
- [Container Labels](container-labels.md) - Label configuration reference
|
||||
- [Environment Variables](environment-variable.md) - Environment variable reference
|
||||
- [Static Configuration](static.md) - YAML configuration reference
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue