refactor: Improve code quality, error handling, and test coverage
- Add file_lock context manager to eliminate duplicate locking patterns - Add ValidationError, ConfigurationError, CertificateError exceptions - Improve rollback logic in haproxy_add_servers (track successful ops only) - Decompose haproxy_add_domain into smaller helper functions - Consolidate certificate constants (CERTS_DIR, ACME_HOME) to config.py - Enhance docstrings for internal functions and magic numbers - Add pytest framework with 48 new tests (269 -> 317 total) - Increase test coverage from 76% to 86% - servers.py: 58% -> 82% - certificates.py: 67% -> 86% - configuration.py: 69% -> 94% Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ from ..config import (
|
||||
StateField,
|
||||
StatField,
|
||||
STATE_MIN_COLUMNS,
|
||||
logger,
|
||||
)
|
||||
from ..exceptions import HaproxyError
|
||||
from ..validation import validate_domain, validate_ip, validate_backend_name
|
||||
@@ -252,6 +253,7 @@ def register_server_tools(mcp):
|
||||
added = []
|
||||
errors = []
|
||||
failed_slots = []
|
||||
successfully_added_slots = []
|
||||
|
||||
try:
|
||||
for server_config in validated_servers:
|
||||
@@ -260,19 +262,43 @@ def register_server_tools(mcp):
|
||||
http_port = server_config["http_port"]
|
||||
try:
|
||||
configure_server_slot(backend, server_prefix, slot, ip, http_port)
|
||||
successfully_added_slots.append(slot)
|
||||
added.append(f"slot {slot}: {ip}:{http_port}")
|
||||
except HaproxyError as e:
|
||||
failed_slots.append(slot)
|
||||
errors.append(f"slot {slot}: {e}")
|
||||
except Exception as e:
|
||||
# Rollback all saved configs on unexpected error
|
||||
# Rollback only successfully added configs on unexpected error
|
||||
for slot in successfully_added_slots:
|
||||
try:
|
||||
remove_server_from_config(domain, slot)
|
||||
except Exception as rollback_error:
|
||||
logger.error(
|
||||
"Failed to rollback server config for %s slot %d: %s",
|
||||
domain, slot, rollback_error
|
||||
)
|
||||
# Also rollback configs that weren't yet processed
|
||||
for server_config in validated_servers:
|
||||
remove_server_from_config(domain, server_config["slot"])
|
||||
slot = server_config["slot"]
|
||||
if slot not in successfully_added_slots:
|
||||
try:
|
||||
remove_server_from_config(domain, slot)
|
||||
except Exception as rollback_error:
|
||||
logger.error(
|
||||
"Failed to rollback server config for %s slot %d: %s",
|
||||
domain, slot, rollback_error
|
||||
)
|
||||
return f"Error: {e}"
|
||||
|
||||
# Rollback failed slots from config
|
||||
for slot in failed_slots:
|
||||
remove_server_from_config(domain, slot)
|
||||
try:
|
||||
remove_server_from_config(domain, slot)
|
||||
except Exception as rollback_error:
|
||||
logger.error(
|
||||
"Failed to rollback server config for %s slot %d: %s",
|
||||
domain, slot, rollback_error
|
||||
)
|
||||
|
||||
# Build result message
|
||||
result_parts = []
|
||||
|
||||
Reference in New Issue
Block a user