Changes:
- Replace USR2 signal reload with HAProxy Runtime API for cert updates
- new ssl cert → set ssl cert → commit ssl cert
- No connection drops during certificate changes
- Add certificates.json for persistence (domain list only)
- Add haproxy_load_cert tool for manual certificate loading
- Auto-restore certificates on MCP startup
- Update startup sequence to load both servers and certificates
certificates.json format:
{
"domains": ["inouter.com", "anvil.it.com"]
}
Paths derived from convention:
- Host: /opt/haproxy/certs/{domain}.pem
- Container: /etc/haproxy/certs/{domain}.pem
Total MCP tools: 28 → 29
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When adding a domain, now checks if an SSL certificate covers it:
- Exact match: domain.com.pem
- Wildcard match: parent.com.pem with *.parent.com SAN
Output examples:
- "SSL: Using certificate inouter.com (wildcard)"
- "SSL: No certificate found. Use haproxy_issue_cert(...) to issue one."
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New tools for SSL/TLS certificate management via acme.sh:
- haproxy_list_certs: List all certificates with expiry info
- haproxy_cert_info: Get detailed certificate info (expiry, issuer, SANs)
- haproxy_issue_cert: Issue new certificate via Cloudflare DNS validation
- haproxy_renew_cert: Renew specific certificate (with force option)
- haproxy_renew_all_certs: Renew all certificates due for renewal
- haproxy_delete_cert: Delete certificate from acme.sh and HAProxy
Features:
- Automatic PEM deployment to HAProxy certs directory
- HAProxy hot-reload after certificate changes (USR2 signal)
- Cloudflare DNS validation with CF_Token support
- Wildcard certificate support
Total MCP tools: 22 → 28
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
HIGH PRIORITY:
1. Pool allocation race condition
- Add file locking around entire pool allocation in haproxy_add_domain
- Prevents concurrent calls from getting same pool
2. haproxy_remove_server - disk-first pattern
- Remove from config FIRST, then update HAProxy
- Rollback config on HAProxy failure
3. Wildcard domain prefix validation
- Reject domains starting with '.'
- Prevents double-prefix like '..domain.com'
MEDIUM PRIORITY:
4. Variable shadowing fix
- Rename state_output to servers_state in haproxy_set_domain_state
5. JSON size limit
- Add MAX_SERVERS_JSON_SIZE = 10000 limit for haproxy_add_servers
6. Remove get_server_suffixes
- Delete unused abstraction layer
- Inline logic in restore_servers_from_config and haproxy_add_domain
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
MEDIUM PRIORITY:
4. restore operations - use haproxy_cmd_checked()
- restore_servers_from_config() now validates commands
- haproxy_restore_state() logs warnings for individual failures
5. container health check - add exception logging
- logger.warning() for unexpected exceptions
6. haproxy_add_domain - optimize map file reading
- Read map contents once, reuse for domain check and pool lookup
- Eliminates redundant file reads
LOW PRIORITY:
7. Remove unused IP_PATTERN constant
- Was unused since validate_ip() uses ipaddress module
8. haproxy_add_server - auto-select slot
- slot=0 or slot=-1 finds first available slot
- Returns error if all slots in use
9. haproxy_wait_drain - new tool
- Wait for connections to drain before maintenance
- Polls HAProxy stats until scur=0 or timeout
MCP Tools: 21 → 22
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1. haproxy_add_servers - disk-first pattern
- Save ALL servers to config FIRST
- Then update HAProxy
- Rollback all on unexpected error
- Rollback failed slots individually
2. remove_domain_from_config - file locking
- Add fcntl.LOCK_EX for consistency with other config ops
- Prevents race conditions during concurrent access
3. haproxy_add_domain - rollback on HAProxy failure
- Wrap HAProxy map update in try/except
- Rollback map file if HAProxy command fails
- Rollback server config if server setup fails
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update tool count: 20 → 21
- Add haproxy_set_domain_state to server management tools
- Add container status to health check example
- Update server.py description (~1600 lines, 21 tools)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7. Add haproxy_set_domain_state() tool
- Set all servers of a domain to ready/drain/maint at once
- Useful for maintenance windows and deployments
- Reports changed servers and any errors
8. Add container status to haproxy_health()
- Check HAProxy container state via podman inspect
- Reports "ok" when running, actual state otherwise
- Sets overall health to "unhealthy" on container issues
9. Extract configure_server_slot() helper
- Eliminates duplicated server configuration code
- Used by haproxy_add_server() and haproxy_add_servers()
- Cleaner, more maintainable code
MCP Tools: 20 → 21
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4. Pool exhaustion - explicit error
- Add NoAvailablePoolError exception class
- find_available_pool() now raises instead of returning None
- haproxy_add_domain() catches and returns user-friendly error
5. haproxy_add_server - disk-first pattern
- Save to config FIRST, then update HAProxy
- If HAProxy update fails, rollback config automatically
- Prevents inconsistency between disk and runtime
6. Wildcard removal - log failures
- Changed silent pass to logger.warning()
- Failures now visible in logs for debugging
- Does not block domain removal operation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1. File locking for config operations
- add_server_to_config() and remove_server_from_config() now use
exclusive file locking (fcntl.LOCK_EX) to prevent race conditions
- Prevents data loss from concurrent modifications
2. Bulk server limit
- Add MAX_BULK_SERVERS = 10 constant
- haproxy_add_servers() now rejects requests exceeding limit
- Prevents potential DoS via large payloads
3. HAProxy command response validation
- Add haproxy_cmd_checked() helper function
- Validates responses for error indicators (No such, not found, etc.)
- State-modifying commands now properly detect and report failures
- Read-only commands continue using haproxy_cmd()
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1. Add timeout to HAProxy response wait
- Use select() for non-blocking recv with 30s timeout
- Prevents indefinite blocking on slow/hung HAProxy
2. Log warnings for failed server clears
- haproxy_remove_domain now logs warnings instead of silent pass
- Helps debugging without breaking cleanup flow
3. Add HAPROXY_CONTAINER environment variable
- Container name now configurable (default: "haproxy")
- Used in reload_haproxy() and haproxy_check_config()
4. Add haproxy_add_servers() for bulk operations
- Add multiple servers in single call
- Accepts JSON array of server configs
- More efficient than multiple haproxy_add_server calls
5. Add wildcard domain support in haproxy_list_domains()
- New include_wildcards parameter (default: false)
- Shows .domain entries with (wildcard) label when enabled
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1. Fix order: Save to disk FIRST, then update HAProxy
- Prevents inconsistency if HAProxy update succeeds but disk write fails
- Data is preserved correctly on restart
2. Add IPv6 support
- Use Python ipaddress module instead of regex
- Now accepts both IPv4 and IPv6 addresses
3. Extract atomic_write_file() helper
- Eliminates duplicated code in save_map_file, save_servers_config, haproxy_save_state
- Single source of truth for atomic file operations
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
haproxy_reload now automatically restores server configurations from
servers.json after a successful reload, preventing service disruption.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- haproxy_add_domain: Explain pool backend, link to haproxy_add_server
- haproxy_add_server: Clarify slots 1-10 for load balancing, add examples
- haproxy_remove_server: Add usage example
- haproxy_list_servers: Explain output format with example
- haproxy_list_domains: Add output format example
- haproxy_health: Describe JSON structure and monitoring use case
- haproxy_domain_health: Explain status values (healthy/degraded/down)
- haproxy_set_server_state: Document ready/drain/maint with examples
- haproxy_set_server_weight: Explain weight ratio and soft disable
- haproxy_get_server_health: Clarify vs haproxy_domain_health
- haproxy_get_connections: Add usage examples
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Environment Variables table with all configurable options
- Add Health Check section with haproxy_health and haproxy_domain_health examples
- Update MCP Tools count from 17 to 19
- Add new Health Check tools section
- Update server.py description (line count and tool count)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major improvements:
- Atomic file writes using temp file + rename pattern
- Structured logging with logging module (replaces print)
- StateField class for HAProxy state field indices
- Helper function get_backend_and_prefix() to reduce duplication
- Consistent exception chaining with 'from e'
- Proper fd/temp_path tracking to prevent resource leaks
- Added IOError handling in server management functions
Technical changes:
- save_map_file, save_servers_config, haproxy_save_state now use
atomic writes with tempfile.mkstemp() + os.rename()
- Standardized on 'set server state ready' (was 'enable server')
- All magic numbers for state parsing replaced with StateField class
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove SSL/QUIC backend templates - all backends now use HTTP only
with SSL termination at HAProxy frontend. This improves performance
(~33% faster than HTTPS backends based on benchmarks).
Changes:
- server.py: Remove https_port parameter from all functions
- haproxy.cfg: Remove ssl/h3 server templates from pool backends
- CLAUDE.md: Update docs for HTTP-only backends and acme.sh
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Zero-reload domain management with map-based routing
- 100 pool backends with 10 server slots each
- Runtime API integration for dynamic configuration
- Auto-restore servers from persistent config on startup
- 17 MCP tools for domain/server management
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>