1#!@PERL@ 2# Copyright (C) 2002 Stanislav Sinyagin 3# 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation; either version 2 of the License, or 7# (at your option) any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program; if not, write to the Free Software 16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 17 18# Stanislav Sinyagin <ssinyagin@k-open.com> 19 20# Generate the SNMP discovery instructions XML file out of plaintext 21# list of hosts. 22 23use strict; 24use warnings; 25BEGIN { require '@devdiscover_config_pl@'; } 26 27use Getopt::Long; 28use XML::LibXML; 29use IO::File; 30 31use Torrus::Log; 32 33our $outFormatVersion = '1.0'; 34 35our @hosts = (); 36our $hostfile; 37 38our %globalParams = 39 ( 40 'output-file' => 'routers.xml', 41 'domain-name' => '', 42 'host-subtree' => '/Routers', 43 'snmp-port' => '161', 44 'snmp-community' => 'public', 45 'snmp-version' => '2c', 46 'snmp-timeout' => 10, 47 'snmp-retries' => 2, 48 'rrd-hwpredict' => 0, 49 'data-dir' => '@defrrddir@', 50 ); 51 52our $outfile = 'routers.ddx'; 53 54 55my $creator = "Torrus version @VERSION@\n" . 56 "This file was generated by command:\n" . 57 $0 . " \\\n"; 58foreach my $arg ( @ARGV ) 59{ 60 if( $arg =~ /^--/ ) 61 { 62 $creator .= ' ' . $arg . ' '; 63 } 64 else 65 { 66 $creator .= "\'" . $arg . "\'\\\n"; 67 } 68} 69$creator .= "\nOn " . scalar(localtime(time)); 70 71my $ok = GetOptions( 72 'host=s' => \@hosts, 73 'hostfile=s' => \$hostfile, 74 'out=s' => \$outfile, 75 'discout=s' => \$globalParams{'output-file'}, 76 'domain=s' => \$globalParams{'domain-name'}, 77 'version=s' => \$globalParams{'snmp-version'}, 78 'community=s' => \$globalParams{'snmp-community'}, 79 'port=i' => \$globalParams{'snmp-port'}, 80 'timeout=i' => \$globalParams{'snmp-timeout'}, 81 'retries=i' => \$globalParams{'snmp-retries'}, 82 'subtree=s' => \$globalParams{'host-subtree'}, 83 'holtwinters' => \$globalParams{'rrd-hwpredict'}, 84 'datadir=s' => \$globalParams{'data-dir'}, 85 ); 86 87if( not $ok or 88 ( not $hostfile and scalar(@hosts) == 0 ) or 89 scalar( @ARGV ) > 0 ) 90{ 91 print STDERR "Generate devdiscover XML configuration\n"; 92 93 print STDERR "Usage: $0 options...\n", 94 "Options:\n", 95 " --host=hostname device hostname\n", 96 " --hostfile=filename space-separated device hostnames file\n", 97 " --out=filename output file [".$outfile."]\n", 98 99 " --discout=filename discovery output file\n", 100 " [", $globalParams{'output-file'}, "]\n", 101 102 " --domain=domain optional DNS domain name\n", 103 104 " --version=v SNMP version [", 105 $globalParams{'snmp-version'}, "]\n", 106 107 " --community=string SNMP read community [", 108 $globalParams{'snmp-community'}, "]\n", 109 110 " --port=number SNMP port [", 111 $globalParams{'snmp-port'}, "]\n", 112 113 " --retries=number SNMP retries [", 114 $globalParams{'snmp-retries'}, "]\n", 115 116 " --timeout=number SNMP timeout [", 117 $globalParams{'snmp-timeout'}, "]\n", 118 119 " --subtree=string Subtree name [", 120 $globalParams{'host-subtree'}, "]\n", 121 122 " --datadir=path data-dir parameter [", 123 $globalParams{'data-dir'}, "]\n", 124 125 " --holtwinters Enable Holt-Winters analysis\n", 126 "\n", 127 "Host names may be of form \"host:devname\" where devname is a symbolic\n", 128 "device name.\n", 129 "Output file is placed into " . $Torrus::Global::discoveryDir, 130 "\n if no path is given.\n"; 131 exit 1; 132} 133 134# Place the output file in discovery directory if the path is not given 135if( $outfile !~ /\// ) 136{ 137 $outfile = $Torrus::Global::discoveryDir . '/' . $outfile; 138} 139 140# Convert flags from true/false to yes/no 141foreach my $param ( 'rrd-hwpredict' ) 142{ 143 if( $globalParams{$param} ) 144 { 145 $globalParams{$param} = 'yes'; 146 } 147 else 148 { 149 $globalParams{$param} = 'no'; 150 } 151} 152 153if( $globalParams{'host-subtree'} !~ /^\/[0-9A-Za-z_\-\.\/]*$/ or 154 $globalParams{'host-subtree'} =~ /\.\./ ) 155{ 156 Error("Invalid format for subtree name: " . $globalParams{'host-subtree'}); 157 exit 1; 158} 159 160if( defined $hostfile ) 161{ 162 my $fh = IO::File->new($hostfile, 'r'); 163 if( not defined($fh) ) 164 { 165 print STDERR "Cannot open $hostfile: $!"; 166 exit 1; 167 } 168 while(<$fh>) 169 { 170 s/^\s+//; 171 s/\s+$//; 172 push( @hosts, split( /\s+/ ) ); 173 } 174 $fh->close() 175} 176 177# Create XML DOM 178 179my $doc = XML::LibXML->createDocument( "1.0", "UTF-8" ); 180my $root = $doc->createElement('snmp-discovery'); 181$doc->setDocumentElement( $root ); 182 183{ 184 my $fileInfoNode = $doc->createElement('file-info'); 185 $root->appendChild( $fileInfoNode ); 186 187 my $formatNode = $doc->createElement('format-version'); 188 $formatNode->appendText( $outFormatVersion ); 189 $fileInfoNode->appendChild( $formatNode ); 190} 191 192{ 193 my $creatorNode = $doc->createElement('creator-info'); 194 $creatorNode->appendText( $creator ); 195 $root->appendChild( $creatorNode ); 196} 197 198createParamsDom( \%globalParams, $doc, $root ); 199 200 201foreach my $host ( @hosts ) 202{ 203 my $devname = $host; 204 if( $host =~ /([^:]+):(.+)/ ) 205 { 206 $host = $1; 207 $devname = $2; 208 } 209 210 my $hostNode = $doc->createElement('host'); 211 $root->appendChild( $hostNode ); 212 213 my %hostParams = ( 'snmp-host' => $host ); 214 if( $devname ne $host ) 215 { 216 $hostParams{'symbolic-name'} = $devname; 217 } 218 219 createParamsDom( \%hostParams, $doc, $hostNode ); 220} 221 222$ok = $doc->toFile( $outfile, 2 ); 223if( $ok ) 224{ 225 print STDERR ("Wrote $outfile\n"); 226} 227else 228{ 229 print STDERR ("Cannot write $outfile: $!\n"); 230} 231 232 233exit($ok ? 0:1); 234 235 236sub createParamsDom 237{ 238 my $params = shift; 239 my $document = shift; 240 my $parentNode = shift; 241 242 foreach my $param ( sort keys %{$params} ) 243 { 244 my $paramNode = $document->createElement('param'); 245 $paramNode->setAttribute( 'name', $param ); 246 $paramNode->setAttribute( 'value', $params->{$param} ); 247 $parentNode->appendChild( $paramNode ); 248 } 249 return; 250} 251 252 253 254 255# Local Variables: 256# mode: perl 257# indent-tabs-mode: nil 258# perl-indent-level: 4 259# End: 260