blob: 46bc3d5113ade212ba7b02efc152ee2a6b91b15c [file] [log] [blame]
#!/usr/bin/env ruby
require 'optparse'
require 'open3'
require 'inifile'
require 'io/console'
require 'pty'
require 'httpx'
require 'json'
require 'bcrypt'
module ResCli
class AuthService
def self.backend_login(username, password)
url = 'https://server.resilientdb.com/getUser'
encrypted_password = BCrypt::Password.create(password)
payload = { email: username, password: password }
response = HTTPX.post(url, json: payload)
case response.status
when 200
body = response.to_s
json_response = JSON.parse(body)
if json_response['success'] == true
return true
else
return false
end
when 500
return false # Server error
else
return false # Other HTTP errors
end
rescue HTTPX::Error => e
false
end
def self.login
print "Enter your username: "
username = gets.chomp
print "Enter your password: "
password = STDIN.noecho(&:gets).chomp
puts
if backend_login(username, password)
ResCli::CLI.set_logged_in_user(username)
puts "Login successful. Welcome, #{username}!"
else
puts "Login failed. Invalid username or password."
end
end
def self.logout
ResCli::CLI.set_logged_in_user(nil)
puts "Logout successful. Goodbye!"
end
def self.backend_sign_up(email, password)
url = 'https://server.resilientdb.com/setUser'
encrypted_password = BCrypt::Password.create(password)
payload = { email: email, password: encrypted_password }
response = HTTPX.post(url, json: payload)
if response.status == 200
return { success: true, message: "Sign up successful. Welcome, #{email}!" }
elsif response.status == 409
return { success: false, message: "Sign up failed. User with email #{email} already exists." }
else
return { success: false, message: "Sign up failed. Error registering user with email #{email}." }
end
rescue HTTPX::Error => e
{ success: false, message: "Sign up failed. #{e.message}" }
end
def self.sign_up
print "Enter your email: "
email = gets.chomp
print "Enter your password: "
password = STDIN.noecho(&:gets).chomp
puts
result = backend_sign_up(email, password)
if result[:success]
ResCli::CLI.set_logged_in_user(email)
puts result[:message]
else
puts result[:message]
end
end
# def self.github_login
# print "Enter your GitHub username: "
# github_username = gets.chomp
# print "Enter your GitHub token (you can use a personal access token): "
# github_token = STDIN.noecho(&:gets).chomp
# puts
# if github_authentication(github_username, github_token)
# ResCli::CLI.set_logged_in_user(github_username)
# puts "GitHub login successful. Welcome, #{github_username}!"
# else
# puts "GitHub login failed. Invalid username or token."
# end
# end
private
# def self.github_authentication(username, token)
# return !username.empty? && !token.empty?
# end
end
class CLI
CONFIG_FILE_PATH = 'config.ini'
@@config = IniFile.load(CONFIG_FILE_PATH)
def self.start
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
opts.on('-c', '--create TYPE', [:resdb, :sdk], 'Create a new ResDB or PythonSDK instance') do |type|
create_instance(type)
end
opts.on('-e', '--exec-into INSTANCE_ID', 'Bash into a running ResDB or PythonSDK instance') do |instance_id|
exec_into(instance_id)
end
opts.on('-v', '--view-instances', 'View details about running instances') do
view_instances
end
opts.on('-d', '--delete INSTANCE_ID', 'Delete a running ResDB or PythonSDK instance') do |instance_id|
delete_instance(instance_id)
end
opts.on('-t', '--test-api', 'Test API') do
testAPI
end
opts.on('-h', '--help', 'Display this help message') do
help
exit
end
opts.on('--login', 'Login with username and password') do
AuthService.login
end
opts.on('--sign-up', 'Sign up with email and password') do
AuthService.sign_up
end
# opts.on('-gl', '--github-login', 'Login with GitHub') do
# AuthService.github_login
# end
opts.on('--whoami', 'Display the current logged-in user') do
CLI.whoami
end
opts.on('--logout', 'Logout') do
AuthService.logout
end
end.parse!
end
def self.get_logged_in_user
@@config['User']['Current_User'].split('@').first
end
def self.whoami
logged_in_user = get_logged_in_user
puts "Current logged-in user: #{logged_in_user}"
end
def self.set_logged_in_user(username)
@@config['User']['Current_User'] = username
@@config.write
end
def self.create_instance(type)
begin
# Implement create instance logic
puts "Creating #{type} instance..."
# Run Docker command to create a new instance
loggedin_user = get_logged_in_user
container_name = "#{loggedin_user}-#{type}_instance"
command = ["docker", "run", "--name", container_name, "-d", "expolab/#{type}:arm64"]
output, status = Open3.capture2(*command)
unless status.success?
raise "Error creating instance: #{output}"
end
puts "#{type} instance created successfully with container name: #{container_name}"
rescue => error
$stderr.puts "Error creating instance: #{error}"
end
end
def self.exec_into(instance_id)
begin
command = ["docker", "exec", "-it", instance_id, "bash"]
pid = Process.spawn(*command, in: STDIN, out: STDOUT, err: STDERR, unsetenv_others: true)
Process.wait(pid)
rescue => error
$stderr.puts "Error executing command: #{error}"
end
end
def self.view_instances
begin
docker_command = ["docker", "container", "ls", "--format", "table {{.ID}}\t{{.Image}}\t{{.Names}}"]
output, status = Open3.capture2(*docker_command)
unless status.success?
raise "Error running docker command: #{output}"
end
puts output
rescue => error
$stderr.puts "An unexpected error occurred: #{error}"
end
end
def self.delete_instance(instance_id)
begin
# Implement delete instance logic
puts "Deleting instance #{instance_id}..."
# Stop the Docker container
_, stop_status = Open3.capture2("docker stop #{instance_id}")
unless stop_status.success?
raise "Error stopping instance: #{stop_status}"
end
# Remove the Docker container
_, rm_status = Open3.capture2("docker rm #{instance_id}")
unless rm_status.success?
raise "Error removing instance: #{rm_status}"
end
puts "Instance deleted successfully."
rescue => error
$stderr.puts "Error deleting instance: #{error}"
end
end
def self.testAPI()
begin
puts "Testing API..."
response = HTTPX.get("https://server.resilientdb.com/test")
if response.status == 200
puts response.body
else
puts "Error: #{response.status}"
end
rescue HTTPX::Error => e
puts "HTTPX Error: #{e.message}"
rescue StandardError => e
puts "Error: #{e.message}"
end
end
def self.help
puts "Usage: #{$PROGRAM_NAME} [options]"
puts "\nOptions:"
puts " -li, --login Login with username and password"
puts " -su, --sign-up Sign up with email and password"
# puts " -gl, --github-login Login with GitHub"
puts " -lo, --logout Logout"
puts " -c, --create TYPE Create a new ResDB or PythonSDK instance"
puts " -e, --exec-into INSTANCE_ID Bash into a running ResDB or PythonSDK instance"
puts " -v, --view-instances View details about running instances"
puts " -d, --delete INSTANCE_ID Delete a running ResDB or PythonSDK instance"
puts " -w, --whoami Display the current logged-in user"
puts " -h, --help Display this help message"
end
end
end
# Entry point
ResCli::CLI.start