mongo-db-utils 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 415c2d49fcbcad5aa3e835eb0b5fe88c880e8cfe
4
- data.tar.gz: 93218696727910919cd569d0658fa1f2fe8f6a65
3
+ metadata.gz: 64d078336bb048c54737b7b64e60fcf47c4f3d0e
4
+ data.tar.gz: 58354687f31dccf5167fd7b0b29137169a28d3b6
5
5
  SHA512:
6
- metadata.gz: d6b92ba1baa0e548c2f845370e2a909602897ff216e6bb6366803c7535f286a22783be2cc9557a6816751bc9e74da2ebc137f3320214a4538bc5d9c91100ea49
7
- data.tar.gz: a56d22c2bc234e4e9c9c2cadab2a27b019228a4ac577b620a1462e2cfd584ac6f3848f59ab4e8cd1447c8446102edc75cd923923a22e561ac1446faebbb326ba
6
+ metadata.gz: 8aaf333d8260db8be954322607dbd274dc618996c0dda3af22ec2e15682bc1b3c61cddb7bae22feecc351468afafb01d22e0ef59928d9dabb83ba64c11a781f5
7
+ data.tar.gz: a2aeaf7c4bca99df2cc66c356f05a151791aff770587e6aad751b4d0012d6c1db1150c1ef90cfd0748bf01cde71ff15979916e9c9e3f73a2a82497523e0feef7
@@ -40,6 +40,17 @@ module MongoDbUtils
40
40
  Cmd.backup_s3(backup_folder, db, bucket_name, access_key_id, secret_access_key)
41
41
  end
42
42
 
43
+ desc "restore_from_s3 MONGO_URI BUCKET ACCESS_KEY SECRET_ACCESS_KEY SOURCE_DB [REPLICA_SET_NAME]", "restore a db from Amason s3 with a mongo uri eg: mongodb://user:pass@server:port/dbname"
44
+ def restore_from_s3(mongo_uri, bucket_name, access_key_id, secret_access_key, source_db, replica_set_name = nil)
45
+ config = get_config
46
+ db = get_db(mongo_uri, replica_set_name)
47
+ raise "can't parse uri" if db.nil?
48
+ Dir.mktmpdir do |tmp_dir|
49
+ backup = Cmd.download_backup_from_s3(tmp_dir, 'latest', bucket_name, access_key_id, secret_access_key)
50
+ Cmd.restore_from_backup(tmp_dir, db, backup, source_db)
51
+ end
52
+ end
53
+
43
54
  private
44
55
 
45
56
  def get_config(path = ConfigLoader::CONFIG_LOCATION)
@@ -8,14 +8,14 @@ module MongoDbUtils
8
8
 
9
9
  def self.backup(db, folder, final_path = nil, tar_it = true)
10
10
  puts ">> Backing up: #{db}, #{folder}, #{final_path}"
11
- unless( db_exists?(db) )
11
+ unless (db_exists?(db))
12
12
  return false
13
13
  end
14
14
 
15
- if( final_path.nil? )
16
- out_path = "#{folder}/#{db.to_host_s}/#{db.name}/#{timestamp}"
15
+ if (final_path.nil?)
16
+ out_path = File.join(folder, db.to_host_s, db.name, timestamp)
17
17
  else
18
- out_path = "#{folder}/#{final_path}"
18
+ out_path = File.join(folder, final_path)
19
19
  end
20
20
 
21
21
  full_path = File.expand_path(out_path)
@@ -23,6 +23,7 @@ module MongoDbUtils
23
23
  puts ">> final backup path: #{full_path}"
24
24
 
25
25
  FileUtils.mkdir_p(full_path)
26
+
26
27
  Dump.new(
27
28
  db.to_host_s,
28
29
  db.name,
@@ -30,42 +31,48 @@ module MongoDbUtils
30
31
  db.username,
31
32
  db.password).run
32
33
 
33
- if( tar_it )
34
+ full_db_path = File.join(full_path, db.name)
35
+
36
+ if (tar_it)
34
37
  Dir.chdir(full_path)
35
- `tar cvf #{db.name}.tar #{db.name}`
36
- `rm -fr #{full_path}/#{db.name}`
37
- "#{full_path}/#{db.name}.tar"
38
+ `tar --create --verbose --file=#{db.name}.tar #{db.name}`
39
+ delete_folder full_db_path
40
+ "#{full_db_path}.tar"
38
41
  else
39
- "#{full_path}/#{db.name}"
42
+ full_db_path
40
43
  end
41
44
  end
42
45
 
43
46
  # With remote dbs you can't do a copy_database if you're not an admin.
44
47
  def self.copy(path, source, destination, halt_on_no_backup = true, skip_backup = false)
45
48
 
46
- backup_made = if skip_backup then true else backup(destination, path) end
49
+ backup_made = if skip_backup
50
+ true
51
+ else
52
+ backup(destination, path)
53
+ end
47
54
 
48
- if( !backup_made && halt_on_no_backup)
49
- puts "aborting - no backup was made"
55
+ if !backup_made && halt_on_no_backup
56
+ puts 'aborting - no backup was made'
50
57
  return
51
58
  end
52
59
 
