mongo3 0.0.6 → 0.0.7
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.
- 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
|