refactor: Modularize MCP server with command batching
- Split monolithic mcp/server.py (1874 lines) into haproxy_mcp/ package:
- config.py: Configuration constants and environment variables
- exceptions.py: Custom exception classes
- validation.py: Input validation functions
- haproxy_client.py: HAProxy Runtime API client with batch support
- file_ops.py: Atomic file operations with locking
- utils.py: CSV parsing utilities
- tools/: MCP tools organized by function
- domains.py: Domain management (3 tools)
- servers.py: Server management (7 tools)
- health.py: Health checks (3 tools)
- monitoring.py: Monitoring (4 tools)
- configuration.py: Config management (4 tools)
- Add haproxy_cmd_batch() for sending multiple commands in single TCP connection
- Optimize server operations: 1 connection instead of 2 per server
- Optimize startup restore: All servers in 1 connection (was 2×N)
- Update type hints to Python 3.9+ style (built-in generics)
- Remove unused imports and functions
- Update CLAUDE.md with new structure and performance notes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
29
haproxy_mcp/utils.py
Normal file
29
haproxy_mcp/utils.py
Normal file
@@ -0,0 +1,29 @@
|
||||
"""Utility functions for HAProxy MCP Server."""
|
||||
|
||||
from typing import Dict, Generator
|
||||
from .config import StatField
|
||||
|
||||
|
||||
def parse_stat_csv(stat_output: str) -> Generator[Dict[str, str], None, None]:
|
||||
"""Parse HAProxy stat CSV output into structured data.
|
||||
|
||||
Args:
|
||||
stat_output: Raw output from 'show stat' command
|
||||
|
||||
Yields:
|
||||
Dictionaries with parsed stat fields for each row
|
||||
"""
|
||||
for line in stat_output.split("\n"):
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
parts = line.split(",")
|
||||
if len(parts) > StatField.STATUS:
|
||||
yield {
|
||||
"pxname": parts[StatField.PXNAME],
|
||||
"svname": parts[StatField.SVNAME],
|
||||
"scur": parts[StatField.SCUR] if len(parts) > StatField.SCUR else "0",
|
||||
"smax": parts[StatField.SMAX] if len(parts) > StatField.SMAX else "0",
|
||||
"status": parts[StatField.STATUS],
|
||||
"weight": parts[StatField.WEIGHT] if len(parts) > StatField.WEIGHT else "0",
|
||||
"check_status": parts[StatField.CHECK_STATUS] if len(parts) > StatField.CHECK_STATUS else "",
|
||||
}
|
||||
Reference in New Issue
Block a user