53
- tmp_path = "~/.mongo-db-utils/tmp"
60
+ tmp_path = File.join(ConfigLoader::CONFIG_LOCATION, 'tmp')
54
61
 
55
62
  FileUtils.mkdir_p(tmp_path)
56
63
 
57
- puts "backup to: #{tmp_path}/#{source.name}"
58
- tmp_dump_path = backup(source,tmp_path, source.name, false)
59
-
60
- username = destination.username
61
- password = destination.password
64
+ puts "backup to: #{File.join(tmp_path, source.name)}"
65
+ tmp_dump_path = backup(source, tmp_path, source.name, false)
62
66
 
63
67
  # if the destination db doesn't exist
64
68
  # we assume that the user has admin control of the server
65
69
  # eg its a local server (this needs to be thought through a bit more)
66
- if( !db_exists?(destination) )
67
- username = ""
68
- password = ""
70
+ username = ''
71
+ password = ''
72
+
73
+ if db_exists? destination
74
+ username = destination.username
75
+ password = destination.password
69
76
  end
70
77
 
71
78
  Restore.new(
@@ -75,16 +82,62 @@ module MongoDbUtils
75
82
  username,
76
83
  password).run
77
84
 
78
- `rm -fr #{tmp_path}`
85
+ delete_folder tmp_path
79
86
  end
80
87
 
81
- def self.backup_s3(backup_folder, db, bucket_name, access_key_id, secret_access_key)
88
+ def self.backup_s3(backup_folder, db, bucket_name, access_key_id, secret_access_key)
82
89
  tar_file = MongoDbUtils::Cmd.backup(db, backup_folder)
83
- name = tar_file.gsub(File.expand_path(backup_folder), "")
90
+ name = tar_file.gsub(File.expand_path(backup_folder), '')
84
91
  MongoDbUtils::S3::put_file(tar_file, name, bucket_name, access_key_id, secret_access_key)
85
92
  file = File.basename(tar_file)
86
- folder = tar_file.gsub(file, "")
87
- `rm -fr #{folder}`
93
+ folder = tar_file.gsub(file, '')
94
+ delete_folder folder
95
+ end
96
+
97
+ def self.list_backups(bucket_name, access_key_id, secret_access_key)
98
+ MongoDbUtils::S3::list_bucket(bucket_name, access_key_id, secret_access_key)
99
+ end
100
+
101
+ def self.list_downloaded_backups(backup_folder)
102
+ FileUtils.mkdir_p(backup_folder)
103
+ Dir.entries(backup_folder).select { |a| a.end_with? '.tgz' }
104
+ end
105
+
106
+ def self.list_backup_folders(backup_folder, backup)
107
+ puts "reading backup folders from #{backup_folder} #{backup}"
108
+ folders = list_archive_folders(backup_folder, backup)
109
+ folders.map { |a| a.slice! File.basename(backup, '.tgz'); a.delete '/' }.select { |a| a != '' }
110
+ end
111
+
112
+ def self.download_backup_from_s3(backup_folder, backup, bucket_name, access_key_id, secret_access_key)
113
+ if backup == 'latest'
114
+ backup = get_latest_backup(bucket_name, access_key_id, secret_access_key)
115
+ end
116
+ backup_file = File.join(backup_folder, File.basename(backup))
117
+
118
+ puts "download_backup_from_s3 #{backup_file}"
119
+ if File.exists? backup_file
120
+ puts "File downloaded already #{backup_file}"
121
+ else
122
+ FileUtils.mkdir_p(backup_folder)
123
+ puts "Downloading #{backup_file}"
124
+ download_backup(backup_file, backup, bucket_name, access_key_id, secret_access_key)
125
+ end
126
+ backup
127
+ end
128
+
129
+ def self.restore_from_backup(backup_folder, db, backup, source_db)
130
+ Dir.mktmpdir do |dir|
131
+ puts "Unzipping archive ..."
132
+ unzip(File.join(backup_folder, backup), dir)
133
+ puts "Restoring db ..."
134
+ restore_db(db, File.join(dir, source_db ))
135
+ end
136
+ end
137
+
138
+
139
+ def self.delete_backup(backup_folder, backup)
140
+ delete_folder File.join(backup_folder, backup)
88
141
  end
89
142
 
90
143
 
@@ -92,7 +145,7 @@ module MongoDbUtils
92
145
 
93
146
  def self.timestamp
94
147
  t = Time.new
95
- t.strftime("%Y.%m.%d__%H.%M")
148
+ t.strftime('%Y.%m.%d__%H.%M')
96
149
  end
97
150
 
98
151
  def self.db_exists?(db)
@@ -108,5 +161,56 @@ module MongoDbUtils
108
161
  exists
109
162
  end
110
163
 
