lib/shelly/cli/main.rb in shelly-0.0.43 vs lib/shelly/cli/main.rb in shelly-0.0.44.pre
- old
+ new
@@ -7,27 +7,28 @@
module Shelly
module CLI
class Main < Command
include Thor::Actions
- register(User, "user", "user <command>", "Manages users using this cloud")
- register(Backup, "backup", "backup <command>", "Manages database backups from this cloud")
- register(Deploys, "deploys", "deploys <command>", "View cloud deploy logs")
- register(Config, "config", "config <command>", "Manages cloud configuration files")
+ register(User, "user", "user <command>", "Manage collaborators")
+ register(Backup, "backup", "backup <command>", "Manage database backups")
+ register(Deploys, "deploys", "deploys <command>", "View deploy logs")
+ register(Config, "config", "config <command>", "Manage application configuration files")
check_unknown_options!
- before_hook :logged_in?, :only => [:add, :list, :start, :stop, :logs, :delete]
- before_hook :inside_git_repository?, :only => [:add, :ip]
+ # FIXME: it should be possible to pass single symbol, instead of one element array
+ before_hook :logged_in?, :only => [:add, :list, :start, :stop, :logs, :delete, :ip, :logout]
+ before_hook :inside_git_repository?, :only => [:add]
before_hook :cloudfile_present?, :only => [:logs, :stop, :start, :ip]
map %w(-v --version) => :version
- desc "version", "Displays shelly version"
+ desc "version", "Display shelly version"
def version
say "shelly version #{Shelly::VERSION}"
end
- desc "register [EMAIL]", "Registers new user account on Shelly Cloud"
+ desc "register [EMAIL]", "Register new account"
def register(email = nil)
user = Shelly::User.new
user.ssh_key_registered?
say "Registering with email: #{email}" if email
user.email = (email || ask_for_email)
@@ -36,59 +37,53 @@
if user.ssh_key_exists?
say "Uploading your public SSH key from #{user.ssh_key_path}"
end
say "Successfully registered!"
say "Check you mailbox for email address confirmation"
- rescue Client::APIError => e
- if e.validation?
- e.each_error { |error| say_error "#{error}", :with_exit => false }
- exit 1
- end
- rescue RestClient::Conflict
+ rescue Client::ValidationException => e
+ e.each_error { |error| say_error "#{error}", :with_exit => false }
+ exit 1
+ rescue Client::ConflictException
say_error "User with your ssh key already exists.", :with_exit => false
say_error "You can login using: shelly login [EMAIL]", :with_exit => false
exit 1
rescue Errno::ENOENT => e
say_error e, :with_exit => false
say_error "Use ssh-keygen to generate ssh key pair"
end
- desc "login [EMAIL]", "Logs user in to Shelly Cloud"
+ desc "login [EMAIL]", "Log into Shelly Cloud"
def login(email = nil)
user = Shelly::User.new
raise Errno::ENOENT, user.ssh_key_path unless user.ssh_key_exists?
user.email = email || ask_for_email
user.password = ask_for_password(:with_confirmation => false)
user.login
say "Login successful"
user.upload_ssh_key
say "Uploading your public SSH key"
list
- rescue Client::APIError => e
- if e.validation?
- e.each_error { |error| say_error "#{error}", :with_exit => false }
- end
- if e.unauthorized?
- say_error "Wrong email or password", :with_exit => false
- say_error "You can reset password by using link:", :with_exit => false
- say_error "#{e.url}", :with_exit => false
- end
- exit 1
+ rescue Client::ValidationException => e
+ e.each_error { |error| say_error "#{error}", :with_exit => false }
+ rescue Client::UnauthorizedException => e
+ say_error "Wrong email or password", :with_exit => false
+ say_error "You can reset password by using link:", :with_exit => false
+ say_error "#{e[:url]}"
rescue Errno::ENOENT => e
say_error e, :with_exit => false
say_error "Use ssh-keygen to generate ssh key pair"
end
method_option "code-name", :type => :string, :aliases => "-c",
:desc => "Unique code-name of your cloud"
method_option :databases, :type => :array, :aliases => "-d",
:banner => Shelly::App::DATABASE_KINDS.join(', '),
- :desc => "Array of databases of your choice"
+ :desc => "List of databases of your choice"
method_option :domains, :type => :array,
:banner => "CODE-NAME.shellyapp.com, YOUR-DOMAIN.com",
- :desc => "Array of your domains"
- desc "add", "Adds new cloud to Shelly Cloud"
+ :desc => "List of your domains"
+ desc "add", "Add a new cloud"
def add
check_options(options)
@app = Shelly::App.new
@app.code_name = options["code-name"] || ask_for_code_name
@app.databases = options["databases"] || ask_for_databases
@@ -105,20 +100,18 @@
@app.open_billing_page
info_adding_cloudfile_to_repository
info_deploying_to_shellycloud
- rescue Client::APIError => e
- if e.validation?
- e.each_error { |error| say_error error, :with_exit => false }
- say_new_line
- say_error "Fix erros in the below command and type it again to create your cloud" , :with_exit => false
- say_error "shelly add --code-name=#{@app.code_name} --databases=#{@app.databases.join} --domains=#{@app.code_name}.shellyapp.com"
- end
+ rescue Client::ValidationException => e
+ e.each_error { |error| say_error error, :with_exit => false }
+ say_new_line
+ say_error "Fix erros in the below command and type it again to create your cloud" , :with_exit => false
+ say_error "shelly add --code-name=#{@app.code_name} --databases=#{@app.databases.join} --domains=#{@app.code_name}.shellyapp.com"
end
- desc "list", "Lists all your clouds"
+ desc "list", "List available clouds"
def list
user = Shelly::User.new
apps = user.apps
unless apps.empty?
say "You have following clouds available:", :green
@@ -127,89 +120,76 @@
[app["code_name"], "| #{app["state"].gsub("_", " ")}#{state}"]
end, :ident => 2)
else
say "You have no clouds yet", :green
end
- rescue Client::APIError => e
- if e.unauthorized?
- say_error "You are not logged in, use `shelly login`"
- end
end
+
map "status" => :list
- desc "ip", "Lists clouds IP's"
+ desc "ip", "List cloud's IP addresses"
def ip
- say_error "No Cloudfile found" unless Cloudfile.present?
@cloudfile = Cloudfile.new
@cloudfile.clouds.each do |cloud|
begin
@app = App.new(cloud)
say "Cloud #{cloud}:", :green
print_wrapped "Web server IP: #{@app.web_server_ip}", :ident => 2
print_wrapped "Mail server IP: #{@app.mail_server_ip}", :ident => 2
- rescue Client::APIError => e
- if e.not_found?
- say_error "You have no access to '#{cloud}' cloud defined in Cloudfile", :with_exit => false
- else
- say_error e.message, :with_exit => false
- end
+ rescue Client::NotFoundException => e
+ raise unless e.resource == :cloud
+ say_error "You have no access to '#{cloud}' cloud defined in Cloudfile", :with_exit => false
end
end
end
- desc "start", "Starts the cloud"
- method_option :cloud, :type => :string, :aliases => "-c",
- :desc => "Specify which cloud to start"
+ desc "start", "Start the cloud"
+ method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
def start
- multiple_clouds(options[:cloud], "start", "Select cloud to start using:")
+ multiple_clouds(options[:cloud], "start")
@app.start
- say "Starting cloud #{@app.code_name}. Check status with:", :green
+ say "Starting cloud #{@app}. Check status with:", :green
say " shelly list"
- rescue RestClient::Conflict => e
- response = JSON.parse(e.response)
- case response['state']
+ rescue Client::ConflictException => e
+ case e[:state]
when "running"
- say_error "Not starting: cloud '#{@app.code_name}' is already running"
+ say_error "Not starting: cloud '#{@app}' is already running"
when "deploying", "configuring"
- say_error "Not starting: cloud '#{@app.code_name}' is currently deploying"
+ say_error "Not starting: cloud '#{@app}' is currently deploying"
when "no_code"
say_error "Not starting: no source code provided", :with_exit => false
say_error "Push source code using:", :with_exit => false
say " git push production master"
when "deploy_failed", "configuration_failed"
say_error "Not starting: deployment failed", :with_exit => false
say_error "Support has been notified", :with_exit => false
- say_error "See #{response['link']} for reasons of failure"
+ say_error "Check `shelly deploys show last --cloud #{@app}` for reasons of failure"
when "no_billing"
say_error "Please fill in billing details to start foo-production. Opening browser.", :with_exit => false
@app.open_billing_page
end
exit 1
- rescue Client::APIError => e
- if e.not_found?
- say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
- end
+ rescue Client::NotFoundException => e
+ raise unless e.resource == :cloud
+ say_error "You have no access to '#{@app}' cloud defined in Cloudfile"
end
- desc "stop", "Stops the cloud"
- method_option :cloud, :type => :string, :aliases => "-c",
- :desc => "Specify which cloud to stop"
+ desc "stop", "Stop the cloud"
+ method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
def stop
- multiple_clouds(options[:cloud], "stop", "Select cloud to stop using:")
+ multiple_clouds(options[:cloud], "stop")
@app.stop
say "Cloud '#{@app.code_name}' stopped"
- rescue Client::APIError => e
- if e.not_found?
- say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
- end
+ rescue Client::NotFoundException => e
+ raise unless e.resource == :cloud
+ say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
end
- desc "delete", "Delete cloud from Shelly Cloud"
- method_option :cloud, :type => :string, :aliases => "-c",
- :desc => "Specify which cloud to delete"
+ desc "delete", "Delete the cloud"
+ method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
def delete
- multiple_clouds(options[:cloud], "delete", "Select cloud to delete using:")
+ multiple_clouds(options[:cloud], "delete")
say "You are about to delete application: #{@app.code_name}."
say "Press Control-C at any moment to cancel."
say "Please confirm each question by typing yes and pressing Enter."
say_new_line
ask_to_delete_files
@@ -222,43 +202,70 @@
@app.remove_git_remote
say "Removing git remote - done"
else
say "Missing git remote"
end
- rescue Client::APIError => e
- if e.not_found?
- say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
- end
+ rescue Client::NotFoundException => e
+ raise unless e.resource == :cloud
+ say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
end
- desc "logs", "Show latest application logs from each instance"
- method_option :cloud, :type => :string, :aliases => "-c",
- :desc => "Specify which cloud to show logs for"
+ desc "logs", "Show latest application logs"
+ method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
def logs
cloud = options[:cloud]
- multiple_clouds(cloud, "logs", "Select which to show logs for using:")
+ multiple_clouds(cloud, "logs")
begin
logs = @app.application_logs
say "Cloud #{@app.code_name}:", :green
logs.each_with_index do |log, i|
say "Instance #{i+1}:", :green
say log
end
- rescue Client::APIError => e
- if e.not_found?
- say_error "You have no access to cloud '#{cloud || @app.code_name}'"
- end
+ rescue Client::NotFoundException => e
+ raise unless e.resource == :cloud
+ say_error "You have no access to '#{cloud || @app.code_name}' cloud defined in Cloudfile"
end
end
+ desc "logout", "Logout from Shelly Cloud"
+ def logout
+ user = Shelly::User.new
+ say "Your public SSH key has been removed from Shelly Cloud" if user.delete_ssh_key
+ say "You have been successfully logged out" if user.delete_credentials
+ end
+
+ desc "redeploy", "Redeploy application"
+ method_option :cloud, :type => :string, :aliases => "-c",
+ :desc => "Specify which cloud to redeploy application for"
+ def redeploy
+ multiple_clouds(options[:cloud], "redeploy")
+ @app.redeploy
+ say "Redeploying your application for cloud '#{@app}'", :green
+ rescue Client::ConflictException => e
+ case e[:state]
+ when "deploying", "configuring"
+ say_error "Your application is being redeployed at the moment"
+ when "no_code", "no_billing", "turned_off"
+ say_error "Cloud #{@app} is not running", :with_exit => false
+ say "Start your cloud with `shelly start --cloud #{@app}`"
+ exit 1
+ else raise
+ end
+ rescue Client::NotFoundException => e
+ raise unless e.resource == :cloud
+ say_error "You have no access to '#{@app}' cloud defined in Cloudfile"
+ end
+
# FIXME: move to helpers
no_tasks do
def check_options(options)
unless options.empty?
unless ["code-name", "databases", "domains"].all? do |option|
options.include?(option.to_s) && options[option.to_s] != option.to_s
end && valid_databases?(options["databases"])
+ # FIXME: ' to `
say_error "Try 'shelly help add' for more information"
end
end
end
@@ -300,10 +307,10 @@
valid = valid_databases?(databases)
break if valid
databases = ask("Unknown database kind. Supported are: #{kinds.join(", ")}:")
end while not valid
- databases.empty? ? ["postgresql"] : databases
+ databases.empty? ? ["postgresql"] : databases - ["none"]
end
def info_adding_cloudfile_to_repository
say_new_line
say "Project is now configured for use with Shell Cloud:", :green