mongo-db-utils 0.0.9 → 0.0.9.2

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.
@@ -1,59 +1,68 @@
1
- require 'mongo-db-utils/models'
1
+ project_root = File.dirname(File.absolute_path(__FILE__))
2
+
3
+ Dir.glob(project_root + '/lib/mongo-db-utils/models/*', &method(:require))
4
+
2
5
  require 'yaml'
3
6
 
4
7
  module MongoDbUtils
5
8
 
6
9
  class ConfigLoader
7
-
10
+
8
11
  ROOT_FOLDER = "~/.mongo-db-utils"
9
12
  CONFIG_LOCATION = "#{ROOT_FOLDER}/config.yml"
10
13
 
11
- def self.load(load_path = CONFIG_LOCATION)
12
- full_path = File.expand_path(load_path)
13
- puts "loading config from #{full_path}"
14
+ attr_reader :config
14
15
 
15
- if File.exist?(full_path) && YAML.load(File.open(full_path))
16
- config = YAML.load(File.open(full_path))
17
- config.writer = self
18
- config
19
- else
20
- self.create_fresh_install_config(full_path)
21
- end
16
+ def initialize(config_path)
17
+ @config_path = config_path
18
+ load
22
19
  end
23
20
 
24
- def self.flush(path = CONFIG_LOCATION)
25
- path = File.expand_path(path)
21
+ def flush
22
+ path = File.expand_path(@config_path)
26
23
  puts "removing: #{path}"
27
24
  FileUtils.rm(path) if File.exist?(path)
28
- self.initialize_files(path)
25
+ initialize_files(path)
29
26
  end
30
27
 
31
- def self.save(config, path = CONFIG_LOCATION)
28
+ def save(config)
32
29
  raise "config is nil" if config.nil?
33
-
34
- File.open( File.expand_path(path), 'w' ) do |out|
30
+ File.open( File.expand_path(@config_path), 'w' ) do |out|
35
31
  YAML.dump( config, out )
36
32
  end
37
33
  end
38
34
 
39
- private
40
- def self.create_fresh_install_config(full_path)
35
+ private
36
+ def load
37
+ full_path = File.expand_path(@config_path)
38
+ puts "loading config from #{full_path}"
39
+
40
+ if File.exist?(full_path) && YAML.load(File.open(full_path))
41
+ config = YAML.load(File.open(full_path))
42
+ config.writer = self
43
+ @config = config
44
+ else
45
+ @config = create_fresh_install_config(full_path)
46
+ end
47
+ end
48
+
49
+ def create_fresh_install_config(full_path)
41
50
  config = Model::Config.new
42
51
  config.writer = self
43
52
  config.backup_folder = "#{ROOT_FOLDER}/backups"
44
- self.initialize_files(full_path)
53
+ initialize_files(full_path)
45
54
  File.open( full_path, 'w' ) do |out|
46
55
  YAML.dump( config, out )
47
56
  end
48
57
  config
49
58
  end
50
59
 
51
- def self.get_folder_name(path)
60
+ def get_folder_name(path)
52
61
  /(.*)\/.*.yml/.match(path)[1]
53
62
  end
54
63
 
55
- def self.initialize_files(path)
56
- folder = self.get_folder_name(path)
64
+ def initialize_files(path)
65
+ folder = get_folder_name(path)
57
66
  FileUtils.mkdir_p(folder) unless File.exist?(folder)
58
67
  FileUtils.touch(path)
59
68
  end
@@ -1,8 +1,45 @@
1
1
  require 'highline/import'
2
2
  require 'mongo-db-utils/version'
3
- require 'mongo-db-utils/models'
3
+ Dir['lib/mongo-db-utils/models/*.rb'].each {|file| require file.gsub("lib/", "") }
4
+
4
5
 
5
6
  module MongoDbUtils
7
+
8
+ # This is a workaround for this issue:
9
+ # https://github.com/JEG2/highline/issues/69
10
+ # In ruby 2 + highline the yaml strings don't get serialized correctly.
11
+ # The workaround is for any argument that is of type HighLine::String to call to_s on it
12
+ class ConfigProxy
13
+
14
+ def initialize(config)
15
+ @config = config
16
+ end
17
+
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
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
32
+
33
+ def trim(s)
34
+ if(s.class.to_s == "String")
35
+ s.strip
36
+ else
37
+ s
38
+ end
39
+ end
40
+ end
41
+
42
+
6
43
  class Console
7
44
 
8
45
  HEADER = <<-eos
@@ -13,7 +50,7 @@ eos
13
50
 
14
51
 
15
52
  def initialize(config, cmd)
16
- @config = config
53
+ @config = ConfigProxy.new(config)
17
54
  @cmd = cmd