164
+ def self.download_backup(download_file_name, backup, bucket_name, access_key_id, secret_access_key)
165
+ puts "downloading backup to #{download_file_name} from #{bucket_name} key #{backup}"
166
+ MongoDbUtils::S3::get_file(download_file_name, backup, bucket_name, access_key_id, secret_access_key)
167
+ end
168
+
169
+ def self.restore_db(destination, backup)
170
+ puts "restoring db #{destination} from #{backup}"
171
+
172
+ # if the destination db doesn't exist
173
+ # we assume that the user has admin control of the server
174
+ # eg its a local server (this needs to be thought through a bit more)
175
+ username = ''
176
+ password = ''
177
+
178
+ if db_exists? destination
179
+ username = destination.username
180
+ password = destination.password
181
+ end
182
+
183
+ Restore.new(
184
+ destination.to_host_s,
185
+ destination.name,
186
+ backup,
187
+ username,
188
+ password).run
189
+ end
190
+
191
+ def self.unzip(archive, dir)
192
+ command = "tar --extract --gzip --file=#{archive} --directory=#{dir} --strip 1"
193
+ output = `#{command} 2>&1`
194
+ raise "#{output} cmd <#{command}>" unless $?.to_i == 0
195
+ end
196
+
197
+ def self.list_archive_folders(folder, archive)
198
+ command = "tar --list --file=#{File.join(folder, archive)} | grep '/$'"
199
+ output = `#{command} 2>&1`
200
+ raise "#{output} cmd <#{command}>" unless $?.to_i == 0
201
+ output.split
202
+ end
203
+
204
+ def self.get_latest_backup(bucket_name, access_key_id, secret_access_key)
205
+ list_backups(
206
+ bucket_name,
207
+ access_key_id,
208
+ secret_access_key).select { |a| a.end_with? ".tgz" }.sort.pop
209
+ end
210
+
211
+ def self.delete_folder(path)
212
+ puts "deleting folder #{path}"
213
+ `rm --force --recursive #{path}`
214
+ end
111
215
  end
112
216
  end
@@ -8,8 +8,8 @@ module MongoDbUtils
8
8
 
9
9
  class ConfigLoader
10
10
 
11
- ROOT_FOLDER = "~/.mongo-db-utils"
12
- CONFIG_LOCATION = "#{ROOT_FOLDER}/config.yml"
11
+ ROOT_FOLDER = File.join("~",".mongo-db-utils")
12
+ CONFIG_LOCATION = File.join(ROOT_FOLDER, "config.yml")
13
13
 
14
14
  attr_reader :config
15
15
 
@@ -33,6 +33,7 @@ module MongoDbUtils
33
33
  end
34
34
 
35
35
  private
36
+
36
37
  def load
37
38
  full_path = File.expand_path(@config_path)
38
39
  puts "loading config from #{full_path}"
@@ -49,7 +50,7 @@ module MongoDbUtils
49
50
  def create_fresh_install_config(full_path)
50
51
  config = Model::Config.new
51
52
  config.writer = self
52
- config.backup_folder = "#{ROOT_FOLDER}/backups"
53
+ config.backup_folder = File.join(ROOT_FOLDER, "backups")
53
54
  initialize_files(full_path)
54
55
  File.open( full_path, 'w' ) do |out|
55
56
  YAML.dump( config, out )
@@ -1,6 +1,6 @@
1
1
  require 'highline/import'
2
2
  require 'mongo-db-utils/version'
3
- Dir['lib/mongo-db-utils/models/*.rb'].each {|file| require file.gsub("lib/", "") }
3
+ Dir['lib/mongo-db-utils/models/*.rb'].each { |file| require file.gsub("lib/", "") }
4
4
 
5
5
 
6
6
  module MongoDbUtils
@@ -16,27 +16,27 @@ module MongoDbUtils
16
16
  end
17
17
 
18
18
  protected
19
- def method_missing(name, *args, &block)
20
- cleaned_args = args.map{ |a| trim(clean(a)) }
21
- cleaned_args.each{ |a| puts "#{a} -> #{a.class}"}
22
- @config.send(name, *cleaned_args, &block)
23
- end
19
+ def method_missing(name, *args, &block)
20
+ cleaned_args = args.map { |a| trim(clean(a)) }
21
+ cleaned_args.each { |a| puts "#{a} -> #{a.class}" }
22
+ @config.send(name, *cleaned_args, &block)
23
+ end
24
24
 
25
- def clean(a)
26
- if a.class.to_s == "HighLine::String"
27
- a.to_s
28
- else
29
- a
30
- end
31
- end
25
+ def clean(a)
26
+ if a.class.to_s == "HighLine::String"
27
+ a.to_s
28
+ else
29
+ a
30
+ end
31
+ end
32
32
 
33
- def trim(s)
34
- if(s.class.to_s == "String")
35
- s.strip
36
- else
37
- s
38
- end
39
- end
33
+ def trim(s)
34
+ if (s.class.to_s == "String")
35
+ s.strip
36
+ else
37
+ s
38
+ end
39
+ end
40
40
  end
41
41
 
42
42
 
@@ -46,7 +46,7 @@ module MongoDbUtils
46
46
  =====================================
47
47
  || Mongo Db Utils - Version: #{MongoDbUtils::VERSION} ||
48
48
  =====================================
49
- eos
49
+ eos
50
50
 
51
51
 
52
52
  def initialize(config, cmd)
@@ -64,14 +64,39 @@ eos
64
64
  def main_menu
65
65
 
66
66
  my_menu("What do you want to do?") do |menu|
