treequel 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +354 -0
- data/LICENSE +27 -0
- data/README +66 -0
- data/Rakefile +345 -0
- data/Rakefile.local +43 -0
- data/bin/treeirb +14 -0
- data/bin/treequel +229 -0
- data/examples/company-directory.rb +112 -0
- data/examples/ldap-monitor.rb +143 -0
- data/examples/ldap-monitor/public/css/master.css +328 -0
- data/examples/ldap-monitor/public/images/card_small.png +0 -0
- data/examples/ldap-monitor/public/images/chain_small.png +0 -0
- data/examples/ldap-monitor/public/images/globe_small.png +0 -0
- data/examples/ldap-monitor/public/images/globe_small_green.png +0 -0
- data/examples/ldap-monitor/public/images/plug.png +0 -0
- data/examples/ldap-monitor/public/images/shadows/large-30-down.png +0 -0
- data/examples/ldap-monitor/public/images/tick.png +0 -0
- data/examples/ldap-monitor/public/images/tick_circle.png +0 -0
- data/examples/ldap-monitor/public/images/treequel-favicon.png +0 -0
- data/examples/ldap-monitor/views/backends.erb +41 -0
- data/examples/ldap-monitor/views/connections.erb +74 -0
- data/examples/ldap-monitor/views/databases.erb +39 -0
- data/examples/ldap-monitor/views/dump_subsystem.erb +14 -0
- data/examples/ldap-monitor/views/index.erb +14 -0
- data/examples/ldap-monitor/views/layout.erb +35 -0
- data/examples/ldap-monitor/views/listeners.erb +30 -0
- data/examples/ldap_state.rb +62 -0
- data/lib/treequel.rb +145 -0
- data/lib/treequel/branch.rb +589 -0
- data/lib/treequel/branchcollection.rb +204 -0
- data/lib/treequel/branchset.rb +360 -0
- data/lib/treequel/constants.rb +604 -0
- data/lib/treequel/directory.rb +541 -0
- data/lib/treequel/exceptions.rb +32 -0
- data/lib/treequel/filter.rb +704 -0
- data/lib/treequel/mixins.rb +325 -0
- data/lib/treequel/schema.rb +245 -0
- data/lib/treequel/schema/attributetype.rb +252 -0
- data/lib/treequel/schema/ldapsyntax.rb +96 -0
- data/lib/treequel/schema/matchingrule.rb +124 -0
- data/lib/treequel/schema/matchingruleuse.rb +124 -0
- data/lib/treequel/schema/objectclass.rb +289 -0
- data/lib/treequel/sequel_integration.rb +26 -0
- data/lib/treequel/utils.rb +169 -0
- data/rake/191_compat.rb +26 -0
- data/rake/dependencies.rb +76 -0
- data/rake/helpers.rb +434 -0
- data/rake/hg.rb +261 -0
- data/rake/manual.rb +782 -0
- data/rake/packaging.rb +135 -0
- data/rake/publishing.rb +318 -0
- data/rake/rdoc.rb +30 -0
- data/rake/style.rb +62 -0
- data/rake/svn.rb +668 -0
- data/rake/testing.rb +187 -0
- data/rake/verifytask.rb +64 -0
- data/rake/win32.rb +190 -0
- data/spec/lib/constants.rb +93 -0
- data/spec/lib/helpers.rb +100 -0
- data/spec/treequel/branch_spec.rb +569 -0
- data/spec/treequel/branchcollection_spec.rb +213 -0
- data/spec/treequel/branchset_spec.rb +376 -0
- data/spec/treequel/directory_spec.rb +487 -0
- data/spec/treequel/filter_spec.rb +482 -0
- data/spec/treequel/mixins_spec.rb +330 -0
- data/spec/treequel/schema/attributetype_spec.rb +237 -0
- data/spec/treequel/schema/ldapsyntax_spec.rb +83 -0
- data/spec/treequel/schema/matchingrule_spec.rb +158 -0
- data/spec/treequel/schema/matchingruleuse_spec.rb +137 -0
- data/spec/treequel/schema/objectclass_spec.rb +262 -0
- data/spec/treequel/schema_spec.rb +118 -0
- data/spec/treequel/utils_spec.rb +49 -0
- data/spec/treequel_spec.rb +179 -0
- metadata +169 -0
data/Rakefile.local
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#!rake
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require 'pathname'
|
5
|
+
require 'English'
|
6
|
+
require 'pp'
|
7
|
+
|
8
|
+
# Project-specific tasks
|
9
|
+
|
10
|
+
#####################################################################
|
11
|
+
### T A S K S
|
12
|
+
#####################################################################
|
13
|
+
|
14
|
+
MANUAL_PAGES = Pathname.glob( MANUALDIR + '**/*.page' )
|
15
|
+
|
16
|
+
task :local => :check_manual
|
17
|
+
|
18
|
+
# Check the manual for laika references before committing
|
19
|
+
Rake::Task[ 'checkin' ].prerequisites.unshift( 'check_manual' )
|
20
|
+
|
21
|
+
desc "Check the manual for various problems and/or inconsistencies"
|
22
|
+
task :check_manual => MANUAL_PAGES do
|
23
|
+
MANUAL_PAGES.each do |page|
|
24
|
+
lines = page.readlines
|
25
|
+
lines.each_with_index do |line, i|
|
26
|
+
if line =~ /\blaika\b/i
|
27
|
+
msg = [
|
28
|
+
' ',
|
29
|
+
i.zero? ? "" : lines[ i - 1 ],
|
30
|
+
' ',
|
31
|
+
$PREMATCH,
|
32
|
+
colorize( :bold, :yellow ) { $MATCH },
|
33
|
+
$POSTMATCH,
|
34
|
+
' ',
|
35
|
+
lines[ i + 1 ]
|
36
|
+
].join
|
37
|
+
abort "Page #{page} has a LAIKA reference on line #{i + 1}:\n#{msg}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
data/bin/treeirb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'irb'
|
4
|
+
require 'irb/extend-command'
|
5
|
+
require 'irb/cmd/nop'
|
6
|
+
require 'treequel'
|
7
|
+
|
8
|
+
|
9
|
+
uri = ARGV.shift or raise "usage: #$0 [LDAPURI]"
|
10
|
+
$dir = Treequel.directory( uri )
|
11
|
+
$stderr.puts "Directory is in $dir:", ' ' + $dir.inspect
|
12
|
+
|
13
|
+
IRB.start( $0 )
|
14
|
+
|
data/bin/treequel
ADDED
@@ -0,0 +1,229 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'readline'
|
5
|
+
require 'logger'
|
6
|
+
require 'shellwords'
|
7
|
+
require 'tempfile'
|
8
|
+
require 'digest/sha1'
|
9
|
+
require 'abbrev'
|
10
|
+
require 'treequel'
|
11
|
+
require 'treequel/mixins'
|
12
|
+
require 'treequel/constants'
|
13
|
+
|
14
|
+
|
15
|
+
class Shell
|
16
|
+
include Treequel::Loggable,
|
17
|
+
Treequel::Constants::Patterns
|
18
|
+
|
19
|
+
|
20
|
+
### Create a new shell that will traverse the directory at the specified +uri+.
|
21
|
+
def initialize( uri )
|
22
|
+
Treequel.logger.level = Logger::WARN
|
23
|
+
|
24
|
+
@uri = uri
|
25
|
+
@quit = false
|
26
|
+
@dir = Treequel.directory( @uri )
|
27
|
+
@currbranch = @dir
|
28
|
+
|
29
|
+
@commands = self.find_commands
|
30
|
+
@completions = @commands.abbrev
|
31
|
+
@command_table = make_command_table( @commands )
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
### The command loop: run the shell until the user wants to quit
|
36
|
+
def run
|
37
|
+
$stderr.puts "Connected to %s" % [ @uri ]
|
38
|
+
|
39
|
+
self.setup_completion
|
40
|
+
|
41
|
+
until @quit
|
42
|
+
input = Readline.readline( @currbranch.dn + '> ', true )
|
43
|
+
self.log.debug "Input is: %p" % [ input ]
|
44
|
+
|
45
|
+
# EOL makes the shell quit
|
46
|
+
if input.nil?
|
47
|
+
@quit = true
|
48
|
+
|
49
|
+
elsif input == ''
|
50
|
+
self.log.debug "No command. Re-displaying the prompt."
|
51
|
+
|
52
|
+
# Parse everything else into command + everything else
|
53
|
+
else
|
54
|
+
command, *args = Shellwords.shellwords( input )
|
55
|
+
|
56
|
+
begin
|
57
|
+
if meth = @command_table[ command ]
|
58
|
+
meth.call( *args )
|
59
|
+
else
|
60
|
+
self.handle_missing_command( command )
|
61
|
+
end
|
62
|
+
rescue => err
|
63
|
+
$stderr.puts "Error: %s" % [ err.message ]
|
64
|
+
err.backtrace.each do |frame|
|
65
|
+
self.log.debug " " + frame
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
$stderr.puts "done."
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
#########
|
76
|
+
protected
|
77
|
+
#########
|
78
|
+
|
79
|
+
### Set up Readline completion
|
80
|
+
def setup_completion
|
81
|
+
Readline.completion_proc = self.method( :completion_callback ).to_proc
|
82
|
+
Readline.completer_word_break_characters = ''
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
### Handle completion requests from Readline.
|
87
|
+
def completion_callback( input )
|
88
|
+
if command = @completions[ input ]
|
89
|
+
return []
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
### Quit the shell.
|
95
|
+
def quit_command( *args )
|
96
|
+
$stderr.puts "Okay, exiting."
|
97
|
+
@quit = true
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
LOG_LEVELS = {
|
102
|
+
'debug' => Logger::DEBUG,
|
103
|
+
'info' => Logger::INFO,
|
104
|
+
'warn' => Logger::WARN,
|
105
|
+
'error' => Logger::ERROR,
|
106
|
+
'fatal' => Logger::FATAL,
|
107
|
+
}.freeze
|
108
|
+
LOG_LEVEL_NAMES = LOG_LEVELS.invert.freeze
|
109
|
+
|
110
|
+
### Set the logging level (if invoked with an argument) or display the current
|
111
|
+
### level (with no argument).
|
112
|
+
def log_command( *args )
|
113
|
+
newlevel = args.shift
|
114
|
+
if newlevel
|
115
|
+
if LOG_LEVELS.key?( newlevel )
|
116
|
+
Treequel.logger.level = LOG_LEVELS[ newlevel ]
|
117
|
+
$stderr.puts "Set log level to: %s" % [ newlevel ]
|
118
|
+
else
|
119
|
+
levelnames = LOG_LEVEL_NAMES.keys.sort.join(', ')
|
120
|
+
raise "Invalid log level %p: valid values are:\n %s" % [ newlevel, levelnames ]
|
121
|
+
end
|
122
|
+
else
|
123
|
+
$stderr.puts "Log level is currently: %s" %
|
124
|
+
[ LOG_LEVEL_NAMES[Treequel.logger.level] ]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
### Show the completions hash
|
130
|
+
def show_completions_command
|
131
|
+
$stderr.puts "Completions:",
|
132
|
+
@completions.inspect
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
### Display LDIF for the specified RDNs.
|
137
|
+
def cat_command( *args )
|
138
|
+
args.each do |rdn|
|
139
|
+
branch = rdn.split( /\s*,\s*/ ).inject( @currbranch ) do |branch, dnpair|
|
140
|
+
attribute, value = dnpair.split( /\s*=\s*/, 2 )
|
141
|
+
branch.send( attribute, value )
|
142
|
+
end
|
143
|
+
|
144
|
+
$stdout.puts( branch.to_ldif )
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
### List the children of the current branch.
|
150
|
+
def ls_command( *args )
|
151
|
+
$stdout.puts *@currbranch.children.collect {|b| b.rdn }.sort
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
### Change the current working DN to +rdn+.
|
156
|
+
def cdn_command( rdn, *args )
|
157
|
+
raise "invalid RDN %p" % [ rdn ] unless RELATIVE_DISTINGUISHED_NAME.match( rdn )
|
158
|
+
|
159
|
+
pairs = rdn.split( /\s*,\s*/ )
|
160
|
+
pairs.each do |dnpair|
|
161
|
+
self.log.debug " cd to %p" % [ dnpair ]
|
162
|
+
attribute, value = dnpair.split( /=/, 2 )
|
163
|
+
self.log.debug " changing to %s( %p )" % [ attribute, value ]
|
164
|
+
@currbranch = @currbranch.send( attribute, value )
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
### Change the current working DN to the current entry's parent.
|
170
|
+
def parent_command( *args )
|
171
|
+
parent = @currbranch.parent or raise "%s is the root DN" % [ @currbranch.dn ]
|
172
|
+
|
173
|
+
self.log.debug " changing to %s" % [ parent.dn ]
|
174
|
+
@currbranch = parent
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
### Edit the entry specified by +rdn+.
|
179
|
+
def edit_command( rdn, *args )
|
180
|
+
branch = @currbranch.get_child( rdn )
|
181
|
+
|
182
|
+
fn = Digest::SHA1.hexdigest( rdn )
|
183
|
+
tf = Tempfile.new( fn )
|
184
|
+
if branch.exists?
|
185
|
+
tf.print( )
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
### Handle a command from the user that doesn't exist.
|
190
|
+
def handle_missing_command( *args )
|
191
|
+
command = args.shift || '(testing?)'
|
192
|
+
$stderr.puts "Unknown command %p" % [ command ]
|
193
|
+
$stderr.puts "Known commands: ", ' ' + @commands.join(', ')
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
### Find methods that implement commands and return them in a sorted Array.
|
198
|
+
def find_commands
|
199
|
+
return self.methods.
|
200
|
+
grep( /^(\w+)_command$/ ).
|
201
|
+
collect {|mname| mname[/^(\w+)_command$/, 1] }.
|
202
|
+
sort
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
#######
|
207
|
+
private
|
208
|
+
#######
|
209
|
+
|
210
|
+
### Create a command table that maps command abbreviations to the Method object that
|
211
|
+
### implements it.
|
212
|
+
def make_command_table( commands )
|
213
|
+
table = commands.abbrev
|
214
|
+
table.keys.each do |abbrev|
|
215
|
+
mname = table.delete( abbrev )
|
216
|
+
table[ abbrev ] = self.method( mname + '_command' )
|
217
|
+
end
|
218
|
+
|
219
|
+
return table
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
if __FILE__ == $0
|
226
|
+
ldapuri = URI( ARGV.shift || 'ldap://localhost' )
|
227
|
+
Shell.new( ldapuri ).run
|
228
|
+
end
|
229
|
+
|
@@ -0,0 +1,112 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'sinatra'
|
5
|
+
require 'treequel'
|
6
|
+
require 'pathname'
|
7
|
+
|
8
|
+
# A barebones web-based company directory
|
9
|
+
|
10
|
+
LDAP_URL = "ldap://ldap.yourcompany.com/dc=yourcompany,dc=com"
|
11
|
+
|
12
|
+
configure do
|
13
|
+
# Borrow the CSS and images from the 'ldap-monitor' example
|
14
|
+
set :root, Pathname( __FILE__ ).dirname + 'ldap-monitor'
|
15
|
+
end
|
16
|
+
|
17
|
+
before do
|
18
|
+
$stderr.puts "Connecting to #{LDAP_URL}"
|
19
|
+
@ldap ||= Treequel.directory( LDAP_URL )
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
### GET /
|
24
|
+
get '/' do
|
25
|
+
|
26
|
+
# Get every entry under ou=people that has an email address and sort them
|
27
|
+
# by last name, first name, and UID.
|
28
|
+
people = @ldap.ou( :people ).filter( :mail ).sort_by do |person|
|
29
|
+
[ person[:sn], person[:givenName], person[:uid] ]
|
30
|
+
end
|
31
|
+
|
32
|
+
erb :index,
|
33
|
+
:locals => {
|
34
|
+
:people => people
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
### GET /uid
|
40
|
+
get '/:uid' do
|
41
|
+
|
42
|
+
# Look up the person associated with the given UID, returning NOT FOUND if
|
43
|
+
# there isn't any such entry
|
44
|
+
uid = params[:uid]
|
45
|
+
person = @ldap.ou( :people ).uid( uid )
|
46
|
+
halt 404, "No such person" unless person.exists?
|
47
|
+
|
48
|
+
erb :details,
|
49
|
+
:locals => {
|
50
|
+
:person => person
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
__END__
|
57
|
+
|
58
|
+
@@layout
|
59
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
60
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
61
|
+
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
62
|
+
|
63
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
64
|
+
<head>
|
65
|
+
<title>Company Directory</title>
|
66
|
+
<link rel="stylesheet" href="/css/master.css" type="text/css" media="screen" title="no title" charset="utf-8" />
|
67
|
+
</head>
|
68
|
+
|
69
|
+
<body>
|
70
|
+
|
71
|
+
<div id="content">
|
72
|
+
<h1>Company Directory</h1>
|
73
|
+
|
74
|
+
<%= yield %>
|
75
|
+
|
76
|
+
</div>
|
77
|
+
|
78
|
+
<div id="footer">Treequel Company Directory Example</div>
|
79
|
+
</body>
|
80
|
+
</html>
|
81
|
+
|
82
|
+
|
83
|
+
@@index
|
84
|
+
<table>
|
85
|
+
<thead>
|
86
|
+
<tr>
|
87
|
+
<th class="odd">Name</th>
|
88
|
+
<th class="even">Email</th>
|
89
|
+
<th class="odd">Badge #</th>
|
90
|
+
</tr>
|
91
|
+
</thead>
|
92
|
+
<tbody>
|
93
|
+
<% people.each_with_index do |person, i| %>
|
94
|
+
<% rowclass = i.divmod(2).last.zero? ? "even" : "odd" %>
|
95
|
+
<tr class="<%= rowclass %>">
|
96
|
+
<td class="odd"><a href="/<%= person[:uid] %>"><%= person[:cn] %></p></td>
|
97
|
+
<td class="even"><a href="/<%= person[:uid] %>"><%= person[:mail] %></a></td>
|
98
|
+
<td class="odd"><%= person[:employeeNumber] %></td>
|
99
|
+
</tr>
|
100
|
+
<% end %>
|
101
|
+
</tbody>
|
102
|
+
</table>
|
103
|
+
|
104
|
+
@@details
|
105
|
+
|
106
|
+
<h2>Details for <%= person[:cn] %> <%= person[:sn] %>
|
107
|
+
<<%= person[:mail] %>></h2>
|
108
|
+
|
109
|
+
<pre>
|
110
|
+
<%= person.to_ldif %>
|
111
|
+
</pre>
|
112
|
+
|
@@ -0,0 +1,143 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
BEGIN {
|
4
|
+
require 'pathname'
|
5
|
+
basedir = Pathname( __FILE__ ).dirname.parent
|
6
|
+
libdir = basedir + 'lib'
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift( libdir.to_s )
|
9
|
+
}
|
10
|
+
|
11
|
+
require 'rubygems'
|
12
|
+
require 'sinatra'
|
13
|
+
require 'treequel'
|
14
|
+
require 'erb'
|
15
|
+
|
16
|
+
include ERB::Util
|
17
|
+
|
18
|
+
# The real data is all in operational attributes, so fetch them by default
|
19
|
+
Treequel::Branch.include_operational_attrs = true
|
20
|
+
|
21
|
+
configure do
|
22
|
+
set :root, Pathname( __FILE__ ).dirname + 'ldap-monitor'
|
23
|
+
end
|
24
|
+
|
25
|
+
before do
|
26
|
+
@monitor ||= Treequel.directory( 'ldap://localhost/cn=Monitor',
|
27
|
+
:bind_dn => 'cn=admin,cn=Monitor', :pass => 'monitor' )
|
28
|
+
end
|
29
|
+
|
30
|
+
helpers do
|
31
|
+
|
32
|
+
### Return a string describing the amount of time in the given number of
|
33
|
+
### seconds in terms a human can understand easily.
|
34
|
+
def time_delta_string( start_time )
|
35
|
+
start = Time.parse( start_time ) or return "some time"
|
36
|
+
seconds = Time.now - start
|
37
|
+
|
38
|
+
return 'less than a minute' if seconds < 60
|
39
|
+
|
40
|
+
if seconds < 50 * 60
|
41
|
+
return "%d minute%s" % [seconds / 60, seconds/60 == 1 ? '' : 's']
|
42
|
+
end
|
43
|
+
|
44
|
+
return 'about an hour' if seconds < 90 * MINUTES
|
45
|
+
return "%d hours" % [seconds / HOURS] if seconds < 18 * HOURS
|
46
|
+
return 'one day' if seconds < 1 * DAYS
|
47
|
+
return 'about a day' if seconds < 2 * DAYS
|
48
|
+
return "%d days" % [seconds / DAYS] if seconds < 1 * WEEKS
|
49
|
+
return 'about a week' if seconds < 2 * WEEKS
|
50
|
+
return "%d weeks" % [seconds / WEEKS] if seconds < 3 * MONTHS
|
51
|
+
return "%d months" % [seconds / MONTHS] if seconds < 2 * YEARS
|
52
|
+
return "%d years" % [seconds / YEARS]
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
### GET /
|
58
|
+
get '/' do
|
59
|
+
erb :index,
|
60
|
+
:locals => {
|
61
|
+
:server_info => @monitor.base['monitoredInfo'],
|
62
|
+
:datapoints => @monitor.children,
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
#
|
68
|
+
# Subsystems
|
69
|
+
#
|
70
|
+
|
71
|
+
get '/backends' do
|
72
|
+
subsystem = @monitor.cn( :backends )
|
73
|
+
backends = subsystem.
|
74
|
+
filter( :objectClass => :monitoredObject ).
|
75
|
+
select( :+, :* )
|
76
|
+
|
77
|
+
erb :backends,
|
78
|
+
:locals => {
|
79
|
+
:subsystem => subsystem,
|
80
|
+
:backends => backends,
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
get '/connections' do
|
86
|
+
subsystem = @monitor.cn( :connections )
|
87
|
+
connections = subsystem.
|
88
|
+
filter( :objectClass => :monitorConnection ).
|
89
|
+
select( :+, :* )
|
90
|
+
|
91
|
+
erb :connections,
|
92
|
+
:locals => {
|
93
|
+
:subsystem => subsystem,
|
94
|
+
:total => subsystem.cn( :total ),
|
95
|
+
:current => subsystem.cn( :current ),
|
96
|
+
:connections => connections.all,
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
get '/databases' do
|
102
|
+
subsystem = @monitor.cn( :databases )
|
103
|
+
databases = subsystem.
|
104
|
+
filter( :objectClass => :monitoredObject ).
|
105
|
+
select( :+, :* )
|
106
|
+
|
107
|
+
erb :databases,
|
108
|
+
:locals => {
|
109
|
+
:subsystem => subsystem,
|
110
|
+
:databases => databases,
|
111
|
+
}
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
get '/listeners' do
|
116
|
+
subsystem = @monitor.cn( :listeners )
|
117
|
+
listeners = subsystem.
|
118
|
+
filter( :objectClass => :monitoredObject ).
|
119
|
+
select( :+, :* )
|
120
|
+
|
121
|
+
erb :listeners,
|
122
|
+
:locals => {
|
123
|
+
:subsystem => subsystem,
|
124
|
+
:listeners => listeners,
|
125
|
+
}
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
### Fallback handler for subsystems
|
130
|
+
get '/:subsystem' do
|
131
|
+
subsystem = @monitor.cn( params[:subsystem] )
|
132
|
+
contents = subsystem.
|
133
|
+
filter( :objectClass => :monitoredObject ).
|
134
|
+
select( :+, :* )
|
135
|
+
|
136
|
+
erb :dump_subsystem,
|
137
|
+
:locals => {
|
138
|
+
:subsystem => subsystem,
|
139
|
+
:contents => contents,
|
140
|
+
}
|
141
|
+
end
|
142
|
+
|
143
|
+
|