dnsmanager/src/client/main.cr

281 lines
6.7 KiB
Crystal

require "authd"
require "ipc"
require "../network.cr"
require "../storage.cr"
require "yaml"
require "baguette-crystal-base"
require "../config"
require "./lib/*"
require "../lib"
class Context
class_property command = "not-implemented"
class_property args : Array(String)? = nil
end
require "./parser.cr"
def read_zones
Array(DNSManager::Storage::Zone).from_json_files Context.args.not_nil!
end
class Actions
property the_call = {} of String => Proc(Nil)
property dnsmanagerd : DNSManager::Client
property config : Baguette::Configuration::DNSManager
def initialize(@dnsmanagerd, @config)
#
# Admin section.
#
# Maintenance.
@the_call["admin-maintenance"] = ->admin_maintenance
@the_call["admin-generate-zonefile"] = ->admin_generate_zonefile
@the_call["admin-generate-all-zonefiles"] = ->admin_generate_all_zonefiles
# Domain operations.
@the_call["user-domain-add"] = ->user_domain_add
@the_call["user-domain-del"] = ->user_domain_del
@the_call["user-domain-list"] = ->user_domain_list
# Zone operations.
@the_call["user-zone-add"] = ->user_zone_add
@the_call["user-zone-get"] = ->user_zone_get
# Zone RR operations.
@the_call["user-rr-add-a"] = ->user_rr_add_a
@the_call["user-rr-update-a"] = ->user_rr_update_a
@the_call["user-rr-del"] = ->user_rr_del
end
def admin_maintenance
subjects = Context.args.not_nil!
past_is_verbosity = false
subjects.each do |subject|
begin
case subject
when /verbosity/i
Baguette::Log.info "changing verbosity"
past_is_verbosity = true
next
end
if past_is_verbosity
sub = DNSManager::Request::Maintenance::Subject::Verbosity
int = subject.to_i
@dnsmanagerd.admin_maintenance sub, int
else
sub = DNSManager::Request::Maintenance::Subject.parse(subject)
pp! sub
pp! @dnsmanagerd.admin_maintenance sub
end
rescue e
puts "error for admin_maintenance #{subject}: #{e.message}"
end
end
end
def admin_generate_zonefile
domains = Context.args.not_nil!
domains.each do |domain|
begin
pp! domain
pp! @dnsmanagerd.generate_zonefile domain
rescue e
puts "error for generate_zonefile: #{e.message}"
end
end
end
def admin_generate_all_zonefiles
pp! @dnsmanagerd.generate_all_zonefiles
rescue e
puts "error for generate_all_zonefiles: #{e.message}"
end
def user_domain_add
domains = Context.args.not_nil!
domains.each do |domain|
begin
pp! domain
pp! @dnsmanagerd.user_domain_add domain
rescue e
puts "error for user_domain_add: #{e.message}"
end
end
end
def user_domain_del
domains = Context.args.not_nil!
domains.each do |domain|
begin
pp! domain
pp! @dnsmanagerd.user_domain_del domain
rescue e
puts "error for user_domain_del: #{e.message}"
end
end
end
def user_zone_add
zones = read_zones
zones.each do |zone|
begin
pp! zone
pp! @dnsmanagerd.user_zone_add zone
rescue e
puts "error for user_zone_add: #{e.message}"
end
end
end
def user_zone_get
domains = Context.args.not_nil!
domains.each do |domain|
begin
pp! domain
response = @dnsmanagerd.user_zone_get domain
case response
when DNSManager::Response::Zone
pp! response.zone
puts response.zone
else
puts "Didn't get the zone"
pp! response
end
rescue e
puts "error for user_zone_get: #{e.message}"
end
end
end
def user_domain_list
response = @dnsmanagerd.user_domain_list
case response
when DNSManager::Response::DomainList
response.domains.each do |domain|
puts "- #{domain}"
end
else
pp! response
end
rescue e
puts "error for user_zone_del: #{e.message}"
end
def user_rr_add_a
domain, name, ttl, target = Context.args.not_nil!
rr = DNSManager::Storage::Zone::A.new name, ttl.to_u32, target
pp! @dnsmanagerd.user_rr_add domain, rr
rescue e
puts "error for user_rr_add_a: #{e.message}"
end
def user_rr_update_a
domain, rrid, name, ttl, target = Context.args.not_nil!
rr = DNSManager::Storage::Zone::A.new name, ttl.to_u32, target
rr.rrid = rrid.to_u32
pp! @dnsmanagerd.user_rr_update domain, rr
rescue e
puts "error for user_rr_update_a: #{e.message}"
end
def user_rr_del
domain, rrid = Context.args.not_nil!
pp! @dnsmanagerd.user_rr_delete domain, rrid.to_u32
rescue e
puts "error for user_rr_del: #{e.message}"
end
end
def main
simulation, no_configuration, configuration_file = Baguette::Configuration.option_parser
# Authd configuration.
authd_config = if no_configuration
Baguette::Log.info "do not load a configuration file (authd)."
Baguette::Configuration::Auth.new
else
# Configuration file is for dnsmanagerd.
Baguette::Configuration::Auth.get || Baguette::Configuration::Auth.new
end
# DNSmanager configuration.
config = if no_configuration
Baguette::Log.info "do not load a configuration file (dnsmanagerd)."
Baguette::Configuration::DNSManager.new
else
# Configuration file is for dnsmanagerd.
Baguette::Configuration::DNSManager.get || Baguette::Configuration::DNSManager.new
end
Baguette::Context.verbosity = config.verbosity
Baguette::Log.info "verbosity: #{config.verbosity}."
parsing_cli authd_config
if simulation
pp! authd_config
pp! Context.command
pp! Context.args
exit 0
end
# dnsmanagerd connection and authentication
dnsmanagerd = DNSManager::Client.new
if authd_config.login.nil? || authd_config.pass.nil?
Baguette::Log.info "no authd login."
else
Baguette::Log.info "authd login..."
login = authd_config.login.not_nil!
pass = authd_config.pass.not_nil!
# Authd authentication, get the token and quit right away.
token = authd_get_token login: login, pass: pass
# Then push the token to the dnsmanager daemon.
logged_message = dnsmanagerd.login token
case logged_message
when DNSManager::Response::Logged
Baguette::Log.info "logged to dnsmanagerd as '#{login}'"
Baguette::Log.debug "from logging message, accepted domains:"
logged_message.accepted_domains.each do |d|
Baguette::Log.debug "- #{d}"
end
Baguette::Log.debug "from logging message, owned domains:"
logged_message.my_domains.each do |d|
Baguette::Log.debug "- #{d}"
end
else
Baguette::Log.info "not logged to dnsmanagerd?"
end
end
actions = Actions.new dnsmanagerd, config
# Now we did read the intent, we should proceed doing what was asked.
begin
actions.the_call[Context.command].call
rescue e
Baguette::Log.info "The command is not recognized (or implemented)."
Baguette::Log.info "Exception: #{e}."
pp! e
end
# dnsmanagerd disconnection
dnsmanagerd.close
rescue e
Baguette::Log.info "Exception: #{e}"
end
# Command line:
# tool [options] command subcommand [options-for-subcommand] [YAML-or-JSON-files]
main