67
- menu.choice "copy a db" do copy_a_db end
68
- menu.choice "backup a db locally" do do_backup end
69
- menu.choice "backup a db to an amazon s3 bucket" do backup_to_s3 end
70
- menu.choice "remove config" do remove_config end
71
- menu.choice "show config" do show_config end
72
- menu.choice "add server to config" do add_config end
73
- menu.choice "add Amazon bucket to config" do add_bucket_to_config end
74
- menu.choice "remove server from config" do remove_server_from_config end
67
+ menu.choice "copy a db" do
68
+ copy_a_db
69
+ end
70
+ menu.choice "backup a db locally" do
71
+ do_backup
72
+ end
73
+ menu.choice "backup a db to an amazon s3 bucket" do
74
+ backup_to_s3
75
+ end
76
+ menu.choice "download a backup from an amazon s3 bucket" do
77
+ download_backup_from_s3
78
+ end
79
+ menu.choice "delete a backup from the downloads" do
80
+ delete_downloaded_backup
81
+ end
82
+ menu.choice "restore a db from a downloaded backup" do
83
+ restore_db_from_backup
84
+ end
85
+ menu.choice "remove config" do
86
+ remove_config
87
+ end
88
+ menu.choice "show config" do
89
+ show_config
90
+ end
91
+ menu.choice "add db server to config" do
92
+ add_config
93
+ end
94
+ menu.choice "add Amazon bucket to config" do
95
+ add_bucket_to_config
96
+ end
97
+ menu.choice "remove db server from config" do
98
+ remove_server_from_config
99
+ end
75
100
  end
76
101
  end
77
102
 
@@ -93,7 +118,6 @@ eos
93
118
 
94
119
 
95
120
  def backup_to_s3
96
-
97
121
  plan = Hash.new
98
122
 
99
123
  db_list_menu("Choose a DB:") do |db|
@@ -101,7 +125,7 @@ eos
101
125
  end
102
126
 
103
127
  if @config.has_buckets?
104
- list_buckets("Choose a Bucket:") do |bucket|
128
+ bucket_list_menu("Choose a Bucket:") do |bucket|
105
129
  plan[:bucket] = bucket
106
130
  end
107
131
  else
@@ -119,6 +143,91 @@ eos
119
143
  end
120
144
 
121
145
 
146
+ def download_backup_from_s3
147
+ plan = Hash.new
148
+
149
+ if @config.has_buckets?
150
+ bucket_list_menu("Choose a source bucket:", true) do |bucket|
151
+ if bucket == 'back'
152
+ main_menu
153
+ return
154
+ end
155
+ plan[:bucket] = bucket
156
+ end
157
+ else
158
+ say("You don't have any buckets yet - add one..")
159
+ add_bucket_to_config
160
+ return
161
+ end
162
+
163
+ backups = @cmd.list_backups(
164
+ plan[:bucket].name,
165
+ plan[:bucket].access_key,
166
+ plan[:bucket].secret_key).select { |a| a.end_with? ".tgz" }
167
+
168
+ backup_list_menu("Choose a backup:", backups, true) do |backup|
169
+ if backup == 'back'
170
+ main_menu
171
+ else
172
+ plan[:backup] = backup
173
+ @cmd.download_backup_from_s3(
174
+ @config.backup_folder,
175
+ plan[:backup],
176
+ plan[:bucket].name,
177
+ plan[:bucket].access_key,
178
+ plan[:bucket].secret_key)
179
+ end
180
+ end
181
+ end
182
+
183
+
184
+ def delete_downloaded_backup
185
+ plan = Hash.new
186
+
187
+ downloaded_backups_list_menu("Choose a backup:", @cmd.list_downloaded_backups(@config.backup_folder), true) do |backup|
188
+ if backup == 'back'
189
+ main_menu
190
+ return
191
+ end
192
+ if ask("Delete backup #{backup}? (Y|n) [n]") != 'Y'
193
+ main_menu
194
+ return
195
+ end
196
+ plan[:backup] = backup
197
+ @cmd.delete_backup(
198
+ @config.backup_folder,
199
+ plan[:backup])
200
+ end
201
+ end
202
+
203
+
204
+ def restore_db_from_backup
205
+ plan = Hash.new
206
+
207
+ db_list_menu("Choose a target DB:") do |db|
208
+ plan[:db] = db
209
+ end
210
+
211
+ downloaded_backups_list_menu("Choose a backup:", @cmd.list_downloaded_backups(@config.backup_folder)) do |backup|
212
+ plan[:backup] = backup
213
+ end
214
+
215
+ source_db_list_menu("Choose a source_db in the backup:", @cmd.list_backup_folders(@config.backup_folder, plan[:backup])) do |folder|
216
+ plan[:source_db] = folder
217
+ end
218
+
219
+ if ask("Restore db #{db}? (Y|n) [n]") != 'Y'
220
+ main_menu
221
+ return
222
+ end
223
+
224
+ @cmd.restore_from_backup(
225
+ @config.backup_folder,
226
+ plan[:db],
227
+ plan[:backup],
228
+ plan[:source_db])
229
+ end
230
+
122
231
  def add_bucket_to_config
123
232
  say("add an amazon bucket:")
