From 7cb52179b891061803869b21c1000aa35a51e27c Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Mon, 14 Oct 2013 13:13:24 -0400 Subject: [PATCH 181/225] Ticket 47538 - RFE: repl-monitor.pl plain text output, cmdline config options RFE Description: Request option to print report in plain text(instead of HTML), and be able to add the configfuration file directives as command line options. Fix Description: Add a new option "-s" for displaying plain text report. Added new options for the config file directives: -c "connection value" -a "alias value" -k "color value" Added a new option (-W, --prompt) to prompt for passwords. Added "long names" to the commandline options. Updated to use: GetOpts::Long, strict, warnings Cleaned up some HTML code/colors, and indentation. Update man page. https://fedorahosted.org/389/ticket/47538 Reviewed by: nhosoi, nkinder, and rmeggins(Thanks!!!) (cherry picked from commit 76abd736d3bf763cc0e7bc1987fe76c27159db6f) (cherry picked from commit dae03f042334ede551a6c1972e2163a2f923f352) --- ldap/admin/src/scripts/repl-monitor.pl.in | 576 ++++++++++++++++++++---------- man/man1/repl-monitor.1 | 35 +- 2 files changed, 415 insertions(+), 196 deletions(-) diff --git a/ldap/admin/src/scripts/repl-monitor.pl.in b/ldap/admin/src/scripts/repl-monitor.pl.in index 8839ed2..45d58a1 100755 --- a/ldap/admin/src/scripts/repl-monitor.pl.in +++ b/ldap/admin/src/scripts/repl-monitor.pl.in @@ -41,8 +41,9 @@ # FILE: repl-monitor.pl # # SYNOPSIS: -# repl-monitor.pl -f configuration-file [-h host] [-p port] [-r] -# [-u refresh-url] [-t refresh-interval] +# repl-monitor.pl [-f configuration-file] [-h host] [-p port] [-r] +# [-c connection] [-a alias] [-k color] [-u refresh-url] +# [-t refresh-interval] [-s] [-W] # # repl-monitor.pl -v # @@ -111,6 +112,22 @@ # If the color section or color entry is missing, the default color # set is: green for [0-5) minutes lag, yellow [5-60), and red 60 and more. # +# The following three options (-c, -a, -k) are used if not providing a +# configuration file: +# +# -c connection +# The connection value is the same as the configuration file value(see above): +# -c "host:port:binddn:bindpwd:bindcert" +# +# -a alias +# The alias value is the same as the configuration file value(see above): +# -a "alias=host:port" +# +# -k color +# The color value is written as "lowmark:color". Where the lowmark is in minutes. +# This option is ignored if printing a plain text report. +# -k "5=#ccffcc" +# # -h host # Initial replication supplier's host. Default to the current host. # @@ -132,6 +149,10 @@ # the output HTML file would automatically refresh itself. This # is useful for continuing monitoring. See also option -t. # +# -s Print output in plain text, instead of HTML. +# +# -W Prompt for connection passwords. +# # -v Print out the version of this script # # DIAGNOSTICS: @@ -156,11 +177,17 @@ # If using this script standalone, be sure to set the shared lib path and # the path to the perldap modules. +use strict; +use warnings; use lib qw(@perlpath@); -$usage = "\nusage: $0 -f configuration-file [-h host] [-p port] [-r] [-u refresh-url] [-t refresh-interval]\n\nor : $0 -v\n"; +my $usage = "\nusage: $0 [-f configuration-file | --configfile configuration-file] " . + "[-c connection, --conn connection] [-a alias, --alias alias] [-k color, --color color] " . + "[-h host, --host host] [-p port, --port port] [-r, --skip-header] [-s, --text] " . + "[-u refresh-url, --url refresh-url] [-t refresh-interval, --interval refresh-interval ] " . + "[-W, --prompt]\n\nor : $0 -v | --version\n"; -use Getopt::Std; # parse command line arguments +use Getopt::Long; # parse command line arguments use Mozilla::LDAP::Conn; # LDAP module for Perl use Mozilla::LDAP::Utils qw(normalizeDN); # LULU, utilities. use Mozilla::LDAP::API qw(:api :ssl :apiv3 :constant); # Direct access to C API @@ -169,29 +196,43 @@ use Time::Local; # to convert GMT Z strings to localtime # # Global variables # -$product = "Directory Server Replication Monitor"; -$version = "Version 1.0"; +my $product = "Directory Server Replication Monitor"; +my $version = "Version 1.1"; # # ldap servers given or discovered from the replication agreements: -# @servers = (host:port=shadowport:binddn:password:cert_db) +my @servers; # = (host:port=shadowport:binddn:password:cert_db) +my $serveridx; # # entries read from the connection section of the configuration file: -# @allconnections = (host:port=shadowport:binddn:password:cert_db) +my @allconnections; # = (host:port=shadowport:binddn:password:cert_db) # # aliases of ldap servers read from the configuration file: -# %allaliases{$host:$port}= (alias) +my %allaliases; # = {$host:$port} = (alias) +# colors +my %allcolors; +my @colorkeys; + # # replicas discovered on all ldap servers -# @allreplicas = (server#:replicaroot:replicatype:serverid:replicadn) +my @allreplicas; # = (server#:replicaroot:replicatype:serverid:replicadn) # # ruvs retrieved from all replicas -# @allruvs{replica#:masterid} = (rawcsn:decimalcsn;mon/day/year hh:mi:ss) +my %allruvs; # = {replica#:masterid} = (rawcsn:decimalcsn;mon/day/year hh:mi:ss) # # agreements discovered on all ldap supplier servers: -# @allagreements = (supplier_replica#:consumer#:conntype:schedule:status) +my @allagreements; # = (supplier_replica#:consumer#:conntype:schedule:status) # the array may take another format after the consumer replicas are located: -# @allagreements = (supplier_replica#:consumer_replica#:conntype:schedule:status) +# @allagreements; # = (supplier_replica#:consumer_replica#:conntype:schedule:status) +# +my %ld; # ldap connection hash # +my ($opt_f, $opt_h, $opt_p, $opt_u, $opt_t, $opt_r, $opt_s); +my (@conns, @alias, @color); +my ($section, $interval, $nowraw, $now, $mm, $dd, $tt, $yy, $wday); +my ($fn, $rc, $prompt, $last_sidx); +my %passwords = (); +my $passwd = ""; +$prompt = ""; #main { @@ -199,15 +240,23 @@ $version = "Version 1.0"; $| = 1; # Check for legal options - if (!getopts('h:p:f:ru:t:v')) { - print $usage; - exit -1; - } - - if ($opt_v) { - print "$product - $version\n"; - exit; - } + GetOptions( + 'h|host=s' => \$opt_h, + 'p|port=s' => \$opt_p, + 'f|configfile=s' => \$opt_f, + 'c|conn=s' => \@conns, + 'a|alias=s' => \@alias, + 'k|color=s' => \@color, + 'u|url=s' => \$opt_u, + 't|interval=s' => \$opt_t, + 'W|prompt' => sub { $prompt = "yes"; }, + 'r|skip-header' => sub { $opt_r = "1"; }, + 's|text' => sub {$opt_s = "1"; }, + 'v|version' => sub { print "$product - $version\n"; exit ;} + ) or die "Usage error: $usage\n"; + + exit -1 if &validateArgs < 0; + exit if &read_cfg_file ($opt_f) < 0; $interval = $opt_t; $interval = 300 if ( !$interval || $interval <= 0 ); @@ -221,22 +270,23 @@ $version = "Version 1.0"; if (!$opt_r) { # print the HTML header &print_html_header; - } else { - # print separator for new replication set - print "

