mongo-db-utils 0.0.9 → 0.0.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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