rename files from Daemon to Backend
This commit is contained in:
		
							
								
								
									
										462
									
								
								bin/netdisco-do-e
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										462
									
								
								bin/netdisco-do-e
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,462 @@ | ||||
| #!/usr/bin/env perl | ||||
|  | ||||
| use strict; | ||||
| use warnings; | ||||
|  | ||||
| our $home; | ||||
|  | ||||
| BEGIN { | ||||
|   use FindBin; | ||||
|   FindBin::again(); | ||||
|  | ||||
|   $home = ($ENV{NETDISCO_HOME} || $ENV{HOME}); | ||||
|  | ||||
|   # try to find a localenv if one isn't already in place. | ||||
|   if (!exists $ENV{PERL_LOCAL_LIB_ROOT}) { | ||||
|       use File::Spec; | ||||
|       my $localenv = File::Spec->catfile($FindBin::RealBin, 'localenv'); | ||||
|       exec($localenv, $0, @ARGV) if -f $localenv; | ||||
|       $localenv = File::Spec->catfile($home, 'perl5', 'bin', 'localenv'); | ||||
|       exec($localenv, $0, @ARGV) if -f $localenv; | ||||
|  | ||||
|       die "Sorry, can't find libs required for App::Netdisco.\n" | ||||
|         if !exists $ENV{PERLBREW_PERL}; | ||||
|   } | ||||
| } | ||||
|  | ||||
| BEGIN { | ||||
|   use Path::Class; | ||||
|  | ||||
|   # stuff useful locations into @INC and $PATH | ||||
|   unshift @INC, | ||||
|     dir($FindBin::RealBin)->parent->subdir('lib')->stringify, | ||||
|     dir($FindBin::RealBin, 'lib')->stringify; | ||||
| } | ||||
|  | ||||
| # for netdisco app config | ||||
| use App::Netdisco; | ||||
| use App::Netdisco::Daemon::Job; | ||||
| use Dancer qw/:moose :script/; | ||||
|  | ||||
| info "App::Netdisco version $App::Netdisco::VERSION loaded."; | ||||
|  | ||||
| use NetAddr::IP qw/:rfc3021 :lower/; | ||||
| use App::Netdisco::Util::Device 'get_device'; | ||||
|  | ||||
| use Try::Tiny; | ||||
| use Pod::Usage; | ||||
| use Scalar::Util 'blessed'; | ||||
| use Getopt::Long; | ||||
| Getopt::Long::Configure ("bundling"); | ||||
|  | ||||
| my ($device, $port, $extra, $debug); | ||||
| my ($infotrace, $snmptrace, $sqltrace) = (0, 0, 0); | ||||
|  | ||||
| my $result = GetOptions( | ||||
|   'device|d=s' => \$device, | ||||
|   'port|p=s'   => \$port, | ||||
|   'extra|e=s'  => \$extra, | ||||
|   'debug|D'    => \$debug, | ||||
|   'infotrace|I+' => \$infotrace, | ||||
|   'snmptrace|S+' => \$snmptrace, | ||||
|   'sqltrace|Q+'  => \$sqltrace, | ||||
| ) or pod2usage( | ||||
|   -msg => 'error: bad options', | ||||
|   -verbose => 0, | ||||
|   -exitval => 1, | ||||
| ); | ||||
|  | ||||
| my $CONFIG = config(); | ||||
| $CONFIG->{logger} = 'console'; | ||||
| $CONFIG->{log} = ($debug ? 'debug' : 'info'); | ||||
|  | ||||
| $ENV{INFO_TRACE} ||= $infotrace; | ||||
| $ENV{SNMP_TRACE} ||= $snmptrace; | ||||
| $ENV{DBIC_TRACE} ||= $sqltrace; | ||||
|  | ||||
| # reconfigure logging to force console output | ||||
| Dancer::Logger->init('console', $CONFIG); | ||||
|  | ||||
| # get requested action | ||||
| (my $action = shift @ARGV) =~ s/^set_// | ||||
|   if scalar @ARGV; | ||||
|  | ||||
| unless ($action) { | ||||
|     pod2usage( | ||||
|       -msg => 'error: missing action!', | ||||
|       -verbose => 2, | ||||
|       -exitval => 2, | ||||
|     ); | ||||
| } | ||||
|  | ||||
| # create worker (placeholder object for the role methods) | ||||
| { | ||||
|   package MyWorker; | ||||
|  | ||||
|   use Moo; | ||||
|   use Module::Load (); | ||||
|   use Data::Printer (); | ||||
|   use Scalar::Util 'blessed'; | ||||
|   use NetAddr::IP qw/:rfc3021 :lower/; | ||||
|   use Dancer ':script'; | ||||
|  | ||||
|   use App::Netdisco::Util::SNMP (); | ||||
|   use App::Netdisco::Util::Device | ||||
|     qw/get_device delete_device renumber_device/; | ||||
|  | ||||
|   with 'App::Netdisco::Daemon::Worker::Poller::Device'; | ||||
|   with 'App::Netdisco::Daemon::Worker::Poller::Arpnip'; | ||||
|   with 'App::Netdisco::Daemon::Worker::Poller::Macsuck'; | ||||
|   with 'App::Netdisco::Daemon::Worker::Poller::Nbtstat'; | ||||
|   with 'App::Netdisco::Daemon::Worker::Poller::Expiry'; | ||||
|   with 'App::Netdisco::Daemon::Worker::Interactive::DeviceActions'; | ||||
|   with 'App::Netdisco::Daemon::Worker::Interactive::PortActions'; | ||||
|  | ||||
|   eval { Module::Load::load 'App::Netdisco::Util::Graph' }; | ||||
|   sub graph { | ||||
|     App::Netdisco::Util::Graph::graph(); | ||||
|     return ('done', 'Generated graph data.'); | ||||
|   } | ||||
|  | ||||
|   use App::Netdisco::Util::NodeMonitor (); | ||||
|   sub monitor { | ||||
|     App::Netdisco::Util::NodeMonitor::monitor(); | ||||
|     return ('done', 'Generated monitor data.'); | ||||
|   } | ||||
|  | ||||
|   sub show { | ||||
|     my ($self, $job) = @_; | ||||
|     my ($device, $port, $extra) = map {$job->$_} qw/device port extra/; | ||||
|     return ('error', 'Missing device (-d).') if !defined $device; | ||||
|  | ||||
|     $extra ||= 'interfaces'; my $class = undef; | ||||
|     ($class, $extra) = split(/::([^:]+)$/, $extra); | ||||
|     if ($class and $extra) { | ||||
|         $class = 'SNMP::Info::'.$class; | ||||
|     } | ||||
|     else { | ||||
|         $extra = $class; | ||||
|         undef $class; | ||||
|     } | ||||
|     my $i = App::Netdisco::Util::SNMP::snmp_connect($device, $class); | ||||
|     Data::Printer::p($i->$extra); | ||||
|     return ('done', sprintf "Showed %s response from %s.", $extra, $device->ip); | ||||
|   } | ||||
|  | ||||
|   sub delete { | ||||
|     my ($self, $job) = @_; | ||||
|     my ($device, $port, $extra) = map {$job->$_} qw/device port extra/; | ||||
|     return ('error', 'Missing device (-d).') if !defined $device; | ||||
|  | ||||
|     $port = ($port ? 1 : 0); | ||||
|     delete_device($device, $port, $extra); | ||||
|     return ('done', sprintf "Deleted device %s.", $device->ip); | ||||
|   } | ||||
|  | ||||
|   sub renumber { | ||||
|     my ($self, $job) = @_; | ||||
|     my ($device, $port, $extra) = map {$job->$_} qw/device port extra/; | ||||
|     return ('error', 'Missing device (-d).') if !defined $device; | ||||
|     my $old_ip = $device->ip; | ||||
|  | ||||
|     my $new_ip = NetAddr::IP->new($extra); | ||||
|     unless ($new_ip and $new_ip->addr ne '0.0.0.0') { | ||||
|         return ('error', "Bad host or IP: ".($extra || '0.0.0.0')); | ||||
|     } | ||||
|  | ||||
|     my $new_dev = get_device($new_ip->addr); | ||||
|     if ($new_dev and $new_dev->in_storage and ($new_dev->ip ne $device->ip)) { | ||||
|         return ('error', sprintf "Already know new device as: %s.", $new_dev->ip); | ||||
|     } | ||||
|  | ||||
|     renumber_device($device, $new_ip); | ||||
|     return ('done', sprintf 'Renumbered device %s to %s (%s).', | ||||
|       $device->ip, $new_ip, ($device->dns || '')); | ||||
|   } | ||||
|  | ||||
|   sub psql { | ||||
|     my ($self, $job) = @_; | ||||
|     my ($device, $port, $extra) = map {$job->$_} qw/device port extra/; | ||||
|  | ||||
|     my $name = (setting('database')->{name} || 'netdisco'); | ||||
|     my $host = setting('database')->{host}; | ||||
|     my $user = setting('database')->{user}; | ||||
|     my $pass = setting('database')->{pass}; | ||||
|  | ||||
|     my $portnum = undef; | ||||
|     if ($host and $host =~ m/([^;]+);port=(\d+)/) { | ||||
|         $host = $1; | ||||
|         $portnum = $2; | ||||
|     } | ||||
|  | ||||
|     $ENV{PGHOST} = $host if $host; | ||||
|     $ENV{PGPORT} = $portnum if defined $portnum; | ||||
|     $ENV{PGDATABASE} = $name; | ||||
|     $ENV{PGUSER} = $user; | ||||
|     $ENV{PGPASSWORD} = $pass; | ||||
|     $ENV{PGCLIENTENCODING} = 'UTF8'; | ||||
|  | ||||
|     if ($extra) { | ||||
|         system('psql', '-c', $extra); | ||||
|     } | ||||
|     else { | ||||
|         system('psql'); | ||||
|     } | ||||
|     return ('done', "psql session closed."); | ||||
|   } | ||||
| } | ||||
| my $worker = MyWorker->new(); | ||||
|  | ||||
| # belt and braces check before we go ahead | ||||
| if (not $worker->can( $action )) { | ||||
|   pod2usage( | ||||
|     -msg => (sprintf 'error: %s is not a valid action', $action), | ||||
|     -verbose => 2, | ||||
|     -exitval => 3, | ||||
|   ); | ||||
| } | ||||
|  | ||||
| my $net = NetAddr::IP->new($device); | ||||
| if ($device and (!$net or $net->num == 0 or $net->addr eq '0.0.0.0')) { | ||||
|     info sprintf '%s: error - Bad host, IP or prefix: %s', $action, $device; | ||||
|     exit 1; | ||||
| } | ||||
|  | ||||
| my @hostlist = defined $device ? ($net->hostenum) : (undef); | ||||
| my $exitstatus = 0; | ||||
|  | ||||
| foreach my $host (@hostlist) { | ||||
|     my $dev = $host ? get_device($host->addr) : undef; | ||||
|     if ($dev and not (blessed $dev and $dev->in_storage) and $action ne 'discover') { | ||||
|         info sprintf "%s: error - Don't know device: %s", $action, $host->addr; | ||||
|         next; | ||||
|     } | ||||
|  | ||||
|     # what job are we asked to do? | ||||
|     my $job = App::Netdisco::Daemon::Job->new({ | ||||
|       job => 0, | ||||
|       action => $action, | ||||
|       device => $dev, | ||||
|       port   => $port, | ||||
|       subaction => $extra, | ||||
|     }); | ||||
|  | ||||
|     # do job | ||||
|     my ($status, $log); | ||||
|     try { | ||||
|         info sprintf '%s: started at %s', $action, scalar localtime; | ||||
|         ($status, $log) = $worker->$action($job); | ||||
|     } | ||||
|     catch { | ||||
|         $status = 'error'; | ||||
|         $log = "error running job: $_"; | ||||
|     }; | ||||
|  | ||||
|     info sprintf '%s: finished at %s', $action, scalar localtime; | ||||
|     info sprintf '%s: status %s: %s', $action, $status, $log; | ||||
|     $exitstatus = 1 if !defined $status or $status eq 'error'; | ||||
| } | ||||
|  | ||||
| exit $exitstatus; | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| netdisco-do - Run any Netdisco job from the command-line. | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  ~/bin/netdisco-do <action> [-DISQ] [-d <device> [-p <port>] [-e <extra>]] | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| This program allows you to run any Netdisco poller job from the command-line. | ||||
|  | ||||
| The C<-d> option will accept a hostname (that can be resolved to an IP with | ||||
| DNS), an IP address, or IP prefix (subnets in CIDR format). It can be any | ||||
| interface on the device known to Netdisco. | ||||
|  | ||||
| Note that some jobs (C<discoverall>, C<macwalk>, C<arpwalk>, C<nbtwalk>) | ||||
| simply add entries to the Netdisco job queue for other jobs, so won't seem | ||||
| to do much when you trigger them. | ||||
|  | ||||
| =head1 ACTIONS | ||||
|  | ||||
| =head2 discover | ||||
|  | ||||
| Run a discover on the device (specified with C<-d>). | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do discover -d 192.0.2.1 | ||||
|  | ||||
| =head2 discoverall | ||||
|  | ||||
| Run a discover for all known devices. | ||||
|  | ||||
| =head2 macsuck | ||||
|  | ||||
| Run a macsuck on the device (specified with C<-d>). | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do macsuck -d 192.0.2.1 | ||||
|  | ||||
| =head2 macwalk | ||||
|  | ||||
| Run a macsuck for all known devices. | ||||
|  | ||||
| =head2 arpnip | ||||
|  | ||||
| Run an arpnip on the device (specified with C<-d>). | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do arpnip -d 192.0.2.1 | ||||
|  | ||||
| =head2 arpwalk | ||||
|  | ||||
| Run an arpnip for all known devices. | ||||
|  | ||||
| =head2 delete | ||||
|  | ||||
| Delete a device (specified with C<-d>). Pass a log message for the action in | ||||
| the C<-e> parameter. Optionally request for associated nodes to be archived | ||||
| (rather than deleted) by setting the C<-p> parameter to "C<yes>" (mnemonic: | ||||
| B<p>reserve). | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do delete -d 192.0.2.1 | ||||
|  ~netdisco/bin/netdisco-do delete -d 192.0.2.1 -e 'older than the sun' | ||||
|  ~netdisco/bin/netdisco-do delete -d 192.0.2.1 -e 'older than the sun' -p yes | ||||
|  | ||||
| =head2 renumber | ||||
|  | ||||
| Change the canonical IP address of a device (specified with C<-d>). Pass the | ||||
| new IP address in the C<-e> parameter. All related records such as topology, | ||||
| log and node information will also be updated to refer to the new device. | ||||
|  | ||||
| Note that I<no> check is made as to whether the new IP is reachable for future | ||||
| polling. | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do renumber -d 192.0.2.1 -e 192.0.2.254 | ||||
|  | ||||
| =head2 nbtstat | ||||
|  | ||||
| Run an nbtstat on the node (specified with C<-d>). | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do nbtstat -d 192.0.2.2 | ||||
|  | ||||
| =head2 nbtwalk | ||||
|  | ||||
| Run an nbtstat for all known nodes. | ||||
|  | ||||
| =head2 expire | ||||
|  | ||||
| Run Device and Node expiry actions according to configuration. | ||||
|  | ||||
| =head2 expirenodes | ||||
|  | ||||
| Archive nodes on the specified device. If you want to delete nodes, set the | ||||
| C<-e> parameter to "C<no>" (mnemonic: B<e>xpire). If you want to perform the | ||||
| action on a specific port, set the C<-p> parameter. | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do expirenodes -d 192.0.2.1 | ||||
|  ~netdisco/bin/netdisco-do expirenodes -d 192.0.2.1 -p FastEthernet0/1 -e no | ||||
|  | ||||
| =head2 graph | ||||
|  | ||||
| Generate GraphViz graphs for the largest cluster of devices. | ||||
|  | ||||
| You'll need to install the L<Graph::Undirected> and L<GraphViz> Perl modules, | ||||
| and possibly also the C<graphviz> utility for your operating system. Also | ||||
| create a directory for the output files. | ||||
|  | ||||
|  mkdir ~netdisco/graph | ||||
|  ~netdisco/bin/localenv cpanm Graph::Undirected | ||||
|  ~netdisco/bin/localenv cpanm GraphViz | ||||
|  | ||||
| =head2 show | ||||
|  | ||||
| Dump the content of an SNMP MIB leaf, which is useful for diagnostics and | ||||
| troubleshooting. You should provide the "C<-e>" option which is the name of | ||||
| the leaf (such as C<interfaces> or C<uptime>). | ||||
|  | ||||
| If you wish to test with a device class other than that discovered, prefix the | ||||
| leaf with the class short name, for example "C<Layer3::C3550::interfaces>" or | ||||
| "C<Layer2::HP::uptime>". | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do show -d 192.0.2.1 -e interfaces | ||||
|  ~netdisco/bin/netdisco-do show -d 192.0.2.1 -e Layer2::HP::interfaces | ||||
|  | ||||
| =head2 psql | ||||
|  | ||||
| Start an interactive terminal with the Netdisco PostgreSQL database. If you | ||||
| pass an SQL statement in the C<-e> option then it will be executed. | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do psql | ||||
|  ~netdisco/bin/netdisco-do psql -e 'SELECT ip, dns FROM device' | ||||
|  ~netdisco/bin/netdisco-do psql -e 'COPY (SELECT ip, dns FROM device) TO STDOUT WITH CSV HEADER' | ||||
|  | ||||
| =head2 location | ||||
|  | ||||
| Set the SNMP location field on the device (specified with C<-d>). Pass the | ||||
| location string in the C<-e> extra parameter. | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do location -d 192.0.2.1 -e 'wiring closet' | ||||
|  | ||||
| =head2 contact | ||||
|  | ||||
| Set the SNMP contact field on the device (specified with C<-d>). Pass the | ||||
| contact name in the C<-e> extra parameter. | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do contact -d 192.0.2.1 -e 'tel: 555-2453' | ||||
|  | ||||
| =head2 portname | ||||
|  | ||||
| Set the description on a device port. Requires the C<-d> parameter (device), | ||||
| C<-p> parameter (port), and C<-e> parameter (description). | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do portname -d 192.0.2.1 -p FastEthernet0/1 -e 'Web Server' | ||||
|  | ||||
| =head2 portcontrol | ||||
|  | ||||
| Set the up/down status on a device port. Requires the C<-d> parameter | ||||
| (device), C<-p> parameter (port), and C<-e> parameter ("up" or "down"). | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do portcontrol -d 192.0.2.1 -p FastEthernet0/1 -e up | ||||
|  ~netdisco/bin/netdisco-do portcontrol -d 192.0.2.1 -p FastEthernet0/1 -e down | ||||
|  | ||||
| =head2 vlan | ||||
|  | ||||
| Set the native VLAN on a device port. Requires the C<-d> parameter (device), | ||||
| C<-p> parameter (port), and C<-e> parameter (VLAN number). | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do vlan -d 192.0.2.1 -p FastEthernet0/1 -e 102 | ||||
|  | ||||
| =head2 power | ||||
|  | ||||
| Set the PoE on/off status on a device port. Requires the C<-d> parameter | ||||
| (device), C<-p> parameter (port), and C<-e> parameter ("on" or "off"). | ||||
|  | ||||
|  ~netdisco/bin/netdisco-do power -d 192.0.2.1 -p FastEthernet0/1 -e on | ||||
|  ~netdisco/bin/netdisco-do power -d 192.0.2.1 -p FastEthernet0/1 -e off | ||||
|  | ||||
| =head1 DEBUG LEVELS | ||||
|  | ||||
| The flags "C<-DISQ>" can be specified, multiple times, and enable the | ||||
| following items in order: | ||||
|  | ||||
| =over 4 | ||||
|  | ||||
| =item C<-D> | ||||
|  | ||||
| Netdisco debug log level | ||||
|  | ||||
| =item C<-I> or C<-II> | ||||
|  | ||||
| L<SNMP::Info> trace level (1 or 2). | ||||
|  | ||||
| =item C<-S> or C<-SS> or C<-SSS> | ||||
|  | ||||
| L<SNMP> (net-snmp) trace level (1, 2 or 3). | ||||
|  | ||||
| =item C<-Q> | ||||
|  | ||||
| L<DBIx::Class> trace enabled | ||||
|  | ||||
| =back | ||||
|  | ||||
| =cut | ||||
		Reference in New Issue
	
	Block a user