Client: first draft.
This commit is contained in:
parent
ce74c1c2c1
commit
c1ef4f6235
@ -21,5 +21,7 @@ dependencies:
|
||||
targets:
|
||||
dnsmanager:
|
||||
main: src/main.cr
|
||||
dnsmanager-client:
|
||||
main: src/client/main.cr
|
||||
|
||||
license: MIT
|
||||
|
142
src/client/main.cr
Normal file
142
src/client/main.cr
Normal file
@ -0,0 +1,142 @@
|
||||
require "authd"
|
||||
require "ipc"
|
||||
require "../network.cr"
|
||||
require "../storage.cr"
|
||||
require "yaml"
|
||||
|
||||
require "baguette-crystal-base"
|
||||
|
||||
require "../config"
|
||||
|
||||
require "./lib/*"
|
||||
|
||||
class Context
|
||||
class_property command = "not-implemented"
|
||||
class_property args : Array(String)? = nil
|
||||
end
|
||||
|
||||
require "./parser.cr"
|
||||
|
||||
#def read_searches
|
||||
# Array(DNSManager::Request::BLAH).from_json_files Context.args.not_nil!
|
||||
#end
|
||||
|
||||
class Actions
|
||||
property the_call = {} of String => Proc(Nil)
|
||||
property dnsmanagerd : DNSManager::Client
|
||||
property authd : AuthD::Client
|
||||
property authd_config : Baguette::Configuration::Auth
|
||||
property config : Baguette::Configuration::DNSManager
|
||||
|
||||
def initialize(@dnsmanagerd, @authd, @authd_config, @config)
|
||||
#
|
||||
# Admin section.
|
||||
#
|
||||
|
||||
# Maintainance
|
||||
@the_call["admin-maintainance"] = ->admin_maintainance
|
||||
end
|
||||
|
||||
def admin_maintainance
|
||||
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
|
||||
|
||||
key = @authd_config.shared_key
|
||||
|
||||
if past_is_verbosity
|
||||
sub = DNSManager::Request::Maintainance::Subject::Verbosity
|
||||
value = subject.to_i
|
||||
pp! sub, value
|
||||
pp! @dnsmanagerd.admin_maintainance key, sub, value
|
||||
else
|
||||
sub = DNSManager::Request::Maintainance::Subject.parse(subject)
|
||||
pp! sub
|
||||
pp! @dnsmanagerd.admin_maintainance key, sub
|
||||
end
|
||||
rescue e
|
||||
puts "error for admin_maintainance #{subject}: #{e.message}"
|
||||
end
|
||||
end
|
||||
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."
|
||||
Baguette::Configuration::Auth.new
|
||||
else
|
||||
# Configuration file is for dnsmanagerd.
|
||||
Baguette::Configuration::Auth.get || Baguette::Configuration::Auth.new
|
||||
end
|
||||
if key_file = authd_config.shared_key_file
|
||||
authd_config.shared_key = File.read(key_file).chomp
|
||||
end
|
||||
|
||||
# Authd configuration.
|
||||
config = if no_configuration
|
||||
Baguette::Log.info "do not load a configuration file."
|
||||
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
|
||||
|
||||
# dnsmanagerd connection and authentication
|
||||
dnsmanagerd = DNSManager::Client.new
|
||||
|
||||
if simulation
|
||||
pp! authd_config
|
||||
pp! Context.command
|
||||
pp! Context.args
|
||||
exit 0
|
||||
end
|
||||
|
||||
# Authd authentication, get the token and quit right away.
|
||||
# If login == pass == "undef": do not even try.
|
||||
if authd_config.login.nil? || authd_config.pass.nil?
|
||||
Baguette::Log.info "no authd login"
|
||||
else
|
||||
login = authd_config.login.not_nil!
|
||||
pass = authd_config.pass.not_nil!
|
||||
token = authd_get_token login: login, pass: pass
|
||||
dnsmanagerd.login token
|
||||
end
|
||||
|
||||
authd = AuthD::Client.new
|
||||
actions = Actions.new dnsmanagerd, authd, authd_config, 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)."
|
||||
end
|
||||
|
||||
# dnsmanagerd disconnection
|
||||
dnsmanagerd.close
|
||||
authd.close
|
||||
rescue e
|
||||
Baguette::Log.info "Exception: #{e}"
|
||||
end
|
||||
|
||||
# Command line:
|
||||
# tool [options] command subcommand [options-for-subcommand] [YAML-or-JSON-files]
|
||||
|
||||
main
|
115
src/client/parser.cr
Normal file
115
src/client/parser.cr
Normal file
@ -0,0 +1,115 @@
|
||||
require "option_parser"
|
||||
|
||||
|
||||
class OptionParser
|
||||
def to_s(io : IO)
|
||||
if banner = @banner
|
||||
io << banner
|
||||
io << "\n\n"
|
||||
end
|
||||
@flags.join io, "\n"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def parsing_cli(authd_config : Baguette::Configuration::Auth)
|
||||
|
||||
opt_authd_admin = -> (parser : OptionParser, authd_config : Baguette::Configuration::Auth) {
|
||||
parser.on "-k file", "--key-file file", "Read the authd shared key from a file." do |file|
|
||||
authd_config.shared_key = File.read(file).chomp
|
||||
Baguette::Log.info "Key for admin operations: #{authd_config.shared_key}."
|
||||
end
|
||||
}
|
||||
|
||||
# frequently used functions
|
||||
opt_authd_login = -> (parser : OptionParser, authd_config : Baguette::Configuration::Auth) {
|
||||
parser.on "-l LOGIN", "--login LOGIN", "Authd user login." do |login|
|
||||
authd_config.login = login
|
||||
Baguette::Log.info "User login for authd: #{authd_config.login}."
|
||||
end
|
||||
parser.on "-p PASSWORD", "--password PASSWORD", "Authd user password." do |password|
|
||||
authd_config.pass = password
|
||||
Baguette::Log.info "User password for authd: #{authd_config.pass}."
|
||||
end
|
||||
}
|
||||
|
||||
opt_help = -> (parser : OptionParser) {
|
||||
parser.on "-h", "--help", "Prints command usage." do
|
||||
puts "usage: #{PROGRAM_NAME} command -h"
|
||||
puts
|
||||
puts parser
|
||||
|
||||
case Context.command
|
||||
when /admin-maintainance/
|
||||
Baguette::Log.warning "should provide subjects to request"
|
||||
Baguette::Log.warning "as in:"
|
||||
DNSManager::Request::Maintainance::Subject.names.each do |n|
|
||||
Baguette::Log.warning "- #{n}"
|
||||
end
|
||||
end
|
||||
|
||||
exit 0
|
||||
end
|
||||
}
|
||||
|
||||
# Unrecognized parameters are used to create commands with multiple arguments.
|
||||
# Example: user add _login email phone_
|
||||
# Here, login, email and phone are unrecognized arguments.
|
||||
# Still, the "user add" command expect them.
|
||||
unrecognized_args_to_context_args = -> (parser : OptionParser,
|
||||
nexact : Int32?,
|
||||
at_least : Int32?) {
|
||||
|
||||
# With the right args, these will be interpreted as serialized data.
|
||||
parser.unknown_args do |args|
|
||||
|
||||
# either we test with the exact expected number of arguments or the least.
|
||||
if exact = nexact
|
||||
if args.size != exact
|
||||
Baguette::Log.error "#{parser}"
|
||||
exit 1
|
||||
end
|
||||
elsif least = at_least
|
||||
if args.size < least
|
||||
Baguette::Log.error "#{parser}"
|
||||
exit 1
|
||||
end
|
||||
else
|
||||
Baguette::Log.error "Number of parameters not even provided!"
|
||||
Baguette::Log.error "#{parser}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
args.each do |arg|
|
||||
Baguette::Log.debug "Unrecognized argument: #{arg} (adding to Context.args)"
|
||||
if Context.args.nil?
|
||||
Context.args = Array(String).new
|
||||
end
|
||||
Context.args.not_nil! << arg
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
parser = OptionParser.new do |parser|
|
||||
parser.banner = "Welcome on the DNSManager CLI administration."
|
||||
|
||||
# Admin section.
|
||||
parser.on "admin", "Admin operations." do
|
||||
# All admin operations require the shared key.
|
||||
opt_authd_admin.call parser, authd_config
|
||||
|
||||
# Maintenance.
|
||||
parser.on("maintainance", "Maintainance operation of the website.") do
|
||||
Baguette::Log.info "Maintainance operation of the website."
|
||||
Context.command = "admin-maintainance"
|
||||
parser.banner = "COMMAND: admin maintainance subject [value]"
|
||||
unrecognized_args_to_context_args.call parser, nil, 1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
opt_help.call parser
|
||||
end
|
||||
|
||||
parser.parse
|
||||
end
|
11
src/config.cr
Normal file
11
src/config.cr
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
class Baguette::Configuration
|
||||
class DNSManager < IPC
|
||||
property service_name : String = "dnsmanager"
|
||||
property recreate_indexes : Bool = false
|
||||
property storage_directory : String = "storage"
|
||||
|
||||
def initialize
|
||||
end
|
||||
end
|
||||
end
|
11
src/main.cr
11
src/main.cr
@ -6,16 +6,7 @@ require "ipc/json"
|
||||
require "authd"
|
||||
require "baguette-crystal-base"
|
||||
|
||||
class Baguette::Configuration
|
||||
class DNSManager < IPC
|
||||
property service_name : String = "dnsmanager"
|
||||
property recreate_indexes : Bool = false
|
||||
property storage_directory : String = "storage"
|
||||
|
||||
def initialize
|
||||
end
|
||||
end
|
||||
end
|
||||
require "./config"
|
||||
|
||||
module DNSManager
|
||||
class Exception < ::Exception
|
||||
|
Loading…
Reference in New Issue
Block a user