This allows the server to take appropriate action based on client version. It we add new features that require an updated client version, we can check the client's version, and give them a give the clients a nice error message instructing them to upgrade. This required a minor change to Rodish to execute code after option parsing and before subcommand processing, even if there are no valid subcommands provided. I made that change and released a new version, so this bumps the rodish version. The cli version is stored in cli/version.txt. bin/ubi reads this file when run. In the rake ubi/ubi-cross tasks, the Rakefile reads this file and sets the version in the compiled go file.
122 lines
3.0 KiB
Ruby
Executable File
122 lines
3.0 KiB
Ruby
Executable File
#!/usr/bin/env ruby
|
|
# frozen_string_literal: true
|
|
|
|
begin
|
|
require_relative "../.env"
|
|
rescue LoadError
|
|
end
|
|
|
|
require "net/http"
|
|
require "json"
|
|
|
|
unless (token = ENV["UBI_TOKEN"])
|
|
warn "! Personal access token must be provided in UBI_TOKEN env variable for use"
|
|
exit 1
|
|
end
|
|
|
|
url = ENV["UBI_URL"] || "https://api.ubicloud.com/cli"
|
|
allowed_progs = %w[ssh scp sftp psql pg_dump pg_dumpall]
|
|
|
|
get_prog = lambda do |prog|
|
|
return unless allowed_progs.include?(prog)
|
|
ENV["UBI_#{prog.upcase}"] || prog
|
|
end
|
|
|
|
uri = URI(url)
|
|
argv = ARGV
|
|
headers = {
|
|
"authorization" => "Bearer: #{token}",
|
|
"x-ubi-version" => File.read(File.expand_path("../../cli/version.txt", __FILE__)).chomp,
|
|
"content-type" => "application/json",
|
|
"accept" => "text/plain",
|
|
"connection" => "close"
|
|
}
|
|
confirmation_prompt = false
|
|
confirmation = nil
|
|
|
|
1.times do
|
|
if ENV["UBI_DEBUG"] == "1"
|
|
p [:sending, *argv]
|
|
end
|
|
response = Net::HTTP.post(uri, {"argv" => argv}.to_json, headers)
|
|
|
|
case response.code.to_i
|
|
when 200...300
|
|
if (prog_type = response["ubi-command-execute"])
|
|
unless ARGV.include?(prog_type)
|
|
warn "! Invalid server response, not executing program not in original argv"
|
|
exit 1
|
|
end
|
|
|
|
unless (prog = get_prog[prog_type])
|
|
warn "! Invalid server response, unsupported program requested"
|
|
exit 1
|
|
end
|
|
|
|
argv_set = ARGV.to_set
|
|
|
|
args = response.body.split("\0")
|
|
invalid_message = nil
|
|
sep_seen = false
|
|
custom_arg_seen = false
|
|
pg_dumpall = false
|
|
|
|
args.each do |arg|
|
|
if arg == "--"
|
|
sep_seen = true
|
|
elsif !argv_set.include?(arg)
|
|
if custom_arg_seen
|
|
invalid_message = "! Invalid server response, multiple arguments not in submitted argv"
|
|
break
|
|
elsif sep_seen
|
|
custom_arg_seen = true
|
|
elsif prog_type == "pg_dumpall" && arg.start_with?("-d")
|
|
pg_dumpall = true
|
|
custom_arg_seen = true
|
|
else
|
|
invalid_message = "! Invalid server response, argument before '--' not in submitted argv"
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
unless sep_seen || pg_dumpall
|
|
invalid_message ||= "! Invalid server response, no '--' in returned argv"
|
|
end
|
|
|
|
if invalid_message
|
|
if ENV["UBI_DEBUG"] == "1"
|
|
p [:failure, prog, *args]
|
|
end
|
|
warn invalid_message
|
|
exit 1
|
|
else
|
|
if ENV["UBI_DEBUG"] == "1"
|
|
p [:exec, prog, *args]
|
|
end
|
|
Process.exec(prog, *args)
|
|
end
|
|
else
|
|
if (confirmation_prompt = response["ubi-confirm"])
|
|
if confirmation
|
|
warn "! Invalid server response, repeated confirmation attempt"
|
|
exit 1
|
|
else
|
|
$stdout.print response.body
|
|
$stdout.print "\n#{confirmation_prompt}: "
|
|
confirmation = $stdin.readline.chomp
|
|
argv.unshift(confirmation)
|
|
argv.unshift("--confirm")
|
|
redo
|
|
end
|
|
else
|
|
$stdout.print response.body
|
|
end
|
|
exit 0
|
|
end
|
|
else
|
|
warn response.body
|
|
exit 1
|
|
end
|
|
end
|