junos_dump.pl 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #! /usr/bin/perl -w
  2. #############################################################################
  3. # (c) 2001, 2003 Juniper Networks, Inc. #
  4. # (c) 2011 Sebastian "tokkee" Harl <sh@teamix.net> #
  5. # and team(ix) GmbH, Nuernberg, Germany #
  6. # #
  7. # This file is part of "team(ix) Monitoring Plugins" #
  8. # URL: http://oss.teamix.org/projects/monitoringplugins/ #
  9. # It is based on the example diagnose_bgp.pl script of the #
  10. # JUNOScript distribution. #
  11. # #
  12. # All rights reserved. #
  13. # Redistribution and use in source and binary forms, with or without #
  14. # modification, are permitted provided that the following conditions #
  15. # are met: #
  16. # 1. Redistributions of source code must retain the above copyright #
  17. # notice, this list of conditions and the following disclaimer. #
  18. # 2. Redistributions in binary form must reproduce the above copyright #
  19. # notice, this list of conditions and the following disclaimer in the #
  20. # documentation and/or other materials provided with the distribution. #
  21. # 3. The name of the copyright owner may not be used to endorse or #
  22. # promote products derived from this software without specific prior #
  23. # written permission. #
  24. # #
  25. # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR #
  26. # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED #
  27. # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE #
  28. # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, #
  29. # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES #
  30. # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR #
  31. # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) #
  32. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, #
  33. # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING #
  34. # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE #
  35. # POSSIBILITY OF SUCH DAMAGE. #
  36. #############################################################################
  37. use strict;
  38. use warnings;
  39. use JUNOS::Device;
  40. use JUNOS::Trace;
  41. use Getopt::Std;
  42. use Term::ReadKey;
  43. use File::Basename;
  44. use Data::Dumper;
  45. my $jnx;
  46. # send a query
  47. sub send_query
  48. {
  49. my $device = shift;
  50. my $query = shift;
  51. my $href_queryargs = shift;
  52. my $res;
  53. unless ( ref $href_queryargs ) {
  54. eval {
  55. $res = $device->$query();
  56. };
  57. if ($@) {
  58. $res = $device->command($query);
  59. }
  60. } else {
  61. my %queryargs = %$href_queryargs;
  62. print "$_ => $queryargs{$_}\n" foreach (keys %queryargs);
  63. $res = $device->$query(%queryargs);
  64. }
  65. unless ( ref $res ) {
  66. print STDERR "ERROR: Failed to execute query '$query'\n";
  67. return 0;
  68. }
  69. unless (ref $res) {
  70. print STDERR "ERROR: failed to execute command $query\n";
  71. return undef;
  72. }
  73. my $err = $res->getFirstError();
  74. if ($err) {
  75. print STDERR "ERROR: ", $err->{message}, "\n";
  76. return 0;
  77. }
  78. return $res;
  79. }
  80. # get object identified by the specified spec
  81. sub get_object_by_spec
  82. {
  83. my $res = shift;
  84. my $spec = shift;
  85. my $iter = $res;
  86. for (my $i = 0; $i < scalar(@$spec) - 1; ++$i) {
  87. my $tmp = $iter->getElementsByTagName($spec->[$i]);
  88. if ((! $tmp) || (! $tmp->item(0))) {
  89. return;
  90. }
  91. $iter = $tmp->item(0);
  92. }
  93. if (wantarray) {
  94. my @ret = $iter->getElementsByTagName($spec->[scalar(@$spec) - 1]);
  95. return @ret;
  96. }
  97. else {
  98. my $ret = $iter->getElementsByTagName($spec->[scalar(@$spec) - 1]);
  99. if ((! $ret) || (! $ret->item(0))) {
  100. return;
  101. }
  102. return $ret->item(0);
  103. }
  104. }
  105. # print the usage of this script
  106. sub output_usage
  107. {
  108. my $usage = "Usage: $0 [options] <target> <query> [<arg1>=<value1> [...]]
  109. Where:
  110. <target> The hostname of the target router.
  111. <query> The query to send to the target router.
  112. Options:
  113. -l <login> A login name accepted by the target router.
  114. -p <password> The password for the login name.
  115. -m <access> Access method. It can be clear-text, ssl, ssh or telnet. Default: telnet.
  116. -s <spec> Specify a value to extract from the output.
  117. -o <file> Output file. Default: dump.xml.
  118. -d Turn on debug, full blast.\n\n";
  119. die $usage;
  120. }
  121. my %opt;
  122. getopts('l:p:dm:x:o:s:h', \%opt) || output_usage();
  123. output_usage() if $opt{h};
  124. # Check whether trace should be turned on
  125. JUNOS::Trace::init(1) if $opt{d};
  126. my $hostname = shift || output_usage();
  127. my $query = shift || output_usage();
  128. my %args = map { split m/=/, $_ } @ARGV;
  129. if ($opt{d}) {
  130. print "Args:\n";
  131. foreach my $key (keys %args) {
  132. print "\t$key => $args{$key}\n";
  133. }
  134. }
  135. # Retrieve the access method, can only be telnet or ssh.
  136. my $access = $opt{m} || "telnet";
  137. use constant VALID_ACCESSES => "telnet|ssh|clear-text|ssl";
  138. output_usage() unless (VALID_ACCESSES =~ /$access/);
  139. # Check whether login name has been entered. Otherwise prompt for it
  140. my $login = "";
  141. if ($opt{l}) {
  142. $login = $opt{l};
  143. } else {
  144. print "login: ";
  145. $login = ReadLine 0;
  146. chomp $login;
  147. }
  148. # Check whether password has been entered. Otherwise prompt for it
  149. my $password = "";
  150. if ($opt{p}) {
  151. $password = $opt{p};
  152. } else {
  153. print "password: ";
  154. ReadMode 'noecho';
  155. $password = ReadLine 0;
  156. chomp $password;
  157. ReadMode 'normal';
  158. print "\n";
  159. }
  160. # Get the name of the output file
  161. my $outfile = $opt{o} || 'dump.xml';
  162. # Retrieve command line arguments
  163. my %deviceinfo = (
  164. access => $access,
  165. login => $login,
  166. password => $password,
  167. hostname => $hostname,
  168. 'ssh-compress' => 0,
  169. );
  170. #
  171. # CONNECT TO the JUNOScript server
  172. # Create a device object that contains all necessary information to
  173. # connect to the JUNOScript server at a specific router.
  174. #
  175. $jnx = new JUNOS::Device(%deviceinfo);
  176. unless ( ref $jnx ) {
  177. die "ERROR: $deviceinfo{hostname}: failed to connect.\n";
  178. }
  179. my $spec = $opt{s} || undef;
  180. if ($spec) {
  181. $spec = [ split(",", $spec) ];
  182. }
  183. my $res = send_query($jnx, $query, scalar(keys %args) ? \%args : undef);
  184. while ($res) {
  185. if ($spec) {
  186. $res = get_object_by_spec($res, $spec);
  187. }
  188. if (! $res) {
  189. print "NO OUTPUT!\n";
  190. last;
  191. }
  192. if ($outfile eq "-") {
  193. print STDOUT $res->toString;
  194. }
  195. else {
  196. $res->printToFile($outfile);
  197. }
  198. last;
  199. }
  200. $jnx->request_end_session();
  201. $jnx->disconnect();