shelly 0.0.43 → 0.0.44.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/lib/shelly/app.rb +4 -0
- data/lib/shelly/cli/backup.rb +42 -43
- data/lib/shelly/cli/config.rb +34 -47
- data/lib/shelly/cli/deploys.rb +14 -22
- data/lib/shelly/cli/main.rb +95 -88
- data/lib/shelly/cli/runner.rb +6 -2
- data/lib/shelly/cli/user.rb +10 -16
- data/lib/shelly/client.rb +36 -32
- data/lib/shelly/download_progress_bar.rb +1 -1
- data/lib/shelly/helpers.rb +5 -10
- data/lib/shelly/user.rb +10 -2
- data/lib/shelly/version.rb +1 -1
- data/lib/thor/thor.rb +4 -0
- data/shelly.gemspec +2 -1
- data/spec/helpers.rb +7 -0
- data/spec/shelly/app_spec.rb +11 -5
- data/spec/shelly/cli/backup_spec.rb +36 -31
- data/spec/shelly/cli/config_spec.rb +70 -35
- data/spec/shelly/cli/deploys_spec.rb +19 -19
- data/spec/shelly/cli/main_spec.rb +213 -105
- data/spec/shelly/cli/runner_spec.rb +29 -1
- data/spec/shelly/cli/user_spec.rb +20 -53
- data/spec/shelly/client_spec.rb +90 -81
- data/spec/shelly/download_progress_bar_spec.rb +4 -4
- data/spec/shelly/user_spec.rb +23 -0
- data/spec/spec_helper.rb +5 -1
- metadata +43 -32
data/lib/shelly/cli/main.rb
CHANGED
@@ -9,23 +9,24 @@ module Shelly
|
|
9
9
|
class Main < Command
|
10
10
|
include Thor::Actions
|
11
11
|
|
12
|
-
register(User, "user", "user <command>", "
|
13
|
-
register(Backup, "backup", "backup <command>", "
|
14
|
-
register(Deploys, "deploys", "deploys <command>", "View
|
15
|
-
register(Config, "config", "config <command>", "
|
12
|
+
register(User, "user", "user <command>", "Manage collaborators")
|
13
|
+
register(Backup, "backup", "backup <command>", "Manage database backups")
|
14
|
+
register(Deploys, "deploys", "deploys <command>", "View deploy logs")
|
15
|
+
register(Config, "config", "config <command>", "Manage application configuration files")
|
16
16
|
check_unknown_options!
|
17
17
|
|
18
|
-
|
19
|
-
before_hook :
|
18
|
+
# FIXME: it should be possible to pass single symbol, instead of one element array
|
19
|
+
before_hook :logged_in?, :only => [:add, :list, :start, :stop, :logs, :delete, :ip, :logout]
|
20
|
+
before_hook :inside_git_repository?, :only => [:add]
|
20
21
|
before_hook :cloudfile_present?, :only => [:logs, :stop, :start, :ip]
|
21
22
|
|
22
23
|
map %w(-v --version) => :version
|
23
|
-
desc "version", "
|
24
|
+
desc "version", "Display shelly version"
|
24
25
|
def version
|
25
26
|
say "shelly version #{Shelly::VERSION}"
|
26
27
|
end
|
27
28
|
|
28
|
-
desc "register [EMAIL]", "
|
29
|
+
desc "register [EMAIL]", "Register new account"
|
29
30
|
def register(email = nil)
|
30
31
|
user = Shelly::User.new
|
31
32
|
user.ssh_key_registered?
|
@@ -38,12 +39,10 @@ module Shelly
|
|
38
39
|
end
|
39
40
|
say "Successfully registered!"
|
40
41
|
say "Check you mailbox for email address confirmation"
|
41
|
-
rescue Client::
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
rescue RestClient::Conflict
|
42
|
+
rescue Client::ValidationException => e
|
43
|
+
e.each_error { |error| say_error "#{error}", :with_exit => false }
|
44
|
+
exit 1
|
45
|
+
rescue Client::ConflictException
|
47
46
|
say_error "User with your ssh key already exists.", :with_exit => false
|
48
47
|
say_error "You can login using: shelly login [EMAIL]", :with_exit => false
|
49
48
|
exit 1
|
@@ -52,7 +51,7 @@ module Shelly
|
|
52
51
|
say_error "Use ssh-keygen to generate ssh key pair"
|
53
52
|
end
|
54
53
|
|
55
|
-
desc "login [EMAIL]", "
|
54
|
+
desc "login [EMAIL]", "Log into Shelly Cloud"
|
56
55
|
def login(email = nil)
|
57
56
|
user = Shelly::User.new
|
58
57
|
raise Errno::ENOENT, user.ssh_key_path unless user.ssh_key_exists?
|
@@ -63,16 +62,12 @@ module Shelly
|
|
63
62
|
user.upload_ssh_key
|
64
63
|
say "Uploading your public SSH key"
|
65
64
|
list
|
66
|
-
rescue Client::
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
say_error "You can reset password by using link:", :with_exit => false
|
73
|
-
say_error "#{e.url}", :with_exit => false
|
74
|
-
end
|
75
|
-
exit 1
|
65
|
+
rescue Client::ValidationException => e
|
66
|
+
e.each_error { |error| say_error "#{error}", :with_exit => false }
|
67
|
+
rescue Client::UnauthorizedException => e
|
68
|
+
say_error "Wrong email or password", :with_exit => false
|
69
|
+
say_error "You can reset password by using link:", :with_exit => false
|
70
|
+
say_error "#{e[:url]}"
|
76
71
|
rescue Errno::ENOENT => e
|
77
72
|
say_error e, :with_exit => false
|
78
73
|
say_error "Use ssh-keygen to generate ssh key pair"
|
@@ -82,11 +77,11 @@ module Shelly
|
|
82
77
|
:desc => "Unique code-name of your cloud"
|
83
78
|
method_option :databases, :type => :array, :aliases => "-d",
|
84
79
|
:banner => Shelly::App::DATABASE_KINDS.join(', '),
|
85
|
-
:desc => "
|
80
|
+
:desc => "List of databases of your choice"
|
86
81
|
method_option :domains, :type => :array,
|
87
82
|
:banner => "CODE-NAME.shellyapp.com, YOUR-DOMAIN.com",
|
88
|
-
:desc => "
|
89
|
-
desc "add", "
|
83
|
+
:desc => "List of your domains"
|
84
|
+
desc "add", "Add a new cloud"
|
90
85
|
def add
|
91
86
|
check_options(options)
|
92
87
|
@app = Shelly::App.new
|
@@ -107,16 +102,14 @@ module Shelly
|
|
107
102
|
info_adding_cloudfile_to_repository
|
108
103
|
info_deploying_to_shellycloud
|
109
104
|
|
110
|
-
rescue Client::
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
say_error "shelly add --code-name=#{@app.code_name} --databases=#{@app.databases.join} --domains=#{@app.code_name}.shellyapp.com"
|
116
|
-
end
|
105
|
+
rescue Client::ValidationException => e
|
106
|
+
e.each_error { |error| say_error error, :with_exit => false }
|
107
|
+
say_new_line
|
108
|
+
say_error "Fix erros in the below command and type it again to create your cloud" , :with_exit => false
|
109
|
+
say_error "shelly add --code-name=#{@app.code_name} --databases=#{@app.databases.join} --domains=#{@app.code_name}.shellyapp.com"
|
117
110
|
end
|
118
111
|
|
119
|
-
desc "list", "
|
112
|
+
desc "list", "List available clouds"
|
120
113
|
def list
|
121
114
|
user = Shelly::User.new
|
122
115
|
apps = user.apps
|
@@ -129,16 +122,12 @@ module Shelly
|
|
129
122
|
else
|
130
123
|
say "You have no clouds yet", :green
|
131
124
|
end
|
132
|
-
rescue Client::APIError => e
|
133
|
-
if e.unauthorized?
|
134
|
-
say_error "You are not logged in, use `shelly login`"
|
135
|
-
end
|
136
125
|
end
|
126
|
+
|
137
127
|
map "status" => :list
|
138
128
|
|
139
|
-
desc "ip", "
|
129
|
+
desc "ip", "List cloud's IP addresses"
|
140
130
|
def ip
|
141
|
-
say_error "No Cloudfile found" unless Cloudfile.present?
|
142
131
|
@cloudfile = Cloudfile.new
|
143
132
|
@cloudfile.clouds.each do |cloud|
|
144
133
|
begin
|
@@ -146,31 +135,26 @@ module Shelly
|
|
146
135
|
say "Cloud #{cloud}:", :green
|
147
136
|
print_wrapped "Web server IP: #{@app.web_server_ip}", :ident => 2
|
148
137
|
print_wrapped "Mail server IP: #{@app.mail_server_ip}", :ident => 2
|
149
|
-
rescue Client::
|
150
|
-
|
151
|
-
|
152
|
-
else
|
153
|
-
say_error e.message, :with_exit => false
|
154
|
-
end
|
138
|
+
rescue Client::NotFoundException => e
|
139
|
+
raise unless e.resource == :cloud
|
140
|
+
say_error "You have no access to '#{cloud}' cloud defined in Cloudfile", :with_exit => false
|
155
141
|
end
|
156
142
|
end
|
157
143
|
end
|
158
144
|
|
159
|
-
desc "start", "
|
160
|
-
method_option :cloud, :type => :string, :aliases => "-c",
|
161
|
-
:desc => "Specify which cloud to start"
|
145
|
+
desc "start", "Start the cloud"
|
146
|
+
method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
|
162
147
|
def start
|
163
|
-
multiple_clouds(options[:cloud], "start"
|
148
|
+
multiple_clouds(options[:cloud], "start")
|
164
149
|
@app.start
|
165
|
-
say "Starting cloud #{@app
|
150
|
+
say "Starting cloud #{@app}. Check status with:", :green
|
166
151
|
say " shelly list"
|
167
|
-
rescue
|
168
|
-
|
169
|
-
case response['state']
|
152
|
+
rescue Client::ConflictException => e
|
153
|
+
case e[:state]
|
170
154
|
when "running"
|
171
|
-
say_error "Not starting: cloud '#{@app
|
155
|
+
say_error "Not starting: cloud '#{@app}' is already running"
|
172
156
|
when "deploying", "configuring"
|
173
|
-
say_error "Not starting: cloud '#{@app
|
157
|
+
say_error "Not starting: cloud '#{@app}' is currently deploying"
|
174
158
|
when "no_code"
|
175
159
|
say_error "Not starting: no source code provided", :with_exit => false
|
176
160
|
say_error "Push source code using:", :with_exit => false
|
@@ -178,36 +162,32 @@ module Shelly
|
|
178
162
|
when "deploy_failed", "configuration_failed"
|
179
163
|
say_error "Not starting: deployment failed", :with_exit => false
|
180
164
|
say_error "Support has been notified", :with_exit => false
|
181
|
-
say_error "
|
165
|
+
say_error "Check `shelly deploys show last --cloud #{@app}` for reasons of failure"
|
182
166
|
when "no_billing"
|
183
167
|
say_error "Please fill in billing details to start foo-production. Opening browser.", :with_exit => false
|
184
168
|
@app.open_billing_page
|
185
169
|
end
|
186
170
|
exit 1
|
187
|
-
rescue Client::
|
188
|
-
|
189
|
-
|
190
|
-
end
|
171
|
+
rescue Client::NotFoundException => e
|
172
|
+
raise unless e.resource == :cloud
|
173
|
+
say_error "You have no access to '#{@app}' cloud defined in Cloudfile"
|
191
174
|
end
|
192
175
|
|
193
|
-
desc "stop", "
|
194
|
-
method_option :cloud, :type => :string, :aliases => "-c",
|
195
|
-
:desc => "Specify which cloud to stop"
|
176
|
+
desc "stop", "Stop the cloud"
|
177
|
+
method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
|
196
178
|
def stop
|
197
|
-
multiple_clouds(options[:cloud], "stop"
|
179
|
+
multiple_clouds(options[:cloud], "stop")
|
198
180
|
@app.stop
|
199
181
|
say "Cloud '#{@app.code_name}' stopped"
|
200
|
-
rescue Client::
|
201
|
-
|
202
|
-
|
203
|
-
end
|
182
|
+
rescue Client::NotFoundException => e
|
183
|
+
raise unless e.resource == :cloud
|
184
|
+
say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
|
204
185
|
end
|
205
186
|
|
206
|
-
desc "delete", "Delete cloud
|
207
|
-
method_option :cloud, :type => :string, :aliases => "-c",
|
208
|
-
:desc => "Specify which cloud to delete"
|
187
|
+
desc "delete", "Delete the cloud"
|
188
|
+
method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
|
209
189
|
def delete
|
210
|
-
multiple_clouds(options[:cloud], "delete"
|
190
|
+
multiple_clouds(options[:cloud], "delete")
|
211
191
|
say "You are about to delete application: #{@app.code_name}."
|
212
192
|
say "Press Control-C at any moment to cancel."
|
213
193
|
say "Please confirm each question by typing yes and pressing Enter."
|
@@ -224,18 +204,16 @@ module Shelly
|
|
224
204
|
else
|
225
205
|
say "Missing git remote"
|
226
206
|
end
|
227
|
-
rescue Client::
|
228
|
-
|
229
|
-
|
230
|
-
end
|
207
|
+
rescue Client::NotFoundException => e
|
208
|
+
raise unless e.resource == :cloud
|
209
|
+
say_error "You have no access to '#{@app.code_name}' cloud defined in Cloudfile"
|
231
210
|
end
|
232
211
|
|
233
|
-
desc "logs", "Show latest application logs
|
234
|
-
method_option :cloud, :type => :string, :aliases => "-c",
|
235
|
-
:desc => "Specify which cloud to show logs for"
|
212
|
+
desc "logs", "Show latest application logs"
|
213
|
+
method_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
|
236
214
|
def logs
|
237
215
|
cloud = options[:cloud]
|
238
|
-
multiple_clouds(cloud, "logs"
|
216
|
+
multiple_clouds(cloud, "logs")
|
239
217
|
begin
|
240
218
|
logs = @app.application_logs
|
241
219
|
say "Cloud #{@app.code_name}:", :green
|
@@ -243,11 +221,39 @@ module Shelly
|
|
243
221
|
say "Instance #{i+1}:", :green
|
244
222
|
say log
|
245
223
|
end
|
246
|
-
rescue Client::
|
247
|
-
|
248
|
-
|
249
|
-
|
224
|
+
rescue Client::NotFoundException => e
|
225
|
+
raise unless e.resource == :cloud
|
226
|
+
say_error "You have no access to '#{cloud || @app.code_name}' cloud defined in Cloudfile"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
desc "logout", "Logout from Shelly Cloud"
|
231
|
+
def logout
|
232
|
+
user = Shelly::User.new
|
233
|
+
say "Your public SSH key has been removed from Shelly Cloud" if user.delete_ssh_key
|
234
|
+
say "You have been successfully logged out" if user.delete_credentials
|
235
|
+
end
|
236
|
+
|
237
|
+
desc "redeploy", "Redeploy application"
|
238
|
+
method_option :cloud, :type => :string, :aliases => "-c",
|
239
|
+
:desc => "Specify which cloud to redeploy application for"
|
240
|
+
def redeploy
|
241
|
+
multiple_clouds(options[:cloud], "redeploy")
|
242
|
+
@app.redeploy
|
243
|
+
say "Redeploying your application for cloud '#{@app}'", :green
|
244
|
+
rescue Client::ConflictException => e
|
245
|
+
case e[:state]
|
246
|
+
when "deploying", "configuring"
|
247
|
+
say_error "Your application is being redeployed at the moment"
|
248
|
+
when "no_code", "no_billing", "turned_off"
|
249
|
+
say_error "Cloud #{@app} is not running", :with_exit => false
|
250
|
+
say "Start your cloud with `shelly start --cloud #{@app}`"
|
251
|
+
exit 1
|
252
|
+
else raise
|
250
253
|
end
|
254
|
+
rescue Client::NotFoundException => e
|
255
|
+
raise unless e.resource == :cloud
|
256
|
+
say_error "You have no access to '#{@app}' cloud defined in Cloudfile"
|
251
257
|
end
|
252
258
|
|
253
259
|
# FIXME: move to helpers
|
@@ -257,6 +263,7 @@ module Shelly
|
|
257
263
|
unless ["code-name", "databases", "domains"].all? do |option|
|
258
264
|
options.include?(option.to_s) && options[option.to_s] != option.to_s
|
259
265
|
end && valid_databases?(options["databases"])
|
266
|
+
# FIXME: ' to `
|
260
267
|
say_error "Try 'shelly help add' for more information"
|
261
268
|
end
|
262
269
|
end
|
@@ -302,7 +309,7 @@ module Shelly
|
|
302
309
|
databases = ask("Unknown database kind. Supported are: #{kinds.join(", ")}:")
|
303
310
|
end while not valid
|
304
311
|
|
305
|
-
databases.empty? ? ["postgresql"] : databases
|
312
|
+
databases.empty? ? ["postgresql"] : databases - ["none"]
|
306
313
|
end
|
307
314
|
|
308
315
|
def info_adding_cloudfile_to_repository
|
data/lib/shelly/cli/runner.rb
CHANGED
@@ -17,8 +17,12 @@ module Shelly
|
|
17
17
|
|
18
18
|
def start
|
19
19
|
Shelly::CLI::Main.start(args)
|
20
|
-
rescue
|
21
|
-
|
20
|
+
rescue SystemExit; raise
|
21
|
+
rescue Interrupt
|
22
|
+
say_new_line
|
23
|
+
say_error "[canceled]"
|
24
|
+
rescue Exception
|
25
|
+
raise if debug?
|
22
26
|
say_error "Unknown error, to see debug information run command with --debug"
|
23
27
|
end
|
24
28
|
end
|
data/lib/shelly/cli/user.rb
CHANGED
@@ -7,7 +7,6 @@ module Shelly
|
|
7
7
|
include Helpers
|
8
8
|
|
9
9
|
before_hook :logged_in?, :only => [:list, :add]
|
10
|
-
before_hook :inside_git_repository?, :only => [:list, :add]
|
11
10
|
before_hook :cloudfile_present?, :only => [:list, :add]
|
12
11
|
|
13
12
|
desc "list", "List users with access to clouds defined in Cloudfile"
|
@@ -18,12 +17,9 @@ module Shelly
|
|
18
17
|
@app = App.new(cloud)
|
19
18
|
say "Cloud #{cloud}:"
|
20
19
|
@app.users.each { |user| say " #{user["email"]}" }
|
21
|
-
rescue Client::
|
22
|
-
|
23
|
-
|
24
|
-
else
|
25
|
-
say_error e.message, :with_exit => false
|
26
|
-
end
|
20
|
+
rescue Client::NotFoundException => e
|
21
|
+
raise unless e.resource == :cloud
|
22
|
+
say_error "You have no access to '#{cloud}' cloud defined in Cloudfile"
|
27
23
|
end
|
28
24
|
end
|
29
25
|
end
|
@@ -36,19 +32,17 @@ module Shelly
|
|
36
32
|
@cloudfile.clouds.each do |cloud|
|
37
33
|
begin
|
38
34
|
@user.send_invitation(cloud, user_email)
|
39
|
-
|
40
|
-
|
35
|
+
say "Sending invitation to #{user_email} to work on #{cloud}", :green
|
36
|
+
rescue Client::ValidationException => e
|
37
|
+
if e.errors.include?(["email", "#{email} has already been taken"])
|
41
38
|
say_error "User #{email} is already in the cloud #{cloud}", :with_exit => false
|
42
|
-
|
43
|
-
say_error "You have no access to '#{cloud}' cloud defined in Cloudfile", :with_exit => false
|
44
|
-
elsif e.validation?
|
39
|
+
else
|
45
40
|
e.each_error { |error| say_error error, :with_exit => false }
|
46
41
|
exit 1
|
47
|
-
else
|
48
|
-
say_error e.message, :with_exit => false
|
49
42
|
end
|
50
|
-
|
51
|
-
|
43
|
+
rescue Client::NotFoundException => e
|
44
|
+
raise unless e.resource == :cloud
|
45
|
+
say_error "You have no access to '#{cloud}' cloud defined in Cloudfile"
|
52
46
|
end
|
53
47
|
end
|
54
48
|
end
|
data/lib/shelly/client.rb
CHANGED
@@ -4,41 +4,24 @@ require "cgi"
|
|
4
4
|
|
5
5
|
module Shelly
|
6
6
|
class Client
|
7
|
-
class
|
7
|
+
class APIException < Exception
|
8
8
|
attr_reader :status_code, :body
|
9
9
|
|
10
|
-
def initialize(
|
10
|
+
def initialize(body = {}, status_code = nil)
|
11
11
|
@status_code = status_code
|
12
12
|
@body = body
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
body[
|
15
|
+
def [](key)
|
16
|
+
body[key.to_s]
|
17
17
|
end
|
18
|
+
end
|
18
19
|
|
20
|
+
class UnauthorizedException < APIException; end
|
21
|
+
class ConflictException < APIException; end
|
22
|
+
class ValidationException < APIException
|
19
23
|
def errors
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
def url
|
24
|
-
body["url"]
|
25
|
-
end
|
26
|
-
|
27
|
-
def validation?
|
28
|
-
message == "Validation Failed"
|
29
|
-
end
|
30
|
-
|
31
|
-
def not_found?
|
32
|
-
status_code == 404
|
33
|
-
end
|
34
|
-
|
35
|
-
def resource_not_found
|
36
|
-
return unless not_found?
|
37
|
-
message =~ /Couldn't find (.*) with/ && $1.downcase.to_sym
|
38
|
-
end
|
39
|
-
|
40
|
-
def unauthorized?
|
41
|
-
status_code == 401
|
24
|
+
self[:errors]
|
42
25
|
end
|
43
26
|
|
44
27
|
def each_error
|
@@ -47,6 +30,11 @@ module Shelly
|
|
47
30
|
end
|
48
31
|
end
|
49
32
|
end
|
33
|
+
class NotFoundException < APIException
|
34
|
+
def resource
|
35
|
+
self[:resource].to_sym
|
36
|
+
end
|
37
|
+
end
|
50
38
|
|
51
39
|
attr_reader :email, :password
|
52
40
|
|
@@ -104,7 +92,11 @@ module Shelly
|
|
104
92
|
end
|
105
93
|
|
106
94
|
def add_ssh_key(ssh_key)
|
107
|
-
post("/
|
95
|
+
post("/ssh_keys", :ssh_key => ssh_key)
|
96
|
+
end
|
97
|
+
|
98
|
+
def logout(ssh_key)
|
99
|
+
delete("/ssh_keys", :ssh_key => ssh_key)
|
108
100
|
end
|
109
101
|
|
110
102
|
def start_cloud(cloud)
|
@@ -124,15 +116,15 @@ module Shelly
|
|
124
116
|
end
|
125
117
|
|
126
118
|
def deploy_logs(cloud)
|
127
|
-
get("/apps/#{cloud}/
|
119
|
+
get("/apps/#{cloud}/deployment_logs")
|
128
120
|
end
|
129
121
|
|
130
122
|
def deploy_log(cloud, log)
|
131
|
-
get("/apps/#{cloud}/
|
123
|
+
get("/apps/#{cloud}/deployment_logs/#{log}")
|
132
124
|
end
|
133
125
|
|
134
126
|
def application_logs(cloud)
|
135
|
-
get("/apps/#{cloud}/
|
127
|
+
get("/apps/#{cloud}/application_logs")
|
136
128
|
end
|
137
129
|
|
138
130
|
def database_backups(code_name)
|
@@ -159,6 +151,10 @@ module Shelly
|
|
159
151
|
get("/apps/#{cloud}/users")
|
160
152
|
end
|
161
153
|
|
154
|
+
def redeploy(cloud)
|
155
|
+
post("/apps/#{cloud}/deploys")
|
156
|
+
end
|
157
|
+
|
162
158
|
def post(path, params = {})
|
163
159
|
request(path, :post, params)
|
164
160
|
end
|
@@ -220,10 +216,18 @@ module Shelly
|
|
220
216
|
def process_response(response)
|
221
217
|
body = JSON.parse(response.body) rescue JSON::ParserError && {}
|
222
218
|
code = response.code
|
223
|
-
|
219
|
+
if (400..599).include?(code)
|
220
|
+
exception_class = case response.code
|
221
|
+
when 401; UnauthorizedException
|
222
|
+
when 404; NotFoundException
|
223
|
+
when 409; ConflictException
|
224
|
+
when 422; ValidationException
|
225
|
+
else; APIException
|
226
|
+
end
|
227
|
+
raise exception_class.new(body, code)
|
228
|
+
end
|
224
229
|
response.return!
|
225
230
|
body
|
226
231
|
end
|
227
232
|
end
|
228
233
|
end
|
229
|
-
|
data/lib/shelly/helpers.rb
CHANGED
@@ -63,19 +63,15 @@ module Shelly
|
|
63
63
|
user = Shelly::User.new
|
64
64
|
user.token
|
65
65
|
user
|
66
|
-
rescue Client::
|
67
|
-
|
68
|
-
say_error "You are not logged in. To log in use:", :with_exit => false
|
69
|
-
say " shelly login"
|
70
|
-
exit 1
|
71
|
-
end
|
66
|
+
rescue Client::UnauthorizedException
|
67
|
+
say_error "You are not logged in. To log in use: `shelly login`"
|
72
68
|
end
|
73
69
|
|
74
|
-
def multiple_clouds(cloud, action
|
70
|
+
def multiple_clouds(cloud, action)
|
75
71
|
clouds = Cloudfile.new.clouds
|
76
72
|
if clouds.count > 1 && cloud.nil?
|
77
|
-
|
78
|
-
say "
|
73
|
+
say_error "You have multiple clouds in Cloudfile.", :with_exit => false
|
74
|
+
say "Select cloud using `shelly #{action} --cloud #{clouds.first}`"
|
79
75
|
say "Available clouds:"
|
80
76
|
clouds.each do |cloud|
|
81
77
|
say " * #{cloud}"
|
@@ -85,6 +81,5 @@ module Shelly
|
|
85
81
|
@app = Shelly::App.new
|
86
82
|
@app.code_name = cloud || clouds.first
|
87
83
|
end
|
88
|
-
|
89
84
|
end
|
90
85
|
end
|
data/lib/shelly/user.rb
CHANGED
@@ -44,6 +44,14 @@ module Shelly
|
|
44
44
|
set_credentials_permissions
|
45
45
|
end
|
46
46
|
|
47
|
+
def delete_credentials
|
48
|
+
File.delete(credentials_path) if credentials_exists?
|
49
|
+
end
|
50
|
+
|
51
|
+
def delete_ssh_key
|
52
|
+
shelly.logout(File.read(ssh_key_path)) if ssh_key_exists?
|
53
|
+
end
|
54
|
+
|
47
55
|
def ssh_key_exists?
|
48
56
|
File.exists?(ssh_key_path)
|
49
57
|
end
|
@@ -53,8 +61,8 @@ module Shelly
|
|
53
61
|
end
|
54
62
|
|
55
63
|
def ssh_key_registered?
|
56
|
-
|
57
|
-
|
64
|
+
ssh_key = File.read(ssh_key_path).strip
|
65
|
+
shelly.ssh_key_available?(ssh_key)
|
58
66
|
end
|
59
67
|
|
60
68
|
def self.guess_email
|
data/lib/shelly/version.rb
CHANGED
data/lib/thor/thor.rb
CHANGED
data/shelly.gemspec
CHANGED
@@ -16,8 +16,9 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.add_development_dependency "rake"
|
17
17
|
s.add_development_dependency "guard"
|
18
18
|
s.add_development_dependency "guard-rspec"
|
19
|
+
s.add_development_dependency "simplecov"
|
19
20
|
if RUBY_PLATFORM =~ /darwin/
|
20
|
-
s.add_development_dependency "
|
21
|
+
s.add_development_dependency "ruby_gntp"
|
21
22
|
s.add_development_dependency "rb-fsevent"
|
22
23
|
end
|
23
24
|
s.add_development_dependency "fakefs"
|
data/spec/helpers.rb
CHANGED
data/spec/shelly/app_spec.rb
CHANGED
@@ -82,24 +82,24 @@ describe Shelly::App do
|
|
82
82
|
@app.delete_config("path")
|
83
83
|
end
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
describe "#attributes" do
|
87
87
|
before do
|
88
88
|
@response = {"web_server_ip" => "192.0.2.1", "mail_server_ip" => "192.0.2.3"}
|
89
89
|
@client.stub(:app).and_return(@response)
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
it "should fetch app attributes from API and cache them" do
|
93
93
|
@client.should_receive(:app).with("foo-staging").exactly(:once).and_return(@response)
|
94
94
|
2.times { @app.attributes }
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
describe "#web_server_ip" do
|
98
98
|
it "should return web server ip address" do
|
99
99
|
@app.web_server_ip.should == "192.0.2.1"
|
100
100
|
end
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
describe "#mail_server_ip" do
|
104
104
|
it "should return mail server ip address" do
|
105
105
|
@app.mail_server_ip.should == "192.0.2.3"
|
@@ -280,6 +280,13 @@ config
|
|
280
280
|
end
|
281
281
|
end
|
282
282
|
end
|
283
|
+
|
284
|
+
describe "#redeploy" do
|
285
|
+
it "should redeploy app via API" do
|
286
|
+
@client.should_receive(:redeploy).with("foo-staging")
|
287
|
+
@app.redeploy
|
288
|
+
end
|
289
|
+
end
|
283
290
|
|
284
291
|
describe "#to_s" do
|
285
292
|
it "should return code_name" do
|
@@ -287,4 +294,3 @@ config
|
|
287
294
|
end
|
288
295
|
end
|
289
296
|
end
|
290
|
-
|