fix: apply_domain now removes all stale zone files when renaming
Previously the loop broke after processing the first zone file it found. If dev.zone already existed (created by apply_ip_range), it would be processed and the loop would stop — leaving any other zone files (e.g. cell.zone from an earlier domain) in place. get_dns_records() reads all .zone files so the stale zone appeared doubled in the UI. Fix: collect all non-local zone files first, write the target, then delete every file that is not the current domain's zone. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+28
-21
@@ -419,30 +419,37 @@ class NetworkManager(BaseServiceManager):
|
||||
except Exception as e:
|
||||
warnings.append(f"Corefile domain update failed: {e}")
|
||||
|
||||
# 3. Update zone file: rename and rewrite $ORIGIN / SOA
|
||||
# 3. Update zone file: rename and rewrite $ORIGIN / SOA, remove stale zones
|
||||
try:
|
||||
dns_data = os.path.join(self.data_dir, 'dns')
|
||||
if os.path.isdir(dns_data):
|
||||
# Find existing primary zone file (anything not named 'local')
|
||||
for fname in os.listdir(dns_data):
|
||||
if fname.endswith('.zone') and 'local' not in fname:
|
||||
src = os.path.join(dns_data, fname)
|
||||
with open(src) as f:
|
||||
zone_content = f.read()
|
||||
# Detect old domain from $ORIGIN line
|
||||
m = re.search(r'^\$ORIGIN\s+(\S+)', zone_content, re.MULTILINE)
|
||||
old_origin = m.group(1).rstrip('.') if m else None
|
||||
if old_origin and old_origin != domain:
|
||||
zone_content = zone_content.replace(
|
||||
f'{old_origin}.', f'{domain}.')
|
||||
zone_content = re.sub(
|
||||
r'^\$ORIGIN\s+\S+', f'$ORIGIN {domain}.', zone_content, flags=re.MULTILINE)
|
||||
dst = os.path.join(dns_data, f'{domain}.zone')
|
||||
with open(dst, 'w') as f:
|
||||
f.write(zone_content)
|
||||
if src != dst:
|
||||
os.remove(src)
|
||||
break
|
||||
dst = os.path.join(dns_data, f'{domain}.zone')
|
||||
# Find the best source: prefer a non-target zone (old domain) so we
|
||||
# can migrate its content; fall back to the target zone itself.
|
||||
zone_files = [
|
||||
os.path.join(dns_data, f)
|
||||
for f in os.listdir(dns_data)
|
||||
if f.endswith('.zone') and 'local' not in f
|
||||
]
|
||||
src = next((p for p in zone_files if p != dst), dst)
|
||||
if os.path.exists(src):
|
||||
with open(src) as f:
|
||||
zone_content = f.read()
|
||||
m = re.search(r'^\$ORIGIN\s+(\S+)', zone_content, re.MULTILINE)
|
||||
old_origin = m.group(1).rstrip('.') if m else None
|
||||
if old_origin and old_origin != domain:
|
||||
zone_content = zone_content.replace(f'{old_origin}.', f'{domain}.')
|
||||
zone_content = re.sub(
|
||||
r'^\$ORIGIN\s+\S+', f'$ORIGIN {domain}.', zone_content, flags=re.MULTILINE)
|
||||
with open(dst, 'w') as f:
|
||||
f.write(zone_content)
|
||||
# Remove every zone file that is not the current domain's file
|
||||
for zone_path in zone_files:
|
||||
if zone_path != dst:
|
||||
try:
|
||||
os.remove(zone_path)
|
||||
except OSError:
|
||||
pass
|
||||
except Exception as e:
|
||||
warnings.append(f"zone file domain update failed: {e}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user