\n"; + } else { + if($opt_s){ + print"\n"; + } else { + # print separator for new replication set + print "

\n"; + } } - exit -1 if &validateArgs < 0; - exit if &read_cfg_file ($opt_f) < 0; - # Start with the given host and port # The index names in %ld are defined in Mozilla::LDAP::Utils::ldapArgs() &add_server ("$ld{host}:$ld{port}:$ld{bind}:$ld{pswd}:$ld{cert}"); $serveridx = 0; - while ($serveridx <= $#servers) { + while ($serveridx <= $#servers) { if (&get_replicas ($serveridx) != 0 && $serveridx == 0) { - my ($host, $port, $binddn) = split (/:/, $servers[0]); + my ($host, $port, $binddn) = split (/:/, $servers[$serveridx]); print("Login to $host:$port as \"$binddn\" failed\n"); exit; } @@ -253,14 +303,19 @@ $version = "Version 1.0"; sub validateArgs { - my ($rc) = 0; + $rc = 0; %ld = Mozilla::LDAP::Utils::ldapArgs(); - - if (!$opt_v && !$opt_f) { - print "

Error: Missing configuration file.\n"; - print "

If you need help on the configuration file, Please go back and click the Help button.\n"; - #print $usage; # Don't show usage in CGI + if (!$opt_f && $#conns < 0) { + if($opt_s){ + print "Error: Missing configuration file or connection parameter.\n"; + print $usage; + } else { + print "

Error: Missing configuration file or connection paramater.\n"; + print "

If you need help on the configuration file, or script usage, " . + "Please go back and click the Help button.\n"; + #print $usage; # Don't show usage in CGI + } $rc = -1; } elsif (!$opt_h) { @@ -272,63 +327,90 @@ sub validateArgs sub read_cfg_file { - my ($fn) = @_; - unless (open(CFGFILEHANDLE, $fn)) { - print "

Error: Can't open \"$fn\": $!.\n"; - print "

If you need help on the configuration file, Please go back and click the Help button.\n"; - return -1; + ($fn) = @_; + my $tmp; + + # process the command line config params + @allconnections = @conns; + if($#alias >= 0){ + foreach $tmp (@alias){ + $tmp =~ m/^\s*(\S.*)\s*=\s*(\S+)/; + $allaliases{$2} = $1; + } } - $section = 0; - while () { - next if (/^\s*\#/ || /^\s*$/); - chop ($_); - if (m/^\[(.*)\]/) { - $section = $1; + if($#color >= 0){ + foreach $tmp (@color){ + $tmp =~ m/^\s*(-?\d+)\s*=\s*(\S+)/; + $allcolors{$1} = $2; } - else { - if ( $section =~ /conn/i ) { - push (@allconnections, $_); - } - elsif ( $section =~ /alias/i ) { - m/^\s*(\S.*)\s*=\s*(\S+)/; - $allaliases {$2} = $1; - } - elsif ( $section =~ /color/i ) { - m/^\s*(-?\d+)\s*=\s*(\S+)/; - $allcolors {$1} = $2; + } + + if($opt_f){ + unless (open(CFGFILEHANDLE, $fn)) { + if($opt_s){ + print "Error: Can't open configuration file\"$fn\": $!.\n"; + } else { + print "

Error: Can't open configuration file\"$fn\": $!.\n"; + print "

If you need help on the configuration file, Please go back and click the Help button.\n"; } - } + return -1; + } + $section = 0; + while () { + next if (/^\s*\#/ || /^\s*$/); + chop ($_); + if (m/^\[(.*)\]/) { + $section = $1; + } + else { + if ( $section =~ /conn/i ) { + push (@allconnections, $_); + } + elsif ( $section =~ /alias/i ) { + m/^\s*(\S.*)\s*=\s*(\S+)/; + $allaliases {$2} = $1; + } + elsif ( $section =~ /color/i ) { + m/^\s*(-?\d+)\s*=\s*(\S+)/; + $allcolors {$1} = $2; + } + } + } + close (CFGFILEHANDLE); } if ( ! keys (%allcolors) ) { - $allcolors {0} = "#ccffcc"; #apple green - $allcolors {5} = "#ffffcc"; #cream yellow - $allcolors {60} = "#ffcccc"; #pale pink + $allcolors {0} = "#ccffcc"; #apple green + $allcolors {5} = "#ffffcc"; #cream yellow + $allcolors {60} = "#ffcccc"; #pale pink } @colorkeys = sort (keys (%allcolors)); - close (CFGFILEHANDLE); + return 0; } sub get_replicas { - my ($serveridx) = @_; + $serveridx = $_[0]; my ($conn, $host, $port, $shadowport, $binddn, $bindpwd, $bindcert); my ($others); my ($replica, $replicadn); my ($ruv, $replicaroot, $replicatype, $serverid, $masterid, $maxcsn); my ($type, $flag, $i); my ($myridx, $ridx, $cidx); + my ($lastmodifiedat, $agreement); # # Bind to the server # - ($host, $port, $binddn, $bindpwd, $bindcert) = split (/:/, "$servers[$serveridx]", 5); + if($#servers < 0 || $serveridx > $#servers + 1){ + return -1; + } + ($host, $port, $binddn, $bindpwd, $bindcert) = split (/:/, "$servers[$serveridx]", 5); ($port, $shadowport) = split (/=/, $port); $shadowport = $port if !$shadowport; $conn = new Mozilla::LDAP::Conn ($host, $shadowport, "$binddn", $bindpwd, $bindcert); - return -1 if (!$conn); # @@ -508,24 +590,21 @@ sub find_consumer_replicas sub process_suppliers { - my ($ridx, $mid, $maxcsn); - - $mid = ""; + my ($ridx, $mid, $maxcsn, $ismaster); $ismaster = 0; + $mid = ""; $last_sidx = -1; # global variable for print html page for ($ridx = 0; $ridx <= $#allreplicas; $ridx++) { - # Handle masters and hubs if ($allreplicas[$ridx] =~ /:master:(\d+):/i) { $mid = $1; # Skip replicas without agreements defined yet next if (! grep {$_->{ridx} == $ridx} @allagreements); - $maxcsn = &print_master_header ($ridx, $mid); - if ( "$maxcsn" != "none" ) { + if ( "$maxcsn" ne "none" ) { &print_consumer_header (); &print_consumers ($ridx, $mid); } @@ -536,7 +615,7 @@ sub process_suppliers # Skip replicas without agreements defined yet next if (! grep {$_->{ridx} == $ridx} @allagreements); - foreach $key (keys %allruvs) { + foreach my $key (keys %allruvs) { if ( $key =~ /$ridx:/) { my ($myridx, $mymid) = split ( /:/, "$key" ); $maxcsn = &print_hub_header($myridx, $mymid); @@ -549,7 +628,11 @@ sub process_suppliers } if ($mid eq "") { - print "

The server is not a master or a hub or it has no replication agreement\n"; + if($opt_s){ + print "The server is not a master or a hub or it has no replication agreement\n"; + } else { + print "

The server is not a master or a hub or it has no replication agreement\n"; + } } } @@ -560,34 +643,40 @@ sub print_master_header my ($maxcsnval) = split ( /;/, "$myruv" ); my ($maxcsn) = &to_string_csn ($maxcsnval); my ($sidx, $replicaroot, $replicatype, $serverid) = split (/:/, $allreplicas[$ridx]); - - if ( $maxcsn == "" ) { + + if ( $maxcsn eq "" ) { return $maxcsn; } # Print the master name - if ( $last_sidx != $sidx ) { + if ( $last_sidx ne $sidx ) { my ($ldapurl) = &get_ldap_url ($sidx, $sidx); &print_legend if ( $last_sidx < 0); - print "


\n"; - print "\n

\n"; - print "Master:  $ldapurl
\n"; + if($opt_s){ + print "Master: $ldapurl\n" + } else { + print "


\n"; + print "\n

\n"; + print "Master:  $ldapurl
\n"; + } $last_sidx = $sidx; } # Print the current replica info onthe master - print "\n

\n"; - - print "\n
\n"; - print "Replica ID: "; - print "$serverid\n"; - - print "Replica Root: "; - print "$replicaroot\n"; - - print "Max CSN: "; - print "$maxcsn\n"; - + if($opt_s){ + print "Replica ID: $serverid\n"; + print "Replica Root: $replicaroot\n"; + print "Max CSN: $maxcsn\n"; + } else { + print "\n

\n"; + print "\n
\n"; + print "Replica ID: "; + print "$serverid\n"; + print "Replica Root: "; + print "$replicaroot\n"; + print "Max CSN: "; + print "$maxcsn\n"; + } return $maxcsn; } @@ -597,36 +686,44 @@ sub print_hub_header my ($myruv) = $allruvs {"$ridx:$mid"}; my ($maxcsnval) = split ( /;/, "$myruv" ); my ($maxcsn) = &to_string_csn ($maxcsnval); - my ($sidx, $replicaroot, $replicatype, $serverid) = split (/:/, $allreplicas[$ridx]); + my ($sidx, $last_sidx, $replicaroot, $replicatype, $serverid) = split (/:/, $allreplicas[$ridx]); # Print the master name if ( $last_sidx != $sidx ) { my ($ldapurl) = &get_ldap_url ($sidx, $sidx); &print_legend if ( $last_sidx < 0); - print "


\n"; - print "\n

\n"; - print "Hub:  $ldapurl
\n"; + if($opt_s){ + print "Hub: $ldapurl\n"; + } else { + print "


\n"; + print "\n

\n"; + print "Hub:  $ldapurl
\n"; + } $last_sidx = $sidx; } # Print the current replica info onthe master - print "\n

\n"; - - print "\n
\n"; - print "Replica ID: "; - print "$serverid\n"; - - print "Replica Root: "; - print "$replicaroot\n"; - - print "Max CSN: "; - print "$maxcsn\n"; - + if($opt_s){ + print "Replica ID: $serverid\n"; + print "Replica Root: $replicaroot\n"; + print "Max CSN: $maxcsn\n"; + } else { + print "\n

\n"; + print "\n\n"; print "\n"; @@ -648,15 +745,16 @@ sub print_consumers my ($m_ridx, $mid) = @_; my ($ignore, $m_replicaroot) = split (/:/, $allreplicas[$m_ridx]); my (@consumers, @ouragreements, @myagreements); - my ($s_ridx, $c_ridx, $conntype, $schedule, $status); - my ($c_maxcsn_str, $lag, $markcolor); + my ($s_ridx, $c_ridx, $s_sidx, $conntype, $schedule, $status); + my ($c_maxcsn, $c_maxcsn_str, $c_lastmodified, $c_sidx, $lag, $markcolor); my ($c_replicaroot, $c_replicatype); - my ($first_entry); + my ($first_entry, $s_ldapurl, $c_ldapurl); my ($nrows); my ($found); undef @ouragreements; - + $c_lastmodified = ""; + # Collect all the consumer replicas for the current master replica push (@consumers, $m_ridx); foreach (@consumers) { @@ -688,7 +786,7 @@ sub print_consumers $myruv = $allruvs {"$c_ridx:$mid"}; ($c_maxcsn, $c_lastmodified) = split ( /;/, "$myruv" ); ($c_maxcsn_str, $lag, $markcolor) = &cacl_time_lag ($m_maxcsn, $c_maxcsn); - $c_maxcsn_str =~ s/ /\/; + if(!$opt_s){ $c_maxcsn_str =~ s/ /\/; } ($c_sidx, $c_replicaroot, $c_replicatype) = split (/:/, $allreplicas[$c_ridx]); $c_replicaroot = "same as master" if $m_replicaroot eq $c_replicaroot; } @@ -697,7 +795,7 @@ sub print_consumers $c_sidx = -$c_ridx; $c_maxcsn_str = "_"; $lag = "n/a"; - $markcolor = red; + $markcolor = "red"; $c_replicaroot = "_"; $c_replicatype = "_"; } @@ -719,16 +817,27 @@ sub print_consumers $s_ldapurl = &get_ldap_url ($s_sidx, "n/a"); # Print out the consumer's replica and ruvs - print "\n\n"; + if(!$opt_s){ print "\n\n"; } if ($first_entry) { $first_entry = 0; $c_ldapurl = &get_ldap_url ($c_sidx, $conntype); - print "\n"; - print "\n"; - print "\n"; - print "\n"; + if($opt_s){ + print "Receiver: $c_ldapurl\nType: $c_replicatype\n"; + print "Time Lag: $lag\n"; + print "Max CSN: $c_maxcsn_str\n"; + print "Last Modify Time: $c_lastmodified\n"; + } else { + print "\n"; + print "\n"; + print "\n"; + print "\n"; + } + } + if($opt_s){ + print "Supplier: $s_ldapurl\n"; + } else { + print "\n"; } - print "\n"; my $changecount = $_->{nsds5replicaChangesSentSinceStartup}; if ( $changecount =~ /^$mid:(\d+)\/(\d+) / || $changecount =~ / $mid:(\d+)\/(\d+) / ) { $changecount = "$1 / $2"; @@ -739,7 +848,11 @@ sub print_consumers else { $changecount = "0 / 0"; } - print "\n"; + if($opt_s){ + print "Sent/Skipped: $changecount\n"; + } else { + print "\n"; + } my $redfontstart = ""; my $redfontend = ""; if ($status =~ /error/i) { @@ -753,22 +866,44 @@ sub print_consumers $redfontend = ""; } } - print "\n"; - print "\n"; - print "\n"; + if($opt_s){ + print "Update Status: $status\n"; + print "Update Started: ", &format_z_time($_->{nsds5replicaLastUpdateStart}), "\n"; + print "Update Ended: ", &format_z_time($_->{nsds5replicaLastUpdateEnd}), "\n"; + } else { + print "\n"; + print "\n"; + print "\n"; + } if ( $schedule =~ /always/i ) { - print "\n"; + if($opt_s){ + print "Schedule: $schedule\n"; + } else { + print "\n"; + } } else { my ($ndays, @days); $schedule =~ /(\d\d)(\d\d)-(\d\d)(\d\d) (\d+)/; - print "\n"; + if($opt_s){ + print "Schedule: $1:$2-$3:$4 "; + } else { + print "\n"; + } $ndays = $5; $ndays =~ s/(\d)/$1,/g; - @days = (Sun,Mon,Tue,Wed,Thu,Fri,Sat)[eval $ndays]; - print "\n"; + @days = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat")[eval $ndays]; + if($opt_s){ + print "@days\n"; + } else { + print "\n"; + } + } + if($opt_s){ + print "SSL: $conntype\n"; + } else { + print "\n"; } - print "\n"; } } } @@ -778,7 +913,7 @@ sub cacl_time_lag my ($s_maxcsn, $c_maxcsn) = @_; my ($markcolor); my ($csn_str); - my ($s_tm, $c_tm, $lag_tm, $lag_str, $hours, $minute); + my ($s_tm, $c_tm, $lag_tm, $lag_str, $hours, $minutes); $csn_str = &to_string_csn ($c_maxcsn); @@ -831,7 +966,7 @@ sub cacl_time_lag # sub add_server { - my ($host, $port, $binddn, $bindpwd, $bindcert) = split (/:/, "@_"); + my ($host, $port, $binddn, $bindpwd, $bindcert) = split (/:/, "$_[0]"); my ($shadowport) = $port; my ($domainpattern) = '\.[^:]+'; my ($i); @@ -846,7 +981,7 @@ sub add_server $hostnode = $1 if $host =~ /^(.+?)\./; # new host:port - if ($binddn eq "" || $bindpwd eq "" && $bindcert eq "") { + if (!$binddn || $binddn eq "" || !$bindpwd || $bindpwd eq "" || !$bindcert || $bindcert eq "") { # # Look up connection parameter in the order of # host:port @@ -855,17 +990,25 @@ sub add_server # *:* # my (@myconfig, $h, $p, $d, $w, $c); - (@myconfig = grep (/^$hostnode($domainpattern)*:$port\D/i, @allconnections)) || + $h = ""; $p = ""; $d = ""; $w = ""; $c = ""; + (@myconfig = grep (/^$hostnode($domainpattern)*:[0-9]+\D/i, @allconnections)) || (@myconfig = grep (/^$hostnode($domainpattern)*:\*:/i, @allconnections)) || (@myconfig = grep (/^\*:$port\D/, @allconnections)) || (@myconfig = grep (/^\*:\*\D/, @allconnections)); if ($#myconfig >= 0) { ($h, $p, $d, $w, $c) = split (/:/, $myconfig[0]); ($p, $shadowport) = split (/=/, $p); - $p = "" if $p eq "*"; - $c = "" if $c eq "*"; + if(!$p || $p eq "*"){ + $p = ""; + } + if(!$c || $c eq "*"){ + $c = ""; + } + if(!$w || $w eq "*"){ + $w = ""; + } } - if ($binddn eq "" || $binddn eq "*") { + if (!$binddn || $binddn eq "" || $binddn eq "*") { if ($d eq "" || $d eq "*") { $binddn = "cn=Directory Manager"; } @@ -873,8 +1016,14 @@ sub add_server $binddn = $d; } } - $bindpwd = $w if ($bindpwd eq "" || $bindpwd eq "*"); - $bindcert = $c if ($bindcert eq "" || $bindcert eq "*"); + if($prompt eq "yes" && ($w eq "" || (!$bindpwd || $bindpwd eq ""))){ + $bindpwd = passwdPrompt($h, $p); + } elsif ($passwd ne ""){ + $bindpwd = $passwd; + } else { + $bindpwd = $w if (!$bindpwd || $bindpwd eq "" || $bindpwd eq "*"); + } + $bindcert = $c if (!$bindcert || $bindcert eq "" || $bindcert eq "*"); } if ($shadowport) { @@ -885,6 +1034,43 @@ sub add_server return $i; } +sub +passwdPrompt +{ + my ($h, $p) = @_; + my $key = "$h:$p"; + my $pw = ""; + + if ($passwords{$key}){ + # we already have a password for this replica + return $passwords{$key}; + } + # Disable console echo + system("@sttyexec@ -echo") if -t STDIN; + + while ($pw eq ""){ + if($passwd ne ""){ + print "Enter password for ($h:$p) : "; + chomp($pw = <>); + if ($pw eq ""){ + $pw = $passwd; + } else { + $passwords{$key} = $pw; + $passwd = $pw; + } + } else { + print "Enter password for ($h:$p): "; + chomp($pw = <>); + $passwords{$key} = $pw; + $passwd = $pw; + } + } + # Enable console echo + system("@sttyexec@ echo") if -t STDIN; + + return $pw; +} + sub get_ldap_url { my ($sidx, $conntype) = @_; @@ -893,19 +1079,22 @@ sub get_ldap_url ($port, $shadowport) = split (/=/, $port); my ($protocol, $ldapurl); - if ($port eq 636 && $conntype eq "0" || $conntype =~ /SSL/i) { - $protocol = ldaps; + if ($port == 636 && $conntype eq "0" || $conntype =~ /SSL/i) { + $protocol = "ldaps"; } else { - $protocol = ldap; + $protocol = "ldap"; } my ($instance) = $allaliases { "$host:$port" }; $instance = "$host:$port" if !$instance; if ($conntype eq "n/a") { $ldapurl = $instance; - } - else { - $ldapurl = "$instance"; + } else { + if($opt_s){ + $ldapurl = "$instance $protocol://$host:$port/"; + } else { + $ldapurl = "$instance"; + } } return $ldapurl; } @@ -950,7 +1139,8 @@ sub get_color my ($lag_minute) = @_; $lag_minute /= 60; my ($color) = $allcolors { $colorkeys[0] }; - foreach (@colorkeys) { + + foreach ( keys %allcolors) { last if ($lag_minute < $_); $color = $allcolors {$_}; } @@ -969,53 +1159,63 @@ sub unescape sub print_html_header { - # print the HTML header - - print "Content-type: text/html\n\n"; - print "\n"; - print "Replication Status\n"; - # print "\n"; - print "\n\n"; - - if ($opt_u) { - print "\n"; - } - - print "
\n"; + print "Replica ID: "; + print "$serverid\n"; + print "Replica Root: "; + print "$replicaroot\n"; + print "Max CSN: "; + print "$maxcsn\n"; + } return $maxcsn; } sub print_consumer_header { + if($opt_s) { return; } # we'll do the text printing in "print_consumers" + #Print the header of consumer print "\n
Receiver
$c_ldapurl
Type: $c_replicatype
$lag
$c_maxcsn_str$c_lastmodified$c_ldapurl
Type: $c_replicatype
$lag
$c_maxcsn_str$c_lastmodified
$s_ldapurl
$s_ldapurl
$changecount$changecount$redfontstart$status$redfontend", &format_z_time($_->{nsds5replicaLastUpdateStart}), "", &format_z_time($_->{nsds5replicaLastUpdateEnd}), "$redfontstart$status$redfontend", &format_z_time($_->{nsds5replicaLastUpdateStart}), "", &format_z_time($_->{nsds5replicaLastUpdateEnd}), "$schedule$schedule$1:$2-$3:$4$1:$2-$3:$4@days@days$conntype$conntype
\n"; - print "\n"; - print "
$now"; - print "Directory Server Replication Status\n"; - - if ($opt_u) { - print "
(This page updates every $interval seconds)\n"; - } - - print "
$version"; - print "
\n"; + if(!$opt_s){ + # print the HTML header + + print "\n"; + print "\n"; + print "Replication Status\n"; + # print "\n"; + print "\n\n"; + + if ($opt_u) { + print "\n"; + } + + print "\n"; + print "\n"; + print "
$now"; + print "Directory Server Replication Status\n"; + + if ($opt_u) { + print "
(This page updates every $interval seconds)\n"; + } + + print "
$version"; + print "
\n"; + } else { + print "Directory Server Replication Status ($version)\n\n"; + print "Time: $now"; + if ($opt_u) { + print " - This report updates every $interval seconds\n\n"; + } else { + print "\n\n"; + } + } } sub print_legend { my ($nlegends) = $#colorkeys + 1; + if($opt_s){ return; } print "\n

