mongo3 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.bnignore +3 -0
- data/.bnsignore +16 -0
- data/.gitignore +1 -0
- data/HISTORY +2 -0
- data/README.rdoc +78 -0
- data/Rakefile +31 -0
- data/bin/mongo3 +29 -0
- data/config/mongo3.yml +33 -0
- data/lib/controllers/collections.rb +7 -0
- data/lib/controllers/databases.rb +7 -0
- data/lib/controllers/explore.rb +46 -0
- data/lib/helpers/crumb_helper.rb +46 -0
- data/lib/helpers/main_helper.rb +43 -0
- data/lib/main.rb +41 -0
- data/lib/mongo3/connection.rb +191 -0
- data/lib/mongo3/node.rb +80 -0
- data/lib/mongo3.rb +57 -0
- data/lib/public/images/c292199_a.jpg +0 -0
- data/lib/public/images/close.png +0 -0
- data/lib/public/images/close.psd +0 -0
- data/lib/public/images/cluster.png +0 -0
- data/lib/public/images/cluster.psd +0 -0
- data/lib/public/images/db.jpg +0 -0
- data/lib/public/images/db.png +0 -0
- data/lib/public/images/db.psd +0 -0
- data/lib/public/images/delete.png +0 -0
- data/lib/public/images/header.png +0 -0
- data/lib/public/images/header.psd +0 -0
- data/lib/public/images/li_select.png +0 -0
- data/lib/public/images/li_select.psd +0 -0
- data/lib/public/images/lock.png +0 -0
- data/lib/public/images/lock.psd +0 -0
- data/lib/public/images/mongo.png +0 -0
- data/lib/public/images/mongo.psd +0 -0
- data/lib/public/images/mongo3.png +0 -0
- data/lib/public/images/mongo3.psd +0 -0
- data/lib/public/images/mongo3_db.png +0 -0
- data/lib/public/images/mongo3_db.psd +0 -0
- data/lib/public/images/mongo_10.psd +0 -0
- data/lib/public/images/mongo_db.jpg +0 -0
- data/lib/public/images/mongo_db.png +0 -0
- data/lib/public/images/mongo_db.psd +0 -0
- data/lib/public/images/mongo_db_1.jpg +0 -0
- data/lib/public/images/mongo_db_2 +0 -0
- data/lib/public/images/mongo_db_4 +0 -0
- data/lib/public/images/monkey.jpg +0 -0
- data/lib/public/images/monkey.png +0 -0
- data/lib/public/images/monkey.psd +0 -0
- data/lib/public/images/monkey_1.jpg +8 -0
- data/lib/public/images/monkey_10.jpg +8 -0
- data/lib/public/javascripts/Jit/Examples/Hypertree/example1.html +57 -0
- data/lib/public/javascripts/Jit/Examples/Hypertree/example1.js +427 -0
- data/lib/public/javascripts/Jit/Examples/Hypertree/example2.html +58 -0
- data/lib/public/javascripts/Jit/Examples/Hypertree/example2.js +310 -0
- data/lib/public/javascripts/Jit/Examples/Hypertree/example3.html +199 -0
- data/lib/public/javascripts/Jit/Examples/Hypertree/example3.js +615 -0
- data/lib/public/javascripts/Jit/Examples/Other/example1.html +58 -0
- data/lib/public/javascripts/Jit/Examples/Other/example1.js +566 -0
- data/lib/public/javascripts/Jit/Examples/Other/example2.html +58 -0
- data/lib/public/javascripts/Jit/Examples/Other/example2.js +304 -0
- data/lib/public/javascripts/Jit/Examples/Other/example3.html +58 -0
- data/lib/public/javascripts/Jit/Examples/Other/example3.js +304 -0
- data/lib/public/javascripts/Jit/Examples/RGraph/example1.html +57 -0
- data/lib/public/javascripts/Jit/Examples/RGraph/example1.js +475 -0
- data/lib/public/javascripts/Jit/Examples/RGraph/example2.html +58 -0
- data/lib/public/javascripts/Jit/Examples/RGraph/example2.js +356 -0
- data/lib/public/javascripts/Jit/Examples/RGraph/example3.html +199 -0
- data/lib/public/javascripts/Jit/Examples/RGraph/example3.js +622 -0
- data/lib/public/javascripts/Jit/Examples/Spacetree/example1.html +91 -0
- data/lib/public/javascripts/Jit/Examples/Spacetree/example1.js +890 -0
- data/lib/public/javascripts/Jit/Examples/Spacetree/example2.html +90 -0
- data/lib/public/javascripts/Jit/Examples/Spacetree/example2.js +213 -0
- data/lib/public/javascripts/Jit/Examples/Spacetree/example3.html +75 -0
- data/lib/public/javascripts/Jit/Examples/Spacetree/example3.js +863 -0
- data/lib/public/javascripts/Jit/Examples/Treemap/example1.html +56 -0
- data/lib/public/javascripts/Jit/Examples/Treemap/example1.js +95 -0
- data/lib/public/javascripts/Jit/Examples/Treemap/example2.html +61 -0
- data/lib/public/javascripts/Jit/Examples/Treemap/example2.js +750 -0
- data/lib/public/javascripts/Jit/Examples/Treemap/example3.html +62 -0
- data/lib/public/javascripts/Jit/Examples/Treemap/example3.js +775 -0
- data/lib/public/javascripts/Jit/Examples/css/Hypertree.css +0 -0
- data/lib/public/javascripts/Jit/Examples/css/Other.css +8 -0
- data/lib/public/javascripts/Jit/Examples/css/RGraph.css +0 -0
- data/lib/public/javascripts/Jit/Examples/css/Spacetree.css +0 -0
- data/lib/public/javascripts/Jit/Examples/css/Treemap.css +78 -0
- data/lib/public/javascripts/Jit/Examples/css/base.css +106 -0
- data/lib/public/javascripts/Jit/Examples/css/col1.png +0 -0
- data/lib/public/javascripts/Jit/Examples/css/col2.png +0 -0
- data/lib/public/javascripts/Jit/Examples/css/gradient.png +0 -0
- data/lib/public/javascripts/Jit/Extras/excanvas.js +35 -0
- data/lib/public/javascripts/Jit/jit-yc.js +1 -0
- data/lib/public/javascripts/Jit/jit.js +9052 -0
- data/lib/public/javascripts/Jit-1.1.3.zip +0 -0
- data/lib/public/javascripts/application.js +28 -0
- data/lib/public/javascripts/jit.min.js +1 -0
- data/lib/public/javascripts/jquery.tools.min.js +38 -0
- data/lib/public/javascripts/jquery_min.js +19 -0
- data/lib/public/javascripts/jquery_ui_min.js +298 -0
- data/lib/public/stylesheets/mongo3.css +275 -0
- data/lib/utils.rb +3 -0
- data/lib/views/_cltn_info.erb +95 -0
- data/lib/views/_collection.erb +5 -0
- data/lib/views/_crumbs.erb +13 -0
- data/lib/views/_dump_array.erb +5 -0
- data/lib/views/_dump_hash.erb +14 -0
- data/lib/views/_info.erb +15 -0
- data/lib/views/center_js.erb +3 -0
- data/lib/views/cltn_show.erb +1 -0
- data/lib/views/collection.erb +44 -0
- data/lib/views/database.erb +37 -0
- data/lib/views/db_show.erb +1 -0
- data/lib/views/explore.erb +250 -0
- data/lib/views/landscape.erb +45 -0
- data/lib/views/layout.erb +28 -0
- data/lib/views/more_data_js.erb +3 -0
- data/lib/views/show_cltn.erb +1 -0
- data/lib/views/update_crumb_js.erb +1 -0
- data/spec/mongo3/node_spec.rb +84 -0
- data/spec/spec_helper.rb +8 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +32 -0
- data/tasks/rdoc.rake +56 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- metadata +213 -0
data/.bnignore
ADDED
data/.bnsignore
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# The list of files that should be ignored by Mr Bones.
|
2
|
+
# Lines that start with '#' are comments.
|
3
|
+
#
|
4
|
+
# A .gitignore file can be used instead by setting it as the ignore
|
5
|
+
# file in your Rakefile:
|
6
|
+
#
|
7
|
+
# PROJ.ignore_file = '.gitignore'
|
8
|
+
#
|
9
|
+
# For a project with a C extension, the following would be a good set of
|
10
|
+
# exclude patterns (uncomment them if you want to use them):
|
11
|
+
# *.[oa]
|
12
|
+
# *~
|
13
|
+
announcement.txt
|
14
|
+
coverage
|
15
|
+
doc
|
16
|
+
pkg
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.psd
|
data/HISTORY
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
== Mongo3
|
2
|
+
|
3
|
+
Rule your mongoDB clusters!
|
4
|
+
A Sinatra based admin console for mongoDB
|
5
|
+
|
6
|
+
== DESCRIPTION:
|
7
|
+
|
8
|
+
Mongo3 allows you to manage your mongoDB clusters using a web based admin console.
|
9
|
+
The console provides for getting an overview of your mongo landscape and drilldown to
|
10
|
+
see various information about your databases. You will be able to manage your clusters
|
11
|
+
by performing common database admin tasks directly from the web console.
|
12
|
+
|
13
|
+
The initial release of Mongo3 will be a read only shallow mode. Further development
|
14
|
+
still needs to take place to build up the functionality from the existing code base.
|
15
|
+
|
16
|
+
== PROJECT INFORMATION
|
17
|
+
|
18
|
+
* Developer: Fernand Galiana
|
19
|
+
* Site: http://mongo3.com
|
20
|
+
* Twitter: http://twitter.com/mongo_3
|
21
|
+
* Forum: http://groups.google.com/group/mongo3
|
22
|
+
|
23
|
+
== FEATURES:
|
24
|
+
|
25
|
+
* Easily administer your mongo cluster information
|
26
|
+
* Get a real time snapshot of what your configuration looks like
|
27
|
+
* Drill down on clusters, databases, collections and indexes
|
28
|
+
* Manage all mongo artifacts from a single web interface
|
29
|
+
|
30
|
+
== ROAD MAP:
|
31
|
+
|
32
|
+
* Provide support for db authentication
|
33
|
+
* Ability to drilldown in collections and query for content
|
34
|
+
* CRUD on dbs, collections, indexes, users
|
35
|
+
* Support for managing shards and replication
|
36
|
+
|
37
|
+
== INSTALL:
|
38
|
+
|
39
|
+
sudo gem install mongo3
|
40
|
+
|
41
|
+
== USAGE:
|
42
|
+
|
43
|
+
=== Configure It!
|
44
|
+
|
45
|
+
You will need to give mongo3 some information about your mongo configuration.
|
46
|
+
In order to do so create a .mongo3 directory in your home directory and create
|
47
|
+
a file landscape.yml. You will need to specify the envs, host and ports specific
|
48
|
+
to your configuration, but here is a sample.
|
49
|
+
|
50
|
+
landscape.yml
|
51
|
+
development:
|
52
|
+
host: localhost
|
53
|
+
port: 27017
|
54
|
+
|
55
|
+
beta:
|
56
|
+
host: beta_host_name
|
57
|
+
port: 27017
|
58
|
+
|
59
|
+
=== Launch It!
|
60
|
+
|
61
|
+
Launch it. Fires up sinatra and opens up the console
|
62
|
+
> mongo3
|
63
|
+
|
64
|
+
== LICENSE:
|
65
|
+
|
66
|
+
Copyright 2009-2010 LiquidRail LLC
|
67
|
+
|
68
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
69
|
+
you may not use this file except in compliance with the License.
|
70
|
+
You may obtain a copy of the License at
|
71
|
+
|
72
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
73
|
+
|
74
|
+
Unless required by applicable law or agreed to in writing, software
|
75
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
76
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
77
|
+
See the License for the specific language governing permissions and
|
78
|
+
limitations under the License.
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Look in the tasks/setup.rb file for the various options that can be
|
2
|
+
# configured in this Rakefile. The .rake files in the tasks directory
|
3
|
+
# are where the options are used.
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'bones'
|
7
|
+
Bones.setup
|
8
|
+
rescue LoadError
|
9
|
+
begin
|
10
|
+
load 'tasks/setup.rb'
|
11
|
+
rescue LoadError
|
12
|
+
raise RuntimeError, '### please install the "bones" gem ###'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
ensure_in_path 'lib'
|
17
|
+
require 'mongo3'
|
18
|
+
|
19
|
+
task :default => 'spec:run'
|
20
|
+
|
21
|
+
PROJ.name = 'mongo3'
|
22
|
+
PROJ.authors = 'Fernand Galiana'
|
23
|
+
PROJ.email = 'fernand.galiana@gmail.com'
|
24
|
+
PROJ.url = 'http://www.mongo3.com'
|
25
|
+
PROJ.version = Mongo3::VERSION
|
26
|
+
PROJ.ruby_opts = %w[-W0]
|
27
|
+
PROJ.readme = 'README.rdoc'
|
28
|
+
PROJ.rcov.opts = ["--sort", "coverage", "-T"]
|
29
|
+
PROJ.ignore_file = "*.log"
|
30
|
+
PROJ.spec.opts << '--color'
|
31
|
+
PROJ.rdoc.include = %w[.rb]
|
data/bin/mongo3
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'sinatra'
|
4
|
+
require File.expand_path( File.join(File.dirname(__FILE__), %w[.. lib mongo3]))
|
5
|
+
require File.join(File.dirname(__FILE__), %w[.. lib main.rb])
|
6
|
+
|
7
|
+
def open(path)
|
8
|
+
case RUBY_PLATFORM
|
9
|
+
when /darwin/
|
10
|
+
system 'open', path
|
11
|
+
when /mswin(?!ce)|mingw|cygwin|bccwin/
|
12
|
+
system 'start', path
|
13
|
+
else
|
14
|
+
system 'firefox', path
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Thread.new do
|
19
|
+
puts "\n"*2
|
20
|
+
puts ">>> Waiting for Franky to warm up..."
|
21
|
+
puts "\n"*2
|
22
|
+
sleep( 3 )
|
23
|
+
puts "\n"*2
|
24
|
+
puts "\n\n >>> Opening console..."
|
25
|
+
puts "\n"*2
|
26
|
+
open( "http://localhost:6666/explore" )
|
27
|
+
end
|
28
|
+
|
29
|
+
Sinatra::Application.run! :port => 6666
|
data/config/mongo3.yml
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
development:
|
2
|
+
:host: localhost
|
3
|
+
:port: 27017
|
4
|
+
|
5
|
+
beta:
|
6
|
+
:host: dev8
|
7
|
+
:port: 27018
|
8
|
+
:user: "blee"
|
9
|
+
:password: "fred"
|
10
|
+
|
11
|
+
# production:
|
12
|
+
# :host: dev8
|
13
|
+
# :port: 27018
|
14
|
+
# :user: "blee"
|
15
|
+
# :password: "fred"
|
16
|
+
#
|
17
|
+
# serv1:
|
18
|
+
# :host: dev8
|
19
|
+
# :port: 27018
|
20
|
+
# :user: "blee"
|
21
|
+
# :password: "fred"
|
22
|
+
#
|
23
|
+
# serv2:
|
24
|
+
# :host: dev8
|
25
|
+
# :port: 27018
|
26
|
+
# :user: "blee"
|
27
|
+
# :password: "fred"
|
28
|
+
#
|
29
|
+
# serv3:
|
30
|
+
# :host: dev8
|
31
|
+
# :port: 27018
|
32
|
+
# :user: "blee"
|
33
|
+
# :password: "fred"
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Explore
|
2
|
+
|
3
|
+
# -----------------------------------------------------------------------------
|
4
|
+
get '/explore' do
|
5
|
+
reset_crumbs!
|
6
|
+
@root = options.connection.build_tree
|
7
|
+
erb :explore
|
8
|
+
end
|
9
|
+
|
10
|
+
# -----------------------------------------------------------------------------
|
11
|
+
get '/explore/show/:path/:crumbs' do
|
12
|
+
path = params[:path]
|
13
|
+
crumbs = params[:crumbs]
|
14
|
+
|
15
|
+
@info = options.connection.show( path, crumbs )
|
16
|
+
|
17
|
+
partial :info
|
18
|
+
end
|
19
|
+
|
20
|
+
# -----------------------------------------------------------------------------
|
21
|
+
get '/explore/more_data/:path/:crumbs/*' do
|
22
|
+
path = params[:path]
|
23
|
+
crumbs = params[:crumbs]
|
24
|
+
|
25
|
+
crumbs_from_path( path, crumbs )
|
26
|
+
|
27
|
+
@sub_tree = options.connection.build_sub_tree( path, crumbs )
|
28
|
+
@node_id = @sub_tree.first[:id]
|
29
|
+
|
30
|
+
erb :more_data_js, :layout => false
|
31
|
+
end
|
32
|
+
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
get '/explore/update_crumb/:path/:crumbs' do
|
35
|
+
crumbs_from_path( params[:path], params[:crumbs] )
|
36
|
+
erb :update_crumb_js, :layout => false
|
37
|
+
end
|
38
|
+
|
39
|
+
# -----------------------------------------------------------------------------
|
40
|
+
get '/explore/center/:node_id' do
|
41
|
+
@node_id = params[:node_id]
|
42
|
+
pop_crumb!( @node_id )
|
43
|
+
erb :center_js, :layout => false
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module CrumbHelper
|
2
|
+
|
3
|
+
helpers do
|
4
|
+
def crumbs_from_path( path, crumbs )
|
5
|
+
crumb_tokens = crumbs.split( "|" )
|
6
|
+
path_tokens = path.split( "|" )
|
7
|
+
|
8
|
+
@crumbs = []
|
9
|
+
count = 0
|
10
|
+
crumb_tokens.each do |crumb|
|
11
|
+
@crumbs << [crumb, "/explore/center/#{path_tokens[count]}"]
|
12
|
+
count += 1
|
13
|
+
end
|
14
|
+
session[:crumbs] = @crumbs
|
15
|
+
end
|
16
|
+
|
17
|
+
def pop_crumb!( node_id )
|
18
|
+
level = 0
|
19
|
+
range = nil
|
20
|
+
path = "/explore/center/#{node_id}"
|
21
|
+
@crumbs.each do |pair|
|
22
|
+
if pair.last == path
|
23
|
+
range = level
|
24
|
+
break
|
25
|
+
end
|
26
|
+
level += 1
|
27
|
+
end
|
28
|
+
@crumbs = ( range > 0 ? @crumbs[0..range] : [@crumbs[0]] )
|
29
|
+
session[:crumbs] = @crumbs
|
30
|
+
end
|
31
|
+
|
32
|
+
def reset_crumbs!
|
33
|
+
@crumbs = [ ["home", '/explore/center/home'] ]
|
34
|
+
session[:crumbs] = @crumbs
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_crumb( title, url )
|
38
|
+
titles = @crumbs.map{ |p| p.first }
|
39
|
+
unless titles.include?( title )
|
40
|
+
@crumbs.pop if @crumbs.size == 3
|
41
|
+
@crumbs << [title, url]
|
42
|
+
session[:crumbs] = @crumbs
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module MainHelper
|
2
|
+
|
3
|
+
JS_ESCAPE_MAP =
|
4
|
+
{
|
5
|
+
'\\' => '\\\\',
|
6
|
+
'</' => '<\/',
|
7
|
+
"\r\n" => '\n',
|
8
|
+
"\n" => '\n',
|
9
|
+
"\r" => '\n',
|
10
|
+
'"' => '\\"',
|
11
|
+
"'" => "\\'"
|
12
|
+
}
|
13
|
+
|
14
|
+
helpers do
|
15
|
+
|
16
|
+
def display_info( info )
|
17
|
+
return info if info.is_a?( String )
|
18
|
+
if info.is_a?( Hash )
|
19
|
+
@info = info
|
20
|
+
partial :dump_hash
|
21
|
+
elsif info.is_a?( Array )
|
22
|
+
@info = info
|
23
|
+
partial :dump_array
|
24
|
+
else
|
25
|
+
info
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def partial( page, options={} )
|
30
|
+
erb "_#{page}".to_sym, options.merge!( :layout => false )
|
31
|
+
end
|
32
|
+
|
33
|
+
def escape_javascript(javascript)
|
34
|
+
if javascript
|
35
|
+
javascript.gsub(/(\\|<\/|\r\n|[\n\r"'])/) { JS_ESCAPE_MAP[$1] }
|
36
|
+
else
|
37
|
+
''
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/lib/main.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sinatra'
|
3
|
+
require 'forwardable'
|
4
|
+
require File.join( File.dirname(__FILE__), 'mongo3.rb' )
|
5
|
+
require 'mongo'
|
6
|
+
|
7
|
+
set :public, File.join( File.dirname(__FILE__), %w[public] )
|
8
|
+
set :views , File.join( File.dirname(__FILE__), %w[views] )
|
9
|
+
|
10
|
+
# -----------------------------------------------------------------------------
|
11
|
+
# Configuration
|
12
|
+
configure do
|
13
|
+
Mongo3.load_all_libs_relative_to(__FILE__, 'helpers' )
|
14
|
+
Mongo3.load_all_libs_relative_to(__FILE__, 'controllers' )
|
15
|
+
|
16
|
+
set :sessions , true
|
17
|
+
set :connection, Mongo3::Connection.new( File.join( ENV['HOME'], %w[.mongo3 landscape.yml] ) )
|
18
|
+
end
|
19
|
+
|
20
|
+
# -----------------------------------------------------------------------------
|
21
|
+
# Before filters
|
22
|
+
before do
|
23
|
+
unless request.path =~ /\.[css gif png js]/
|
24
|
+
@crumbs = session[:crumbs]
|
25
|
+
unless @crumbs
|
26
|
+
@crumbs = [ ['HOME', '/center'] ]
|
27
|
+
session[:crumbs] = @crumbs
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# =============================================================================
|
33
|
+
# Helpers
|
34
|
+
helpers do
|
35
|
+
|
36
|
+
# Convert size to mb
|
37
|
+
def to_mb( val )
|
38
|
+
return val if val < 1_000_000
|
39
|
+
"#{val/1_000_000}Mb"
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
module Mongo3
|
2
|
+
class Connection
|
3
|
+
|
4
|
+
def initialize( config_file )
|
5
|
+
@config_file = config_file
|
6
|
+
end
|
7
|
+
|
8
|
+
# Connects to mongo given an environment
|
9
|
+
# BOZO !! Auth...
|
10
|
+
# TODO - Need to close out connection via block
|
11
|
+
def connect_for( env, &block )
|
12
|
+
info = landscape[env]
|
13
|
+
puts ">>> Connecting for #{env} -- #{info[:host]}-#{info[:port]}"
|
14
|
+
con = Mongo::Connection.new( info[:host], info[:port] )
|
15
|
+
yield con
|
16
|
+
con.close()
|
17
|
+
end
|
18
|
+
|
19
|
+
def show( path, crumbs )
|
20
|
+
path_tokens = path.split( "|" )
|
21
|
+
crumb_tokens = crumbs.split( "|" )
|
22
|
+
info = OrderedHash.new
|
23
|
+
env = path_tokens[1]
|
24
|
+
|
25
|
+
if path_tokens.size == 2
|
26
|
+
connect_for( env ) do |con|
|
27
|
+
info[:name] = env
|
28
|
+
info[:host] = con.host
|
29
|
+
info[:port] = con.port
|
30
|
+
info[:databases] = OrderedHash.new
|
31
|
+
con.database_info.sort { |a,b| b[1] <=> a[1] }.each { |e| info[:databases][e[0]] = to_mb( e[1] ) }
|
32
|
+
info[:server] = con.server_info
|
33
|
+
end
|
34
|
+
elsif path_tokens.size == 3
|
35
|
+
db_name = crumb_tokens.pop
|
36
|
+
connect_for( env ) do |con|
|
37
|
+
db = con.db( db_name )
|
38
|
+
info[:size] = to_mb( con.database_info[db_name] )
|
39
|
+
info[:node] = db.nodes
|
40
|
+
info[:collections] = db.collection_names.size
|
41
|
+
info[:error] = db.error
|
42
|
+
info[:last_status] = db.last_status
|
43
|
+
end
|
44
|
+
elsif path_tokens.size == 4
|
45
|
+
cltn_name = crumb_tokens.pop
|
46
|
+
db_name = crumb_tokens.pop
|
47
|
+
connect_for( env ) do |con|
|
48
|
+
db = con.db( db_name )
|
49
|
+
cltn = db[cltn_name]
|
50
|
+
info[:size] = cltn.count
|
51
|
+
|
52
|
+
indexes = db.index_information( cltn_name )
|
53
|
+
info[:indexes] = format_indexes( db.index_information( cltn_name ) ) if indexes and !indexes.empty?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
info
|
58
|
+
end
|
59
|
+
|
60
|
+
def format_indexes( indexes )
|
61
|
+
formatted = {}
|
62
|
+
indexes.each_pair do |key, values|
|
63
|
+
buff = []
|
64
|
+
values.each do |pair|
|
65
|
+
buff << "#{pair.first} [#{pair.last}]"
|
66
|
+
end
|
67
|
+
formatted[key] = buff
|
68
|
+
end
|
69
|
+
formatted
|
70
|
+
end
|
71
|
+
|
72
|
+
# Fetch the environment landscape from the config file
|
73
|
+
def landscape
|
74
|
+
config
|
75
|
+
end
|
76
|
+
|
77
|
+
# db request occurs within dist 2
|
78
|
+
def db_request?( path )
|
79
|
+
path.size == 2
|
80
|
+
end
|
81
|
+
|
82
|
+
# cltn request occurs within dist 3
|
83
|
+
def cltn_request?( path )
|
84
|
+
path.size == 3
|
85
|
+
end
|
86
|
+
|
87
|
+
# Build environment tree
|
88
|
+
def build_tree
|
89
|
+
root = Node.new( "home", "home", :path => 'home', :crumbs => 'home' )
|
90
|
+
|
91
|
+
# iterate thru envs
|
92
|
+
id = 1
|
93
|
+
config.each_pair do |env, info|
|
94
|
+
node = Node.new( env, env, :dyna => true )
|
95
|
+
root << node
|
96
|
+
id += 1
|
97
|
+
end
|
98
|
+
root
|
99
|
+
end
|
100
|
+
|
101
|
+
# Build an appropriate subtree based on requested item
|
102
|
+
def build_sub_tree( path, crumbs )
|
103
|
+
path_tokens = path.split( "|" )
|
104
|
+
crumb_tokens = crumbs.split( "|" )
|
105
|
+
parent_id = path_tokens.last
|
106
|
+
db_name = crumb_tokens.last
|
107
|
+
|
108
|
+
if db_request?( path_tokens )
|
109
|
+
sub_tree = build_db_tree( parent_id, db_name )
|
110
|
+
else
|
111
|
+
env = crumb_tokens[1]
|
112
|
+
sub_tree = build_cltn_tree( parent_id, env, db_name )
|
113
|
+
end
|
114
|
+
sub_tree.to_adjacencies
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
# Connects to host and spews out all available dbs
|
119
|
+
# BOZO !! Need to deal with Auth?
|
120
|
+
def build_db_tree( parent_id, env )
|
121
|
+
sub_root = nil
|
122
|
+
connect_for( env ) do |con|
|
123
|
+
root = Node.new( "home", "home" )
|
124
|
+
sub_root = Node.new( parent_id, env )
|
125
|
+
|
126
|
+
root << sub_root
|
127
|
+
|
128
|
+
count = 0
|
129
|
+
data = { :dyna => true }
|
130
|
+
# excludes = %w[admin local]
|
131
|
+
con.database_names.each do |db_name|
|
132
|
+
# next if excludes.include?( db_name )
|
133
|
+
db = con.db( db_name, :strict => true )
|
134
|
+
cltns = db.collection_names.size
|
135
|
+
node = Node.new( "#{env}_#{count}", "#{db_name}(#{cltns})", data.clone )
|
136
|
+
sub_root << node
|
137
|
+
count += 1
|
138
|
+
end
|
139
|
+
end
|
140
|
+
sub_root
|
141
|
+
end
|
142
|
+
|
143
|
+
# Show collections
|
144
|
+
def build_cltn_tree( parent_id, env, db_name )
|
145
|
+
sub_root = nil
|
146
|
+
connect_for( env ) do |con|
|
147
|
+
db = con.db( db_name )
|
148
|
+
root = Node.new( "home", "home" )
|
149
|
+
env_node = Node.new( env, env )
|
150
|
+
sub_root = Node.new( parent_id, db_name )
|
151
|
+
root << env_node
|
152
|
+
env_node << sub_root
|
153
|
+
|
154
|
+
count = 0
|
155
|
+
# excludes = %w[system.indexes]
|
156
|
+
data = { :dyna => false }
|
157
|
+
db.collection_names.each do |cltn_name|
|
158
|
+
# next if excludes.include?( cltn_name )
|
159
|
+
size = db[cltn_name].count
|
160
|
+
node = Node.new( "#{db_name}_#{count}", "#{cltn_name}(#{size})", data.clone )
|
161
|
+
sub_root << node
|
162
|
+
count += 1
|
163
|
+
end
|
164
|
+
end
|
165
|
+
sub_root
|
166
|
+
end
|
167
|
+
|
168
|
+
# =========================================================================
|
169
|
+
private
|
170
|
+
|
171
|
+
# Convert size to mb
|
172
|
+
def to_mb( val )
|
173
|
+
return val if val < 1_000_000
|
174
|
+
"#{format_number(val/1_000_000)}Mb"
|
175
|
+
end
|
176
|
+
|
177
|
+
# Add thousand markers
|
178
|
+
def format_number( numb )
|
179
|
+
numb.to_s.gsub(/(\d)(?=\d{3}+(\.\d*)?$)/, '\1,')
|
180
|
+
end
|
181
|
+
|
182
|
+
# Initialize the mongo installation landscape
|
183
|
+
def config
|
184
|
+
unless @config
|
185
|
+
@config = YAML.load_file( @config_file )
|
186
|
+
end
|
187
|
+
@config
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
end
|
data/lib/mongo3/node.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Mongo3
|
4
|
+
class Node
|
5
|
+
attr_accessor :oid, :name, :children, :data, :parent
|
6
|
+
|
7
|
+
def initialize( oid, name, data={} )
|
8
|
+
@oid = oid
|
9
|
+
@name = name
|
10
|
+
@children = []
|
11
|
+
@data = data || {}
|
12
|
+
@parent = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
# Add a child node
|
16
|
+
def <<( new_one )
|
17
|
+
new_one.parent = self
|
18
|
+
@children << new_one
|
19
|
+
update_paths( new_one )
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_paths( node )
|
23
|
+
node.data[:crumbs] = node.path( :name )
|
24
|
+
node.data[:path] = node.path
|
25
|
+
node.children.each do |child|
|
26
|
+
child.update_paths( child )
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# convert a tree node to a set of adjacencies
|
31
|
+
def to_adjacencies
|
32
|
+
root_level = { :id => self.oid, :name => self.name, :data => self.data, :adjacencies => [] }
|
33
|
+
cltn = [ root_level ]
|
34
|
+
self.children.each do |child|
|
35
|
+
root_level[:adjacencies] << child.oid
|
36
|
+
cltn << { :id => child.oid, :name => child.name, :data => child.data, :adjacencies => [] }
|
37
|
+
end
|
38
|
+
cltn
|
39
|
+
end
|
40
|
+
|
41
|
+
def path( accessor=:oid )
|
42
|
+
path = []
|
43
|
+
traverse( path, self, accessor )
|
44
|
+
path.reverse.join( "|" )
|
45
|
+
end
|
46
|
+
|
47
|
+
def traverse( path, node, accessor )
|
48
|
+
path << node.send( accessor ).gsub( /\(\d+\)/, "" )
|
49
|
+
if node.parent
|
50
|
+
traverse( path, node.parent, accessor )
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# converts to json
|
55
|
+
def to_json(*a)
|
56
|
+
{
|
57
|
+
'id' => oid,
|
58
|
+
'name' => self.name,
|
59
|
+
'children' => self.children,
|
60
|
+
'data' => self.data
|
61
|
+
}.to_json(*a)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Debug...
|
65
|
+
|
66
|
+
# Dump nodes to stdout
|
67
|
+
def self.dump( node, level=0 )
|
68
|
+
puts ' '*level + "%-#{20-level}s (%d) [%s] -- %s" % [node.oid, node.children.size, node.name, (node.data ? node.data.inspect : 'N/A' )]
|
69
|
+
node.children.each { |c| dump( c, level+1 ) }
|
70
|
+
end
|
71
|
+
|
72
|
+
# Dump adjancencies to stdout
|
73
|
+
def self.dump_adj( adjs, level = 0 )
|
74
|
+
adjs.each do |adj|
|
75
|
+
puts ' '*level + "%-#{20-level}s (%d) [%s] -- %s" % [adj[:id], adj[:adjacencies].size, adj[:name], (adj[:data] ? adj[:data].inspect : 'N/A' )]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|