124
233
  bucket = MongoDbUtils::Model::Bucket.new
@@ -133,7 +242,6 @@ eos
133
242
  my_menu("")
134
243
  end
135
244
 
136
-
137
245
  def get_config
138
246
  say("You don't have any servers configured, please add one:")
139
247
  add_config
@@ -149,7 +257,7 @@ eos
149
257
  end
150
258
  say("--------------------")
151
259
  say("Amazon S3 Buckets")
152
- if( @config.buckets.nil?)
260
+ if (@config.buckets.nil?)
153
261
  say("no buckets")
154
262
  else
155
263
  @config.buckets.sort.each do |bucket|
@@ -166,8 +274,12 @@ eos
166
274
 
167
275
  def add_config
168
276
  my_menu("Single db or replica set?") do |menu|
169
- menu.choice "single db" do add_single_db end
170
- menu.choice "replica set db" do add_replica_set end
277
+ menu.choice "single db" do
278
+ add_single_db
279
+ end
280
+ menu.choice "replica set db" do
281
+ add_replica_set
282
+ end
171
283
  end
172
284
  end
173
285
 
@@ -181,7 +293,9 @@ eos
181
293
  label = successful ? "add another?" : "try again?"
182
294
 
183
295
  my_menu("") do |menu|
184
- menu.choice label do add_config end
296
+ menu.choice label do
297
+ add_config
298
+ end
185
299
  end
186
300
  end
187
301
 
@@ -195,11 +309,12 @@ eos
195
309
  say("bad replica set uri") unless successful
196
310
 
197
311
  my_menu("") do |menu|
198
- menu.choice (successful ? "add another" : "try again?") do add_config end
312
+ menu.choice (successful ? "add another" : "try again?") do
313
+ add_config
314
+ end
199
315
  end
200
316
  end
201
317
 
202
-
203
318
  def remove_server_from_config
204
319
  db_list_menu("Remove server from config:") do |db|
205
320
  @config.remove_db(db)
@@ -223,10 +338,14 @@ eos
223
338
  say("#{plan[:source].to_s} --> #{plan[:destination].to_s}")
224
339
 
225
340
  my_menu("") do |menu|
226
- menu.choice "Do it!" do begin_copy(plan, false) end
227
- menu.choice "Do it - skip backup" do begin_copy(plan, true) end
341
+ menu.choice "Do it!" do
342
+ begin_copy(plan, false)
343
+ end
344
+ menu.choice "Do it - skip backup" do
345
+ begin_copy(plan, true)
346
+ end
228
347
  menu.choice "Reverse" do
229
- show_copy_plan( {:source => plan[:destination], :destination => plan[:source]})
348
+ show_copy_plan({:source => plan[:destination], :destination => plan[:source]})
230
349
  end
231
350
  end
232
351
  end
@@ -238,16 +357,20 @@ eos
238
357
  def my_menu(prompt, show_defaults = true)
239
358
  say(prompt)
240
359
  choose do |menu|
241
- menu.shell = true
360
+ menu.shell = true
242
361
  menu.index = :number
243
362
  menu.prompt = "\n#{prompt}\n"
244
363
  menu.index_suffix = ") "
245
364
  menu.prompt = "?"
246
- if( show_defaults)
247
- menu.choice "Back" do main_menu end
248
- menu.choice "Exit" do say("Goodbye"); abort("--"); end
365
+ if (show_defaults)
366
+ menu.choice "Back" do
367
+ main_menu
368
+ end
369
+ menu.choice "Exit" do
370
+ say("Goodbye"); abort("--");
371
+ end
249
372
  end
250
- say(" ")
373
+ say("")
251
374
  yield menu if block_given?
252
375
  end
253
376
  end
@@ -255,19 +378,72 @@ eos
255
378
  def db_list_menu(prompt)
256
379
  my_menu(prompt, false) do |menu|
257
380
  @config.dbs.sort.each do |db|
258
- menu.choice "#{db.to_s_simple}" do yield db if block_given? end
381
+ menu.choice "#{db.to_s_simple}" do
382
+ yield db if block_given?
383
+ end
259
384
  end
260
385
  end
261
386
  end
262
387
 
263
- def list_buckets(prompt)
264
- my_menu(prompt) do |menu|
388
+ def bucket_list_menu(prompt, show_defaults = false)
389
+ my_menu(prompt, false) do |menu|
390
+ if show_defaults
391
+ menu.choice 'Back' do
392
+ yield 'back' if block_given?
393
+ end
394
+ end
265
395
  @config.buckets.sort.each do |bucket|
266
- menu.choice "#{bucket}" do yield bucket if block_given? end
396
+ menu.choice "#{bucket}" do
397
+ yield bucket if block_given?
398
+ end
399
+ end
400
+ end
401
+ end
402
+
403
+ def backup_list_menu(prompt, backups, show_defaults = false)
404
+ my_menu(prompt, false) do |menu|
405
+ if show_defaults
406
+ menu.choice 'Back' do
407
+ yield 'back' if block_given?
408
+ end
409
+ end
410
+ menu.choice 'latest' do
411
+ yield 'latest' if block_given?
412
+ end
413
+ backups.sort.each do |backup|
414
+ menu.choice "#{backup}" do
415
+ yield backup if block_given?
416
+ end
417
+ end
418
+ end
419
+ end
420
+
421
+ def source_db_list_menu(prompt, folders)
422
+ my_menu(prompt, false) do |menu|
423
+ folders.sort.each do |item|
424
+ menu.choice "#{item}" do
425
+ yield item if block_given?
426
+ end
267
427
  end
