mongo-db-utils 0.1.6 → 0.2.0

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 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