A Sample Directory Monitoring Utility

   

The following Perl scripts implement a very simple monitoring and notification system for LDAP servers. You can use the scripts as they appear here or as a starting point for a more elaborate monitoring system.

The first script, ldap_probe.pl , probes the directory server once per minute. It attempts to retrieve the entry whose distinguished name is given on the command line. For example, the following command:

 ./ldap_probe.pl dir.example.com 389 "cn=Test Entry, dc=example, dc=com" 

attempts to read the entry cn=Test Entry,dc=example,dc=com from the LDAP server. If the probe succeeds, the script waits 60 seconds and repeats the probe. If the probe fails for any reason, the script invokes the notify.pl notification script. The notification script is passed a host identifier string and an indication of whether the server has gone down or has come back up. The notify.pl script then looks up the host/port combination in its configuration file ( notify.conf ) and performs the appropriate notification.

This division of work illustrates a concept we introduced earlier: keeping the probing and notification functions separate. To alter the notification actions performed, all that is necessary is to edit the notify.conf configuration file. Notification via e-mail is supported by the script, although it can easily be extended to support text paging.

The scripts assume that you are using a Unix workstation, although modifying them to run under Windows should be simple. They also assume that the Netscape LDAP command-line client ldapsearch utility is available in a directory contained in your search path .

Listing 19.1 contains the ldap_probe.pl script, which performs the probing functions. Listing 19.2 contains the notify.pl script, which is called by ldap_probe.pl when someone is to be notified about a problem. Listing 19.3 contains a sample notify.conf file. This file contains the configuration information that describes whom should be notified for each type of failure detected by the ldap_probe.pl script.

Listing 19.1 The ldap_probe.pl Script
 #!/usr/local/bin/perl # # usage: ldap_probe.pl host port DN [router] # # This script periodically probes an LDAP server to check whether # it is still responding to queries. If the server does not # respond, the notify.pl script is called to generate a # notification. The notify.pl script is called on each up-down # or down-up transition. # # For each probe, the script connects to the LDAP server # running on the given host and port, and attempts to read # the entry given by "DN". If the entry cannot be read, and # the error returned indicates that the directory server # could not be contacted, "router" (if given) is pinged. If # the router cannot be pinged, then the script does not # notify, on the assumption that the directory server is # "hidden" behind a network failure. Otherwise, notification # is performed. $ping_timeout = 10;     # Wait 10 seconds for a response from ping $test_interval = 60;    # 60 seconds between probes # Check arguments if ($#ARGV < 2  $#ARGV > 3) {     print "usage: ldap_probe.pl host port DN [router]\n";     exit; } # Get arguments $host = $ARGV[0]; $port = $ARGV[1]; $dn = $ARGV[2]; if ($#ARGV == 3) {     $router = $ARGV[3]; } else {     $router = ""; } $is_down = 0; # Loop forever for (;;) {     # Initialize state for this loop     $prev_is_down = $is_down;     $is_down = 0;     $do_check_router = 0;     $transition = "";     # Attempt to read the entry named by "DN"     $search_result = system "ldapsearch -h $host -p $port -s base -b \"$dn\" \"(  objectclass=*)\" cn > /dev/null 2>&1";     $search_result = $search_result / 256;     # Check for errors indicating that the server is not     # running or is unreachable, or that the domain name could     # not be looked up.     if ($search_result == 91                     # LDAP_CONNECT_ERROR              $search_result == 85              # LDAP_TIMEOUT              $search_result == 81) {           # LDAP_SERVER_DOWN         # These errors are generated if the server is not running or         # is unreachable, or if the domain name could not be looked         # up.         $do_check_router = 1;     } elsif ($search_result != 0) {         # Some other error occurred.         $is_down = 1;     }     # If the server is down or unreachable, check the router by     # pinging it (if a router address was provided). If the router     # is unpingable, we can't know about the state of the server.     if ($do_check_router) {         if ($router ne "") {             $ping_result = system "ping $router $ping_timeout > /dev/null 2>&1";             $ping_result = $ping_result / 256;             if ($ping_result == 0) {                 # Router was pingable, so assume that the LDAP                 # server is down.                 $is_down = 1;             }         } else {             # No router address provided.             $is_down = 1;         }     }     # Did we just notice a transition?     if (!$prev_is_down && $is_down) {         # Up - down transition         $transition = "down";     } elsif ($prev_is_down && !$is_down) {         # Down - up transition         $transition = "up";     } else {         $transition = "";     }     if ($transition ne "") {         # Call the notification script         system ("notify.pl $host:$port ldap_probe $transition");     }     # Wait a while until testing again     sleep($test_interval); } 