268
428
  end
269
429
  end
270
430
 
431
+ def downloaded_backups_list_menu(prompt, backups, show_defaults = false)
432
+ my_menu(prompt, false) do |menu|
433
+ if show_defaults
434
+ menu.choice 'Back' do
435
+ yield 'back' if block_given?
436
+ end
437
+ end
438
+ backups.sort.each do |item|
439
+ menu.choice "#{item}" do
440
+ yield item if block_given?
441
+ end
442
+ end
443
+ end
444
+ end
445
+
446
+
271
447
  private
272
448
  def clean(s)
273
449
  s.to_s.strip
@@ -6,10 +6,8 @@ module MongoDbUtils
6
6
 
7
7
  def self.put_file(file, name, bucket_name, access_key_id, secret_access_key)
8
8
  puts "putting file to Amazon S3"
9
- AWS::S3::Base.establish_connection!(
10
- :access_key_id => access_key_id,
11
- :secret_access_key => secret_access_key
12
- )
9
+
10
+ self.s3connect(access_key_id, secret_access_key)
13
11
 
14
12
  begin
15
13
  AWS::S3::Bucket.find(bucket_name)
@@ -21,5 +19,46 @@ module MongoDbUtils
21
19
  end
22
20
  AWS::S3::S3Object.store(name, open(file), bucket_name)
23
21
  end
22
+
23
+
24
+ def self.get_file(filename, key, bucket_name, access_key_id, secret_access_key)
25
+ puts "getting file from Amazon S3"
26
+
27
+ self.s3connect(access_key_id, secret_access_key)
28
+
29
+ File.open(filename, 'wb') do |file|
30
+ AWS::S3::S3Object.stream(key, bucket_name) do |chunk|
31
+ file.write chunk
32
+ end
33
+ file.close
34
+ end
35
+ end
36
+
37
+
38
+ def self.list_bucket(bucket_name, access_key_id, secret_access_key)
39
+ puts "getting list of bucket keys from Amazon S3"
40
+
41
+ self.s3connect(access_key_id, secret_access_key)
42
+
43
+ begin
44
+ AWS::S3::Bucket.find(bucket_name).objects.collect(&:key)
45
+ rescue AWS::S3::NoSuchBucket
46
+ puts "Error:: Bucket does not exist: #{bucket_name}"
47
+ return nil
48
+ rescue AWS::S3::AllAccessDisabled
49
+ puts "Error:: You cannot access this bucket: #{bucket_name}"
50
+ return nil
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def self.s3connect(access_key_id, secret_access_key)
57
+ AWS::S3::Base.establish_connection!(
58
+ :access_key_id => access_key_id,
59
+ :secret_access_key => secret_access_key
60
+ )
61
+ end
62
+
24
63
  end
25
64
  end
@@ -6,39 +6,41 @@ module MongoDbUtils
6
6
 
7
7
  class ToolsException < RuntimeError
8
8
  attr :cmd, :output
9
- def initialize(cmd, output)
9
+ def initialize(cmd, output, message)
10
+ super(message)
10
11
  @cmd = cmd
11
- @output =output
12
+ @output = output
12
13
  end
14
+
13
15
  end
14
16
 
15
17
  class BaseCmd
16
18
 
17
- def initialize(cmd_name, host_and_port, db, username = "", password = "")
18
- @unsafeOptions = build_base_options(host_and_port, db, username, password)
19
- @optionsWithoutCredentials = build_base_options(host_and_port, db, username.empty? ? '':'****', password.empty? ? '':'****')
19
+ def initialize(cmd_name, host_and_port, db, username = '', password = '')
20
+ @unsafe_options = build_base_options(host_and_port, db, username, password)
21
+ @options_without_credentials = build_base_options(host_and_port, db, username.empty? ? '':'****', password.empty? ? '':'****')
20
22
  @cmd_name = cmd_name
21
23
  end
22
24
 
23
25
  def run
24
26
  puts "[#{self.class}] run: #{cmd}"
25
- output = `#{executableCmd}`
26
- raise ToolsException.new("#{cmd}", output) unless $?.to_i == 0
27
+ output = `#{executable_cmd} 2>&1`
28
+ raise ToolsException.new("#{cmd}", output, "Error in #{cmd_name}:: #{output} cmd #{cmd}") unless $?.to_i == 0
27
29
  end
28
30
 
29
31
  def cmd
30
- "#{@cmd_name} #{options_string(@optionsWithoutCredentials)}"
32
+ "#{@cmd_name} #{options_string(@options_without_credentials)}"
31
33
  end
32
34
 
33
- def executableCmd
34
- "#{@cmd_name} #{options_string(@unsafeOptions)}"
35
+ def executable_cmd
36
+ "#{@cmd_name} #{options_string(@unsafe_options)}"
35
37
  end
