shelly 0.0.41.pre → 0.0.41

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/lib/shelly/app.rb CHANGED
@@ -74,6 +74,10 @@ module Shelly
74
74
  Shelly::Backup.new(attributes.merge("code_name" => code_name))
75
75
  end
76
76
 
77
+ def restore_backup(filename)
78
+ shelly.restore_backup(code_name, filename)
79
+ end
80
+
77
81
  def request_backup(kind)
78
82
  shelly.request_backup(code_name, kind)
79
83
  end
data/lib/shelly/backup.rb CHANGED
@@ -1,12 +1,13 @@
1
1
  module Shelly
2
2
  class Backup < Model
3
- attr_reader :filename, :size, :human_size, :code_name
3
+ attr_reader :filename, :size, :human_size, :code_name, :kind
4
4
 
5
5
  def initialize(attributes = {})
6
6
  @filename = attributes["filename"]
7
7
  @size = attributes["size"]
8
8
  @human_size = attributes["human_size"]
9
9
  @code_name = attributes["code_name"]
10
+ @kind = attributes["kind"]
10
11
  end
11
12
 
12
13
  def download(callback)
@@ -65,7 +65,7 @@ module Shelly
65
65
  def create(kind = nil)
66
66
  multiple_clouds(options[:cloud], "backup create", "Select cloud to create snapshot of database")
67
67
  @app.request_backup(kind)
68
- say "Backup requested. It can take up to several minutes for" +
68
+ say "Backup requested. It can take up to several minutes for " +
69
69
  "the backup process to finish and the backup to show up in backups list.", :green
70
70
  rescue Client::APIError => e
71
71
  if e.not_found?
@@ -74,6 +74,29 @@ module Shelly
74
74
  say_error e.message
75
75
  end
76
76
  end
77
+
78
+ desc "restore <filename>", "Restore database to state from filename"
79
+ method_option :cloud, :type => :string, :aliases => "-c",
80
+ :desc => "Specify which cloud to restore database snapshot for"
81
+ def restore(filename = nil)
82
+ logged_in?
83
+ multiple_clouds(options[:cloud], "backup restore <filename>", "Select cloud for which you want restore backup")
84
+ say_error "Filename is required" unless filename
85
+ backup = @app.database_backup(filename)
86
+ say "You are about restore database #{backup.kind} for cloud #{backup.code_name} to state from #{backup.filename}"
87
+ say_new_line
88
+ ask_to_restore_database
89
+ @app.restore_backup(filename)
90
+ say_new_line
91
+ say "Restore has been scheduled. Wait few minutes till database is restored."
92
+ rescue Client::APIError => e
93
+ if e.not_found?
94
+ say_error "Backup not found", :with_exit => false
95
+ say "You can list available backups with 'shelly backup list' command"
96
+ else
97
+ raise e
98
+ end
99
+ end
77
100
  end
78
101
  end
79
102
  end
@@ -60,13 +60,8 @@ module Shelly
60
60
  user.password = ask_for_password(:with_confirmation => false)
61
61
  user.login
62
62
  say "Login successful"
63
- # FIXME: remove conflict boolean, move it to rescue block
64
- begin user.upload_ssh_key
65
- conflict = false
66
- rescue RestClient::Conflict
67
- conflict = true
68
- end
69
- say "Uploading your public SSH key" if conflict == false
63
+ user.upload_ssh_key
64
+ say "Uploading your public SSH key"
70
65
  list
71
66
  rescue Client::APIError => e
72
67
  if e.validation?
data/lib/shelly/client.rb CHANGED
@@ -6,7 +6,7 @@ module Shelly
6
6
  class Client
7
7
  class APIError < Exception
8
8
  attr_reader :status_code, :body
9
-
9
+
10
10
  def initialize(status_code, body = {})
11
11
  @status_code = status_code
12
12
  @body = body
@@ -118,7 +118,7 @@ module Shelly
118
118
  def apps
119
119
  get("/apps")
120
120
  end
121
-
121
+
122
122
  def app(code_name)