Time Lag Legend:

\n"; print "\n\n"; my ($i, $j); @@ -1031,7 +1231,7 @@ sub print_legend sub print_supplier_end { - print "
\n"; + if(!$opt_s){ print "

\n"; } } # given a string in generalized time format, convert to ascii time diff --git a/man/man1/repl-monitor.1 b/man/man1/repl-monitor.1 index 424550e..bd0ede1 100644 --- a/man/man1/repl-monitor.1 +++ b/man/man1/repl-monitor.1 @@ -19,8 +19,9 @@ repl-monitor \- Directory Server replication monitor .SH SYNOPSIS .B repl\(hymonitor -\-f configuration\(hyfile [\fI\(hyh host\fR] [\fI\-p port\fR] [\fI\-r\fR] -[\fI\-u refresh\(hyurl\fR] [\fI\-t refresh\(hyinterval\fR] [\fI\-v\fR] +\ [-f configuration\(hyfile] [\fI\(hyh host\fR] [\fI\-p port\fR] [\fI\-r\fR] +[\fI\-c connection\fR] [\fI\-a alias\fR] [\fI\-k color\fR] [\fI\-u refresh\(hyurl\fR] +[\fI\-s\fR] [\fI\-t refresh\(hyinterval\fR] [\fI\-v\fR] .SH DESCRIPTION Outputs the status of all of the configured Directory Servers @@ -33,23 +34,39 @@ are specified in the configuration file. .SH OPTIONS A summary of options is included below: .TP -.B \-h host +.B \-h, \-\-host\fR host Hostname of DS server .TP -.B \-p port +.B \-p, \-\-port\fR port TCP port .TP -.B \-f configuration\(hyfile +.B \-f, \-\-configfile\fR configuration-file Configuration file .TP -.B \-r +.B \-c, \-\-conn\fR connection +Uses the same format as the configfile directive +.TP +.B \-a, \-\-alias\fR alias +Uses the same format as the configfile directive +.TP +.B \-k, --color\fR color +Uses the same format as the configfile directive +.TP +.B \-r, --skip-header\fR Removes extra HTML tags .TP -.B \-u refresh\(hyurl +.B \-u, \-\-refreshurl\fR refresh url Refresh url .TP -.B \-t refresh\(hyinterval +.B \-t, \-\-interval\fR refresh interval Refresh interval +.TP +.B \-W, \-\-prompt +Prompt for passwords +.TP +.B \-s, \-\-text +Print plain text report + .br .SH AUTHOR repl-monitor was written by the 389 Project. @@ -63,6 +80,8 @@ Copyright \(co 2008 Red Hat, Inc. This manual page was written by Michele Baldessari , for the Debian project (but may be used by others). .br +Manual page updated by Mark Reynolds 10/11/13 +.br This is free software. You may redistribute copies of it under the terms of the Directory Server license found in the LICENSE file of this software distribution. This license is essentially the GNU General Public -- 1.8.1.4