36
38
 
37
39
  private
38
40
 
39
- def addOption(option)
40
- @unsafeOptions << option
41
- @optionsWithoutCredentials << option
41
+ def add_option(option)
42
+ @unsafe_options << option
43
+ @options_without_credentials << option
42
44
  end
43
45
 
44
46
  def o(key,value)
@@ -46,33 +48,33 @@ module MongoDbUtils
46
48
  end
47
49
 
48
50
  # options common to all commands
49
- def build_base_options(host_and_port,db,username="",password="")
51
+ def build_base_options(host_and_port,db,username='',password='')
50
52
  options = []
51
- options << o("-h", host_and_port)
52
- options << o("-db", db)
53
- options << o("-u", username)
54
- options << o("-p", password)
53
+ options << o('-h', host_and_port)
54
+ options << o('-db', db)
55
+ options << o('-u', username)
56
+ options << o('-p', password)
55
57
  options
56
58
  end
57
59
 
58
60
  # given an array of options build a string of those options unless the option is empty
59
61
  def options_string(opts)
60
62
  opt_strings = opts.reject{ |o| o.empty? }.map { |o| o.to_s }
61
- opt_strings.join(" ").strip
63
+ opt_strings.join(' ').strip
62
64
  end
63
65
  end
64
66
 
65
67
  class Dump < BaseCmd
66
- def initialize(host_and_port,db,output,username = "", password = "")
67
- super("mongodump", host_and_port, db, username, password)
68
- addOption(o("-o", output))
68
+ def initialize(host_and_port,db,output,username = '', password = '')
69
+ super('mongodump', host_and_port, db, username, password)
70
+ add_option(o('-o', output))
69
71
  end
70
72
  end
71
73
 
72
74
  class Restore < BaseCmd
73
- def initialize(host_and_port,db,source_folder,username = "", password = "")
74
- super("mongorestore", host_and_port, db, username, password)
75
- addOption("--drop")
75
+ def initialize(host_and_port,db,source_folder,username = '', password = '')
76
+ super('mongorestore', host_and_port, db, username, password)
77
+ add_option('--drop')
76
78
  @source_folder = source_folder
77
79
  end
78
80
 
@@ -80,29 +82,29 @@ module MongoDbUtils
80
82
  "#{super} #{@source_folder}"
81
83
  end
82
84
 
83
- def executableCmd
85
+ def executable_cmd
84
86
  "#{super} #{@source_folder}"
85
87
  end
86
88
  end
87
89
 
88
90
  class Import < BaseCmd
89
- def initialize(host_and_port, db, collection, file, username = "", password = "", opts = {})
90
- super("mongoimport", host_and_port, db, username, password)
91
- addOption(o("-c", collection))
92
- addOption(o("--file", file))
93
- addOption("--jsonArray") if opts[:json_array]
94
- addOption("--drop") if opts[:drop]
91
+ def initialize(host_and_port, db, collection, file, username = '', password = '', opts = {})
92
+ super('mongoimport', host_and_port, db, username, password)
93
+ add_option(o('-c', collection))
94
+ add_option(o('--file', file))
95
+ add_option('--jsonArray') if opts[:json_array]
96
+ add_option('--drop') if opts[:drop]
95
97
  end
96
98
  end
97
99
 
98
100
  class Export < BaseCmd
99
101
 
100
- def initialize(host_and_port, db, collection, query, output, username = "", password = "", opts = {})
101
- super("mongoexport", host_and_port, db, username, password)
102
- addOption(o("-c", collection))
103
- addOption(o("-o", output))
104
- addOption(o("--query", "'#{query}'"))
105
- addOption("--jsonArray") if opts[:json_array]
102
+ def initialize(host_and_port, db, collection, query, output, username = '', password = '', opts = {})
103
+ super('mongoexport', host_and_port, db, username, password)
104
+ add_option(o('-c', collection))
105
+ add_option(o('-o', output))
106
+ add_option(o('--query', "'#{query}'"))
107
+ add_option('--jsonArray') if opts[:json_array]
106
108
  end
107
109
  end
108
110
 
@@ -1,4 +1,4 @@
1
1
  module MongoDbUtils
2
- VERSION = "0.1.6"
2
+ VERSION = "0.2.0"
3
3
  READY_FOR_USE = "(prod version)"
4
4
  end
@@ -9,11 +9,11 @@ describe Dump do
9
9
  end
10
10
 
11
11
  it "should work with single uris" do
12
- Dump.new("host:port", "db", "out", "user", "pass").executableCmd.should eql "mongodump -h host:port -db db -u user -p pass -o out"
12
+ Dump.new("host:port", "db", "out", "user", "pass").executable_cmd.should eql "mongodump -h host:port -db db -u user -p pass -o out"
13
13
  end
14
14
 
15
15
  it "should work with single uris - no user/pass" do
16
- Dump.new("host:port", "db", "out").executableCmd.should eql "mongodump -h host:port -db db -o out"
16
+ Dump.new("host:port", "db", "out").executable_cmd.should eql "mongodump -h host:port -db db -o out"
17
17
  end
18
18
 
19
19
  it "should safely work with replica set uris" do
