mongo3 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +9 -1
- data/README.rdoc +20 -2
- data/Rakefile +2 -0
- data/aa.rb +17 -0
- data/bin/mongo3 +72 -25
- data/lib/{main.rb → app.rb} +23 -4
- data/lib/controllers/collections.rb +4 -3
- data/lib/controllers/explore.rb +1 -2
- data/lib/controllers/users.rb +44 -0
- data/lib/mongo3/connection.rb +57 -23
- data/lib/mongo3/user.rb +53 -0
- data/lib/mongo3/zone.rb +48 -0
- data/lib/mongo3.rb +4 -5
- data/lib/public/stylesheets/mongo3.css +73 -2
- data/lib/views/explore/_node_info.erb +5 -44
- data/lib/views/layout.erb +2 -1
- data/lib/views/users/_new.erb +41 -0
- data/lib/views/users/_results.erb +78 -0
- data/lib/views/users/list.erb +12 -0
- data/lib/views/users/results.js.erb +2 -0
- metadata +35 -3
data/HISTORY
CHANGED
@@ -18,4 +18,12 @@
|
|
18
18
|
0.0.5 - Lots of changes... Yeah!
|
19
19
|
o cleaned up ui
|
20
20
|
o added edit on main context window
|
21
|
-
o added index crud for collection
|
21
|
+
o added index crud for collection
|
22
|
+
|
23
|
+
0.0.6 - Bug fixes and minor cleanups
|
24
|
+
|
25
|
+
0.0.7 - Big changes !
|
26
|
+
o Added user administration - should be able to crub users on zone now
|
27
|
+
o Added mongo based session store using mongo_rack. (Per Kyle's suggestion! ). This is now the default session store.
|
28
|
+
You can alternatively still use memcache ( see README for instructions )
|
29
|
+
o Bug fixes and some cleanup
|
data/README.rdoc
CHANGED
@@ -32,7 +32,7 @@
|
|
32
32
|
* Provide support for db authentication [done]
|
33
33
|
* Ability to drilldown in collections and query for content [done]
|
34
34
|
* CRUD on dbs, collections, indexes [done]
|
35
|
-
* Administer users
|
35
|
+
* Administer users [done]
|
36
36
|
* Collection rename
|
37
37
|
* Manage logs
|
38
38
|
* Support for shards and replication
|
@@ -45,6 +45,8 @@
|
|
45
45
|
* agnostic-will_paginate
|
46
46
|
* memcache-client
|
47
47
|
* sinatra
|
48
|
+
* mongo_rack
|
49
|
+
* main
|
48
50
|
|
49
51
|
== INSTALL:
|
50
52
|
|
@@ -73,9 +75,25 @@
|
|
73
75
|
=== Launch It!
|
74
76
|
|
75
77
|
Launch it. Fires up sinatra and opens up the console
|
76
|
-
NOTE
|
78
|
+
NOTE!!: The gem now leverages mongo_rack ( a mongoDB based session store ).
|
79
|
+
By default, this assumes a mongoDB instance is running on localhost and on default port!
|
77
80
|
|
78
81
|
> mongo3
|
82
|
+
|
83
|
+
Alternatively you can use a different mongo instance to store mongo3 session information
|
84
|
+
or use memcache by specifying the --pool options as follows:
|
85
|
+
|
86
|
+
To use the mongo session store on localhost at port 27030 with db name 'mongo3' and collection named 'sessions'
|
87
|
+
|
88
|
+
> mongo3 --pool "mongo://localhost:27030/mongo3/sessions"
|
89
|
+
|
90
|
+
To use memcache session store on localhost at port 11233 with namespace 'mongo3'
|
91
|
+
|
92
|
+
> mongo3 --pool "memcache://localhost:11233/mongo3"
|
93
|
+
|
94
|
+
The pool options assumes the following format:
|
95
|
+
|
96
|
+
--pool {mongo|memcache}://{host}:{port}/{db_name|namespace}/{cltn_name}
|
79
97
|
|
80
98
|
== LICENSE:
|
81
99
|
|
data/Rakefile
CHANGED
data/aa.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'mongo'
|
3
|
+
|
4
|
+
con = Mongo::Connection.new( 'localhost', 27019 )
|
5
|
+
puts con.database_names.inspect
|
6
|
+
|
7
|
+
admin = con.db('admin')
|
8
|
+
|
9
|
+
users = admin[Mongo::DB::SYSTEM_USER_COLLECTION]
|
10
|
+
|
11
|
+
puts users.count
|
12
|
+
|
13
|
+
row = { :user => "fred", :pwd => admin.send( :hash_password, "fred", "duh" ) }
|
14
|
+
|
15
|
+
users.save( row )
|
16
|
+
|
17
|
+
puts users.find({}).inspect
|
data/bin/mongo3
CHANGED
@@ -1,29 +1,76 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'rubygems'
|
3
|
-
require '
|
4
|
-
require File.expand_path( File.join(File.dirname(__FILE__), %w[.. lib mongo3]))
|
5
|
-
require File.join(File.dirname(__FILE__), %w[.. lib main.rb])
|
3
|
+
require 'main'
|
6
4
|
|
7
|
-
|
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
|
5
|
+
URI_MATCH = /(mongo|memcache):\/\/(.+?)\:(\d+)\/(\w+)\/{0,1}(\w*)/
|
17
6
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
7
|
+
Main {
|
8
|
+
option( 'pool=[pool]', 'p' ) {
|
9
|
+
validate { |pool| pool =~ URI_MATCH }
|
10
|
+
description "specify server uri. Must be of the form {[mongo|memcache]}://{host}:{port}/{[database_name|namespace]}[/{collection_name}]"
|
11
|
+
}
|
12
|
+
environment( 'RACK_ENV' ) {
|
13
|
+
default 'production'
|
14
|
+
}
|
15
|
+
|
16
|
+
@@options = {}
|
17
|
+
|
18
|
+
# Enter main loop
|
19
|
+
def run
|
20
|
+
require File.expand_path( File.join(File.dirname(__FILE__), %w[.. lib mongo3]))
|
21
|
+
|
22
|
+
@@options = parse_args( params[:pool].value )
|
23
|
+
ENV['RACK_ENV'] = params['RACK_ENV'].value
|
24
|
+
|
25
|
+
Thread.new do
|
26
|
+
puts "-"*100
|
27
|
+
puts "Initializing mongo3 -- Version #{Mongo3::VERSION}"
|
28
|
+
puts "-"*100
|
29
|
+
puts "\n"*2
|
30
|
+
puts ">>> Waiting for Franky to warm up..."
|
31
|
+
puts "\n"*2
|
32
|
+
sleep( sleep_time )
|
33
|
+
puts "\n"*2
|
34
|
+
puts ">>> Opening console..."
|
35
|
+
puts "\n"*2
|
36
|
+
open( "http://localhost:6666/explore" )
|
37
|
+
end
|
38
|
+
|
39
|
+
# Clearing args for franky!
|
40
|
+
ARGV.clear
|
41
|
+
require 'sinatra'
|
42
|
+
require File.join(File.dirname(__FILE__), %w[.. lib app.rb])
|
43
|
+
Sinatra::Application.run! :port => 6666, :environment => 'production'
|
44
|
+
end
|
45
|
+
|
46
|
+
# sleepy time...
|
47
|
+
def sleep_time
|
48
|
+
3
|
49
|
+
end
|
50
|
+
|
51
|
+
# open console...
|
52
|
+
def open(path)
|
53
|
+
case RUBY_PLATFORM
|
54
|
+
when /darwin/
|
55
|
+
system 'open', path
|
56
|
+
when /mswin(?!ce)|mingw|cygwin|bccwin/
|
57
|
+
system 'start', path
|
58
|
+
else
|
59
|
+
system 'firefox', path
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# parse uri into sub components
|
64
|
+
def parse_args( server_uri )
|
65
|
+
return unless server_uri
|
66
|
+
tokens = server_uri.match( URI_MATCH ).captures
|
67
|
+
opts = { :protocol => tokens.first, :host => tokens[1], :port => tokens[2] }
|
68
|
+
if opts[:protocol] == "mongo"
|
69
|
+
opts[:db_name] = tokens[3]
|
70
|
+
opts[:cltn_name] = tokens[4]
|
71
|
+
else
|
72
|
+
opts[:namespace] = tokens[3]
|
73
|
+
end
|
74
|
+
opts
|
75
|
+
end
|
76
|
+
}
|
data/lib/{main.rb → app.rb}
RENAMED
@@ -5,18 +5,37 @@ require File.join( File.dirname(__FILE__), 'mongo3.rb' )
|
|
5
5
|
require 'mongo'
|
6
6
|
gem 'agnostic-will_paginate'
|
7
7
|
require 'will_paginate'
|
8
|
+
require 'mongo_rack'
|
8
9
|
|
9
10
|
set :public, File.join( File.dirname(__FILE__), %w[public] )
|
10
11
|
set :views , File.join( File.dirname(__FILE__), %w[views] )
|
11
12
|
|
12
13
|
# -----------------------------------------------------------------------------
|
13
|
-
#
|
14
|
+
# Configurations
|
15
|
+
|
16
|
+
configure :production do
|
17
|
+
set :logging, false
|
18
|
+
end
|
19
|
+
|
14
20
|
configure do
|
15
21
|
Mongo3.load_all_libs_relative_to(__FILE__, 'helpers' )
|
16
22
|
Mongo3.load_all_libs_relative_to(__FILE__, 'controllers' )
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
|
24
|
+
# Pick up command line args if any?
|
25
|
+
if defined? @@options and @@options
|
26
|
+
if @@options[:protocol] == 'mongo'
|
27
|
+
use Rack::Session::Mongo,
|
28
|
+
:server => "%s:%d/%s/%s" % [@@options[:host], @@options[:port], @@options[:db_name], @@options[:cltn_name]]
|
29
|
+
else
|
30
|
+
use Rack::Session::Memcache,
|
31
|
+
:memcache_server => "%s:%d" % [@@options[:host], @@options[:port]],
|
32
|
+
:namespace => @@options[:namespace]
|
33
|
+
end
|
34
|
+
else
|
35
|
+
# Default is a mongo session store
|
36
|
+
use Rack::Session::Mongo
|
37
|
+
end
|
38
|
+
set :config_file, File.join( ENV['HOME'], %w[.mongo3 landscape.yml] )
|
20
39
|
set :connection, Mongo3::Connection.new( File.join( ENV['HOME'], %w[.mongo3 landscape.yml] ) )
|
21
40
|
end
|
22
41
|
|
@@ -2,7 +2,6 @@ require 'json'
|
|
2
2
|
|
3
3
|
module Collections
|
4
4
|
|
5
|
-
# [ ['last_name', -1], ['name', 1] ]
|
6
5
|
# ---------------------------------------------------------------------------
|
7
6
|
post "/collections/create_index/" do
|
8
7
|
json = params[:index].gsub( /'/, "\"" )
|
@@ -56,7 +55,6 @@ module Collections
|
|
56
55
|
end
|
57
56
|
|
58
57
|
# ---------------------------------------------------------------------------
|
59
|
-
# BOZO !! Validation....
|
60
58
|
post "/collections/search/" do
|
61
59
|
json = params[:search].gsub( /'/, "\"" )
|
62
60
|
if json.empty?
|
@@ -78,6 +76,7 @@ module Collections
|
|
78
76
|
erb :'collections/update.js', :layout => false
|
79
77
|
end
|
80
78
|
|
79
|
+
# ---------------------------------------------------------------------------
|
81
80
|
post '/collections/delete/' do
|
82
81
|
path_names = session[:path_names]
|
83
82
|
options.connection.delete_row( path_names, params[:id] )
|
@@ -88,6 +87,7 @@ module Collections
|
|
88
87
|
erb :'collections/update.js', :layout => false
|
89
88
|
end
|
90
89
|
|
90
|
+
# ---------------------------------------------------------------------------
|
91
91
|
get '/collections/clear/' do
|
92
92
|
path_names = session[:path_names]
|
93
93
|
options.connection.clear_cltn( path_names )
|
@@ -95,6 +95,7 @@ module Collections
|
|
95
95
|
erb :'collections/all_done.js', :layout => false
|
96
96
|
end
|
97
97
|
|
98
|
+
# ---------------------------------------------------------------------------
|
98
99
|
get '/collections/drop/' do
|
99
100
|
path_names = session[:path_names]
|
100
101
|
options.connection.drop_cltn( path_names )
|
@@ -104,7 +105,7 @@ module Collections
|
|
104
105
|
|
105
106
|
# ===========================================================================
|
106
107
|
helpers do
|
107
|
-
def load_cltn( page=1 )
|
108
|
+
def load_cltn( page=1 )
|
108
109
|
query_params = session[:query_params] || [{},[]]
|
109
110
|
if ( !query_params.first or query_params.first.empty?) and ( !query_params.last or query_params.last.empty? )
|
110
111
|
@query = nil
|
data/lib/controllers/explore.rb
CHANGED
@@ -23,7 +23,6 @@ module Explore
|
|
23
23
|
reset_crumbs!
|
24
24
|
reset_paths!
|
25
25
|
|
26
|
-
# Mongo3::Node.dump_adj( @root )
|
27
26
|
erb :'explore/explore'
|
28
27
|
end
|
29
28
|
|
@@ -72,7 +71,7 @@ module Explore
|
|
72
71
|
@sub_tree = root.to_adjacencies
|
73
72
|
@node_id = @sub_tree.first[:id]
|
74
73
|
@nodes = root.children
|
75
|
-
|
74
|
+
|
76
75
|
erb :'explore/more_data_js', :layout => false
|
77
76
|
end
|
78
77
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Users
|
2
|
+
# ---------------------------------------------------------------------------
|
3
|
+
# Paginate users
|
4
|
+
get "/users/:page" do
|
5
|
+
@back_url = "/explore/back"
|
6
|
+
@page = params[:page].to_i || 1
|
7
|
+
|
8
|
+
user_mgmt = Mongo3::User.new( options.config_file )
|
9
|
+
@users = user_mgmt.list( session[:path_names], @page, 10 )
|
10
|
+
|
11
|
+
erb :'users/list'
|
12
|
+
end
|
13
|
+
|
14
|
+
# ---------------------------------------------------------------------------
|
15
|
+
post "/users/delete/" do
|
16
|
+
id = params[:id]
|
17
|
+
user_mgmt = Mongo3::User.new( options.config_file )
|
18
|
+
|
19
|
+
user_mgmt.delete( session[:path_names], id )
|
20
|
+
flash_it!( :info, "User was dropped successfully!" )
|
21
|
+
@users = user_mgmt.list( session[:path_names], 1, 10 )
|
22
|
+
|
23
|
+
erb :'users/results.js', :layout => false
|
24
|
+
end
|
25
|
+
|
26
|
+
# ---------------------------------------------------------------------------
|
27
|
+
post "/users/add/" do
|
28
|
+
user_name = params[:user]
|
29
|
+
passwd = params[:passwd]
|
30
|
+
user_mgmt = Mongo3::User.new( options.config_file )
|
31
|
+
|
32
|
+
begin
|
33
|
+
user_mgmt.add( session[:path_names], user_name, passwd )
|
34
|
+
flash_it!( :info, "User #{user_name} was added successfully!" )
|
35
|
+
rescue => boom
|
36
|
+
flash_it!( :error, boom )
|
37
|
+
ensure
|
38
|
+
@users = user_mgmt.list( session[:path_names], 1, 10 )
|
39
|
+
end
|
40
|
+
|
41
|
+
erb :'users/results.js', :layout => false
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/lib/mongo3/connection.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# BOZO !! Time to refact no?
|
1
2
|
module Mongo3
|
2
3
|
class Connection
|
3
4
|
|
@@ -96,38 +97,41 @@ module Mongo3
|
|
96
97
|
cltn.remove( {:_id => Mongo::ObjectID.from_string(id) } )
|
97
98
|
end
|
98
99
|
end
|
99
|
-
|
100
|
+
|
100
101
|
def show( path_names )
|
101
102
|
path_name_tokens = path_names.split( "|" )
|
102
103
|
info = OrderedHash.new
|
103
|
-
zone
|
104
|
-
|
104
|
+
zone = path_name_tokens[1]
|
105
|
+
|
106
|
+
info[:links] = OrderedHash.new
|
105
107
|
info[:title] = path_name_tokens.last
|
106
|
-
|
108
|
+
|
109
|
+
# If detect slave only show reg info
|
110
|
+
slave = slave_zone?( path_name_tokens )
|
111
|
+
if path_name_tokens.size == 2 or slave
|
107
112
|
connect_for( zone ) do |con|
|
108
|
-
info[:
|
109
|
-
info[:
|
110
|
-
info[:
|
111
|
-
info[:
|
113
|
+
info[:links][:users] = "/users/1" unless slave
|
114
|
+
info[:name] = zone
|
115
|
+
info[:host] = con.host
|
116
|
+
info[:users] = con.db('admin')[Mongo::DB::SYSTEM_USER_COLLECTION].count rescue 0
|
117
|
+
info[:port] = con.port
|
118
|
+
info[:databases] = OrderedHash.new
|
112
119
|
con.database_info.sort { |a,b| b[1] <=> a[1] }.each { |e| info[:databases][e[0]] = to_mb( e[1] ) }
|
113
|
-
info[:server]
|
120
|
+
info[:server] = con.server_info
|
114
121
|
end
|
115
122
|
# BOZO !! Need to figure out links strategy!
|
116
123
|
elsif path_name_tokens.size == 3
|
117
124
|
db_name = path_name_tokens.pop
|
118
|
-
info[:links] = OrderedHash.new
|
119
125
|
connect_for( zone ) do |con|
|
120
126
|
db = con.db( db_name )
|
121
127
|
info[:links][:manage] = "/databases/1"
|
122
|
-
|
123
|
-
info[:
|
124
|
-
info[:
|
125
|
-
info[:
|
126
|
-
info[:
|
127
|
-
info[:last_status] = db.last_status
|
128
|
+
info[:size] = to_mb( con.database_info[db_name] )
|
129
|
+
info[:node] = db.nodes
|
130
|
+
info[:collections] = collection_names( db ).size
|
131
|
+
info[:error] = db.error
|
132
|
+
info[:last_status] = db.last_status
|
128
133
|
end
|
129
|
-
elsif path_name_tokens.size == 4
|
130
|
-
info[:links] = OrderedHash.new
|
134
|
+
elsif path_name_tokens.size == 4
|
131
135
|
cltn_name = path_name_tokens.pop
|
132
136
|
db_name = path_name_tokens.pop
|
133
137
|
connect_for( zone ) do |con|
|
@@ -136,7 +140,6 @@ module Mongo3
|
|
136
140
|
indexes = db.index_information( cltn_name )
|
137
141
|
|
138
142
|
info[:links][:manage] = "/collections/1"
|
139
|
-
# info[:links][:drop] = "/collections/drop/"
|
140
143
|
info[:size] = cltn.count
|
141
144
|
info[:indexes] = format_indexes( indexes ) if indexes and !indexes.empty?
|
142
145
|
end
|
@@ -253,19 +256,44 @@ module Mongo3
|
|
253
256
|
# Build zone tree
|
254
257
|
def build_partial_tree( path_names )
|
255
258
|
path_name_tokens = path_names.split( "|" )
|
256
|
-
bm_zone
|
259
|
+
bm_zone = path_name_tokens[1]
|
257
260
|
bm_cltn = path_name_tokens.pop if path_name_tokens.size == 4
|
258
261
|
bm_db = path_name_tokens.pop if path_name_tokens.size == 3
|
259
262
|
|
260
263
|
root = Node.make_node( "home" )
|
261
264
|
|
262
265
|
# iterate thru zones
|
266
|
+
adjacencies = {}
|
263
267
|
config.each_pair do |zone, info|
|
264
268
|
node = Node.new( zone, zone, :dyna => true )
|
265
269
|
root << node
|
266
270
|
|
271
|
+
adjs = adjacencies[zone]
|
272
|
+
if adjs
|
273
|
+
node.mark_master!
|
274
|
+
adjs.each { |n| node << n }
|
275
|
+
end
|
276
|
+
masters = slave?( zone )
|
277
|
+
|
278
|
+
unless masters.empty?
|
279
|
+
node.mark_slave!
|
280
|
+
masters.each do |master|
|
281
|
+
host, port = master.split( ":" )
|
282
|
+
master_zone = zone_for( host, port )
|
283
|
+
next unless master_zone
|
284
|
+
master_node = root.find( "home|#{master_zone}")
|
285
|
+
if master_node
|
286
|
+
master_node.mark_master!
|
287
|
+
master_node << node
|
288
|
+
else
|
289
|
+
adjacencies[master_zone] = [] unless adjacencies[master_zone]
|
290
|
+
adjacencies[master_zone] << node
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
267
295
|
next unless node.name == bm_zone
|
268
|
-
|
296
|
+
|
269
297
|
connect_for( zone ) do |con|
|
270
298
|
count = 0
|
271
299
|
data = { :dyna => true }
|
@@ -366,7 +394,6 @@ module Mongo3
|
|
366
394
|
end
|
367
395
|
|
368
396
|
# Connects to mongo given an zone
|
369
|
-
# BOZO !! Auth...
|
370
397
|
def connect_for( zone, &block )
|
371
398
|
info = landscape[zone]
|
372
399
|
# puts ">>> Connecting for #{zone} -- #{info['host']}-#{info['port']}"
|
@@ -404,6 +431,7 @@ module Mongo3
|
|
404
431
|
|
405
432
|
# Convert size to mb
|
406
433
|
def to_mb( val )
|
434
|
+
return 0 unless val
|
407
435
|
return val if val < 1_000_000
|
408
436
|
"#{format_number(val/1_000_000)}Mb"
|
409
437
|
end
|
@@ -420,11 +448,17 @@ module Mongo3
|
|
420
448
|
end
|
421
449
|
nil
|
422
450
|
end
|
451
|
+
|
452
|
+
# Check if this is a slave or a db path
|
453
|
+
def slave_zone?( tokens )
|
454
|
+
return false unless tokens.size == 3
|
455
|
+
return false unless config.keys.include?( tokens.last )
|
456
|
+
true
|
457
|
+
end
|
423
458
|
|
424
459
|
# Initialize the mongo installation landscape
|
425
460
|
def config
|
426
461
|
unless @config
|
427
|
-
puts ">>>> Loading config from file"
|
428
462
|
@config = YAML.load_file( @config_file )
|
429
463
|
end
|
430
464
|
@config
|
data/lib/mongo3/user.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'mongo'
|
2
|
+
require File.join( File.dirname(__FILE__), %w[zone.rb] )
|
3
|
+
|
4
|
+
module Mongo3
|
5
|
+
# Administer users on a connection
|
6
|
+
class User < Mongo3::Zone
|
7
|
+
|
8
|
+
# add a new user
|
9
|
+
def add( path, user_name, password )
|
10
|
+
connect_for( path ) do |con|
|
11
|
+
admin_db = con.db('admin')
|
12
|
+
user_cltn = admin_db[Mongo::DB::SYSTEM_USER_COLLECTION]
|
13
|
+
|
14
|
+
row = { :user => user_name }
|
15
|
+
user = user_cltn.find_one( row )
|
16
|
+
raise "User #{user_name} already exists!" if user
|
17
|
+
|
18
|
+
row[:pwd] = admin_db.send( :hash_password, user_name, password )
|
19
|
+
user_cltn.save( row )
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def rename( zone, old_name, new_name )
|
24
|
+
end
|
25
|
+
|
26
|
+
def delete( path, id )
|
27
|
+
connect_for( path ) do |con|
|
28
|
+
res = users( con ).remove( :_id => Mongo::ObjectID.from_string( id ) )
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def list( path, page, per_page=10 )
|
33
|
+
connect_for( path ) do |con|
|
34
|
+
user_cltn = users( con )
|
35
|
+
list = WillPaginate::Collection.create( page, per_page, user_cltn.size ) do |pager|
|
36
|
+
offset = (page-1)*per_page
|
37
|
+
results = user_cltn.find( {},
|
38
|
+
:sort => [['user', Mongo::ASCENDING]],
|
39
|
+
:skip => offset,
|
40
|
+
:limit => per_page ).to_a
|
41
|
+
return pager.replace( results )
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def users( con )
|
49
|
+
admin = con.db('admin')
|
50
|
+
admin[Mongo::DB::SYSTEM_USER_COLLECTION]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/mongo3/zone.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Mongo3
|
2
|
+
class Zone
|
3
|
+
|
4
|
+
attr_reader :config
|
5
|
+
|
6
|
+
def initialize( config_file )
|
7
|
+
@config_file = config_file
|
8
|
+
end
|
9
|
+
|
10
|
+
# =========================================================================
|
11
|
+
protected
|
12
|
+
|
13
|
+
def zone_for_path( path )
|
14
|
+
path.split( "|" )[1]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Connects to mongo given an zone
|
18
|
+
def connect_for( path, &block )
|
19
|
+
zone = zone_for_path( path )
|
20
|
+
info = config[zone]
|
21
|
+
# puts ">>> Connecting for #{zone} -- #{info['host']}-#{info['port']}"
|
22
|
+
con = Mongo::Connection.new( info['host'], info['port'], { :slave_ok => true } )
|
23
|
+
|
24
|
+
if info['user'] and info['password']
|
25
|
+
con.db( 'admin' ).authenticate( info['user'], info['password'] )
|
26
|
+
end
|
27
|
+
yield con
|
28
|
+
con.close()
|
29
|
+
end
|
30
|
+
|
31
|
+
# find zone matching the host and port combination
|
32
|
+
def zone_for( host, port )
|
33
|
+
config.each_pair do |zone, info|
|
34
|
+
return zone if info['host'] == host and info['port'] == port.to_i
|
35
|
+
end
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
# Initialize the mongo installation landscape
|
40
|
+
def config
|
41
|
+
unless @config
|
42
|
+
@config = YAML.load_file( @config_file )
|
43
|
+
end
|
44
|
+
@config
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
data/lib/mongo3.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
|
2
1
|
module Mongo3
|
3
|
-
|
2
|
+
|
4
3
|
# :stopdoc:
|
5
|
-
VERSION = '0.0.
|
6
|
-
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
7
|
-
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
4
|
+
VERSION = '0.0.7' unless defined? Mongo3::VERSION
|
5
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR unless defined? Mongo3::LIBPATH
|
6
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR unless defined? Mongo3::LIBPATH
|
8
7
|
# :startdoc:
|
9
8
|
|
10
9
|
# Returns the version string for the library.
|
@@ -1,3 +1,4 @@
|
|
1
|
+
/* BOZO !! Refact! */
|
1
2
|
* {
|
2
3
|
outline-color: invert;
|
3
4
|
outline-style: none;
|
@@ -19,6 +20,13 @@ body {
|
|
19
20
|
margin: 0;
|
20
21
|
}
|
21
22
|
|
23
|
+
span#version {
|
24
|
+
color: #4d7bff;
|
25
|
+
font-size: .4em;
|
26
|
+
vertical-align: bottom;
|
27
|
+
margin: 88px 0px 0px -57px;
|
28
|
+
}
|
29
|
+
|
22
30
|
img {
|
23
31
|
border: none;
|
24
32
|
vertical-align: text-top;
|
@@ -73,7 +81,7 @@ ul {
|
|
73
81
|
|
74
82
|
a {
|
75
83
|
text-decoration: none;
|
76
|
-
color: #
|
84
|
+
color: #c1c1c1;
|
77
85
|
}
|
78
86
|
a:hover {
|
79
87
|
color: #92b948;
|
@@ -333,7 +341,8 @@ table.cltn tr {
|
|
333
341
|
color: #fff;
|
334
342
|
}
|
335
343
|
table.cltn tr.highlight {
|
336
|
-
color:
|
344
|
+
color: #92b948;
|
345
|
+
cursor: pointer;
|
337
346
|
}
|
338
347
|
|
339
348
|
div.cltn div#summary {
|
@@ -474,3 +483,65 @@ span#log {
|
|
474
483
|
div#info {
|
475
484
|
min-height: 520px;
|
476
485
|
}
|
486
|
+
|
487
|
+
/* Node information */
|
488
|
+
div.item img {
|
489
|
+
z-index: 100;
|
490
|
+
display: none;
|
491
|
+
float: left;
|
492
|
+
margin-right: 10px;
|
493
|
+
}
|
494
|
+
|
495
|
+
div#legend {
|
496
|
+
border-bottom: 1px #434343 solid;
|
497
|
+
font-size: 0.5em;
|
498
|
+
color: #92b948;
|
499
|
+
overflow: hidden;
|
500
|
+
}
|
501
|
+
div#legend_link {
|
502
|
+
text-align: right;
|
503
|
+
width: 15%;
|
504
|
+
float: right;
|
505
|
+
font-size: .7em;
|
506
|
+
padding-top: 7px;
|
507
|
+
}
|
508
|
+
|
509
|
+
div.items {
|
510
|
+
margin-top:10px;
|
511
|
+
}
|
512
|
+
|
513
|
+
div.item {
|
514
|
+
border-top: 1px #bcffca solid;
|
515
|
+
height: 30px;
|
516
|
+
width: 100%;
|
517
|
+
font-size: .4em;
|
518
|
+
cursor: pointer;
|
519
|
+
z-index: 1;
|
520
|
+
}
|
521
|
+
div.selected {
|
522
|
+
background-image: url(/images/selected_bg.png);
|
523
|
+
color: #92b948;
|
524
|
+
}
|
525
|
+
|
526
|
+
/* Users */
|
527
|
+
input.field_border {
|
528
|
+
-moz-border-radius-bottomleft: 0px;
|
529
|
+
-moz-border-radius-bottomright: 10px;
|
530
|
+
-moz-border-radius-topleft: 10px;
|
531
|
+
-moz-border-radius-topright: 0px;
|
532
|
+
}
|
533
|
+
|
534
|
+
input.user {
|
535
|
+
background: transparent;
|
536
|
+
width: 200px;
|
537
|
+
border: 2px #434343 solid;
|
538
|
+
height: 25px;
|
539
|
+
font-size: 1.2em;
|
540
|
+
color: #92b948;
|
541
|
+
padding: 5px 0px 0px 5px;
|
542
|
+
margin: 5px 5px;
|
543
|
+
}
|
544
|
+
|
545
|
+
button.user:hover {
|
546
|
+
background-color: #ad1ecb;
|
547
|
+
}
|
@@ -1,47 +1,7 @@
|
|
1
|
-
<style>
|
2
|
-
div.item img {
|
3
|
-
z-index:100;
|
4
|
-
display:none;
|
5
|
-
float:left;
|
6
|
-
margin-right:10px;
|
7
|
-
}
|
8
|
-
|
9
|
-
div#legend {
|
10
|
-
border-bottom: 1px #434343 solid;
|
11
|
-
font-size: 0.5em;
|
12
|
-
color: #92b948;
|
13
|
-
overflow: hidden;
|
14
|
-
}
|
15
|
-
div#legend_link {
|
16
|
-
text-align: right;
|
17
|
-
width: 30%;
|
18
|
-
float: right;
|
19
|
-
font-size: .7em;
|
20
|
-
padding-top: 7px;
|
21
|
-
}
|
22
|
-
|
23
|
-
div.items {
|
24
|
-
margin-top:10px;
|
25
|
-
}
|
26
|
-
|
27
|
-
div.item {
|
28
|
-
border-top: 1px #bcffca solid;
|
29
|
-
height: 30px;
|
30
|
-
width: 100%;
|
31
|
-
font-size: .4em;
|
32
|
-
cursor: pointer;
|
33
|
-
z-index: 1;
|
34
|
-
}
|
35
|
-
div.selected {
|
36
|
-
background-image: url(/images/selected_bg.png);
|
37
|
-
color: #92b948;
|
38
|
-
}
|
39
|
-
</style>
|
40
|
-
|
41
1
|
<% legend = path_type( session[:path_names] ) %>
|
42
2
|
<div id="legend">
|
43
|
-
<div style="width:
|
44
|
-
@ <%= truncate( legend_title( session[:path_names] ),
|
3
|
+
<div style="width:85%;float:left">
|
4
|
+
@ <%= truncate( legend_title( session[:path_names] ), 20 ) %>
|
45
5
|
</div>
|
46
6
|
<% unless zone_path?( session[:path_names] ) %>
|
47
7
|
<div id="legend_link">
|
@@ -59,7 +19,8 @@
|
|
59
19
|
|
60
20
|
<div class="scrollable vertical">
|
61
21
|
<div class="items">
|
62
|
-
<% count=0;@nodes.sort{|a,b| a.name <=> b.name}.each do |node| %>
|
22
|
+
<% count=0;@nodes.sort{|a,b| a.name <=> b.name}.each do |node| %>
|
23
|
+
<% next if node.data[:slave] and !zone_path?( session[:path_names] ) %>
|
63
24
|
<div id="<%=count%>" class="item">
|
64
25
|
<% unless zone_path?( session[:path_names] ) %>
|
65
26
|
<img id="<%=count%>" rel="div#confirm_drop" class="drop" href="/explore/database/<%=node.oid%>/<%=node.name%>/drop" title="drop <%=legend%>..." src="/images/delete.png"/>
|
@@ -84,7 +45,7 @@
|
|
84
45
|
$( function() {
|
85
46
|
$("div.scrollable").scrollable({
|
86
47
|
vertical:true,
|
87
|
-
size:
|
48
|
+
size: 13,
|
88
49
|
}).mousewheel();
|
89
50
|
|
90
51
|
$("div.item").hover(
|
data/lib/views/layout.erb
CHANGED
@@ -14,8 +14,9 @@
|
|
14
14
|
<div id="logo">
|
15
15
|
<a href="/explore" style="float:left">
|
16
16
|
<img src='/images/mongo3.png' style="border:none"/>
|
17
|
+
<span id="version"><%=Mongo3.version%></span>
|
17
18
|
</a>
|
18
|
-
<div class="flash">Hello World</div>
|
19
|
+
<div class="flash">Hello World</div>
|
19
20
|
</div>
|
20
21
|
<div id="main">
|
21
22
|
<%= yield %>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<script src="/javascripts/jquery.example.js" type="text/javascript"></script>
|
2
|
+
|
3
|
+
<form id="add_user" onsubmit="add_user();return false;" action="/users/add/" method="post" style="text-align:center">
|
4
|
+
<fieldset>
|
5
|
+
<input id="user" type="text" name="user" class="user field_border" value=""/>
|
6
|
+
<input id="passwd" type="password" name="passwd" class="user field_border" value=""/>
|
7
|
+
<button type="submit" id="submit_button" class="button user" style="height:30px;font-size:1em">create</button>
|
8
|
+
<img id="add_load" src="/images/loading.gif" style="width:25px;height:25px;vertical-align:sub;display:none"></img>
|
9
|
+
</fieldset>
|
10
|
+
</form>
|
11
|
+
|
12
|
+
<script>
|
13
|
+
$( function() {
|
14
|
+
clear_fields( $('form#add_user') );
|
15
|
+
$('input.user').hover(
|
16
|
+
function() { $(this).css( "border-color", "#92b948") },
|
17
|
+
function() { $(this).css( "border-color", "#434343") })
|
18
|
+
});
|
19
|
+
|
20
|
+
function clear_fields( form )
|
21
|
+
{
|
22
|
+
form.find( ".no_input" ).val( '' );
|
23
|
+
$('input#user').example("user name", { className: 'no_input' } );
|
24
|
+
$('input#passwd').example("secret", { className: 'no_input' } );
|
25
|
+
}
|
26
|
+
|
27
|
+
function add_user()
|
28
|
+
{
|
29
|
+
$.ajax({
|
30
|
+
data: $.param( $("form#add_user").serializeArray() ),
|
31
|
+
dataType: 'script',
|
32
|
+
type: 'post',
|
33
|
+
url: '/users/add/',
|
34
|
+
beforeSend: function() { $('img#add_load').show(); },
|
35
|
+
complete: function() {
|
36
|
+
clear_fields( $(this) );
|
37
|
+
$('img#add_load').hide();
|
38
|
+
}
|
39
|
+
});
|
40
|
+
}
|
41
|
+
</script>
|
@@ -0,0 +1,78 @@
|
|
1
|
+
<%= partial :'users/new'%>
|
2
|
+
|
3
|
+
<div id="summary">
|
4
|
+
<%= page_entries_info @users, :entry_name => 'user' %>
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<% unless @users.empty? %>
|
8
|
+
<div class="borders" style="padding:10px">
|
9
|
+
<table id="cltn" class="cltn" border="0" cellpadding="10" cellspacing="20">
|
10
|
+
<thead>
|
11
|
+
<th width="2%"> </th>
|
12
|
+
<th>Id</th>
|
13
|
+
<th>Name</th>
|
14
|
+
</thead>
|
15
|
+
<tbody>
|
16
|
+
<% count = 0; @users.each do |user| %>
|
17
|
+
<tr id="<%=count%>" valign="top">
|
18
|
+
<td id="<%=count%>">
|
19
|
+
<img rel="div#confirm_drop" class="drop" id="<%=user['_id']%>" rel="<%=count%>" src="/images/delete.png" title="drop this user" style="display:none"/>
|
20
|
+
<img class="wait" id="wait_<%=count%>" src="/images/loading.gif"></img>
|
21
|
+
</td>
|
22
|
+
<td><%= user['_id'] %></td>
|
23
|
+
<td><%= user['user'] %></td>
|
24
|
+
</tr>
|
25
|
+
<% count+=1;end %>
|
26
|
+
</tbody>
|
27
|
+
</table>
|
28
|
+
</div>
|
29
|
+
<div id="links">
|
30
|
+
<%= will_paginate @users, :params => { :url => "/users" } %>
|
31
|
+
</div>
|
32
|
+
<% else %>
|
33
|
+
<div class="no_items">Oh snap! No users found...</span>
|
34
|
+
<% end %>
|
35
|
+
|
36
|
+
<div class="modal" id="confirm_drop" style="font-size:1em">
|
37
|
+
<p>Dropping user. Are you sure?</p>
|
38
|
+
<p style="margin:10px">
|
39
|
+
<button class="close yes">Yes</button>
|
40
|
+
<button class="close">No</button>
|
41
|
+
</p>
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<script>
|
45
|
+
$( function() {
|
46
|
+
$("table#cltn tr" ).hover(
|
47
|
+
function() {
|
48
|
+
$(this).addClass( 'highlight' );
|
49
|
+
$("td#" + $(this).attr('id') + " img.drop" ).show();
|
50
|
+
},
|
51
|
+
function() {
|
52
|
+
$(this).removeClass( 'highlight' );
|
53
|
+
$("td#" + $(this).attr('id') + " img.drop" ).hide();
|
54
|
+
});
|
55
|
+
|
56
|
+
$('img.drop' ).overlay( {
|
57
|
+
expose: {
|
58
|
+
color: '#212021',
|
59
|
+
loadSpeed: 200,
|
60
|
+
opacity: 0.9
|
61
|
+
},
|
62
|
+
onBeforeLoad: function() {
|
63
|
+
$("button.yes").attr( 'id', this.getTrigger().attr('id') );
|
64
|
+
},
|
65
|
+
closeOnClick: false
|
66
|
+
});
|
67
|
+
|
68
|
+
$( 'button.yes' ).click( function() {
|
69
|
+
var self = $(this);
|
70
|
+
$.ajax({
|
71
|
+
data: {id:self.attr('id')},
|
72
|
+
dataType: 'script',
|
73
|
+
type: 'post',
|
74
|
+
url: '/users/delete/'
|
75
|
+
});
|
76
|
+
});
|
77
|
+
});
|
78
|
+
</script>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= zone_locator %>
|
2
|
+
|
3
|
+
<div class="cltn">
|
4
|
+
<a class="back" href="<%=@back_url%>">« back</a>
|
5
|
+
<div class="title">users</div>
|
6
|
+
</div>
|
7
|
+
|
8
|
+
<div class="cltn" style="padding:10px;">
|
9
|
+
<div id="results">
|
10
|
+
<%= partial :'users/results'%>
|
11
|
+
</div>
|
12
|
+
</div>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongo3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fernand Galiana
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-03 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -52,6 +52,26 @@ dependencies:
|
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: 1.5.0
|
54
54
|
version:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mongo_rack
|
57
|
+
type: :runtime
|
58
|
+
version_requirement:
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 0.0.1
|
64
|
+
version:
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: main
|
67
|
+
type: :runtime
|
68
|
+
version_requirement:
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 4.2.0
|
74
|
+
version:
|
55
75
|
- !ruby/object:Gem::Dependency
|
56
76
|
name: bones
|
57
77
|
type: :development
|
@@ -98,6 +118,10 @@ extra_rdoc_files:
|
|
98
118
|
- lib/views/layout.erb
|
99
119
|
- lib/views/shared/_flash.erb
|
100
120
|
- lib/views/shared/flash.js.erb
|
121
|
+
- lib/views/users/_new.erb
|
122
|
+
- lib/views/users/_results.erb
|
123
|
+
- lib/views/users/list.erb
|
124
|
+
- lib/views/users/results.js.erb
|
101
125
|
files:
|
102
126
|
- .bnignore
|
103
127
|
- .bnsignore
|
@@ -105,12 +129,15 @@ files:
|
|
105
129
|
- HISTORY
|
106
130
|
- README.rdoc
|
107
131
|
- Rakefile
|
132
|
+
- aa.rb
|
108
133
|
- bin/mongo3
|
109
134
|
- config/mongo3.yml
|
110
135
|
- data/populate
|
136
|
+
- lib/app.rb
|
111
137
|
- lib/controllers/collections.rb
|
112
138
|
- lib/controllers/databases.rb
|
113
139
|
- lib/controllers/explore.rb
|
140
|
+
- lib/controllers/users.rb
|
114
141
|
- lib/helpers/collection_helper.rb
|
115
142
|
- lib/helpers/crumb_helper.rb
|
116
143
|
- lib/helpers/database_helper.rb
|
@@ -118,10 +145,11 @@ files:
|
|
118
145
|
- lib/helpers/flash_helper.rb
|
119
146
|
- lib/helpers/main_helper.rb
|
120
147
|
- lib/helpers/paths_helper.rb
|
121
|
-
- lib/main.rb
|
122
148
|
- lib/mongo3.rb
|
123
149
|
- lib/mongo3/connection.rb
|
124
150
|
- lib/mongo3/node.rb
|
151
|
+
- lib/mongo3/user.rb
|
152
|
+
- lib/mongo3/zone.rb
|
125
153
|
- lib/public/.DS_Store
|
126
154
|
- lib/public/images/button.png
|
127
155
|
- lib/public/images/button_act.png
|
@@ -216,6 +244,10 @@ files:
|
|
216
244
|
- lib/views/layout.erb
|
217
245
|
- lib/views/shared/_flash.erb
|
218
246
|
- lib/views/shared/flash.js.erb
|
247
|
+
- lib/views/users/_new.erb
|
248
|
+
- lib/views/users/_results.erb
|
249
|
+
- lib/views/users/list.erb
|
250
|
+
- lib/views/users/results.js.erb
|
219
251
|
- spec/landscape.yml
|
220
252
|
- spec/mongo3/connection_spec.rb
|
221
253
|
- spec/mongo3/node_spec.rb
|