2020-12-09 19:01:33 +01:00
|
|
|
|
|
|
|
# Store a DNS zone.
|
|
|
|
class DNSManager::Storage::Zone
|
|
|
|
include JSON::Serializable
|
|
|
|
|
|
|
|
property domain : String
|
|
|
|
property resources = [] of DNSManager::Storage::Zone::ResourceRecord
|
|
|
|
|
|
|
|
def initialize(@domain)
|
|
|
|
end
|
|
|
|
|
2020-12-12 05:38:16 +01:00
|
|
|
alias Error = String
|
2020-12-09 19:01:33 +01:00
|
|
|
|
|
|
|
# Store a Resource Record: A, AAAA, TXT, PTR, CNAME…
|
|
|
|
abstract class ResourceRecord
|
|
|
|
include JSON::Serializable
|
|
|
|
|
2020-12-09 23:38:28 +01:00
|
|
|
use_json_discriminator "rrtype", {
|
2020-12-09 19:01:33 +01:00
|
|
|
a: A,
|
|
|
|
aaaa: AAAA,
|
|
|
|
soa: SOA,
|
|
|
|
txt: TXT,
|
|
|
|
ptr: PTR,
|
|
|
|
ns: NS,
|
|
|
|
cname: CNAME,
|
|
|
|
mx: MX,
|
|
|
|
srv: SRV
|
|
|
|
}
|
|
|
|
|
|
|
|
# Used to discriminate between classes.
|
2020-12-12 05:38:16 +01:00
|
|
|
property rrtype : String = ""
|
2020-12-09 19:01:33 +01:00
|
|
|
|
|
|
|
property name : String
|
|
|
|
property ttl : UInt32
|
|
|
|
property target : String
|
|
|
|
|
|
|
|
# zone class is omited, it always will be IN in our case.
|
|
|
|
def initialize(@name, @ttl, @target)
|
2020-12-09 23:38:28 +01:00
|
|
|
@rrtype = self.class.name.downcase.gsub /dnsmanager::storage::zone::/, ""
|
2020-12-09 19:01:33 +01:00
|
|
|
end
|
2020-12-12 05:38:16 +01:00
|
|
|
|
|
|
|
def get_error : Error?
|
|
|
|
nil
|
|
|
|
end
|
2020-12-09 19:01:33 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
class SOA < ResourceRecord
|
|
|
|
# Start of Authority
|
|
|
|
property mname : String # Master Name Server for the zone.
|
|
|
|
property rname : String # admin email address john.doe@example.com => john\.doe.example.com
|
|
|
|
property serial : UInt64 = 0 # Number for tracking new versions of the zone (master-slaves).
|
|
|
|
property refresh : UInt64 = 86400 # #seconds before requesting new zone version (master-slave).
|
|
|
|
property retry : UInt64 = 7200 # #seconds before retry accessing new data from the master.
|
|
|
|
property expire : UInt64 = 3600000# #seconds slaves should consider master dead.
|
|
|
|
|
|
|
|
def initialize(@name, @ttl, @target,
|
|
|
|
@mname, @rname,
|
|
|
|
@serial = 0, @refresh = 86400, @retry = 7200, @expire = 3600000)
|
2020-12-09 23:38:28 +01:00
|
|
|
@rrtype = "soa"
|
2020-12-09 19:01:33 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class A < ResourceRecord
|
|
|
|
end
|
|
|
|
class AAAA < ResourceRecord
|
|
|
|
end
|
|
|
|
class TXT < ResourceRecord
|
|
|
|
end
|
|
|
|
class PTR < ResourceRecord
|
|
|
|
end
|
|
|
|
class NS < ResourceRecord
|
|
|
|
end
|
|
|
|
class CNAME < ResourceRecord
|
|
|
|
end
|
|
|
|
|
|
|
|
class MX < ResourceRecord
|
|
|
|
property priority : UInt32 = 10
|
|
|
|
def initialize(@name, @ttl, @target, @priority = 10)
|
2020-12-09 23:38:28 +01:00
|
|
|
@rrtype = "mx"
|
2020-12-09 19:01:33 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class SRV < ResourceRecord
|
|
|
|
property port : UInt16
|
|
|
|
property protocol : String = "tcp"
|
|
|
|
property priority : UInt32 = 10
|
|
|
|
property weight : UInt32 = 10
|
|
|
|
def initialize(@name, @ttl, @target, @port, @protocol = "tcp", @priority = 10, @weight = 10)
|
2020-12-09 23:38:28 +01:00
|
|
|
@rrtype = "srv"
|
2020-12-09 19:01:33 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_s(io : IO)
|
|
|
|
io << "TEST"
|
|
|
|
end
|
2020-12-12 05:38:16 +01:00
|
|
|
|
|
|
|
def get_errors? : Array(Error)
|
|
|
|
errors = [] of Error
|
|
|
|
unless Zone.is_domain_valid? @domain
|
|
|
|
errors << "invalid domain"
|
|
|
|
end
|
|
|
|
|
|
|
|
@resources.each do |r|
|
|
|
|
if error = r.get_error
|
|
|
|
errors << error
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
errors
|
|
|
|
end
|
|
|
|
|
|
|
|
# This regex only is "good enough for now".
|
|
|
|
def self.is_domain_valid?(domain) : Bool
|
|
|
|
if domain =~ /^(((?!-))(xn--|_{1,1})?[a-z0-9-]{0,61}[a-z0-9]{1,1}\.)*((xn--)?[a-z0-9][a-z0-9\-]{0,60}[a-z0-9]|(xn--)?[a-z0-9]{1,60})\.[a-z]{2,}$/
|
|
|
|
true
|
|
|
|
else
|
|
|
|
false
|
|
|
|
end
|
|
|
|
rescue e
|
|
|
|
Baguette::Log.error "invalid zone domain #{domain}: #{e}"
|
|
|
|
false
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2020-12-09 19:01:33 +01:00
|
|
|
end
|