18
55
  end
19
56
 
@@ -128,9 +165,15 @@ eos
128
165
  end
129
166
 
130
167
  def add_config
131
- entry = Hash.new
132
- entry[:mongo_uri] = ask("Mongo uri (eg: 'mongodb://user:pass@locahost:27017/db')")
133
- new_uri = entry[:mongo_uri].gsub(" ", "")
168
+ 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
171
+ end
172
+ end
173
+
174
+ def add_single_db
175
+ mongo_uri = ask("Mongo uri (eg: 'mongodb://user:pass@locahost:27017/db')")
176
+ new_uri = mongo_uri.to_s.strip
134
177
  successful = @config.add_db_from_uri(new_uri)
135
178
 
136
179
  say("bad uri!") unless successful
@@ -142,6 +185,21 @@ eos
142
185
  end
143
186
  end
144
187
 
188
+ def add_replica_set
189
+ mongo_uri = ask("Replica Set uri: (eg: mongodb://user:pass@host1:port,host2:port,.../db)1
190
+ ")
191
+ replica_set_name = ask("Replica Set name: ")
192
+
193
+ successful = @config.add_replica_set(mongo_uri, replica_set_name)
194
+
195
+ say("bad replica set uri") unless successful
196
+
197
+ my_menu("") do |menu|
198
+ menu.choice (successful ? "add another" : "try again?") do add_config end
199
+ end
200
+ end
201
+
202
+
145
203
  def remove_server_from_config
146
204
  db_list_menu("Remove server from config:") do |db|
147
205
  @config.remove_db(db)
@@ -209,5 +267,10 @@ eos
209
267
  end
210
268
  end
211
269
 
270
+ private
271
+ def clean(s)
272
+ s.to_s.strip
273
+ end
274
+
212
275
  end
213
276
  end
@@ -0,0 +1,17 @@
1
+ module MongoDbUtils
2
+ module Model
3
+
4
+ class Bucket
5
+ attr_accessor :name, :access_key, :secret_key
6
+
7
+ def to_s
8
+ "#{name} | #{access_key} | #{secret_key}"
9
+ end
10
+
11
+ def <=> (other)
12
+ self.name <=> other.name
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,82 @@
1
+ require 'mongo-db-utils/models/db'
2
+ module MongoDbUtils
3
+
4
+ module Model
5
+ class Config
6
+ attr_reader :dbs, :buckets
7
+ attr_writer :writer
8
+ attr_accessor :backup_folder
9
+
10
+ def initialize
11
+ @dbs = []
12
+ @buckets = []
13
+ end
14
+
15
+ def empty?
16
+ @dbs.nil? || @dbs.empty?
17
+ end
18
+
19
+ def has_buckets?
20
+ !@buckets.nil? && !@buckets.empty?
21
+ end
22
+
23
+ def flush
24
+ @dbs = []
25
+ @writer.flush
26
+ end
27
+
28
+ def remove_db(db)
29
+ @dbs = @dbs - [db]
30
+ save
31
+ end
32
+
33
+ def add_replica_set(uri, name)
34
+ add_db ReplicaSetDb.new(uri,name)
35
+ end
36
+
37
+
38
+ def add_db_from_uri(uri)
39
+ add_db Db.new(uri)
40
+ end
41
+
42
+ def already_contains(db)
43
+ !@dbs.find{|current| current.uri == db.uri }.nil?
44
+ end
45
+
46
+ # because we are serializing the config - the bucket may be nil
47
+ # at this point
48
+ def add_bucket(bucket)
49
+ @buckets = [] if @buckets.nil?
50
+ unless already_contains_bucket?(bucket)
51
+ @buckets << bucket
52
+ save
53
+ end
54
+ end
55
+
56
+ def already_contains_bucket?(bucket)
57
+ !@buckets.find{ |b| b.to_s == bucket.to_s}.nil?
58
+ end
59
+
60
+ def to_s
61
+ "Config"
62
+ end
63
+
64
+ private
65
+ def save
66
+ @writer.save(self) unless @writer.nil?
67
+ end
68
+
69
+ def add_db(db)
70
+ @dbs = [] if @dbs.nil?
71
+ unless db.nil? || already_contains(db)
72
+ @dbs << db
73
+ @dbs.sort!
74
+ save
75
+ end
76
+ @dbs.include?(db) && !db.nil?
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,81 @@
1
+ module MongoDbUtils
2
+ module Model
3
+
4
+ # A Db stored in the config
5
+ class Db
6
+
7
+ URI_NO_USER = /mongodb:\/\/(.*)\/(.*$)/
8
+ URI_USER = /mongodb:\/\/(.*):(.*)@(.*)\/(.*$)/
9
+
10
+ attr_accessor :username, :password, :name, :uri
11
+
12
+ def initialize(uri)
13
+ user,pwd,host_port,db = nil
14
+
15
+ if( uri.match(URI_USER))
16
+ match, user, pwd, host_port, name = *uri.match(URI_USER)
17
+ elsif(uri.match(URI_NO_USER))
18
+ match, host_port, name = *uri.match(URI_NO_USER)
19
+ user = ""
20
+ pwd = ""
21
+ end
22
+
23
+ raise "can't parse uri" if( host_port.nil? || name.nil? )
24
+
25
+ @host_port = host_port
26
+ @name = name
27
+ @username = user
28
+ @password = pwd
29
+ @uri = uri
30
+ end
31
+
32
+ def authentication_required?
33
+ has?(self.username) && has?(self.password)
34
+ end
35
+
36
+ # Return the host string in a format that is compatable with mongo binary tools
37
+ # See: http://docs.mongodb.org/manual/reference/program/mongodump/#cmdoption-mongodump--host
38
+ def to_host_s
39
+ "#{@host_port}"
40
+ end
41
+
42
+ def to_s_simple
43
+ "#{@name} on #{@host_port} - (#{@username}:#{@password})"
44
+ end
45
+
46
+ def to_s
47
+ "[SingleDb-(#{to_host_s}/#{name})]"
48
+ end
49
+
50
+ def <=>(other)
51
+ self.to_s <=> other.to_s
52
+ end
53
+
54
+ private
55
+ def has?(s)
56
+ !s.nil? && !s.empty?
57
+ end
58
+ end
59
+
60
+
61
+ class ReplicaSetDb < Db
62
+
63
+ attr_reader :set_name
64
+ def initialize(uri, name)
65
+ super(uri)
66
+ @set_name = name
67
+ end
68
+
69
+ # Note: we override this to provide a replica set format
70
+ def to_host_s
71
+ "#{@set_name}/#{@host_port}"
72
+ end
73
+
74
+ def to_s
75
+ "[ReplicaSetDb-(#{to_host_s}/#{@name})]"
76
+ end
77
+ end
78
+
79
+
80
+ end
81
+ end
@@ -0,0 +1,80 @@
1
+ require 'aws/s3'
2
+
3
+ module MongoDbUtils
4
+
5
+ module Tools
6
+
7
+ class BaseCmd
8
+ private
9
+ def self.o(key,value)
10
+ Option.new(key,value)
11
+ end
12
+
13
+ # options common to all commands
14
+ def self.build_base_options(host_and_port,db,username="",password="")
15
+ options = []
16
+ options << o("-h", host_and_port)
17
+ options << o("-db", db)
18
+ options << o("-u", username)
19
+ options << o("-p", password)
20
+ options
21
+ end
22
+
23
+ # given an array of options build a string of those options unless the option is empty
24
+ def self.options_string(opts)
25
+ out = ""
26
+ opts.each do |o|
27
+ out << "#{o.key} #{o.value} " unless o.empty?
28
+ end
29
+ out.strip
30
+ end
31
+ end
32
+
33
+ class Dump < BaseCmd
34
+
35
+ # create the cmd string that will be executed by the system
36
+ def self.cmd(host_and_port,db,output,username = "", password = "")
37
+ options = build_base_options(host_and_port,db,username,password)
38
+ options << o("-o", output)
39
+ "mongodump #{options_string(options)}"
40
+ end
41
+
42
+ # run the command
43
+ def self.run(host_and_port,db,output,username="", password ="")
44
+ cmd_string = self.cmd(host_and_port,db,output,username,password)
45
+ puts "[Dump] run: #{cmd_string}"
46
+ `#{cmd_string}`
47
+ end
48
+
49
+ end
50
+
51
+ class Restore < BaseCmd
52
+ def self.cmd(host_and_port,db,source_folder,username = "", password = "")
53
+ options = build_base_options(host_and_port,db,username,password)
54
+ params = options_string(options) << " --drop #{source_folder}"
55
+ "mongorestore #{params}"
56
+ end
57
+
58
+ def self.run(host_and_port,db,source_folder,username="", password ="")
59
+ cmd_string = self.cmd(host_and_port,db,source_folder,username,password)
60
+ puts "[Restore] run: #{cmd_string}"
61
+ `#{cmd_string}`
62
+ end
63
+ end
64
+
65
+
66
+ class Option
67
+ attr_accessor :key, :value
68
+
69
+ def initialize(key,value)
70
+ @key = key
71
+ @value = value
72
+ end
73
+
74
+ def empty?
75
+ @value.nil? || @value.empty?
76
+ end
77
+ end
78
+
79
+ end
80
+ end