Listing 19.2 The notify.pl Script
 #!/usr/local/bin/perl # # usage: notify.pl identifier test transition # # This script reads the file notify.conf and locates lines where the # identifier, test, and transition match those given as input to this # script. For each match, the notification method given by the fourth # argument is performed. For example, if notify.conf contains the # following line: # #directory.example.com ldap_probe down mail bjensen@example.com "directory.example.com  LDAP down" # # the script will send an e-mail message to bjensen@example.com # with the text "directory.example.com LDAP down" # # There are three types of notification methods: # mail:    an electronic mail message is generated and sent. # page:    a text page is generated (you must supply your own # command). # "shell": if the fourth argument begins with a slash (/), the #          argument is treated as a shell command that is #          executed. Any additional arguments on the line #          are quoted and passed to the shell. # # See notify.conf for more details. require "shellwords.pl"; require "ctime.pl"; # Check arguments if ($#ARGV < 2) {     print "usage: notify.pl entity testname transition\n";     exit; } $entity = $ARGV[0]; $testname = $ARGV[1]; $transition = $ARGV[2]; # Open the configuration file if (!open(CONF, "notify.conf")) {     print STDERR "Cannot open configuration file notify.conf.\n";     exit; } # Note the current time $now = &ctime(time); chop $now; $found = 0; while (<CONF>) {     # Skip comment lines.     if (/^ *#/) {         next;     }     # Split the line according to Unix shell-quoting conventions     @_ = &shellwords($_); if ($entity eq $_[0] && $testname eq $_[1] && $transition eq $_[2]) {     # Found a match. Perform the notification.         $found = 1;         &do_notify;     } } if  (!$found) {     # There were no matching lines. Generate a warning.     # You could also perform a default notification here; e.g.,     # send e-mail to the maintainer of the notify.conf file     # to let him/her know about the error.     print STDERR"Could not find a notification method for $entity $testname $transition\  n"; } # Subroutine to perform the notification. sub do_notify {     $method = $_[3];     if ($method eq "page") {         # The "page" notification method is not implemented.  You         # can activate it by adding code to dial out to your         # paging service.         # The pager telephone number is the 4th argument,         # and the pager's PIN is the 5th argument. For         # example, the following line in notify.conf might         # be used:         #dir.example.com ldap_probe down 9,1-800-555-1212 3233 "dir.example.com LDAP down"         $pager = $_[4];         $pager_pin = $_[5];         $message = $_[6];         print "Paging $pager, PIN $pager_pin, message \"$message\"\n";         # Insert your custom paging code here.     } elsif ($method eq "mail") {         # Send an e-mail notification.         $email_addr = $_[4];         $message = $_[5];         print "Sending e-mail to $email_addr, message \"$message\"\n";         open(MAIL, "/bin/mail $email_addr");         print MAIL "To: $email_addr\n";         print MAIL "Subject: $entity $testname $transition\n";         print MAIL "\n";         print MAIL "At $now\n";         print MAIL "$message\n";         close(MAIL);     } elsif (substr($method, 0, 1) eq "/") {         # Any method that begins with a / is treated as a shell command.         shift(@_);         shift(@_);         shift(@_);         shift(@_);         # Quote each argument.         for ($i = 0; $i < @_; $i++) {             $_[$i] = "\"$_[$i]\"";         }         $not_args = join(" ", @_);         print "Sending the following command to the shell: $method $not_args\n";         system "$method $not_args";     } } 
Listing 19.3 The notify.conf Configuration File
 # notify.conf # This file contains the configuration information for notify.pl. # # Format: # # identifier test transition action [arguments...] # # Where: # "identifier" is a string that identifies the service # (typically a host name) # "test" is a string that identifies the type of test performed # "transition" is either "up" or "down" # "action" describes the type of notification to perform. The # notify.pl program knows about the following types: # #   "mail email-address message" # Electronic mail is sent to "email-address". The text # of the message is "message". # #   "/shell-command [arguments...] # The command "/shell-command" is executed. Any arguments # are passed to the shell command. # # # Lines beginning with "#" are comments and are ignored. dir.example.com:389 ldap_probe down mail bjensen@example.com "dir.example.com:389 down" dir.example.com:389 ldap_probe up mail bjensen@example.com "dir.example.com:389 up" dir.example.com:389 ldap_probe down /usr/bin/logger -p user.err "dir.example.com:389 down" dir.example.com:389 ldap_probe up /usr/bin/logger -p user.err "dir.example.com:389 up" 
   


Understanding and Deploying LDAP Directory Services
Understanding and Deploying LDAP Directory Services (2nd Edition)
ISBN: 0672323168
EAN: 2147483647
Year: 2002
Pages: 242

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net