123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- #! /usr/bin/perl -w
- #############################################################################
- # (c) 2001, 2003 Juniper Networks, Inc. #
- # (c) 2011 Sebastian "tokkee" Harl <sh@teamix.net> #
- # and team(ix) GmbH, Nuernberg, Germany #
- # #
- # This file is part of "team(ix) Monitoring Plugins" #
- # URL: http://oss.teamix.org/projects/monitoringplugins/ #
- # It is based on the example diagnose_bgp.pl script of the #
- # JUNOScript distribution. #
- # #
- # All rights reserved. #
- # Redistribution and use in source and binary forms, with or without #
- # modification, are permitted provided that the following conditions #
- # are met: #
- # 1. Redistributions of source code must retain the above copyright #
- # notice, this list of conditions and the following disclaimer. #
- # 2. Redistributions in binary form must reproduce the above copyright #
- # notice, this list of conditions and the following disclaimer in the #
- # documentation and/or other materials provided with the distribution. #
- # 3. The name of the copyright owner may not be used to endorse or #
- # promote products derived from this software without specific prior #
- # written permission. #
- # #
- # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR #
- # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED #
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE #
- # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, #
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES #
- # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR #
- # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) #
- # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, #
- # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING #
- # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE #
- # POSSIBILITY OF SUCH DAMAGE. #
- #############################################################################
- use strict;
- use warnings;
- use JUNOS::Device;
- use JUNOS::Trace;
- use Getopt::Std;
- use Term::ReadKey;
- use File::Basename;
- use Data::Dumper;
- my $jnx;
- # send a query
- sub send_query
- {
- my $device = shift;
- my $query = shift;
- my $href_queryargs = shift;
- my $res;
- unless ( ref $href_queryargs ) {
- eval {
- $res = $device->$query();
- };
- if ($@) {
- $res = $device->command($query);
- }
- } else {
- my %queryargs = %$href_queryargs;
- print "$_ => $queryargs{$_}\n" foreach (keys %queryargs);
- $res = $device->$query(%queryargs);
- }
- unless ( ref $res ) {
- print STDERR "ERROR: Failed to execute query '$query'\n";
- return 0;
- }
- unless (ref $res) {
- print STDERR "ERROR: failed to execute command $query\n";
- return undef;
- }
- my $err = $res->getFirstError();
- if ($err) {
- print STDERR "ERROR: ", $err->{message}, "\n";
- return 0;
- }
- return $res;
- }
- # get object identified by the specified spec
- sub get_object_by_spec
- {
- my $res = shift;
- my $spec = shift;
- my $iter = $res;
- for (my $i = 0; $i < scalar(@$spec) - 1; ++$i) {
- my $tmp = $iter->getElementsByTagName($spec->[$i]);
- if ((! $tmp) || (! $tmp->item(0))) {
- return;
- }
- $iter = $tmp->item(0);
- }
- if (wantarray) {
- my @ret = $iter->getElementsByTagName($spec->[scalar(@$spec) - 1]);
- return @ret;
- }
- else {
- my $ret = $iter->getElementsByTagName($spec->[scalar(@$spec) - 1]);
- if ((! $ret) || (! $ret->item(0))) {
- return;
- }
- return $ret->item(0);
- }
- }
- # print the usage of this script
- sub output_usage
- {
- my $usage = "Usage: $0 [options] <target> <query> [<arg1>=<value1> [...]]
- Where:
- <target> The hostname of the target router.
- <query> The query to send to the target router.
- Options:
- -l <login> A login name accepted by the target router.
- -p <password> The password for the login name.
- -m <access> Access method. It can be clear-text, ssl, ssh or telnet. Default: telnet.
- -s <spec> Specify a value to extract from the output.
- -o <file> Output file. Default: dump.xml.
- -d Turn on debug, full blast.\n\n";
- die $usage;
- }
- my %opt;
- getopts('l:p:dm:x:o:s:h', \%opt) || output_usage();
- output_usage() if $opt{h};
- # Check whether trace should be turned on
- JUNOS::Trace::init(1) if $opt{d};
- my $hostname = shift || output_usage();
- my $query = shift || output_usage();
- my %args = map { split m/=/, $_ } @ARGV;
- if ($opt{d}) {
- print "Args:\n";
- foreach my $key (keys %args) {
- print "\t$key => $args{$key}\n";
- }
- }
- # Retrieve the access method, can only be telnet or ssh.
- my $access = $opt{m} || "telnet";
- use constant VALID_ACCESSES => "telnet|ssh|clear-text|ssl";
- output_usage() unless (VALID_ACCESSES =~ /$access/);
- # Check whether login name has been entered. Otherwise prompt for it
- my $login = "";
- if ($opt{l}) {
- $login = $opt{l};
- } else {
- print "login: ";
- $login = ReadLine 0;
- chomp $login;
- }
- # Check whether password has been entered. Otherwise prompt for it
- my $password = "";
- if ($opt{p}) {
- $password = $opt{p};
- } else {
- print "password: ";
- ReadMode 'noecho';
- $password = ReadLine 0;
- chomp $password;
- ReadMode 'normal';
- print "\n";
- }
- # Get the name of the output file
- my $outfile = $opt{o} || 'dump.xml';
- # Retrieve command line arguments
- my %deviceinfo = (
- access => $access,
- login => $login,
- password => $password,
- hostname => $hostname,
- 'ssh-compress' => 0,
- );
- #
- # CONNECT TO the JUNOScript server
- # Create a device object that contains all necessary information to
- # connect to the JUNOScript server at a specific router.
- #
- $jnx = new JUNOS::Device(%deviceinfo);
- unless ( ref $jnx ) {
- die "ERROR: $deviceinfo{hostname}: failed to connect.\n";
- }
- my $spec = $opt{s} || undef;
- if ($spec) {
- $spec = [ split(",", $spec) ];
- }
- my $res = send_query($jnx, $query, scalar(keys %args) ? \%args : undef);
- while ($res) {
- if ($spec) {
- $res = get_object_by_spec($res, $spec);
- }
- if (! $res) {
- print "NO OUTPUT!\n";
- last;
- }
- if ($outfile eq "-") {
- print STDOUT $res->toString;
- }
- else {
- $res->printToFile($outfile);
- }
- last;
- }
- $jnx->request_end_session();
- $jnx->disconnect();
|