Add haproxy_cleanup_wildcards tool to remove subdomain wildcard entries

New db_remove_wildcard() for surgical wildcard-only deletion.
New haproxy_cleanup_wildcards tool scans all wildcard entries and removes
those belonging to subdomains (e.g., *.nocodb.inouter.com) while keeping
base domain wildcards (e.g., *.anvil.it.com).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-02-08 20:36:59 +09:00
parent 170c48e257
commit 2e22a5d5a8
2 changed files with 61 additions and 1 deletions

View File

@@ -34,7 +34,7 @@ from ..file_ops import (
remove_domain_from_map,
find_available_pool,
)
from ..db import db_load_certs
from ..db import db_load_certs, db_remove_wildcard, sync_map_files
from ..utils import parse_servers_state, disable_server_slot
@@ -408,3 +408,48 @@ def register_domain_tools(mcp):
return f"Error: Failed to update map file: {e}"
except HaproxyError as e:
return f"Error: {e}"
@mcp.tool()
def haproxy_cleanup_wildcards() -> str:
"""Remove unnecessary wildcard entries for subdomain domains.
Scans all wildcard entries and removes those where the domain is a
subdomain (not a base domain). Base domains keep their wildcards.
Example: *.nocodb.inouter.com is removed (subdomain of inouter.com),
but *.anvil.it.com is kept (anvil.it.com is a base domain).
"""
entries = get_map_contents()
# Build registered domains set
registered_domains: set[str] = set()
for entry_domain, _ in entries:
if not entry_domain.startswith("."):
registered_domains.add(entry_domain)
# Find wildcard entries that should be removed
removed = []
for entry_domain, backend in entries:
if not entry_domain.startswith("."):
continue
domain = entry_domain[1:] # strip leading dot
is_sub, parent = _check_subdomain(domain, registered_domains)
if is_sub:
# Remove from DB
if db_remove_wildcard(domain):
# Remove from HAProxy runtime map
try:
haproxy_cmd(f"del map {WILDCARDS_MAP_FILE_CONTAINER} {entry_domain}")
except HaproxyError as e:
logger.warning("Failed to remove wildcard map entry %s: %s", entry_domain, e)
removed.append(f"{entry_domain} -> {backend} (subdomain of {parent})")
if removed:
# Sync map files from DB
sync_map_files()
result = f"Removed {len(removed)} unnecessary wildcard(s):\n"
result += "\n".join(f"{r}" for r in removed)
else:
result = "No unnecessary wildcard entries found."
return result