shelly 0.4.34 → 0.4.35
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/lib/shelly/app.rb +13 -1
- data/lib/shelly/cli/main.rb +12 -9
- data/lib/shelly/cli/maintenance.rb +61 -0
- data/lib/shelly/client.rb +1 -0
- data/lib/shelly/client/errors.rb +7 -1
- data/lib/shelly/client/maintenance.rb +13 -0
- data/lib/shelly/helpers.rb +2 -2
- data/lib/shelly/version.rb +1 -1
- data/spec/shelly/app_spec.rb +25 -2
- data/spec/shelly/cli/main_spec.rb +30 -0
- data/spec/shelly/cli/maintenance_spec.rb +159 -0
- data/spec/shelly/client_spec.rb +38 -0
- metadata +42 -38
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d44ad2b9e90f5650a10edf8a00e494447eca23f0
|
|
4
|
+
data.tar.gz: 7dda9afd2807e4e467b57575af0b97211c3cdad4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4ebecf098fc80b5b34e35ad667f14fe356820e1f7341cadec4ffa60f5242d1ab7cf4a01784890d54fc9282d1e01bb7fb41a2270d2e11178b600fba12deb24aca
|
|
7
|
+
data.tar.gz: a7fe050ad36f6900283f48bc7ba7bc9d6628fc875c352158cfe72e2e9fb196aa20d265c95e37c604923f18e1716f58f53b32554f9eab038c7cf452f1ea27e1b5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
## 0.4.35 / 2014-07-14
|
|
2
|
+
|
|
3
|
+
* [improvement] allow user to turn on/off maintenance mode for cloud
|
|
4
|
+
* [bugfix] Fixed shelly info for newly created clouds
|
|
5
|
+
|
|
1
6
|
## 0.4.34 / 2014-06-12
|
|
2
7
|
|
|
3
8
|
* [improvement] Check if ENV['HOME'] is set on start
|
|
4
|
-
*
|
|
9
|
+
* [improvement] Create Cloudfile with a small server as a default size
|
|
5
10
|
|
|
6
11
|
## 0.4.33 / 2014-05-27
|
|
7
12
|
|
data/lib/shelly/app.rb
CHANGED
|
@@ -162,6 +162,18 @@ module Shelly
|
|
|
162
162
|
shelly.stop_cloud(code_name)["deployment"]["id"]
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
+
def maintenances
|
|
166
|
+
shelly.maintenances(code_name)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def start_maintenance(options)
|
|
170
|
+
shelly.start_maintenance(code_name, options)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def finish_maintenance
|
|
174
|
+
shelly.finish_maintenance(code_name)
|
|
175
|
+
end
|
|
176
|
+
|
|
165
177
|
# returns the id of created deployment
|
|
166
178
|
def redeploy
|
|
167
179
|
shelly.redeploy(code_name)["deployment"]["id"]
|
|
@@ -263,7 +275,7 @@ module Shelly
|
|
|
263
275
|
attributes["state"]
|
|
264
276
|
end
|
|
265
277
|
|
|
266
|
-
def
|
|
278
|
+
def admin_maintenance_in_progress?
|
|
267
279
|
attributes["maintenance"]
|
|
268
280
|
end
|
|
269
281
|
|
data/lib/shelly/cli/main.rb
CHANGED
|
@@ -8,6 +8,7 @@ require "shelly/cli/file"
|
|
|
8
8
|
require "shelly/cli/organization"
|
|
9
9
|
require "shelly/cli/logs"
|
|
10
10
|
require "shelly/cli/cert"
|
|
11
|
+
require "shelly/cli/maintenance"
|
|
11
12
|
|
|
12
13
|
require "shelly/cli/main/add"
|
|
13
14
|
require "shelly/cli/main/check"
|
|
@@ -26,6 +27,7 @@ module Shelly
|
|
|
26
27
|
register_subcommand(Organization, "organization", "organization <command>", "View organizations")
|
|
27
28
|
register_subcommand(Logs, "log", "logs <command>", "View application logs")
|
|
28
29
|
register_subcommand(Cert, "cert", "cert <command>", "Mange application certificates")
|
|
30
|
+
register_subcommand(Maintenance, "maintenance", "maintenance <command>", "Mange application maintenance events")
|
|
29
31
|
|
|
30
32
|
check_unknown_options!(:except => :rake)
|
|
31
33
|
|
|
@@ -118,18 +120,19 @@ module Shelly
|
|
|
118
120
|
print_wrapped "Repository URL: #{app.git_info["repository_url"]}", :ident => 2
|
|
119
121
|
print_wrapped "Web server IP: #{app.web_server_ip}", :ident => 2
|
|
120
122
|
say_new_line
|
|
123
|
+
|
|
121
124
|
print_wrapped "Usage:", :ident => 2
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
print_wrapped "Average: #{number_to_human_size(usage['avg'])}", :ident => 6
|
|
127
|
-
end
|
|
125
|
+
app.usage.each do |usage|
|
|
126
|
+
print_wrapped "#{usage['kind'].capitalize}:", :ident => 4
|
|
127
|
+
print_wrapped "Current: #{number_to_human_size(usage['current'])}", :ident => 6
|
|
128
|
+
print_wrapped "Average: #{number_to_human_size(usage['avg'])}", :ident => 6
|
|
128
129
|
end
|
|
130
|
+
|
|
129
131
|
print_wrapped "Traffic:", :ident => 4
|
|
130
|
-
print_wrapped "Incoming: #{number_to_human_size(app.traffic['incoming'])}", :ident => 6
|
|
131
|
-
print_wrapped "Outgoing: #{number_to_human_size(app.traffic['outgoing'])}", :ident => 6
|
|
132
|
-
print_wrapped "Total: #{number_to_human_size(app.traffic['total'])}", :ident => 6
|
|
132
|
+
print_wrapped "Incoming: #{number_to_human_size(app.traffic['incoming'].to_i)}", :ident => 6
|
|
133
|
+
print_wrapped "Outgoing: #{number_to_human_size(app.traffic['outgoing'].to_i)}", :ident => 6
|
|
134
|
+
print_wrapped "Total: #{number_to_human_size(app.traffic['total'].to_i)}", :ident => 6
|
|
135
|
+
|
|
133
136
|
say_new_line
|
|
134
137
|
if app.statistics.present?
|
|
135
138
|
print_wrapped "Statistics:", :ident => 2
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'shelly/cli/command'
|
|
2
|
+
require 'time'
|
|
3
|
+
|
|
4
|
+
module Shelly
|
|
5
|
+
module CLI
|
|
6
|
+
class Maintenance < Command
|
|
7
|
+
namespace :maintenance
|
|
8
|
+
include Helpers
|
|
9
|
+
|
|
10
|
+
before_hook :logged_in?, :only => [:list, :start, :finish]
|
|
11
|
+
class_option :cloud, :type => :string, :aliases => "-c",
|
|
12
|
+
:desc => "Specify cloud"
|
|
13
|
+
|
|
14
|
+
desc 'list', 'Recent application maintenance events'
|
|
15
|
+
def list
|
|
16
|
+
app = multiple_clouds(options[:cloud], 'maintenance list')
|
|
17
|
+
maintenances = app.maintenances
|
|
18
|
+
|
|
19
|
+
if maintenances.any?
|
|
20
|
+
say 'Recent application maintenance events', :green
|
|
21
|
+
say_new_line
|
|
22
|
+
|
|
23
|
+
maintenances.each do |maintenance|
|
|
24
|
+
started_at = Time.parse(maintenance['created_at']).
|
|
25
|
+
strftime('%Y-%m-%d %H:%M:%S')
|
|
26
|
+
finished_at = if maintenance['finished']
|
|
27
|
+
Time.parse(maintenance['updated_at']).
|
|
28
|
+
strftime('%Y-%m-%d %H:%M:%S')
|
|
29
|
+
else
|
|
30
|
+
'in progress'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
say " * #{started_at} - #{finished_at}"
|
|
34
|
+
say " #{maintenance['description']}"
|
|
35
|
+
say_new_line
|
|
36
|
+
end
|
|
37
|
+
else
|
|
38
|
+
say "There are no maintenance events for #{app}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
desc 'start DESCRIPTION', 'Start maintenance'
|
|
43
|
+
def start(description = nil)
|
|
44
|
+
app = multiple_clouds(options[:cloud], 'start')
|
|
45
|
+
app.start_maintenance({:description => description})
|
|
46
|
+
say "Maintenance has been started", :green
|
|
47
|
+
rescue Client::ValidationException => exception
|
|
48
|
+
exception.each_error { |error| say_error error, :with_exit => false }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
desc 'finish', 'Finish last maintenance'
|
|
52
|
+
def finish
|
|
53
|
+
app = multiple_clouds(options[:cloud], 'finish')
|
|
54
|
+
app.finish_maintenance
|
|
55
|
+
say "Maintenance has been finished", :green
|
|
56
|
+
rescue Client::ValidationException => exception
|
|
57
|
+
exception.each_error { |error| say_error error, :with_exit => false }
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
data/lib/shelly/client.rb
CHANGED
data/lib/shelly/client/errors.rb
CHANGED
|
@@ -32,7 +32,13 @@ class Shelly::Client
|
|
|
32
32
|
|
|
33
33
|
def each_error
|
|
34
34
|
errors.each do |field, message|
|
|
35
|
-
|
|
35
|
+
error = if field == 'base'
|
|
36
|
+
message
|
|
37
|
+
else
|
|
38
|
+
[field.gsub('_',' ').capitalize, message].join(" ")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
yield error
|
|
36
42
|
end
|
|
37
43
|
end
|
|
38
44
|
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class Shelly::Client
|
|
2
|
+
def maintenances(cloud)
|
|
3
|
+
get("/apps/#{cloud}/maintenances")
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def start_maintenance(cloud, attributes)
|
|
7
|
+
post("/apps/#{cloud}/maintenances", :maintenance => attributes)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def finish_maintenance(cloud)
|
|
11
|
+
put("/apps/#{cloud}/maintenances/last", :maintenance => {:finished => true})
|
|
12
|
+
end
|
|
13
|
+
end
|
data/lib/shelly/helpers.rb
CHANGED
|
@@ -10,7 +10,7 @@ module Shelly
|
|
|
10
10
|
# FIXME: errors should be printed on STDERR
|
|
11
11
|
def say_error(message, options = {})
|
|
12
12
|
options = {:with_exit => true}.merge(options)
|
|
13
|
-
say
|
|
13
|
+
say message, :red
|
|
14
14
|
exit 1 if options[:with_exit]
|
|
15
15
|
end
|
|
16
16
|
|
|
@@ -186,7 +186,7 @@ More info at http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository}
|
|
|
186
186
|
end
|
|
187
187
|
|
|
188
188
|
def info_show_last_deploy_logs(app)
|
|
189
|
-
if app.in_deploy_failed_state? && !app.
|
|
189
|
+
if app.in_deploy_failed_state? && !app.admin_maintenance_in_progress?
|
|
190
190
|
" (deployment log: `shelly deploys show last -c #{app}`)"
|
|
191
191
|
end
|
|
192
192
|
end
|
data/lib/shelly/version.rb
CHANGED
data/spec/shelly/app_spec.rb
CHANGED
|
@@ -196,9 +196,9 @@ describe Shelly::App do
|
|
|
196
196
|
end
|
|
197
197
|
end
|
|
198
198
|
|
|
199
|
-
describe "#
|
|
199
|
+
describe "#admin_maintenance_in_progress?" do
|
|
200
200
|
it "should return false" do
|
|
201
|
-
@app.
|
|
201
|
+
@app.admin_maintenance_in_progress?.should be_false
|
|
202
202
|
end
|
|
203
203
|
end
|
|
204
204
|
|
|
@@ -243,6 +243,29 @@ describe Shelly::App do
|
|
|
243
243
|
end
|
|
244
244
|
end
|
|
245
245
|
|
|
246
|
+
describe "#maintenances" do
|
|
247
|
+
it 'should return application maintenances' do
|
|
248
|
+
@client.should_receive(:maintenances).with('foo-staging')
|
|
249
|
+
@app.maintenances
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
describe "#start_maintenance" do
|
|
254
|
+
it 'should start maintenance for application' do
|
|
255
|
+
@client.should_receive(:start_maintenance).with('foo-staging', {
|
|
256
|
+
description: 'Maintenance'
|
|
257
|
+
})
|
|
258
|
+
@app.start_maintenance({description: 'Maintenance'})
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
describe "#finish_maintenance" do
|
|
263
|
+
it 'should finish maintenance for application' do
|
|
264
|
+
@client.should_receive(:finish_maintenance).with('foo-staging')
|
|
265
|
+
@app.finish_maintenance
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
246
269
|
describe "#turned_off?" do
|
|
247
270
|
it "should return true if cloud state is turned_off" do
|
|
248
271
|
@client.should_receive(:app).and_return({'state' => 'turned_off'})
|
|
@@ -46,6 +46,7 @@ describe Shelly::CLI::Main do
|
|
|
46
46
|
out.should include("shelly login [EMAIL] # Log into Shelly Cloud")
|
|
47
47
|
out.should include("shelly logout # Logout from Shelly Cloud")
|
|
48
48
|
out.should include("shelly logs <command> # View application logs")
|
|
49
|
+
out.should include("shelly maintenance <command> # Mange application maintenance events")
|
|
49
50
|
out.should include("shelly mongoconsole # Run MongoDB console")
|
|
50
51
|
out.should include("shelly open # Open application page in browser")
|
|
51
52
|
out.should include("shelly organization <command> # View organizations")
|
|
@@ -1017,6 +1018,35 @@ Wait until cloud is in 'turned off' state and try again.")
|
|
|
1017
1018
|
invoke(@main, :info)
|
|
1018
1019
|
end
|
|
1019
1020
|
|
|
1021
|
+
context "when usage and traffic is not present" do
|
|
1022
|
+
before do
|
|
1023
|
+
@app.stub(:attributes).and_return(response({
|
|
1024
|
+
"billing" => {
|
|
1025
|
+
"current_month_costs" => {
|
|
1026
|
+
"usage" => [],
|
|
1027
|
+
"traffic" => {
|
|
1028
|
+
"incoming" => nil,
|
|
1029
|
+
"outgoing" => nil,
|
|
1030
|
+
"total" => nil
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
},
|
|
1034
|
+
}))
|
|
1035
|
+
end
|
|
1036
|
+
|
|
1037
|
+
it "should print 0.0 B usage" do
|
|
1038
|
+
@main.should_receive(:multiple_clouds).and_return(@app)
|
|
1039
|
+
$stdout.should_receive(:puts).with(" Usage:")
|
|
1040
|
+
$stdout.should_not_receive(:puts).with(" Filesystem:")
|
|
1041
|
+
$stdout.should_not_receive(:puts).with(" Database:")
|
|
1042
|
+
$stdout.should_receive(:puts).with(" Traffic:")
|
|
1043
|
+
$stdout.should_receive(:puts).with(" Incoming: 0.0 B")
|
|
1044
|
+
$stdout.should_receive(:puts).with(" Outgoing: 0.0 B")
|
|
1045
|
+
$stdout.should_receive(:puts).with(" Total: 0.0 B")
|
|
1046
|
+
invoke(@main, :info)
|
|
1047
|
+
end
|
|
1048
|
+
end
|
|
1049
|
+
|
|
1020
1050
|
context "when deploy failed" do
|
|
1021
1051
|
context "and app is in maintenance" do
|
|
1022
1052
|
it "should display basic information without instruction to show last app logs" do
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'shelly/cli/maintenance'
|
|
3
|
+
|
|
4
|
+
describe Shelly::CLI::Maintenance do
|
|
5
|
+
let!(:cli) { Shelly::CLI::Maintenance.new }
|
|
6
|
+
let!(:app) { Shelly::App.new('foo-production') }
|
|
7
|
+
let!(:client) { mock }
|
|
8
|
+
|
|
9
|
+
before do
|
|
10
|
+
Shelly::CLI::Maintenance.stub(:new).and_return(cli)
|
|
11
|
+
Shelly::Client.stub(:new).and_return(client)
|
|
12
|
+
client.stub(:authorize!)
|
|
13
|
+
FileUtils.mkdir_p('/projects/foo')
|
|
14
|
+
Dir.chdir('/projects/foo')
|
|
15
|
+
Shelly::App.stub(:new).and_return(app)
|
|
16
|
+
File.open('Cloudfile', 'w') { |f| f.write("foo-production:\n") }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe '#list' do
|
|
20
|
+
it 'should ensure user has logged in' do
|
|
21
|
+
hooks(cli, :list).should include(:logged_in?)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context 'when cloud have maintenances' do
|
|
25
|
+
before do
|
|
26
|
+
app.should_receive(:maintenances).and_return([{
|
|
27
|
+
'description'=>'Testing',
|
|
28
|
+
'user'=>'user@example.com',
|
|
29
|
+
'created_at'=>'2014-07-03T09:45:42+02:00',
|
|
30
|
+
'updated_at'=>'2014-07-03T09:45:42+02:00',
|
|
31
|
+
'finished'=>false
|
|
32
|
+
}, {
|
|
33
|
+
'description'=>'Short maintenance',
|
|
34
|
+
'user'=>'user@example.com',
|
|
35
|
+
'created_at'=>'2014-07-02T13:32:07+02:00',
|
|
36
|
+
'updated_at'=>'2014-07-02T13:32:40+02:00',
|
|
37
|
+
'finished'=>true
|
|
38
|
+
}])
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'should print list of last maintenance events' do
|
|
42
|
+
$stdout.should_receive(:puts).
|
|
43
|
+
with(green 'Recent application maintenance events')
|
|
44
|
+
$stdout.should_receive(:puts).with("\n")
|
|
45
|
+
$stdout.should_receive(:puts).
|
|
46
|
+
with(" * #{local_time('2014-07-03T09:45:42+02:00')} - in progress")
|
|
47
|
+
$stdout.should_receive(:puts).
|
|
48
|
+
with(' Testing')
|
|
49
|
+
$stdout.should_receive(:puts).with("\n")
|
|
50
|
+
$stdout.should_receive(:puts).
|
|
51
|
+
with(" * #{local_time('2014-07-02T13:32:07+02:00')} -" \
|
|
52
|
+
" #{local_time('2014-07-02T13:32:40+02:00')}")
|
|
53
|
+
$stdout.should_receive(:puts).
|
|
54
|
+
with(' Short maintenance')
|
|
55
|
+
$stdout.should_receive(:puts).with("\n")
|
|
56
|
+
|
|
57
|
+
invoke(cli, :list)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def local_time(date)
|
|
63
|
+
Time.parse(date).getlocal.strftime('%Y-%m-%d %H:%M:%S')
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context 'when cloud does not have any maintenance events' do
|
|
68
|
+
before do
|
|
69
|
+
client.stub(:maintenances).and_return([])
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'should show message' do
|
|
73
|
+
$stdout.should_receive(:puts).
|
|
74
|
+
with('There are no maintenance events for foo-production')
|
|
75
|
+
invoke(cli, :list)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
describe '#start' do
|
|
81
|
+
it 'should ensure user has logged in' do
|
|
82
|
+
hooks(cli, :start).should include(:logged_in?)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'should start new maintenance' do
|
|
86
|
+
client.should_receive(:start_maintenance).
|
|
87
|
+
with('foo-production', {:description=>'Test'})
|
|
88
|
+
$stdout.should_receive(:puts).with(green 'Maintenance has been started')
|
|
89
|
+
invoke(cli, :start, 'Test')
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
context 'on failure' do
|
|
93
|
+
context 'because description is missed' do
|
|
94
|
+
before do
|
|
95
|
+
body = {
|
|
96
|
+
'message' => 'Validation Failed',
|
|
97
|
+
'errors' => [['description', "can't be blank"]]
|
|
98
|
+
}
|
|
99
|
+
exception = Shelly::Client::ValidationException.new(body)
|
|
100
|
+
client.stub(:start_maintenance).and_raise(exception)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it 'should print error message' do
|
|
104
|
+
$stdout.should_receive(:puts).with(red "Description can't be blank")
|
|
105
|
+
invoke(cli, :start)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
context 'because there is another maintenance in progress' do
|
|
110
|
+
before do
|
|
111
|
+
body = {
|
|
112
|
+
'message' => 'Validation Failed',
|
|
113
|
+
'errors' => [['base', 'Maintenance already in progress']]
|
|
114
|
+
}
|
|
115
|
+
exception = Shelly::Client::ValidationException.new(body)
|
|
116
|
+
client.stub(:start_maintenance).and_raise(exception)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it 'should print error message' do
|
|
120
|
+
$stdout.should_receive(:puts).
|
|
121
|
+
with(red 'Maintenance already in progress')
|
|
122
|
+
invoke(cli, :start)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
describe '#finish' do
|
|
129
|
+
it 'should ensure user has logged in' do
|
|
130
|
+
hooks(cli, :finish).should include(:logged_in?)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it 'should finish last maintenance' do
|
|
134
|
+
client.should_receive(:finish_maintenance).
|
|
135
|
+
with('foo-production')
|
|
136
|
+
$stdout.should_receive(:puts).with(green 'Maintenance has been finished')
|
|
137
|
+
invoke(cli, :finish)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
context 'on failure' do
|
|
141
|
+
context 'because there is no maintenances in progress' do
|
|
142
|
+
before do
|
|
143
|
+
body = {
|
|
144
|
+
'message' => 'Validation Failed',
|
|
145
|
+
'errors' => [['base', 'There is no maintenances in progress']]
|
|
146
|
+
}
|
|
147
|
+
exception = Shelly::Client::ValidationException.new(body)
|
|
148
|
+
client.stub(:finish_maintenance).and_raise(exception)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it 'should print error message' do
|
|
152
|
+
$stdout.should_receive(:puts).
|
|
153
|
+
with(red 'There is no maintenances in progress')
|
|
154
|
+
invoke(cli, :finish)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
data/spec/shelly/client_spec.rb
CHANGED
|
@@ -216,6 +216,44 @@ describe Shelly::Client do
|
|
|
216
216
|
end
|
|
217
217
|
end
|
|
218
218
|
|
|
219
|
+
describe '#maintenances' do
|
|
220
|
+
it 'should fetch list of maintenances from API' do
|
|
221
|
+
FakeWeb.register_uri(:get, api_url('apps/staging-foo/maintenances'),
|
|
222
|
+
:body => [{"description"=>"Short maintenance",
|
|
223
|
+
"user"=>"user@example.com",
|
|
224
|
+
"created_at"=>"2014-06-30T21:28:35+02:00",
|
|
225
|
+
"updated_at"=>"2014-06-30T21:28:49+02:00",
|
|
226
|
+
"finished"=>true
|
|
227
|
+
}].to_json
|
|
228
|
+
)
|
|
229
|
+
response = @client.maintenances('staging-foo')
|
|
230
|
+
response.should == [{
|
|
231
|
+
"description"=>"Short maintenance",
|
|
232
|
+
"user"=>"user@example.com",
|
|
233
|
+
"created_at"=>"2014-06-30T21:28:35+02:00",
|
|
234
|
+
"updated_at"=>"2014-06-30T21:28:49+02:00",
|
|
235
|
+
"finished"=>true
|
|
236
|
+
}]
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
describe '#start_maintenance' do
|
|
241
|
+
it 'should post a new maintenance' do
|
|
242
|
+
@client.should_receive(:post).with('/apps/staging-foo/maintenances',
|
|
243
|
+
:maintenance => {:description => 'Short maintenance'})
|
|
244
|
+
@client.start_maintenance('staging-foo',
|
|
245
|
+
:description => 'Short maintenance')
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
describe '#finish_maintenance' do
|
|
250
|
+
it 'should update the last maintenance' do
|
|
251
|
+
@client.should_receive(:put).with('/apps/staging-foo/maintenances/last',
|
|
252
|
+
:maintenance => {:finished => true})
|
|
253
|
+
@client.finish_maintenance('staging-foo')
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
219
257
|
describe "#app" do
|
|
220
258
|
it "should fetch app from API" do
|
|
221
259
|
FakeWeb.register_uri(:get, api_url("apps/staging-foo"),
|
metadata
CHANGED
|
@@ -1,237 +1,237 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shelly
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.35
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shelly Cloud team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-
|
|
11
|
+
date: 2014-07-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rspec
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- -
|
|
17
|
+
- - ~>
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: 2.11.0
|
|
20
20
|
type: :development
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- -
|
|
24
|
+
- - ~>
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: 2.11.0
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rake
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- -
|
|
31
|
+
- - '>='
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: '0'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- -
|
|
38
|
+
- - '>='
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '0'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: simplecov
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
|
-
- -
|
|
45
|
+
- - '>='
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
47
|
version: '0'
|
|
48
48
|
type: :development
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
|
-
- -
|
|
52
|
+
- - '>='
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '0'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: ruby_gntp
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
|
-
- -
|
|
59
|
+
- - '>='
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
61
|
version: '0'
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
|
-
- -
|
|
66
|
+
- - '>='
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '0'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: rb-fsevent
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
|
-
- -
|
|
73
|
+
- - '>='
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
75
|
version: '0'
|
|
76
76
|
type: :development
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
|
-
- -
|
|
80
|
+
- - '>='
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '0'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
84
|
name: fakefs
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
|
-
- -
|
|
87
|
+
- - ~>
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
89
|
version: 0.4.3
|
|
90
90
|
type: :development
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
|
-
- -
|
|
94
|
+
- - ~>
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: 0.4.3
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: fakeweb
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
100
100
|
requirements:
|
|
101
|
-
- -
|
|
101
|
+
- - '>='
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
103
|
version: '0'
|
|
104
104
|
type: :development
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
|
-
- -
|
|
108
|
+
- - '>='
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
110
|
version: '0'
|
|
111
111
|
- !ruby/object:Gem::Dependency
|
|
112
112
|
name: pry
|
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
|
114
114
|
requirements:
|
|
115
|
-
- -
|
|
115
|
+
- - '>='
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
117
|
version: '0'
|
|
118
118
|
type: :development
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
|
-
- -
|
|
122
|
+
- - '>='
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
124
|
version: '0'
|
|
125
125
|
- !ruby/object:Gem::Dependency
|
|
126
126
|
name: wijet-thor
|
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
|
128
128
|
requirements:
|
|
129
|
-
- -
|
|
129
|
+
- - ~>
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
131
|
version: 0.14.10
|
|
132
132
|
type: :runtime
|
|
133
133
|
prerelease: false
|
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
135
|
requirements:
|
|
136
|
-
- -
|
|
136
|
+
- - ~>
|
|
137
137
|
- !ruby/object:Gem::Version
|
|
138
138
|
version: 0.14.10
|
|
139
139
|
- !ruby/object:Gem::Dependency
|
|
140
140
|
name: rest-client
|
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
|
142
142
|
requirements:
|
|
143
|
-
- -
|
|
143
|
+
- - '>='
|
|
144
144
|
- !ruby/object:Gem::Version
|
|
145
145
|
version: '0'
|
|
146
146
|
type: :runtime
|
|
147
147
|
prerelease: false
|
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
149
|
requirements:
|
|
150
|
-
- -
|
|
150
|
+
- - '>='
|
|
151
151
|
- !ruby/object:Gem::Version
|
|
152
152
|
version: '0'
|
|
153
153
|
- !ruby/object:Gem::Dependency
|
|
154
154
|
name: mime-types
|
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
|
156
156
|
requirements:
|
|
157
|
-
- -
|
|
157
|
+
- - ~>
|
|
158
158
|
- !ruby/object:Gem::Version
|
|
159
159
|
version: '1.16'
|
|
160
160
|
type: :runtime
|
|
161
161
|
prerelease: false
|
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
|
163
163
|
requirements:
|
|
164
|
-
- -
|
|
164
|
+
- - ~>
|
|
165
165
|
- !ruby/object:Gem::Version
|
|
166
166
|
version: '1.16'
|
|
167
167
|
- !ruby/object:Gem::Dependency
|
|
168
168
|
name: json
|
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
|
170
170
|
requirements:
|
|
171
|
-
- -
|
|
171
|
+
- - '>='
|
|
172
172
|
- !ruby/object:Gem::Version
|
|
173
173
|
version: '0'
|
|
174
174
|
type: :runtime
|
|
175
175
|
prerelease: false
|
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
|
177
177
|
requirements:
|
|
178
|
-
- -
|
|
178
|
+
- - '>='
|
|
179
179
|
- !ruby/object:Gem::Version
|
|
180
180
|
version: '0'
|
|
181
181
|
- !ruby/object:Gem::Dependency
|
|
182
182
|
name: ruby-progressbar
|
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
|
184
184
|
requirements:
|
|
185
|
-
- -
|
|
185
|
+
- - '>='
|
|
186
186
|
- !ruby/object:Gem::Version
|
|
187
187
|
version: '0'
|
|
188
188
|
type: :runtime
|
|
189
189
|
prerelease: false
|
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
191
|
requirements:
|
|
192
|
-
- -
|
|
192
|
+
- - '>='
|
|
193
193
|
- !ruby/object:Gem::Version
|
|
194
194
|
version: '0'
|
|
195
195
|
- !ruby/object:Gem::Dependency
|
|
196
196
|
name: launchy
|
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
|
198
198
|
requirements:
|
|
199
|
-
- -
|
|
199
|
+
- - '>='
|
|
200
200
|
- !ruby/object:Gem::Version
|
|
201
201
|
version: '0'
|
|
202
202
|
type: :runtime
|
|
203
203
|
prerelease: false
|
|
204
204
|
version_requirements: !ruby/object:Gem::Requirement
|
|
205
205
|
requirements:
|
|
206
|
-
- -
|
|
206
|
+
- - '>='
|
|
207
207
|
- !ruby/object:Gem::Version
|
|
208
208
|
version: '0'
|
|
209
209
|
- !ruby/object:Gem::Dependency
|
|
210
210
|
name: netrc
|
|
211
211
|
requirement: !ruby/object:Gem::Requirement
|
|
212
212
|
requirements:
|
|
213
|
-
- -
|
|
213
|
+
- - '>='
|
|
214
214
|
- !ruby/object:Gem::Version
|
|
215
215
|
version: '0'
|
|
216
216
|
type: :runtime
|
|
217
217
|
prerelease: false
|
|
218
218
|
version_requirements: !ruby/object:Gem::Requirement
|
|
219
219
|
requirements:
|
|
220
|
-
- -
|
|
220
|
+
- - '>='
|
|
221
221
|
- !ruby/object:Gem::Version
|
|
222
222
|
version: '0'
|
|
223
223
|
- !ruby/object:Gem::Dependency
|
|
224
224
|
name: childprocess
|
|
225
225
|
requirement: !ruby/object:Gem::Requirement
|
|
226
226
|
requirements:
|
|
227
|
-
- -
|
|
227
|
+
- - '>='
|
|
228
228
|
- !ruby/object:Gem::Version
|
|
229
229
|
version: '0'
|
|
230
230
|
type: :runtime
|
|
231
231
|
prerelease: false
|
|
232
232
|
version_requirements: !ruby/object:Gem::Requirement
|
|
233
233
|
requirements:
|
|
234
|
-
- -
|
|
234
|
+
- - '>='
|
|
235
235
|
- !ruby/object:Gem::Version
|
|
236
236
|
version: '0'
|
|
237
237
|
description: Tool for managing applications and clouds at shellycloud.com
|
|
@@ -242,8 +242,8 @@ executables:
|
|
|
242
242
|
extensions: []
|
|
243
243
|
extra_rdoc_files: []
|
|
244
244
|
files:
|
|
245
|
-
-
|
|
246
|
-
-
|
|
245
|
+
- .gitignore
|
|
246
|
+
- .travis.yml
|
|
247
247
|
- CHANGELOG.md
|
|
248
248
|
- Gemfile
|
|
249
249
|
- LICENSE
|
|
@@ -268,6 +268,7 @@ files:
|
|
|
268
268
|
- lib/shelly/cli/main.rb
|
|
269
269
|
- lib/shelly/cli/main/add.rb
|
|
270
270
|
- lib/shelly/cli/main/check.rb
|
|
271
|
+
- lib/shelly/cli/maintenance.rb
|
|
271
272
|
- lib/shelly/cli/organization.rb
|
|
272
273
|
- lib/shelly/cli/runner.rb
|
|
273
274
|
- lib/shelly/cli/user.rb
|
|
@@ -281,6 +282,7 @@ files:
|
|
|
281
282
|
- lib/shelly/client/deployment_logs.rb
|
|
282
283
|
- lib/shelly/client/deploys.rb
|
|
283
284
|
- lib/shelly/client/errors.rb
|
|
285
|
+
- lib/shelly/client/maintenance.rb
|
|
284
286
|
- lib/shelly/client/organizations.rb
|
|
285
287
|
- lib/shelly/client/shellyapp.rb
|
|
286
288
|
- lib/shelly/client/ssh_keys.rb
|
|
@@ -316,6 +318,7 @@ files:
|
|
|
316
318
|
- spec/shelly/cli/file_spec.rb
|
|
317
319
|
- spec/shelly/cli/logs_spec.rb
|
|
318
320
|
- spec/shelly/cli/main_spec.rb
|
|
321
|
+
- spec/shelly/cli/maintenance_spec.rb
|
|
319
322
|
- spec/shelly/cli/organization_spec.rb
|
|
320
323
|
- spec/shelly/cli/runner_spec.rb
|
|
321
324
|
- spec/shelly/cli/user_spec.rb
|
|
@@ -340,12 +343,12 @@ require_paths:
|
|
|
340
343
|
- lib
|
|
341
344
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
342
345
|
requirements:
|
|
343
|
-
- -
|
|
346
|
+
- - '>='
|
|
344
347
|
- !ruby/object:Gem::Version
|
|
345
348
|
version: '0'
|
|
346
349
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
347
350
|
requirements:
|
|
348
|
-
- -
|
|
351
|
+
- - '>='
|
|
349
352
|
- !ruby/object:Gem::Version
|
|
350
353
|
version: '0'
|
|
351
354
|
requirements: []
|
|
@@ -368,6 +371,7 @@ test_files:
|
|
|
368
371
|
- spec/shelly/cli/file_spec.rb
|
|
369
372
|
- spec/shelly/cli/logs_spec.rb
|
|
370
373
|
- spec/shelly/cli/main_spec.rb
|
|
374
|
+
- spec/shelly/cli/maintenance_spec.rb
|
|
371
375
|
- spec/shelly/cli/organization_spec.rb
|
|
372
376
|
- spec/shelly/cli/runner_spec.rb
|
|
373
377
|
- spec/shelly/cli/user_spec.rb
|