mongo3 0.0.1

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.
Files changed (132) hide show
  1. data/.bnignore +3 -0
  2. data/.bnsignore +16 -0
  3. data/.gitignore +1 -0
  4. data/HISTORY +2 -0
  5. data/README.rdoc +78 -0
  6. data/Rakefile +31 -0
  7. data/bin/mongo3 +29 -0
  8. data/config/mongo3.yml +33 -0
  9. data/lib/controllers/collections.rb +7 -0
  10. data/lib/controllers/databases.rb +7 -0
  11. data/lib/controllers/explore.rb +46 -0
  12. data/lib/helpers/crumb_helper.rb +46 -0
  13. data/lib/helpers/main_helper.rb +43 -0
  14. data/lib/main.rb +41 -0
  15. data/lib/mongo3/connection.rb +191 -0
  16. data/lib/mongo3/node.rb +80 -0
  17. data/lib/mongo3.rb +57 -0
  18. data/lib/public/images/c292199_a.jpg +0 -0
  19. data/lib/public/images/close.png +0 -0
  20. data/lib/public/images/close.psd +0 -0
  21. data/lib/public/images/cluster.png +0 -0
  22. data/lib/public/images/cluster.psd +0 -0
  23. data/lib/public/images/db.jpg +0 -0
  24. data/lib/public/images/db.png +0 -0
  25. data/lib/public/images/db.psd +0 -0
  26. data/lib/public/images/delete.png +0 -0
  27. data/lib/public/images/header.png +0 -0
  28. data/lib/public/images/header.psd +0 -0
  29. data/lib/public/images/li_select.png +0 -0
  30. data/lib/public/images/li_select.psd +0 -0
  31. data/lib/public/images/lock.png +0 -0
  32. data/lib/public/images/lock.psd +0 -0
  33. data/lib/public/images/mongo.png +0 -0
  34. data/lib/public/images/mongo.psd +0 -0
  35. data/lib/public/images/mongo3.png +0 -0
  36. data/lib/public/images/mongo3.psd +0 -0
  37. data/lib/public/images/mongo3_db.png +0 -0
  38. data/lib/public/images/mongo3_db.psd +0 -0
  39. data/lib/public/images/mongo_10.psd +0 -0
  40. data/lib/public/images/mongo_db.jpg +0 -0
  41. data/lib/public/images/mongo_db.png +0 -0
  42. data/lib/public/images/mongo_db.psd +0 -0
  43. data/lib/public/images/mongo_db_1.jpg +0 -0
  44. data/lib/public/images/mongo_db_2 +0 -0
  45. data/lib/public/images/mongo_db_4 +0 -0
  46. data/lib/public/images/monkey.jpg +0 -0
  47. data/lib/public/images/monkey.png +0 -0
  48. data/lib/public/images/monkey.psd +0 -0
  49. data/lib/public/images/monkey_1.jpg +8 -0
  50. data/lib/public/images/monkey_10.jpg +8 -0
  51. data/lib/public/javascripts/Jit/Examples/Hypertree/example1.html +57 -0
  52. data/lib/public/javascripts/Jit/Examples/Hypertree/example1.js +427 -0
  53. data/lib/public/javascripts/Jit/Examples/Hypertree/example2.html +58 -0
  54. data/lib/public/javascripts/Jit/Examples/Hypertree/example2.js +310 -0
  55. data/lib/public/javascripts/Jit/Examples/Hypertree/example3.html +199 -0
  56. data/lib/public/javascripts/Jit/Examples/Hypertree/example3.js +615 -0
  57. data/lib/public/javascripts/Jit/Examples/Other/example1.html +58 -0
  58. data/lib/public/javascripts/Jit/Examples/Other/example1.js +566 -0
  59. data/lib/public/javascripts/Jit/Examples/Other/example2.html +58 -0
  60. data/lib/public/javascripts/Jit/Examples/Other/example2.js +304 -0
  61. data/lib/public/javascripts/Jit/Examples/Other/example3.html +58 -0
  62. data/lib/public/javascripts/Jit/Examples/Other/example3.js +304 -0
  63. data/lib/public/javascripts/Jit/Examples/RGraph/example1.html +57 -0
  64. data/lib/public/javascripts/Jit/Examples/RGraph/example1.js +475 -0
  65. data/lib/public/javascripts/Jit/Examples/RGraph/example2.html +58 -0
  66. data/lib/public/javascripts/Jit/Examples/RGraph/example2.js +356 -0
  67. data/lib/public/javascripts/Jit/Examples/RGraph/example3.html +199 -0
  68. data/lib/public/javascripts/Jit/Examples/RGraph/example3.js +622 -0
  69. data/lib/public/javascripts/Jit/Examples/Spacetree/example1.html +91 -0
  70. data/lib/public/javascripts/Jit/Examples/Spacetree/example1.js +890 -0
  71. data/lib/public/javascripts/Jit/Examples/Spacetree/example2.html +90 -0
  72. data/lib/public/javascripts/Jit/Examples/Spacetree/example2.js +213 -0
  73. data/lib/public/javascripts/Jit/Examples/Spacetree/example3.html +75 -0
  74. data/lib/public/javascripts/Jit/Examples/Spacetree/example3.js +863 -0
  75. data/lib/public/javascripts/Jit/Examples/Treemap/example1.html +56 -0
  76. data/lib/public/javascripts/Jit/Examples/Treemap/example1.js +95 -0
  77. data/lib/public/javascripts/Jit/Examples/Treemap/example2.html +61 -0
  78. data/lib/public/javascripts/Jit/Examples/Treemap/example2.js +750 -0
  79. data/lib/public/javascripts/Jit/Examples/Treemap/example3.html +62 -0
  80. data/lib/public/javascripts/Jit/Examples/Treemap/example3.js +775 -0
  81. data/lib/public/javascripts/Jit/Examples/css/Hypertree.css +0 -0
  82. data/lib/public/javascripts/Jit/Examples/css/Other.css +8 -0
  83. data/lib/public/javascripts/Jit/Examples/css/RGraph.css +0 -0
  84. data/lib/public/javascripts/Jit/Examples/css/Spacetree.css +0 -0
  85. data/lib/public/javascripts/Jit/Examples/css/Treemap.css +78 -0
  86. data/lib/public/javascripts/Jit/Examples/css/base.css +106 -0
  87. data/lib/public/javascripts/Jit/Examples/css/col1.png +0 -0
  88. data/lib/public/javascripts/Jit/Examples/css/col2.png +0 -0
  89. data/lib/public/javascripts/Jit/Examples/css/gradient.png +0 -0
  90. data/lib/public/javascripts/Jit/Extras/excanvas.js +35 -0
  91. data/lib/public/javascripts/Jit/jit-yc.js +1 -0
  92. data/lib/public/javascripts/Jit/jit.js +9052 -0
  93. data/lib/public/javascripts/Jit-1.1.3.zip +0 -0
  94. data/lib/public/javascripts/application.js +28 -0
  95. data/lib/public/javascripts/jit.min.js +1 -0
  96. data/lib/public/javascripts/jquery.tools.min.js +38 -0
  97. data/lib/public/javascripts/jquery_min.js +19 -0
  98. data/lib/public/javascripts/jquery_ui_min.js +298 -0
  99. data/lib/public/stylesheets/mongo3.css +275 -0
  100. data/lib/utils.rb +3 -0
  101. data/lib/views/_cltn_info.erb +95 -0
  102. data/lib/views/_collection.erb +5 -0
  103. data/lib/views/_crumbs.erb +13 -0
  104. data/lib/views/_dump_array.erb +5 -0
  105. data/lib/views/_dump_hash.erb +14 -0
  106. data/lib/views/_info.erb +15 -0
  107. data/lib/views/center_js.erb +3 -0
  108. data/lib/views/cltn_show.erb +1 -0
  109. data/lib/views/collection.erb +44 -0
  110. data/lib/views/database.erb +37 -0
  111. data/lib/views/db_show.erb +1 -0
  112. data/lib/views/explore.erb +250 -0
  113. data/lib/views/landscape.erb +45 -0
  114. data/lib/views/layout.erb +28 -0
  115. data/lib/views/more_data_js.erb +3 -0
  116. data/lib/views/show_cltn.erb +1 -0
  117. data/lib/views/update_crumb_js.erb +1 -0
  118. data/spec/mongo3/node_spec.rb +84 -0
  119. data/spec/spec_helper.rb +8 -0
  120. data/tasks/bones.rake +20 -0
  121. data/tasks/gem.rake +201 -0
  122. data/tasks/git.rake +40 -0
  123. data/tasks/notes.rake +27 -0
  124. data/tasks/post_load.rake +32 -0
  125. data/tasks/rdoc.rake +56 -0
  126. data/tasks/rubyforge.rake +55 -0
  127. data/tasks/setup.rb +292 -0
  128. data/tasks/spec.rake +54 -0
  129. data/tasks/svn.rake +47 -0
  130. data/tasks/test.rake +40 -0
  131. data/tasks/zentest.rake +36 -0
  132. metadata +213 -0
data/.bnignore ADDED
@@ -0,0 +1,3 @@
1
+ *.log
2
+ *.psd
3
+ .git
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
@@ -0,0 +1,2 @@
1
+ 0.0.1 - Initial Drop
2
+ not much there yet...
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,7 @@
1
+ module Collections
2
+
3
+ get "/cltns" do
4
+ puts "Cltns"
5
+ end
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ module Databases
2
+
3
+ get "/dbs" do
4
+ puts "Dbs"
5
+ end
6
+
7
+ end
@@ -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
@@ -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