142 lines
3.3 KiB
Crystal
142 lines
3.3 KiB
Crystal
require "yaml"
|
|
require "option_parser"
|
|
require "colorize"
|
|
# require "xdg_basedir"
|
|
# require "completion"
|
|
require "log"
|
|
|
|
require "../lib/actions"
|
|
require "../lib/types"
|
|
require "../lib/models"
|
|
require "../lib/version"
|
|
|
|
|
|
module Arkisto
|
|
class CtlCli
|
|
property config : ConfigModel?
|
|
property options : GlobalOptions?
|
|
|
|
def initialize
|
|
# @config = nil
|
|
@options = nil
|
|
end
|
|
|
|
def self.parse_options(args) : GlobalOptions
|
|
# default values
|
|
action = NoneAction
|
|
config_file = "arkisto.yml"
|
|
verbose = true
|
|
dry_run = false
|
|
|
|
# parse
|
|
OptionParser.parse(args) do |parser|
|
|
parser.banner = "Usage: #{Version::PROGRAM_ARKISTOCTL} [options] [commands] [arguments]"
|
|
|
|
parser.separator
|
|
parser.separator "Options"
|
|
|
|
parser.on "-c CONFIG_FILE", "--config=CONFIG_FILE", "Use the following config file" do |file|
|
|
config_file = file
|
|
end
|
|
|
|
parser.on "-v", "--verbose", "Be verbose" do
|
|
verbose = !verbose
|
|
end
|
|
|
|
parser.on "--dry-run", "Dry run (no real openstack command is executed" do
|
|
dry_run = true
|
|
end
|
|
|
|
parser.on "--version", "Show version" do
|
|
puts "version #{Version::VERSION}"
|
|
exit 0
|
|
end
|
|
|
|
parser.on "-h", "--help", "Show this help" do
|
|
puts parser
|
|
exit 0
|
|
end
|
|
|
|
parser.on "--completion", "Provide autocompletion for bash" do
|
|
# nothing here
|
|
end
|
|
|
|
parser.on "plan", "Display backup plan" do
|
|
action = PlanAction
|
|
end
|
|
|
|
parser.on "apply", "Apply backup plan" do
|
|
action = ApplyAction
|
|
end
|
|
|
|
parser.separator
|
|
|
|
parser.missing_option do |flag|
|
|
STDERR.puts parser
|
|
STDERR.puts "ERROR: #{flag} requires an argument.".colorize(:red)
|
|
exit(1)
|
|
end
|
|
|
|
parser.invalid_option do |flag|
|
|
STDERR.puts parser
|
|
STDERR.puts "ERROR: #{flag} is not a valid option.".colorize(:red)
|
|
exit(1)
|
|
end
|
|
|
|
# complete_with Version::PROGRAM_ARKISTOCTL, parser
|
|
end
|
|
|
|
return {
|
|
action: action,
|
|
config_file: config_file,
|
|
dry_run: dry_run,
|
|
verbose: verbose,
|
|
}.as(GlobalOptions)
|
|
end
|
|
|
|
def self.parse_config(options)
|
|
config_file = options[:config_file]
|
|
puts "Loading configuration... #{config_file}".colorize(:yellow) if options[:verbose]
|
|
|
|
if ! File.exists? config_file
|
|
STDERR.puts "ERROR: Unable to read configuration file '#{config_file}'".colorize(:red)
|
|
exit 1
|
|
end
|
|
|
|
yaml_str = File.read(config_file)
|
|
config = ConfigModel.from_yaml(yaml_str)
|
|
|
|
if config.nil?
|
|
STDERR.puts "ERROR: Invalid YAML content in '#{config_file}'"
|
|
exit 1
|
|
end
|
|
|
|
return config
|
|
end
|
|
|
|
def self.run(args)
|
|
app = CtlCli.new
|
|
options = CtlCli.parse_options(args)
|
|
config = CtlCli.parse_config(options)
|
|
app.options = options
|
|
app.config = config
|
|
|
|
action = ActionFactory.build(
|
|
options[:action],
|
|
config,
|
|
{
|
|
dry_run: options[:dry_run],
|
|
verbose: options[:verbose]
|
|
}
|
|
)
|
|
action.perform
|
|
|
|
rescue ex : YAML::ParseException
|
|
STDERR.puts "ERROR: #{ex.message}".colorize(:red)
|
|
end
|
|
end
|
|
end
|
|
|
|
Arkisto::CtlCli.run(ARGV)
|
|
|