185 lines
4.2 KiB
Crystal
185 lines
4.2 KiB
Crystal
class DNSManager::Client < IPC
|
|
property server_fd : Int32 = -1
|
|
|
|
def initialize
|
|
super()
|
|
fd = self.connect "dnsmanager"
|
|
if fd.nil?
|
|
raise "couldn't connect to 'dnsmanager' IPC service"
|
|
end
|
|
@server_fd = fd
|
|
end
|
|
|
|
#
|
|
# Simple users.
|
|
#
|
|
|
|
def authd_get_token(login : String? = nil, pass : String? = nil)
|
|
authd = AuthD::Client.new
|
|
response = authd.login? login, pass
|
|
case response
|
|
when AuthD::Response::Login
|
|
authd.close
|
|
uid = response.uid
|
|
token = response.token
|
|
Baguette::Log.info "Authenticated as #{login} #{uid}, token: #{token}"
|
|
return token
|
|
end
|
|
authd.close
|
|
raise "Cannot authenticate to authd with login #{login}: #{response}."
|
|
end
|
|
|
|
def login(login : String, pass : String)
|
|
# Authd authentication, get the token and quit right away.
|
|
token = authd_get_token login: login, pass: pass
|
|
login token
|
|
end
|
|
|
|
def login(token : String)
|
|
request = Request::Login.new token
|
|
send_now request
|
|
response = parse_message [ Response::Logged ], read
|
|
raise "cannot connect to dnsmanagerd" unless response.class == Response::Logged
|
|
response
|
|
end
|
|
|
|
#
|
|
# Domain operations
|
|
#
|
|
|
|
# Add a domain.
|
|
def user_domain_add(domain : String)
|
|
request = Request::NewDomain.new domain
|
|
send_now request
|
|
parse_message [ Response::Success ], read
|
|
end
|
|
|
|
# Remove a domain.
|
|
def user_domain_del(domain : String)
|
|
request = Request::DeleteDomain.new domain
|
|
send_now request
|
|
parse_message [ Response::Success ], read
|
|
end
|
|
|
|
# Get user domain list.
|
|
def user_domain_list()
|
|
request = Request::UserDomains.new
|
|
send_now request
|
|
parse_message [ Response::DomainList ], read
|
|
end
|
|
|
|
#
|
|
# Zone operations
|
|
#
|
|
|
|
# Add a full zone.
|
|
def user_zone_add(zone : Storage::Zone)
|
|
request = Request::AddOrUpdateZone.new zone
|
|
send_now request
|
|
parse_message [ Response::Success ], read
|
|
end
|
|
|
|
# Get a zone.
|
|
def user_zone_get(domain : String)
|
|
request = Request::GetZone.new domain
|
|
send_now request
|
|
parse_message [ Response::Zone ], read
|
|
end
|
|
|
|
# Get the generated zonefile.
|
|
def user_zonefile(domain : String)
|
|
request = Request::AskGeneratedZoneFile.new domain
|
|
send_now request
|
|
parse_message [ Response::GeneratedZone ], read
|
|
end
|
|
|
|
#
|
|
# Resource Record operations
|
|
#
|
|
|
|
# Add a RR.
|
|
def user_rr_add(domain : String, rr : Storage::Zone::ResourceRecord)
|
|
request = Request::AddRR.new domain, rr
|
|
send_now request
|
|
parse_message [ Response::Success ], read
|
|
end
|
|
|
|
# Update a RR.
|
|
def user_rr_update(domain : String, rr : Storage::Zone::ResourceRecord)
|
|
request = Request::UpdateRR.new domain, rr
|
|
send_now request
|
|
parse_message [ Response::Success ], read
|
|
end
|
|
|
|
# Delete a RR.
|
|
def user_rr_delete(domain : String, rr : UInt32)
|
|
request = Request::DeleteRR.new domain, rr
|
|
send_now request
|
|
parse_message [ Response::Success ], read
|
|
end
|
|
|
|
#
|
|
# Admin stuff
|
|
#
|
|
|
|
def admin_maintenance(subject : Request::Maintenance::Subject,
|
|
int : Int32? = nil,
|
|
string : String? = nil)
|
|
request = Request::Maintenance.new(subject)
|
|
request.int = int if int
|
|
request.string = string if string
|
|
send_now request
|
|
parse_message [ Response::Success ], read
|
|
end
|
|
|
|
def generate_zonefile(domain : String)
|
|
request = Request::GenerateZoneFile.new(domain)
|
|
send_now request
|
|
parse_message [ Response::Success ], read
|
|
end
|
|
|
|
def generate_all_zonefiles
|
|
request = Request::GenerateAllZoneFiles.new
|
|
send_now request
|
|
parse_message [ Response::Success ], read
|
|
end
|
|
|
|
def use_token(token_uuid : String, address : String)
|
|
request = Request::UseToken.new token_uuid, address
|
|
send_now request
|
|
response = parse_message [ Response::Success ], read
|
|
raise "token update failed" unless response.class == Response::Success
|
|
response
|
|
end
|
|
|
|
#
|
|
# Utils
|
|
#
|
|
|
|
def send_now(msg : IPC::JSON)
|
|
m = IPCMessage::TypedMessage.new msg.type.to_u8, msg.to_json
|
|
write @server_fd, m
|
|
end
|
|
|
|
def send_now(type : Request::Type, payload)
|
|
m = IPCMessage::TypedMessage.new type.value.to_u8, payload
|
|
write @server_fd, m
|
|
end
|
|
|
|
def read
|
|
slice = self.read @server_fd
|
|
m = IPCMessage::TypedMessage.deserialize slice
|
|
m.not_nil!
|
|
end
|
|
|
|
# TODO: should raise exception if response not anticipated
|
|
def parse_message(expected_messages, message)
|
|
em = Array(IPC::JSON.class).new
|
|
expected_messages.each do |e|
|
|
em << e
|
|
end
|
|
em << Response::Error
|
|
em.parse_ipc_json message
|
|
end
|
|
end
|