Added debug logging to track tcp_request_rules value when frontend edit modal opens.
This will help diagnose why tcp_request_rules from bulk import are not appearing in the edit form.
CRITICAL FIX: Prevent 'option httpchk' duplication in HAProxy config by implementing 3-layer validation:
1. BULK IMPORT PARSER:
- Frontend: Filter out 'option httpchk' with warning (not applicable to frontends)
- Backend: Already filtering 'option httpchk' (handled by health_check_uri field)
2. BACKEND API:
- Backend create/update: Auto-filter 'option httpchk' from options field
- Frontend create/update: Auto-filter 'option httpchk' from options field
- Added filter_httpchk_from_options() helper function in both routers
3. FRONTEND UI:
- Backend modal: Real-time warning when 'option httpchk' is typed
- Frontend modal: Real-time warning when 'option httpchk' is typed
- Warning messages guide users to use proper fields instead
Changes:
- backend/utils/haproxy_config_parser.py: Added httpchk filtering for frontend parsing
- backend/routers/backend.py: Added filter function + applied to create/update
- backend/routers/frontend.py: Added filter function + applied to create/update
- frontend/src/components/BackendServers.js: Added dynamic warning for httpchk
- frontend/src/components/FrontendManagement.js: Added dynamic warning for httpchk
User Experience:
✅ Bulk Import: Automatically filters httpchk, shows warning in preview
✅ Manual Entry: Shows real-time warning, auto-filters on save
✅ No Config Duplication: 'option httpchk' never appears twice in generated config
Impact: Users can safely paste or type 'option httpchk' without breaking HAProxy config. System automatically filters it and guides users to use the Health Check URI field instead.
Implemented comprehensive HAProxy options field support for both backend and frontend entities to enable standard HAProxy directives like 'option http-keep-alive', 'option httplog', 'option forwardfor', etc.
Changes:
- Database: Added 'options' TEXT column to backends and frontends tables
- Models: Added options field to BackendConfig, BackendConfigUpdate, and FrontendConfig
- API Endpoints: Updated CREATE, UPDATE, and GET endpoints to handle options field
* Backend: CREATE/UPDATE/GET with options support
* Frontend: CREATE/UPDATE/GET with options support (fixed 5 SELECT queries)
- Config Generator: Added options block generation for both backends and frontends
- Bulk Import Parser:
* Added options field to ParsedBackend and ParsedFrontend dataclasses
* Implemented option directive parsing with validation
* Added unknown option warnings
* Fixed bulk parse response to include options field
- Bulk Import Merge: Added options field comparison in UPDATE logic
- UI Components:
* BackendServers.js: Added options TextArea form field
* FrontendManagement.js: Added options TextArea form field
Features:
- Multi-line options support (newline-separated format)
- Option validation with known HAProxy options list
- Backward compatible (NULL options for existing entities)
- Bulk import support with merge strategy
- Full CRUD support for both manual and bulk operations
Technical Details:
- Format: Newline-separated TEXT field for multiple options
- Validation: Warns about unknown options but allows them
- Config Generation: Each option written as separate directive
- Agent: Standard HAProxy config validation applies
Total: 10 files modified, ~195 lines added, 26 integration points verified
This is a comprehensive update that adds SSL certificate differentiation
for frontend (HAProxy bind) and server (backend verification) use cases.
FEATURES:
- SSL certificates can be marked as 'frontend' or 'server' usage type
- Frontend SSL: Private key REQUIRED (for HAProxy bind ssl crt)
- Server SSL: Private key OPTIONAL (CA cert only for backend verification)
- UI dropdown for usage type selection
- Dynamic form validation based on usage type
- Filtering: Frontends see only Frontend SSL, Backends see only Server SSL
DATABASE:
- Added usage_type column to ssl_certificates (default: 'frontend')
- Made private_key_content nullable for server SSL support
- Migration automatically runs on pod restart
BACKEND:
- Pydantic v2 compatibility (@field_validator, @model_validator)
- SSL router: usage_type filtering support
- Agent endpoint: usage_type field included
- Improved migration robustness with better error handling
- Fixed duplicate ensure_agents_table() function
- Fixed JSONB permissions insert with json.dumps()
- Fixed ON CONFLICT constraints with explicit checks
FRONTEND:
- SSL Management: Usage Type dropdown with visual feedback
- Frontend Management: Filters only Frontend SSL certificates
- Backend Servers: Filters only Server SSL certificates
- Dynamic private key validation (required for Frontend, optional for Server)
- Improved form UX with color-coded hints
AGENT SCRIPTS (Linux & macOS):
- Support for Server SSL without private key
- Conditional PEM file creation (cert+key vs cert-only)
- usage_type awareness in SSL deployment
- Backward compatible with existing Frontend SSL certificates
DOCKER:
- Increased npm timeout for slow networks (300s → 600s)
- Increased fetch-retries (5 → 10)
- Reduced maxsockets for stability (3 → 1)
All changes are backward compatible. Existing SSL certificates
default to 'frontend' type and continue working unchanged.
Tested with: HAProxy 2.8+, PostgreSQL 15, React 18
Code cleanup - removed emoji from form field
Changed: extra="🆕 Select one or more..."
To: extra="Select one or more..."
Note: Backend Server SSL is single select (correct)
Frontend SSL is multiple select (correct - supports SNI)
CRITICAL RACE CONDITION FIX - FrontendManagement:
Same race condition pattern found and fixed
Component Analysis:
BackendServers: FIXED (guard clause added)
FrontendManagement: FIXED (guard clause added)
SSLManagement: Already has guard clause
WAFManagement: Already has guard clause
FrontendManagement Issues Fixed:
1. fetchFrontends() - Added guard clause
if (!selectedCluster) → Clear state and return
2. fetchBackends() - Added guard clause
if (!selectedCluster) → Clear state and return
Race Condition Pattern:
Mount → selectedCluster=undefined → fetch() → API returns ALL
Load → selectedCluster=1 → fetch() → API returns filtered
Problem: First response arrives late and overwrites correct data
Solution - Guard Clauses:
if (!selectedCluster) {
setEntities([]);
setFilteredEntities([]);
return; // Don't call API
}
Risk Assessment - SAFE:
- Only adds early return if no cluster selected
- Doesn't change existing logic when cluster IS selected
- Same pattern already used in SSLManagement and WAFManagement
- No breaking changes to other functions
Impact:
- Prevents race condition on component mount
- Prevents all entities appearing briefly
- Consistent behavior across all management pages
Tested Components:
Backend/Frontend/SSL/WAF Management all now protected
Database Migration:
- Added ssl_certificate_id column to backend_servers table
- Added FK constraint to ssl_certificates table
- ON DELETE SET NULL behavior
- Idempotent migration (safe to run multiple times)
Column Details:
Name: ssl_certificate_id
Type: INTEGER
Nullable: YES
Foreign Key: ssl_certificates(id)
On Delete: SET NULL
Migration Function:
add_ssl_certificate_id_to_backend_servers()
Called in run_migrations() at Line 1523
Code Cleanup:
- Removed emojis from migration logs
- Removed emojis from SSL dropdown status icons
- Changed to text: Valid, Expiring, Expired
- Changed to text: Global, Cluster
Error Fixed:
GET /api/backends - 500
column "ssl_certificate_id" does not exist
After migration runs on startup, column will exist and API will work
✨ New Features:
- Added use_backend_rules validator to Frontend model
- UI now supports editing use_backend rules from Frontend Management page
- Array to string conversion for use_backend rules in edit modal
🔧 Model Improvements:
- Changed use_backend_rules field type from Optional[str] to Any (list support)
- Added parse_use_backend_rules validator (same logic as ACL/redirect rules)
- Handles 3 formats: Array, Textarea string (newline-separated), JSON string
💡 UI Improvements:
- Frontend edit modal automatically converts use_backend array to multi-line text
- Users can edit routing rules line by line in textarea
- Format: 'use_backend BackendName if condition'
✅ Complete Workflow:
1. Bulk Import: Config parsed → ACL + use_backend stored as array
2. Frontend Edit: Arrays converted to multi-line string in textarea
3. User edits ACL/use_backend rules in UI
4. Save: Textarea string → validator → array → database
5. Config Generation: Array → HAProxy config format
Example workflow:
Parse: ['use_backend API if is_api']
→ Edit UI: 'use_backend API if is_api' (textarea)
→ User edits: 'use_backend API_v2 if is_api_v2'
→ Save: ['use_backend API_v2 if is_api_v2']
→ Generate: 'use_backend API_v2 if is_api_v2' (HAProxy config)