@@ -23,7 +23,7 @@ describe Dump do
23
23
 
24
24
  it "should work with replica set uris" do
25
25
  expected = "mongodump -h setname/host1:port1,host2:port2 -db db -u user -p pass -o out"
26
- Dump.new("setname/host1:port1,host2:port2","db", "out", "user", "pass").executableCmd.should eql expected
26
+ Dump.new("setname/host1:port1,host2:port2","db", "out", "user", "pass").executable_cmd.should eql expected
27
27
  end
28
28
 
29
29
  end
@@ -35,7 +35,7 @@ describe Restore do
35
35
  end
36
36
 
37
37
  it "should work with single uris" do
38
- Restore.new("host:port", "db", "source", "user", "pass").executableCmd.should eql "mongorestore -h host:port -db db -u user -p pass --drop source"
38
+ Restore.new("host:port", "db", "source", "user", "pass").executable_cmd.should eql "mongorestore -h host:port -db db -u user -p pass --drop source"
39
39
  end
40
40
 
41
41
  it "should safely work with replica set uris" do
@@ -45,7 +45,7 @@ describe Restore do
45
45
 
46
46
  it "should work with replica set uris" do
47
47
  expected = "mongorestore -h setname/host1:port1,host2:port2 -db db -u user -p pass --drop source"
48
- Restore.new("setname/host1:port1,host2:port2","db", "source", "user", "pass").executableCmd.should eql expected
48
+ Restore.new("setname/host1:port1,host2:port2","db", "source", "user", "pass").executable_cmd.should eql expected
49
49
  end
50
50
  end
51
51
 
@@ -56,11 +56,11 @@ describe Import do
56
56
  end
57
57
 
58
58
  it "should work with single uris - with user/pass" do
59
- Import.new("host:port", "db", "coll", "myfile.json", "user", "pass").executableCmd.should eql "mongoimport -h host:port -db db -u user -p pass -c coll --file myfile.json"
59
+ Import.new("host:port", "db", "coll", "myfile.json", "user", "pass").executable_cmd.should eql "mongoimport -h host:port -db db -u user -p pass -c coll --file myfile.json"
60
60
  end
61
61
 
62
62
  it "should work with single uris - no user/pass" do
63
- Import.new("host:port", "db", "coll", "myfile.json").executableCmd.should eql "mongoimport -h host:port -db db -c coll --file myfile.json"
63
+ Import.new("host:port", "db", "coll", "myfile.json").executable_cmd.should eql "mongoimport -h host:port -db db -c coll --file myfile.json"
64
64
  end
65
65
 
66
66
  it "should safely work with replica set uris" do
@@ -70,7 +70,7 @@ describe Import do
70
70
 
71
71
  it "should work with replica set uris" do
72
72
  expected = "mongoimport -h setname/host1:port1,host2:port2 -db db -u user -p pass -c coll --file myfile.json --jsonArray"
73
- Import.new("setname/host1:port1,host2:port2","db", "coll", "myfile.json", "user", "pass", { :json_array => true} ).executableCmd.should eql expected
73
+ Import.new("setname/host1:port1,host2:port2","db", "coll", "myfile.json", "user", "pass", { :json_array => true} ).executable_cmd.should eql expected
74
74
  end
75
75
  end
76
76
 
@@ -81,11 +81,11 @@ describe Export do
81
81
  end
82
82
 
83
83
  it "should work with single uris - with user/pass" do
84
- Export.new("host:port", "db", "coll", "{query}", "myfile.json", "user", "pass").executableCmd.should eql "mongoexport -h host:port -db db -u user -p pass -c coll -o myfile.json --query '{query}'"
84
+ Export.new("host:port", "db", "coll", "{query}", "myfile.json", "user", "pass").executable_cmd.should eql "mongoexport -h host:port -db db -u user -p pass -c coll -o myfile.json --query '{query}'"
85
85
  end
86
86
 
87
87
  it "should work with single uris - no user/pass" do
88
- Export.new("host:port", "db", "coll", "{query}", "myfile.json").executableCmd.should eql "mongoexport -h host:port -db db -c coll -o myfile.json --query '{query}'"
88
+ Export.new("host:port", "db", "coll", "{query}", "myfile.json").executable_cmd.should eql "mongoexport -h host:port -db db -c coll -o myfile.json --query '{query}'"
89
89
  end
90
90
 
91
91
  it "should safely work with replica set uris" do
@@ -95,7 +95,7 @@ describe Export do
95
95
 
96
96
  it "should work with replica set uris" do
97
97
  expected = "mongoexport -h setname/host1:port1,host2:port2 -db db -u user -p pass -c coll -o myfile.json --query '{query}' --jsonArray"
98
- Export.new("setname/host1:port1,host2:port2","db", "coll", "{query}", "myfile.json", "user", "pass", { :json_array => true} ).executableCmd.should eql expected
98
+ Export.new("setname/host1:port1,host2:port2","db", "coll", "{query}", "myfile.json", "user", "pass", { :json_array => true} ).executable_cmd.should eql expected
99
99
  end
100
100
  end
101
101
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo-db-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - edeustace
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-24 00:00:00.000000000 Z
11
+ date: 2014-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec