Delegation (WIP).

This commit is contained in:
Philippe Pittoli 2025-07-29 12:12:16 +02:00
parent 38e3ce432e
commit b3085eed78
3 changed files with 31 additions and 22 deletions

View file

@ -4,17 +4,9 @@ require "uuid/json"
require "baguette-crystal-base"
require "./service.cr"
require "./util.cr"
require "dodb"
def safe_write(filename : String, &block)
filename_wip = "#{filename}.wip"
File.open(filename_wip, "w") do |file|
yield file
end
# Rename WIP filename to final file name.
File.rename filename_wip, filename
end
class DNSManager::Storage
getter domains : DODB::Storage::Common(Domain)
getter domains_by_name : DODB::Trigger::IndexCached(Domain)
@ -461,22 +453,13 @@ class DNSManager::Storage
return Response::InvalidDomainName.new unless Zone.is_domain_valid? nameserver1
return Response::InvalidDomainName.new unless Zone.is_domain_valid? nameserver2
# Wipes the domain from dnsmanager (generated zone file, tokens).
wipe_domain user_id, domain_name
remove_bind9_zonefile domain_name
# Wipes the zone from dnsmanager (zone db entry, generated zone file, tokens).
wipe_zone user_id, domain_name
# Creates the new zone.
zone = Zone.new domain_name
zone.delegation = Zone::Delegation.new nameserver1, nameserver2
filename = "#{@delegationdir}/#{domain_name}"
Baguette::Log.info "New delegation file: #{filename}"
safe_write filename do |file|
zone.to_delegation file
rescue e : NoDelegation
Baguette::Log.error "domain #{domain_name}: trying to delegate but doesn't have delegation parameters"
end
zone.update_delegation @delegationdir
# Once the new delegation file has been written, the script generating the (root) zone file must
# be informed by touching a file (named "delegation token file" in the source code).
@ -561,7 +544,7 @@ class DNSManager::Storage
zone
end
# WARNING: this function removes a domain with all its related data (zone file, delegation file, indexes, etc.).
# WARNING: this function removes a zone with all its related data (zone file, delegation file, indexes, etc.).
#
# RATIONALE: wipe_zone can be used to renew to remove zone-related content (the entry in the zone db, tokens
# and generated zone file) while preserving the entry in the domain db.

View file

@ -1,4 +1,5 @@
require "ipaddress"
require "../util.cr"
# Domains cannot be parsed using regexes.
# Yet, that will be good enough for now.
@ -55,6 +56,17 @@ class DNSManager::Storage::Zone
def_clone
end
# Update the delegation file.
def update_delegation(delegation_directory : String)
filename = "#{delegation_directory}/#{@domain}"
Baguette::Log.info "New delegation file: #{filename}"
safe_write filename do |file|
to_delegation file
rescue e : NoDelegation
Baguette::Log.error "domain #{domain}: trying to delegate but doesn't have delegation parameters"
end
end
def to_delegation(io : IO)
if delegation = @delegation
io << "#{@domain}. 1800 IN NS #{delegation.nameserver1}\n"

14
src/util.cr Normal file
View file

@ -0,0 +1,14 @@
# Writes to a file "safely": a temporary file is generated then the file is moved.
#
# RATIONALE: several problems can occur while writing in a file.
# Using a temporary file prevents database corruption if a writting error occurs.
# Also, moving the temporary file to its final path enables to only read fully-written files
# (once the file is opened the content won't change).
def safe_write(filename : String, &block)
filename_wip = "#{filename}.wip"
File.open(filename_wip, "w") do |file|
yield file
end
# Rename WIP filename to final file name.
File.rename filename_wip, filename
end