123
123
  get("/apps/#{code_name}")
124
124
  end
@@ -138,11 +138,15 @@ module Shelly
138
138
  def database_backups(code_name)
139
139
  get("/apps/#{code_name}/database_backups")
140
140
  end
141
-
141
+
142
142
  def database_backup(code_name, handler)
143
143
  get("/apps/#{code_name}/database_backups/#{handler}")
144
144
  end
145
145
 
146
+ def restore_backup(code_name, filename)
147
+ put("/apps/#{code_name}/database_backups/#{filename}/restore")
148
+ end
149
+
146
150
  def request_backup(code_name, kind = nil)
147
151
  post("/apps/#{code_name}/database_backups", :kind => kind)
148
152
  end
@@ -170,7 +174,7 @@ module Shelly
170
174
  def delete(path, params = {})
171
175
  request(path, :delete, params)
172
176
  end
173
-
177
+
174
178
  def download_backup(cloud, filename, progress_callback = nil)
175
179
  File.open(filename, "w") do |out|
176
180
  process_response = lambda do |response|
@@ -181,9 +185,9 @@ module Shelly
181
185
  end
182
186
 
183
187
  options = request_parameters("/apps/#{cloud}/database_backups/#{filename}", :get)
184
- options = options.merge(:block_response => process_response,
188
+ options = options.merge(:block_response => process_response,
185
189
  :headers => {:accept => "application/x-gzip"})
186
-
190
+
187
191
  RestClient::Request.execute(options)
188
192
  end
189
193
  end
@@ -53,6 +53,12 @@ module Shelly
53
53
  say_error "No Cloudfile found" unless Cloudfile.present?
54
54
  end
55
55
 
56
+ def ask_to_restore_database
57
+ delete_application_question = "I want to restore the database (yes/no):"
58
+ delete_application = ask(delete_application_question)
59
+ say_new_line say_error "Canceled" unless delete_application == "yes"
60
+ end
61
+
56
62
  def logged_in?
57
63
  user = Shelly::User.new
58
64
  user.token
@@ -1,3 +1,3 @@
1
1
  module Shelly
2
- VERSION = "0.0.41.pre"
2
+ VERSION = "0.0.41"
3
3
  end
@@ -149,9 +149,63 @@ describe Shelly::CLI::Backup do
149
149
 
150
150
  it "should display information about request backup" do
151
151
  @client.stub(:request_backup)
152
- $stdout.should_receive(:puts).with(green "Backup requested. It can take up to several minutes for" +
152
+ $stdout.should_receive(:puts).with(green "Backup requested. It can take up to several minutes for " +
153
153
  "the backup process to finish and the backup to show up in backups list.")
154
154
  invoke(@backup, :create)
155
155
  end
156
156
  end
157
+
158
+ describe "restore" do
159
+ before do
160
+ @client.stub(:database_backup).and_return({"filename" => "better.tar.gz", "size" => 12345, "kind" => "postgre"})
161
+ @client.stub(:restore_backup).and_return({"filename" => "better.tar.gz", "size" => 12345, "kind" => "postgre"})
162
+ $stdout.stub(:puts)
163
+ end
164
+
165
+ it "should restore database" do
166
+ $stdout.should_receive(:puts).with("You are about restore database postgre for cloud foo-staging to state from better.tar.gz")
167
+ $stdout.should_receive(:print).with("I want to restore the database (yes/no): ")
168
+ $stdout.should_receive(:puts).with("\n")
169
+ @client.stub(:restore_backup).with("todo-list-test","better.tar.gz")
170
+ $stdout.should_receive(:puts).with("\n")
171
+ $stdout.should_receive(:puts).with("Restore has been scheduled. Wait few minutes till database is restored.")
172
+
173
+ fake_stdin(["yes"]) do
174
+ @backup.restore("better.tar.gz")
175
+ end
176
+ end
177
+
178
+ context "on type no" do
179
+ it "should cancel restore database" do
180
+ $stdout.should_receive(:puts).with("You are about restore database postgre for cloud foo-staging to state from better.tar.gz")
181
+ $stdout.should_receive(:print).with("I want to restore the database (yes/no): ")
182
+ $stdout.should_receive(:puts).with("\n")
183
+ $stdout.should_receive(:puts).with(red "Canceled")
184
+
185
+ lambda {
186
+ fake_stdin(["no"]) do
187
+ @backup.restore("better.tar.gz")
188
+ end
189
+ }.should raise_error(SystemExit)
190
+ end
191
+ end
192
+
193
+ it "should exit with 1 when filename is not specified" do
194
+ $stdout.should_receive(:puts).with(red "Filename is required")
195
+ lambda {
196
+ @backup.restore
197
+ }.should raise_error(SystemExit)
198
+ end
199
+
200
+ context "on backup not found" do
201
+ it "should display error message" do
202
+ response = {"message" => "Backup restore not found"}
203
+ exception = Shelly::Client::APIError.new(404, response)
204
+ @client.stub(:database_backup).and_raise(exception)
205
+ $stdout.should_receive(:puts).with(red "Backup not found")
206
+ $stdout.should_receive(:puts).with("You can list available backups with 'shelly backup list' command")
207
+ @backup.restore("better.tar.gz")
208
+ end
209
+ end
210
+ end
157
211
  end
@@ -227,14 +227,6 @@ OUT
227
227
  end
228
228
  end
229
229
 
230
- it "should upload user's public SSH key and raise HTTP status 409 Conflict when SSH key exists in database" do
231
- @user.should_receive(:upload_ssh_key).and_raise(RestClient::Conflict)
232
- $stdout.should_receive(:puts).with("\e[32mYou have following clouds available:\e[0m")
233
- fake_stdin(["megan@example.com", "secret"]) do
234
- invoke(@main, :login)
235
- end
236
- end
237
-
238
230
  it "should display list of applications to which user has access" do
239
231
  $stdout.should_receive(:puts).with("\e[32mYou have following clouds available:\e[0m")
240
232
  $stdout.should_receive(:puts).with(/ abc\s+\| running/)
metadata CHANGED
@@ -1,167 +1,188 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: shelly
3
- version: !ruby/object:Gem::Version
4
- version: 0.0.41.pre
5
- prerelease: 7
3
+ version: !ruby/object:Gem::Version
4
+ hash: 77
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 41
10
+ version: 0.0.41
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Shelly Cloud team
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-01-02 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2012-01-02 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: rspec
16
- requirement: &70129852876100 !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
22
- type: :development
23
22
  prerelease: false
24
- version_requirements: *70129852876100
25
- - !ruby/object:Gem::Dependency
26
- name: rake
27
- requirement: &70129852875680 !ruby/object:Gem::Requirement
23
+ requirement: &id001 !ruby/object:Gem::Requirement
28
24
  none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '0'
33
- type: :development
34
- prerelease: false
35
- version_requirements: *70129852875680
36
- - !ruby/object:Gem::Dependency
37
- name: guard
38
- requirement: &70129852875260 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
43
- version: '0'
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
44
32
  type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: rake
45
36
  prerelease: false
46
- version_requirements: *70129852875260
47
- - !ruby/object:Gem::Dependency
48
- name: guard-rspec
49
- requirement: &70129852874840 !ruby/object:Gem::Requirement
37
+ requirement: &id002 !ruby/object:Gem::Requirement
50
38
  none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
55
46
  type: :development
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: guard
56
50
  prerelease: false
57
- version_requirements: *70129852874840
58
- - !ruby/object:Gem::Dependency
59
- name: growl_notify
60
- requirement: &70129852890740 !ruby/object:Gem::Requirement
51
+ requirement: &id003 !ruby/object:Gem::Requirement
61
52
  none: false
62
- requirements:
63
- - - ! '>='
64
- - !ruby/object:Gem::Version
65
- version: '0'
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
66
60
  type: :development
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: guard-rspec
67
64
  prerelease: false
68
- version_requirements: *70129852890740
69
- - !ruby/object:Gem::Dependency
70
- name: rb-fsevent
71
- requirement: &70129852890320 !ruby/object:Gem::Requirement
65
+ requirement: &id004 !ruby/object:Gem::Requirement
72
66
  none: false
73
- requirements:
74
- - - ! '>='
75
- - !ruby/object:Gem::Version
76
- version: '0'
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
77
74
  type: :development
78
- prerelease: false
79
- version_requirements: *70129852890320
80
- - !ruby/object:Gem::Dependency
75
+ version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
81
77
  name: fakefs
82
- requirement: &70129852889900 !ruby/object:Gem::Requirement
78
+ prerelease: false
79
+ requirement: &id005 !ruby/object:Gem::Requirement
83
80
  none: false
84
- requirements:
85
- - - ! '>='
86
- - !ruby/object:Gem::Version
87
- version: '0'
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
88
88
  type: :development
89
- prerelease: false
90
- version_requirements: *70129852889900
91
- - !ruby/object:Gem::Dependency
89
+ version_requirements: *id005
90
+ - !ruby/object:Gem::Dependency
92
91
  name: fakeweb
93
- requirement: &70129852889480 !ruby/object:Gem::Requirement
92
+ prerelease: false
93
+ requirement: &id006 !ruby/object:Gem::Requirement
94
94
  none: false
95
- requirements:
96
- - - ! '>='
97
- - !ruby/object:Gem::Version
98
- version: '0'
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ hash: 3
99
+ segments:
100
+ - 0
101
+ version: "0"
99
102
  type: :development
100
- prerelease: false
101
- version_requirements: *70129852889480
102
- - !ruby/object:Gem::Dependency
103
+ version_requirements: *id006
104
+ - !ruby/object:Gem::Dependency
103
105
  name: wijet-thor
104
- requirement: &70129852888980 !ruby/object:Gem::Requirement
106
+ prerelease: false
107
+ requirement: &id007 !ruby/object:Gem::Requirement
105
108
  none: false
106
- requirements:
109
+ requirements:
107
110
  - - ~>
108
- - !ruby/object:Gem::Version
111
+ - !ruby/object:Gem::Version
112
+ hash: 41
113
+ segments:
114
+ - 0
115
+ - 14
116
+ - 7
109
117
  version: 0.14.7
110
118
  type: :runtime
111
- prerelease: false
112
- version_requirements: *70129852888980
113
- - !ruby/object:Gem::Dependency
119
+ version_requirements: *id007
120
+ - !ruby/object:Gem::Dependency
114
121
  name: rest-client
115
- requirement: &70129852888560 !ruby/object:Gem::Requirement
122
+ prerelease: false
123
+ requirement: &id008 !ruby/object:Gem::Requirement
116
124
  none: false
117
- requirements:
118
- - - ! '>='
119
- - !ruby/object:Gem::Version
120
- version: '0'
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ hash: 3
129
+ segments:
130
+ - 0
131
+ version: "0"
121
132
  type: :runtime
122
- prerelease: false
123
- version_requirements: *70129852888560
124
- - !ruby/object:Gem::Dependency
133
+ version_requirements: *id008
134
+ - !ruby/object:Gem::Dependency
125
135
  name: json
126
- requirement: &70129852888100 !ruby/object:Gem::Requirement
136
+ prerelease: false
137
+ requirement: &id009 !ruby/object:Gem::Requirement
127
138
  none: false
128
- requirements:
129
- - - ! '>='
130
- - !ruby/object:Gem::Version
131
- version: '0'
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ hash: 3
143
+ segments:
144
+ - 0
145
+ version: "0"
132
146
  type: :runtime
133
- prerelease: false
134
- version_requirements: *70129852888100
135
- - !ruby/object:Gem::Dependency
147
+ version_requirements: *id009
148
+ - !ruby/object:Gem::Dependency
136
149
  name: wijet-launchy
137
- requirement: &70129852887680 !ruby/object:Gem::Requirement
150
+ prerelease: false
151
+ requirement: &id010 !ruby/object:Gem::Requirement
138
152
  none: false
139
- requirements:
140
- - - ! '>='
141
- - !ruby/object:Gem::Version
142
- version: '0'
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ hash: 3
157
+ segments:
158
+ - 0
159
+ version: "0"
143
160
  type: :runtime
144
- prerelease: false
145
- version_requirements: *70129852887680
146
- - !ruby/object:Gem::Dependency
161
+ version_requirements: *id010
162
+ - !ruby/object:Gem::Dependency
147
163
  name: progressbar
148
- requirement: &70129852887260 !ruby/object:Gem::Requirement
164
+ prerelease: false
165
+ requirement: &id011 !ruby/object:Gem::Requirement
149
166
  none: false
150
- requirements:
151
- - - ! '>='
152
- - !ruby/object:Gem::Version
153
- version: '0'
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ hash: 3
171
+ segments:
172
+ - 0
173
+ version: "0"
154
174
  type: :runtime
155
- prerelease: false
156
- version_requirements: *70129852887260
175
+ version_requirements: *id011
157
176
  description: Tool for managing applications and clouds at shellycloud.com
158
- email:
177
+ email:
159
178
  - support@shellycloud.com
160
- executables:
179
+ executables:
161
180
  - shelly
162
181
  extensions: []
182
+
163
183
  extra_rdoc_files: []
164
- files:
184
+
185
+ files:
165
186
  - .gitignore
166
187
  - .travis.yml
167
188
  - Gemfile
@@ -213,43 +234,36 @@ files:
213
234
  - spec/thor/options_spec.rb
214
235
  homepage: http://shellycloud.com
215
236
  licenses: []
237
+
216
238
  post_install_message:
217
239
  rdoc_options: []
218
- require_paths:
240
+
241
+ require_paths:
219
242
  - lib
220
- required_ruby_version: !ruby/object:Gem::Requirement
243
+ required_ruby_version: !ruby/object:Gem::Requirement
221
244
  none: false
222
- requirements:
223
- - - ! '>='
224
- - !ruby/object:Gem::Version
225
- version: '0'
226
- required_rubygems_version: !ruby/object:Gem::Requirement
245
+ requirements:
246
+ - - ">="
247
+ - !ruby/object:Gem::Version
248
+ hash: 3
249
+ segments:
250
+ - 0
251
+ version: "0"
252
+ required_rubygems_version: !ruby/object:Gem::Requirement
227
253
  none: false
228
- requirements:
229
- - - ! '>'
230
- - !ruby/object:Gem::Version
231
- version: 1.3.1
254
+ requirements:
255
+ - - ">="
256
+ - !ruby/object:Gem::Version
257
+ hash: 3
258
+ segments:
259
+ - 0
260
+ version: "0"
232
261
  requirements: []
262
+
233
263
  rubyforge_project: shelly
234
264
  rubygems_version: 1.8.10
235
265
  signing_key:
236
266
  specification_version: 3
237
267
  summary: Shelly Cloud command line tool
238
- test_files:
239
- - spec/helpers.rb
240
- - spec/input_faker.rb
241
- - spec/shelly/app_spec.rb
242
- - spec/shelly/backup_spec.rb
243
- - spec/shelly/cli/backup_spec.rb
244
- - spec/shelly/cli/config_spec.rb
245
- - spec/shelly/cli/deploys_spec.rb
246
- - spec/shelly/cli/main_spec.rb
247
- - spec/shelly/cli/runner_spec.rb
248
- - spec/shelly/cli/user_spec.rb
249
- - spec/shelly/client_spec.rb
250
- - spec/shelly/cloudfile_spec.rb
251
- - spec/shelly/download_progress_bar_spec.rb
252
- - spec/shelly/model_spec.rb
253
- - spec/shelly/user_spec.rb
254
- - spec/spec_helper.rb
255
- - spec/thor/options_spec.rb
268
+ test_files: []
269
+