Storage is here, with user_data and zone classes.
This commit is contained in:
parent
5dd1d13b46
commit
11c30dd057
19
src/main.cr
19
src/main.cr
@ -38,7 +38,7 @@ class DNSManager::Service < IPC::Server
|
||||
getter storage : DNSManager::Storage
|
||||
getter logged_users : Hash(Int32, AuthD::User::Public)
|
||||
|
||||
@authd : AuthD::Client
|
||||
property authd : AuthD::Client
|
||||
|
||||
def initialize(@configuration, @authd : AuthD::Client)
|
||||
@storage = DNSManager::Storage.new @configuration.storage_directory
|
||||
@ -55,22 +55,7 @@ class DNSManager::Service < IPC::Server
|
||||
end
|
||||
|
||||
def decode_token(token : String)
|
||||
@auth.decode_token token
|
||||
end
|
||||
|
||||
def get_user_data(uid : Int32)
|
||||
@storage.user_data_per_user.get uid.to_s
|
||||
rescue e : DODB::MissingEntry
|
||||
entry = UserData.new uid
|
||||
entry
|
||||
end
|
||||
|
||||
def get_user_data(user : ::AuthD::User::Public)
|
||||
get_user_data user.uid
|
||||
end
|
||||
|
||||
def update_user_data(user_data : UserData)
|
||||
@storage.user_data_per_user.update_or_create user_data.uid.to_s, user_data
|
||||
@authd.decode_token token
|
||||
end
|
||||
|
||||
def handle_request(event : IPC::Event::MessageReceived)
|
||||
|
@ -1,12 +1,56 @@
|
||||
require "json"
|
||||
require "uuid"
|
||||
require "uuid/json"
|
||||
require "baguette-crystal-base"
|
||||
|
||||
require "dodb"
|
||||
|
||||
# require "./storage/*"
|
||||
|
||||
class DNSManager::Storage
|
||||
getter user_data : DODB::CachedDataBase(UserData)
|
||||
getter user_data_by_uid : DODB::Index(UserData)
|
||||
|
||||
getter zones : DODB::CachedDataBase(Zone)
|
||||
getter zones_by_domain : DODB::Index(Zone)
|
||||
|
||||
def initialize(@root : String)
|
||||
@user_data = DODB::CachedDataBase(UserData).new "#{@root}/user-data"
|
||||
@user_data_by_uid = @user_data.new_index "uid", &.uid.to_s
|
||||
@zones = DODB::CachedDataBase(Zone).new "#{@root}/zones"
|
||||
@zones_by_domain = @zones.new_index "domain", &.domain
|
||||
|
||||
Baguette::Log.info "storage initialized"
|
||||
end
|
||||
|
||||
def get_user_data(uid : Int32)
|
||||
user_data_by_uid.get uid.to_s
|
||||
rescue e : DODB::MissingEntry
|
||||
entry = UserData.new uid
|
||||
entry
|
||||
end
|
||||
|
||||
def get_user_data(user : ::AuthD::User::Public)
|
||||
get_user_data user.uid
|
||||
end
|
||||
|
||||
def update_user_data(user_data : UserData)
|
||||
user_data_by_uid.update_or_create user_data.uid.to_s, user_data
|
||||
end
|
||||
|
||||
def new_domain(user_id : Int32, zone : Zone)
|
||||
user_data = user_data_by_uid.get? user_id.to_s
|
||||
if user_data
|
||||
# store the new zone
|
||||
@zones << zone
|
||||
|
||||
# update user data only after ensuring this zone isn't already existing
|
||||
user_data.domains << zone.domain
|
||||
update_user_data user_data
|
||||
else
|
||||
Baguette::Log.error "trying to add zone #{zone.domain} to unknown user #{user_id}"
|
||||
end
|
||||
rescue e
|
||||
Baguette::Log.error "trying to add zone #{zone.domain} #{e}"
|
||||
end
|
||||
end
|
||||
|
||||
require "./storage/*"
|
||||
|
15
src/storage/user_data.cr
Normal file
15
src/storage/user_data.cr
Normal file
@ -0,0 +1,15 @@
|
||||
require "json"
|
||||
require "uuid"
|
||||
require "uuid/json"
|
||||
|
||||
class DNSManager::Storage::UserData
|
||||
include JSON::Serializable
|
||||
|
||||
property uid : Int32
|
||||
|
||||
# Users may have many domains, and a domain can have many owners.
|
||||
property domains = [] of String
|
||||
|
||||
def initialize(@uid)
|
||||
end
|
||||
end
|
91
src/storage/zone.cr
Normal file
91
src/storage/zone.cr
Normal file
@ -0,0 +1,91 @@
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
# Store a Resource Record: A, AAAA, TXT, PTR, CNAME…
|
||||
abstract class ResourceRecord
|
||||
include JSON::Serializable
|
||||
|
||||
use_json_discriminator "type", {
|
||||
a: A,
|
||||
aaaa: AAAA,
|
||||
soa: SOA,
|
||||
txt: TXT,
|
||||
ptr: PTR,
|
||||
ns: NS,
|
||||
cname: CNAME,
|
||||
mx: MX,
|
||||
srv: SRV
|
||||
}
|
||||
|
||||
# Used to discriminate between classes.
|
||||
property type : String = ""
|
||||
|
||||
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)
|
||||
@type = self.name.downcase.gsub /dnsmanager::storage::zone::/, ""
|
||||
end
|
||||
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)
|
||||
@type = "soa"
|
||||
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)
|
||||
@type = "mx"
|
||||
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)
|
||||
@type = "srv"
|
||||
end
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
io << "TEST"
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user